CMake nie może określić języka konsolidatora w C ++

89

Próbuję uruchomić program cmake hello world na Windows 7 x64 z Visual Studio 2010 i Cygwin, ale nie wydaje mi się, aby działał. Moja struktura katalogów jest następująca:

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

Robię a, cd builda po nim a cmake ..i otrzymuję błąd z informacją, że

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

Jeśli jednak zmienię rozszerzenie main.cpp na main.c zarówno w moim systemie plików, jak i we src/CMakeLists.txtwszystkim działa zgodnie z oczekiwaniami. Dzieje się tak w przypadku uruchamiania zarówno z wiersza polecenia programu Visual Studio (Generator rozwiązań programu Visual Studio), jak i terminala Cygwin (generator Unix Makefiles).

Masz jakiś pomysł, dlaczego ten kod nie zadział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
źródło
„[…] jeśli zmienię rozszerzenie main.cpp […]” Na co to zmienisz? .cc?
JAB
ups. Pominąłem to przez przypadek. Zmieniam to na „.c”. Zredagowano w oryginalnym poście. Prawie sprawia, że ​​myślę, że nie ma kompilatora cpp ani czegoś w tym rodzaju, ale g ++ jest wbudowany i Visual Studio nie powinno mieć problemów z c ++.
Chris Covert,

Odpowiedzi:

182

Otrzymałem również błąd, o którym wspomniałeś

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

W moim przypadku było to spowodowane posiadaniem plików C ++ z .ccrozszerzeniem.

Jeśli CMake nie może poprawnie określić języka kodu, możesz skorzystać z:

set_target_properties(hello PROPERTIES LINKER_LANGUAGE CXX)

Przyjęta odpowiedź sugerująca dołączenie języka do project()stwierdzenia po prostu dodaje bardziej rygorystyczne sprawdzanie używanego języka (zgodnie z dokumentacją), ale nie było to dla mnie pomocne:

Opcjonalnie możesz określić, które języki obsługuje Twój projekt. Przykładowe języki to CXX (tj. C ++), C, Fortran itp. Domyślnie C i CXX są włączone. Np. Jeśli nie masz kompilatora C ++, możesz wyłączyć sprawdzanie tego, jawnie wymieniając języki, które chcesz obsługiwać, np. C. Używając specjalnego języka „NONE”, można wyłączyć wszystkie sprawdzanie dowolnego języka. Jeśli istnieje zmienna o nazwie CMAKE_PROJECT__INCLUDE_FILE, plik wskazywany przez tę zmienną zostanie dołączony jako ostatni krok polecenia projektu.

Joakim
źródło
W moim przypadku mój plik miał rozszerzenie .hpp. To rozwiązało problem!
brawner
Dla mnie to samo, plik .hpp i to naprawiło.
KulaGGin
68

W moim przypadku było to tylko dlatego, że w miejscu docelowym nie było pliku źródłowego. Cała moja biblioteka była szablonem z kodem źródłowym w nagłówku. Dodanie pustego pliku.cpp rozwiązało problem.

Moebius
źródło
6
ustawianie właściwości docelowych działa również w przypadku problemu z plikiem cpp.
Denise Skidmore
1
Uznanie za napiwek. Zapomniałem też przenieść swoje źródła do odpowiedniego srcpodkatalogu mojego nowo utworzonego cmakeprojektu (współdzielonej biblioteki) i to było w zasadzie przyczyną całego problemu. W takich przypadkach naprawdę warto mieć kreatora, który zajmie się strukturą cmakeprojektu. : D
rbaleksandar
Z tego samego powodu (błąd kopiowania i wklejania). Dzięki!
Vivit
2
Przydatna wskazówka. Nawet jeśli twoja „biblioteka” jest tylko nagłówkiem, powinieneś utworzyć jeden plik .cpp, który będzie zawierał jeden #includedla każdego pliku. Mimo że po kompilacji biblioteki nie będzie żadnych danych wyjściowych, sprawdzi składnię pliku, a także sprawdzi zależności nagłówków (na przykład nagłówki systemowe), które mogły zostać pominięte.
Mark Lakata,
To takie proste. Literówka w ścieżce prowadzi do braku plików * .cpp w źródłach. Po tym wszystko w porządku. Dziękuję Ci!
Rahul Das
17

