CMake kann die Linkersprache mit C ++ nicht bestimmen

89

Ich versuche, ein cmake hello world-Programm unter Windows 7 x64 mit Visual Studio 2010 und Cygwin auszuführen, kann aber anscheinend auch nicht funktionieren. Meine Verzeichnisstruktur ist wie folgt:

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

Ich mache ein cd buildgefolgt von einem cmake ..und bekomme eine Fehlermeldung, die das besagt

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

Wenn ich jedoch die Erweiterung von main.cpp in main.c ändere, funktioniert sowohl auf meinem Dateisystem als auch in src/CMakeLists.txtallem wie erwartet. Dies ist der Fall, der sowohl über die Visual Studio-Eingabeaufforderung (Visual Studio Solution Generator) als auch über das Cygwin-Terminal (Unix Makefiles Generator) ausgeführt wird.

Irgendeine Idee, warum dieser Code nicht funktionieren würde?

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
quelle
"[...] wenn ich die Erweiterung von main.cpp ändere [...]" In was ändern Sie sie? .cc?
JAB
Hoppla. Das aus Versehen weggelassen. Ich ändere es in '.c'. Im Originalbeitrag bearbeitet. Es lässt mich fast denken, dass es keinen cpp-Compiler oder ähnliches gibt, aber g ++ ist installiert und Visual Studio sollte auch keine Probleme mit c ++ haben.
Chris Covert

Antworten:

182

Ich habe auch den Fehler bekommen, den Sie erwähnen:

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

In meinem Fall lag dies daran, dass C ++ - Dateien mit der .ccErweiterung vorhanden waren.

Wenn CMake die Sprache des Codes nicht korrekt bestimmen kann, können Sie Folgendes verwenden:

set_target_properties(hello PROPERTIES LINKER_LANGUAGE CXX)

Die akzeptierte Antwort, die vorschlägt, die Sprache an die project()Anweisung anzuhängen, fügt lediglich eine strengere Überprüfung der verwendeten Sprache hinzu (gemäß der Dokumentation), war jedoch für mich nicht hilfreich:

Optional können Sie angeben, welche Sprachen Ihr Projekt unterstützt. Beispielsprachen sind CXX (dh C ++), C, Fortran usw. Standardmäßig sind C und CXX aktiviert. Wenn Sie beispielsweise keinen C ++ - Compiler haben, können Sie die Prüfung deaktivieren, indem Sie explizit die Sprachen auflisten, die Sie unterstützen möchten, z. B. C. Mit der speziellen Sprache "NONE" können alle Prüfungen für jede Sprache deaktiviert werden. Wenn eine Variable mit dem Namen CMAKE_PROJECT__INCLUDE_FILE vorhanden ist, wird die Datei, auf die diese Variable verweist, als letzter Schritt des Projektbefehls aufgenommen.

Joakim
quelle
In meinem Fall hatte meine Datei die Erweiterung .hpp. Dies löste es!
Brawner
Das gleiche gilt für mich, .hpp-Datei und das hat es behoben.
KulaGGin
68

In meinem Fall lag es nur daran, dass das Ziel keine Quelldatei enthielt. Meine gesamte Bibliothek bestand aus einer Vorlage mit Quellcode im Header. Das Hinzufügen einer leeren Datei.cpp löste das Problem.

Möbius
quelle
6
Das Festlegen von Zieleigenschaften funktioniert auch für das Problem ohne CPP-Datei.
Denise Skidmore
1
Ein großes Lob für den Tipp. Ich habe auch vergessen, meine Quellen in das jeweilige srcUnterverzeichnis meines neu erstellten cmakeProjekts (eine gemeinsam genutzte Bibliothek) zu verschieben, und dies war im Grunde die Ursache für das gesamte Problem. In solchen Fällen weiß man es wirklich zu schätzen, einen Assistenten zu haben, der sich um die Struktur Ihres cmakeProjekts kümmert . : D
rbaleksandar
Gleicher Grund hier (Copy-Paste-Fehler). Vielen Dank!
Vivit
2
Nützlicher Tipp. Selbst wenn Ihre "Bibliothek" nur ein Header ist, sollten Sie eine CPP-Datei erstellen, die #includefür jede Datei eine. Auch wenn beim Kompilieren Ihrer Bibliothek keine Ausgabe erfolgt, wird die Syntax Ihrer Datei überprüft und es werden auch Headerabhängigkeiten (z. B. Systemheader) überprüft, die Sie möglicherweise übersehen haben.
Mark Lakata
So einfach ist das. Tippfehler im Pfad führen zu keinen * .cpp-Dateien in den Quellen. Danach alles in Ordnung. Vielen Dank!
Rahul Das
17

