CMake no puede determinar el lenguaje del enlazador con C ++

89

Estoy intentando ejecutar un programa cmake hello world en Windows 7 x64 con Visual Studio 2010 y Cygwin, pero parece que ninguno de los dos funciona. Mi estructura de directorio es la siguiente:

HelloWorld
-- CMakeLists.txt
-- src/
-- -- CMakeLists.txt
-- -- main.cpp
-- build/

Hago una cd buildseguida de una cmake .., y obtengo un error que indica que

CMake Error: CMake can not determine linker language for target:helloworld
CMake Error: Cannot determine link language for target "helloworld".

Sin embargo, si cambio la extensión de main.cpp a main.c tanto en mi sistema de archivos como en src/CMakeLists.txttodo, funciona como se esperaba. Este es el caso que se ejecuta tanto desde Visual Studio Command Prompt (Visual Studio Solution Generator) como desde Cygwin Terminal (Unix Makefiles Generator).

¿Alguna idea de por qué este código no funcionaría?

CMakeLists.txt

PROJECT(HelloWorld C)
cmake_minimum_required(VERSION 2.8)

# include the cmake modules directory
set(CMAKE_MODULE_PATH ${HelloWorld_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH})

add_subdirectory(src)

src / CMakeLists.txt

# Include the directory itself as a path to include directories
set(CMAKE_INCLUDE_CURRENT_DIR ON)

# Create a variable called helloworld_SOURCES containing all .cpp files:
set(HelloWorld_SOURCES main.cpp)

# Create an executable file called helloworld from sources:
add_executable(hello ${HelloWorld_SOURCES })

src / main.cpp

int main()
{
  return 0;
}
Chris Covert
fuente
"[...] si cambio la extensión de main.cpp [...]" ¿A qué lo cambia? .cc?
JAB
Ups. Dejé eso por accidente. Lo cambio a '.c'. Editado en la publicación original. Casi me hace pensar que no hay un compilador cpp o algo por el estilo, pero g ++ está instalado y Visual Studio tampoco debería tener problemas con C ++.
Chris Covert

Respuestas:

182

También recibí el error que mencionas:

CMake Error: CMake can not determine linker language for target:helloworld
CMake Error: Cannot determine link language for target "helloworld".

En mi caso, esto se debió a tener archivos C ++ con la .ccextensión.

Si CMake no puede determinar el idioma del código correctamente, puede utilizar lo siguiente:

set_target_properties(hello PROPERTIES LINKER_LANGUAGE CXX)

La respuesta aceptada que sugiere agregar el idioma a la project()declaración simplemente agrega una verificación más estricta del idioma que se usa (de acuerdo con la documentación), pero no fue útil para mí:

Opcionalmente, puede especificar qué idiomas admite su proyecto. Los lenguajes de ejemplo son CXX (es decir, C ++), C, Fortran, etc. Por defecto, C y CXX están habilitados. Por ejemplo, si no tiene un compilador de C ++, puede deshabilitar la verificación enumerando explícitamente los idiomas que desea admitir, p. Ej. C. Al usar el lenguaje especial "NONE", todas las verificaciones para cualquier idioma pueden deshabilitarse. Si existe una variable llamada CMAKE_PROJECT__INCLUDE_FILE, el archivo al que apunta esa variable se incluirá como último paso del comando del proyecto.

Joakim
fuente
En mi caso, mi archivo tenía una extensión .hpp. ¡Esto lo resolvió!
brawner
Lo mismo para mí, archivo .hpp y esto lo solucionó.
KulaGGin
68

En mi caso, fue solo porque no había ningún archivo fuente en el destino. Toda mi biblioteca era una plantilla con código fuente en el encabezado. Agregar un archivo.cpp vacío resolvió el problema.

Moebius
fuente
6
establecer propiedades de destino también funciona para el problema del archivo sin cpp.
Denise Skidmore
1
Felicitaciones por la propina. También olvidé mover mis fuentes al srcsubdirectorio respectivo de mi cmakeproyecto recién creado (una biblioteca compartida) y esta fue básicamente la causa de todo el problema. En tales casos, uno realmente aprecia tener un asistente que se encargue de la estructura de su cmakeproyecto. : D
rbaleksandar
La misma razón aquí (error de copiar y pegar). ¡Gracias!
Vivit
2
Consejo útil. Incluso si su "biblioteca" es solo de encabezado, debe crear un archivo .cpp que haga una #includepara cada archivo. Aunque no habrá salida cuando se compile su biblioteca, comprobará la sintaxis de su archivo y también comprobará las dependencias del encabezado (por ejemplo, los encabezados del sistema) que puede haber pasado por alto.
Mark Lakata
Es tan simple como eso. Un error tipográfico en la ruta no genera archivos * .cpp en las fuentes. Todo bien después de eso. ¡Gracias!
Rahul Das
17