Choć może to być mylące, błąd występuje również, gdy plik cpp zawarty w projekcie nie istnieje.

Jeśli wymienisz pliki źródłowe w CMakeLists.txt i omyłkowo wpiszesz nazwę pliku, pojawi się ten błąd.

Jolly Roger
źródło
Zrób to jak w sekcji komentarzy.
Virb
1
To działa jako własna odpowiedź, ponieważ jest niezależne od tego, co powiedziały inne odpowiedzi. To również rozwiązało mój problem.
Czarking
5

Trochę niepowiązana odpowiedź na OP, ale dla ludzi takich jak ja z nieco podobnym problemem.

Przykład zastosowania: Ubuntu (C, Clion, automatyczne uzupełnianie):

Miałem ten sam błąd,

Błąd CMake: nie można określić języka linku dla docelowego „hello”.

set_target_properties(hello PROPERTIES LINKER_LANGUAGE C) help rozwiązuje ten problem, ale nagłówki nie są dołączane do projektu i autouzupełnianie nie działa.

Oto, co miałem

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)

Żadnych błędów, ale nie to, czego potrzebowałem, zdałem sobie sprawę, że włączenie pojedynczego pliku jako źródła zapewni mi autouzupełnianie, a także ustawi konsolidator na 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
źródło
Właśnie zauważyłem, że używasz CXX_FLAGS do ustawienia standardowej wersji C ++ i pomyślałem, że wspomnę o zmiennej CXX_STANDARD, która moim zdaniem jest zalecanym sposobem cmake.org/cmake/help/latest/prop_tgt/CXX_STANDARD.html i powinna być dostępne w cmake 3.5
Chris Covert
2

Napotkałem również podobny błąd podczas kompilowania kodu w języku C. Rozwiązałem problem, poprawiając ścieżkę do pliku źródłowego w moim cmakepliku. Sprawdź ścieżkę do każdego pliku źródłowego wymienionego w twoim cmakepliku. To też może ci pomóc.

user2999709
źródło
0

Domyślnie folder JNI Native nosi nazwę jni . Zmiana nazwy na cpp rozwiązała problem

HimalayanCoder
źródło
0

Chcę dodać inne rozwiązanie na wypadek, gdyby powstała biblioteka bez żadnych plików źródłowych. Takie biblioteki są również znane jako biblioteki tylko z nagłówkami . Domyślnie add_libraryoczekuje co najmniej jednego dodanego pliku źródłowego lub w przeciwnym razie wystąpi wspomniany błąd. Ponieważ biblioteki obsługujące tylko nagłówki są dość powszechne, cmake ma INTERFACEsłowo kluczowe do tworzenia takich bibliotek. Słowo INTERFACEkluczowe jest używane w sposób pokazany poniżej i eliminuje potrzebę dodawania pustych plików źródłowych do biblioteki.

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

Powyższy przykład utworzyłby bibliotekę tylko z nagłówkiem, zawierającą wszystkie pliki nagłówkowe w tym samym katalogu, co CMakeLists.txt. Zastąp {CMAKE_CURRENT_SOURCE_DIR}ścieżką, jeśli pliki nagłówkowe znajdują się w innym katalogu niż plik CMakeLists.txt.

Zapoznaj się z tym postem na blogu lub dokumentacją cmake, aby uzyskać dalsze informacje dotyczące bibliotek obsługujących tylko nagłówki i cmake.

zhm
źródło
-2

Udało mi się rozwiązać swoje, zmieniając się

add_executable(file1.cpp)

do

add_executable(ProjectName file1.cpp)
AKJ
źródło
-2

W moim przypadku zaimplementowanie funkcji składowej klasy w pliku nagłówkowym powoduje ten błąd. Oddzielenie interfejsu (w pliku xh) i implementacji (w pliku x.cpp) rozwiązuje problem.

adembudak
źródło