So verwirrend es auch sein mag, der Fehler tritt auch auf, wenn eine im Projekt enthaltene CPP-Datei nicht vorhanden ist.

Wenn Sie Ihre Quelldateien in CMakeLists.txt auflisten und versehentlich einen Dateinamen eingeben, wird dieser Fehler angezeigt.

Piratenflagge
quelle
Bitte machen Sie dies wie im Kommentarbereich.
Virb
1
Dies funktioniert als eigene Antwort, da es unabhängig von den anderen Antworten ist. Auch dies hat mein Problem behoben.
Czarking
4

Eine etwas unabhängige Antwort auf OP, aber für Leute wie mich mit einem etwas ähnlichen Problem.

Anwendungsfall: Ubuntu (C, Clion, automatische Vervollständigung):

Ich hatte den gleichen Fehler,

CMake-Fehler: Linksprache für Ziel "Hallo" kann nicht ermittelt werden.

set_target_properties(hello PROPERTIES LINKER_LANGUAGE C) Hilfe behebt dieses Problem, aber die Header sind nicht im Projekt enthalten und die automatische Vervollständigung funktioniert nicht.

Das hatte ich

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)

Keine Fehler, aber nicht das, was ich brauchte. Ich erkannte, dass das Einfügen einer einzelnen Datei als Quelle mir die automatische Vervollständigung ermöglicht und den Linker auf setzt 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
quelle
Ich habe gerade bemerkt, dass Sie CXX_FLAGS verwenden, um die C ++ - Standardversion festzulegen, und dachte, ich würde die Variable CXX_STANDARD erwähnen, die meiner Meinung nach die empfohlene Methode ist, die cmake.org/cmake/help/latest/prop_tgt/CXX_STANDARD.html empfiehlt und sein sollte verfügbar in cmake 3.5
Chris Covert
2

Beim Kompilieren meines C-basierten Codes trat auch ein ähnlicher Fehler auf. Ich habe das Problem behoben, indem ich den Quelldateipfad in meiner cmakeDatei korrigiert habe . Bitte überprüfen Sie den Quelldateipfad jeder in Ihrer cmakeDatei genannten Quelldatei . Dies könnte Ihnen auch helfen.

user2999709
quelle
0

Standardmäßig heißt der native JNI-Ordner jni . Das Umbenennen in cpp hat das Problem behoben

HimalayanCoder
quelle
0

Ich möchte eine weitere Lösung hinzufügen, falls eine Bibliothek ohne Quelldateien erstellt werden soll. Solche Bibliotheken werden auch als reine Header- Bibliotheken bezeichnet. Standardmäßig wird add_librarymindestens eine hinzugefügte Quelldatei erwartet, andernfalls tritt der erwähnte Fehler auf. Da nur Header-Bibliotheken weit verbreitet sind, hat cmake das INTERFACESchlüsselwort, um solche Bibliotheken zu erstellen. Das INTERFACESchlüsselwort wird wie unten gezeigt verwendet und macht leere Quelldateien, die der Bibliothek hinzugefügt werden, überflüssig.

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

Im obigen Beispiel wird eine Nur-Header-Bibliothek erstellt, die alle Header-Dateien im selben Verzeichnis wie die Datei CMakeLists.txt enthält. Ersetzen Sie ihn {CMAKE_CURRENT_SOURCE_DIR}durch einen Pfad, falls sich Ihre Header-Dateien in einem anderen Verzeichnis als die Datei CMakeLists.txt befinden.

Weitere Informationen zu Nur-Header-Bibliotheken und cmake finden Sie in diesem Blog-Beitrag oder in der cmake-Dokumentation .

zhm
quelle
-2

Ich habe es geschafft, meine zu lösen, indem ich mich verändert habe

add_executable(file1.cpp)

zu

add_executable(ProjectName file1.cpp)
AKJ
quelle
-2

In meinem Fall verursacht die Implementierung einer Member-Funktion einer Klasse in einer Header-Datei diesen Fehler. Die Trennung von Schnittstelle (in xh-Datei) und Implementierung (in x.cpp-Datei) löst das Problem.

adembudak
quelle