CMake incapable de déterminer le langage de l'éditeur de liens avec C ++

89

J'essaie d'exécuter un programme cmake hello world sur Windows 7 x64 avec Visual Studio 2010 et Cygwin, mais je n'arrive pas à faire fonctionner l'un ou l'autre. Ma structure de répertoires est la suivante:

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

Je fais un cd buildsuivi d'un cmake .., et j'obtiens une erreur indiquant que

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

Cependant, si je change l'extension de main.cpp en main.c à la fois sur mon filsystem et dans src/CMakeLists.txttout fonctionne comme prévu. C'est le cas à partir de l'invite de commande Visual Studio (Visual Studio Solution Generator) et du terminal Cygwin (Unix Makefiles Generator).

Une idée pourquoi ce code ne fonctionnerait pas?

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
la source
"[...] si je change l'extension de main.cpp [...]" En quoi le changez-vous? .cc?
JAB
Oups. Laissé cela par accident. Je le change en «.c». Modifié dans le message d'origine. Cela me fait presque penser qu'il n'y a pas de compilateur cpp ou quelque chose de ce genre, mais g ++ est installé et Visual Studio ne devrait pas non plus avoir de problèmes avec C ++.
Chris Covert

Réponses:

182

J'ai aussi l'erreur que vous mentionnez:

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

Dans mon cas, cela était dû au fait d'avoir des fichiers C ++ avec l' .ccextension.

Si CMake est incapable de déterminer correctement la langue du code, vous pouvez utiliser ce qui suit:

set_target_properties(hello PROPERTIES LINKER_LANGUAGE CXX)

La réponse acceptée qui suggère d'ajouter la langue à l' project()instruction ajoute simplement une vérification plus stricte de la langue utilisée (selon la documentation), mais cela ne m'a pas été utile:

Vous pouvez éventuellement spécifier les langues prises en charge par votre projet. Des exemples de langages sont CXX (ie C ++), C, Fortran, etc. Par défaut, C et CXX sont activés. Par exemple, si vous n'avez pas de compilateur C ++, vous pouvez désactiver la vérification de celui-ci en listant explicitement les langues que vous souhaitez prendre en charge, par exemple C. En utilisant le langage spécial "NONE", toutes les vérifications pour n'importe quelle langue peuvent être désactivées. S'il existe une variable appelée CMAKE_PROJECT__INCLUDE_FILE, le fichier pointé par cette variable sera inclus comme dernière étape de la commande de projet.

Joakim
la source
Dans mon cas, mon fichier avait une extension .hpp. Cela l'a résolu!
brawner
Même chose pour moi, fichier .hpp et cela l'a corrigé.
KulaGGin
68

Dans mon cas, c'était simplement parce qu'il n'y avait pas de fichier source dans la cible. Toute ma bibliothèque était un modèle avec le code source dans l'en-tête. L'ajout d'un fichier.cpp vide a résolu le problème.

Moebius
la source
6
définir les propriétés de la cible fonctionne également pour le problème de fichier cpp.
Denise Skidmore le
1
Félicitations pour la pointe. J'ai également oublié de déplacer mes sources dans le srcsous-répertoire respectif de mon cmakeprojet nouvellement créé (une bibliothèque partagée) et c'était essentiellement la cause de tout le problème. Dans de tels cas, on apprécie vraiment d'avoir un assistant pour s'occuper de la structure de votre cmakeprojet. : D
rbaleksandar
Même raison ici (erreur de copier-coller). Merci!
Vivit
2
Conseil utile. Même si votre "bibliothèque" est uniquement un en-tête, vous devez créer un fichier .cpp qui effectue un #includepour chaque fichier. Même s'il n'y aura pas de sortie lorsque votre bibliothèque sera compilée, elle vérifiera la syntaxe de votre fichier et vérifiera également les dépendances d'en-tête (par exemple les en-têtes système) que vous avez peut-être manquées.
Mark Lakata
C'est aussi simple que ça. Une faute de frappe dans le chemin ne mène à aucun fichier * .cpp dans les sources. Tout va bien après ça. Merci!
Rahul Das le
17

