CMake non è in grado di determinare il linguaggio del linker con C ++


91

Sto tentando di eseguire un programma cmake hello world su Windows 7 x64 con Visual Studio 2010 e Cygwin, ma non riesco a far funzionare nessuno dei due. La mia struttura di directory è la seguente:

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

Faccio cd buildseguito da a cmake ..e ottengo un errore che lo indica

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

Tuttavia, se cambio l'estensione di main.cpp in main.c sia sul mio file system che in src/CMakeLists.txttutto funziona come previsto. Questo è il caso in esecuzione sia dal prompt dei comandi di Visual Studio (Visual Studio Solution Generator) che dal terminale Cygwin (Unix Makefiles Generator).

Qualche idea sul perché questo codice non funzionerebbe?

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;
}

"[...] se cambio l'estensione di main.cpp [...]" In cosa la modifichi? .cc?
JAB

oops. L'ho lasciato fuori per caso. Lo cambio in ".c". Modificato nel post originale. Mi fa quasi pensare che non ci sia un compilatore cpp o qualcosa del genere, ma g ++ è installato e lo studio visivo non dovrebbe avere problemi con c ++.
Chris Covert

Risposte:



185

Ho anche ricevuto l'errore che hai menzionato:

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

Nel mio caso ciò era dovuto al fatto di avere file C ++ con .ccestensione.

Se CMake non è in grado di determinare correttamente la lingua del codice, puoi utilizzare quanto segue:

set_target_properties(hello PROPERTIES LINKER_LANGUAGE CXX)

La risposta accettata che suggerisce di aggiungere la lingua al file project() dichiarazione aggiunge semplicemente un controllo più rigoroso per quale lingua viene utilizzata (secondo la documentazione), ma non è stato utile per me:

Facoltativamente puoi specificare quali lingue supporta il tuo progetto. I linguaggi di esempio sono CXX (cioè C ++), C, Fortran, ecc. Per impostazione predefinita, C e CXX sono abilitati. Ad esempio, se non si dispone di un compilatore C ++, è possibile disabilitarne il controllo elencando esplicitamente le lingue che si desidera supportare, ad esempio C. Utilizzando il linguaggio speciale "NONE" è possibile disabilitare tutti i controlli per qualsiasi lingua. Se esiste una variabile chiamata CMAKE_PROJECT__INCLUDE_FILE, il file a cui punta quella variabile verrà incluso come ultimo passaggio del comando del progetto.


Nel mio caso, il mio file aveva un'estensione .hpp. Questo l'ha risolto!
brawner

Lo stesso per me, file .hpp e questo lo ha risolto.
KulaGGin

71

Nel mio caso, era solo perché non c'erano file di origine nella destinazione. Tutta la mia libreria era un modello con il codice sorgente nell'intestazione. L'aggiunta di un file.cpp vuoto ha risolto il problema.


6
impostare le proprietà di destinazione funziona anche per il problema del file no cpp.
Denise Skidmore

1
Complimenti per la punta. Ho anche dimenticato di spostare i miei sorgenti nella rispettiva srcsottodirectory del mio cmakeprogetto appena creato (una libreria condivisa) e questa era fondamentalmente la causa dell'intero problema. In questi casi si apprezza davvero avere una procedura guidata che si prenda cura della struttura del cmakeprogetto. : D
rbaleksandar

Stessa ragione qui (errore di copia-incolla). Grazie!
Vivit

2
Consiglio utile. Anche se la tua "libreria" è solo un'intestazione, dovresti creare un file .cpp che faccia una #includeper ogni file. Anche se non ci sarà alcun output quando la libreria viene compilata, eseguirà il controllo della sintassi del file e controllerà anche le dipendenze dell'intestazione (ad esempio le intestazioni di sistema) che potresti aver perso.
Mark Lakata

È così semplice. Un errore di battitura nel percorso non porta a nessun file * .cpp nei sorgenti. Tutto bene dopo. Grazie!
Rahul Das

17

Per quanto possa essere confuso, l'errore si verifica anche quando un file cpp incluso nel progetto non esiste.

Se elenchi i file di origine in CMakeLists.txt e digiti per errore un nome file, viene visualizzato questo errore.


Si prega di farlo come nella sezione commenti.
Virb

1
Funziona come una propria risposta in quanto è indipendente da ciò che hanno detto le altre risposte. Anche questo ha risolto il mio problema.
Czarking

5

Risposta un po 'non correlata a OP ma per persone come me con un problema in qualche modo simile.

Caso d'uso: Ubuntu (C, Clion, completamento automatico):

Ho avuto lo stesso errore

Errore CMake: impossibile determinare la lingua del collegamento per "ciao" di destinazione.

set_target_properties(hello PROPERTIES LINKER_LANGUAGE C) help risolve il problema ma le intestazioni non sono incluse nel progetto e il completamento automatico non funzionerà.

Questo è quello che avevo

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)

Nessun errore ma non quello di cui avevo bisogno, mi sono reso conto che includere un singolo file come sorgente mi porterà al completamento automatico e imposterà il linker su 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})

Ho appena notato che stai usando CXX_FLAGS per impostare la versione standard C ++ e ho pensato di menzionare la variabile CXX_STANDARD, che penso sia il modo consigliato cmake.org/cmake/help/latest/prop_tgt/CXX_STANDARD.html e dovrebbe essere disponibile in cmake 3.5
Chris Covert

2

Ho anche riscontrato un errore simile durante la compilazione del mio codice basato su C. Ho risolto il problema correggendo il percorso del file di origine nel mio cmakefile. Controlla il percorso del file di origine di ogni file di origine menzionato nel tuo cmakefile. Questo potrebbe aiutare anche te.


1

Voglio aggiungere un'altra soluzione nel caso in cui venga creata una libreria senza file sorgente. Tali librerie sono note anche come librerie di sola intestazione . Per impostazione predefinita si add_libraryaspetta che venga aggiunto almeno un file sorgente o altrimenti si verifica l'errore menzionato. Poiché le librerie di sola intestazione sono abbastanza comuni, cmake ha la INTERFACEparola chiave per costruire tali librerie. La INTERFACEparola chiave viene utilizzata come mostrato di seguito ed elimina la necessità di aggiungere file di origine vuoti alla libreria.

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

L'esempio precedente creerebbe una libreria di sola intestazione includendo tutti i file di intestazione nella stessa directory di CMakeLists.txt. Sostituisci {CMAKE_CURRENT_SOURCE_DIR}con un percorso nel caso in cui i tuoi file di intestazione si trovino in una directory diversa dal file CMakeLists.txt.

Dai un'occhiata a questo post del blog o alla documentazione di cmake per ulteriori informazioni sulle librerie di sola intestazione e cmake.


0

Per impostazione predefinita, la cartella JNI Native è denominata jni . Rinominarlo in cpp ha risolto il problema


-2

Sono riuscito a risolvere il mio, cambiando

add_executable(file1.cpp)

per

add_executable(ProjectName file1.cpp)

-2

Nel mio caso, l'implementazione di una funzione membro di una classe in un file di intestazione causa questo errore. Separare l'interfaccia (nel file xh) e l'implementazione (nel file x.cpp) risolve il problema.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.