Por confuso que pueda ser, el error también ocurre cuando un archivo cpp incluido en el proyecto no existe.

Si enumera sus archivos de origen en CMakeLists.txt y escribe por error un nombre de archivo, obtendrá este error.

bandera pirata
fuente
Haga esto como en la sección de comentarios.
Virb
1
Esto funciona como su propia respuesta, ya que es independiente de lo que dijeron las otras respuestas. También esto solucionó mi problema.
Zarking
5

Una respuesta un poco no relacionada con OP pero para personas como yo con un problema algo similar.

Caso de uso: Ubuntu (C, Clion, Autocompletar):

Yo tenía el mismo error,

Error de CMake: No se puede determinar el idioma del enlace para el objetivo "hola".

set_target_properties(hello PROPERTIES LINKER_LANGUAGE C) ayuda a solucionar ese problema, pero los encabezados no están incluidos en el proyecto y el autocompletado no funcionará.

Esto es lo que tuve

cmake_minimum_required(VERSION 3.5)

project(hello)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")

set(SOURCE_FILES ./)

add_executable(hello ${SOURCE_FILES})

set_target_properties(hello PROPERTIES LINKER_LANGUAGE C)

No hay errores, pero no lo que necesitaba, me di cuenta de que incluir un solo archivo como fuente me permitirá completar automáticamente y establecerá el vinculador en C.

cmake_minimum_required(VERSION 3.5)

project(hello)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")

set(SOURCE_FILES ./1_helloworld.c)

add_executable(hello ${SOURCE_FILES})
f_i
fuente
Acabo de notar que está usando CXX_FLAGS para configurar la versión estándar de C ++, y pensé en mencionar la variable CXX_STANDARD, que creo que es la forma recomendada de cmake.org/cmake/help/latest/prop_tgt/CXX_STANDARD.html y debería ser disponible en cmake 3.5
Chris Covert
2

También enfrenté un error similar al compilar mi código basado en C. Solucioné el problema corrigiendo la ruta del archivo de origen en mi cmakearchivo. Compruebe la ruta del archivo de origen de cada archivo de origen mencionado en su cmakearchivo. Esto también podría ayudarte.

usuario2999709
fuente
0

De forma predeterminada, la carpeta nativa de JNI se denomina jni . Cambiar el nombre a cpp solucionó el problema

Codificador del Himalaya
fuente
0

Quiero agregar otra solución en caso de que se construya una biblioteca sin archivos fuente. Estas bibliotecas también se conocen como bibliotecas de encabezado . De forma predeterminada, se add_libraryespera que se agregue al menos un archivo fuente o, de lo contrario, se produce el error mencionado. Dado que las bibliotecas de encabezado son bastante comunes, cmake tiene la INTERFACEpalabra clave para construir dichas bibliotecas. La INTERFACEpalabra clave se usa como se muestra a continuación y elimina la necesidad de agregar archivos fuente vacíos a la biblioteca.

add_library(myLibrary INTERFACE)
target_include_directories(myLibrary INTERFACE {CMAKE_CURRENT_SOURCE_DIR})

El ejemplo anterior crearía una biblioteca de solo encabezado que incluye todos los archivos de encabezado en el mismo directorio que CMakeLists.txt. Reemplazar{CMAKE_CURRENT_SOURCE_DIR} con una ruta en caso de que sus archivos de encabezado estén en un directorio diferente al archivo CMakeLists.txt.

Eche un vistazo a esta publicación de blog o la documentación de cmake para obtener más información sobre las bibliotecas de solo encabezado y cmake.

zhm
fuente
-2

Logré solucionar el mío, cambiando

add_executable(file1.cpp)

a

add_executable(ProjectName file1.cpp)
AKJ
fuente
-2

En mi caso, implementar una función miembro de una clase en un archivo de encabezado causa este error. Separar la interfaz (en el archivo xh) y la implementación (en el archivo x.cpp) resuelve el problema.

adembudak
fuente