Aussi déroutant que cela puisse être, l'erreur se produit également lorsqu'un fichier cpp inclus dans le projet n'existe pas.

Si vous répertoriez vos fichiers source dans CMakeLists.txt et tapez un nom de fichier par erreur, vous obtenez cette erreur.

Jolly Roger
la source
Veuillez faire ceci comme dans la section des commentaires.
Virb
1
Cela fonctionne comme sa propre réponse car elle est indépendante de ce que les autres réponses ont dit. Cela a également résolu mon problème.
Czarking le
5

Une réponse un peu sans rapport avec OP mais pour des gens comme moi avec un problème un peu similaire.

Cas d'utilisation: Ubuntu (C, Clion, Auto-complétion):

J'ai eu la même erreur,

Erreur CMake: impossible de déterminer la langue du lien pour la cible "bonjour".

set_target_properties(hello PROPERTIES LINKER_LANGUAGE C) l'aide corrige ce problème mais les en-têtes ne sont pas inclus dans le projet et l'auto-complétion ne fonctionnera pas.

C'est ce que j'avais

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)

Aucune erreur mais pas ce dont j'avais besoin, j'ai réalisé que l'inclusion d'un seul fichier comme source m'obtiendrait une saisie semi-automatique et définira l'éditeur de liens sur 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})
Fi
la source
Je viens de remarquer que vous utilisez CXX_FLAGS pour définir la version standard C ++, et j'ai pensé mentionner la variable CXX_STANDARD, ce qui, je pense, est la méthode recommandée cmake.org/cmake/help/latest/prop_tgt/CXX_STANDARD.html et devrait être disponible en cmake 3.5
Chris Covert
2

J'ai également rencontré une erreur similaire lors de la compilation de mon code basé sur C. J'ai résolu le problème en corrigeant le chemin du fichier source dans mon cmakefichier. Veuillez vérifier le chemin du fichier source de chaque fichier source mentionné dans votre cmakefichier. Cela pourrait aussi vous aider.

user2999709
la source
0

Par défaut, le dossier JNI Native est nommé jni . Le renommer en cpp a résolu le problème

HimalayanCoder
la source
0

Je souhaite ajouter une autre solution au cas où une bibliothèque sans aucun fichier source serait créée. Ces bibliothèques sont également appelées bibliothèques d' en- tête uniquement . Par défaut, add_libraryattend au moins un fichier source ajouté ou sinon l'erreur mentionnée se produit. Puisque les bibliothèques d'en-tête uniquement sont assez courantes, cmake a le INTERFACEmot - clé pour construire de telles bibliothèques. Le INTERFACEmot-clé est utilisé comme indiqué ci-dessous et élimine le besoin d'ajouter des fichiers source vides à la bibliothèque.

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

L'exemple ci-dessus créerait une bibliothèque d'en-tête uniquement comprenant tous les fichiers d'en-tête dans le même répertoire que CMakeLists.txt. Remplacez-le {CMAKE_CURRENT_SOURCE_DIR}par un chemin au cas où vos fichiers d'en-tête se trouveraient dans un répertoire différent du fichier CMakeLists.txt.

Jetez un œil à ce billet de blog ou à la documentation cmake pour plus d'informations sur les bibliothèques d'en-tête uniquement et cmake.

zhm
la source
-2

J'ai réussi à résoudre le mien, en changeant

add_executable(file1.cpp)

à

add_executable(ProjectName file1.cpp)
AKJ
la source
-2

Dans mon cas, l'implémentation d'une fonction membre d'une classe dans un fichier d'en-tête provoque cette erreur. La séparation de l'interface (dans le fichier xh) et de l'implémentation (dans le fichier x.cpp) résout le problème.

adembudak
la source