CMake не может определить язык компоновщика с C ++

89

Я пытаюсь запустить программу cmake hello world в Windows 7 x64 как с Visual Studio 2010, так и с Cygwin, но, похоже, ни одна из них не работает. Моя структура каталогов выглядит следующим образом:

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

Я делаю cd buildа cmake .., а затем получаю сообщение об ошибке

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

Однако, если я изменю расширение main.cpp на main.c как в моей файловой системе, так и во src/CMakeLists.txtвсем, все будет работать должным образом . Это тот случай, когда запускается как из командной строки Visual Studio (генератор решений Visual Studio), так и из терминала Cygwin (генератор Makefiles Unix).

Есть идеи, почему этот код не работает?

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;
}
Крис Коверт
источник
"[...] если я изменю расширение main.cpp [...]" На что вы его измените? .cc?
JAB
ой. Это случайно не учли. Я меняю его на .c. Отредактировано в исходном посте. Это почти заставляет меня думать, что нет компилятора cpp или чего-то в этом роде, но g ++ установлен, и у Visual Studio тоже не должно быть проблем с c ++.
Крис Коверт,

Ответы:

182

Я также получил указанную вами ошибку:

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

В моем случае это произошло из-за наличия файлов C ++ с .ccрасширением.

Если CMake не может правильно определить язык кода, вы можете использовать следующее:

set_target_properties(hello PROPERTIES LINKER_LANGUAGE CXX)

Принятый ответ, предлагающий добавить язык в project()оператор, просто добавляет более строгую проверку того, какой язык используется (согласно документации), но мне это не помогло:

При желании вы можете указать, какие языки поддерживает ваш проект. Примеры языков: CXX (т.е. C ++), C, Fortran и т. Д. По умолчанию C и CXX включены. Например, если у вас нет компилятора C ++, вы можете отключить его проверку, явно указав языки, которые вы хотите поддерживать, например C. Используя специальный язык «NONE», все проверки для любого языка могут быть отключены. Если существует переменная с именем CMAKE_PROJECT__INCLUDE_FILE, файл, на который указывает эта переменная, будет включен в качестве последнего шага команды проекта.

Иоаким
источник
В моем случае у моего файла было расширение .hpp. Это решило это!
brawner
То же самое для меня, файл .hpp, и это исправило его.
KulaGGin
68

В моем случае это произошло потому, что в целевом объекте не было исходного файла. Вся моя библиотека была шаблоном с исходным кодом в заголовке. Добавление пустого файла .cpp решило проблему.

Мебиус
источник
6
set target properties также работает с проблемой отсутствия файла cpp.
Дениз Скидмор
1
Престижность за чаевые. Я также забыл переместить свои источники в соответствующий srcподкаталог моего недавно созданного cmakeпроекта (общая библиотека), и это было в основном причиной всей проблемы. В таких случаях очень важно иметь мастера, который позаботится о структуре вашего cmakeпроекта. : D
rbaleksandar
Причина та же (ошибка копирования и вставки). Благодарность!
Вивит
2
Полезный совет. Даже если ваша «библиотека» - это только заголовок, вы должны создать один файл .cpp, который будет делать #includeдля каждого файла. Несмотря на то, что при компиляции вашей библиотеки не будет вывода, она выполнит проверку синтаксиса вашего файла, а также проверит зависимости заголовков (например, системные заголовки), которые вы могли пропустить.
Марк Лаката
Это так просто. Опечатка в пути приводит к отсутствию файлов * .cpp в источниках. После этого все в порядке. Спасибо!
Рахул Дас
17

Как это ни сбивает с толку, ошибка также возникает, когда файл cpp, включенный в проект, не существует.

Если вы укажете исходные файлы в CMakeLists.txt и ошибочно введете имя файла, то получите эту ошибку.

Веселый Роджер
источник
Пожалуйста, сделайте это как в разделе комментариев.
Virb
1
Это работает как собственный ответ, поскольку он не зависит от того, что сказали другие ответы. Также это устранило мою проблему.
Czarking,
5

Немного несвязанный ответ на OP, но для людей вроде меня с похожей проблемой.

Пример использования: Ubuntu (C, Clion, автозаполнение):

У меня была такая же ошибка,

Ошибка CMake: не удается определить язык ссылок для целевого "привет".

set_target_properties(hello PROPERTIES LINKER_LANGUAGE C) help устраняет эту проблему, но заголовки не включены в проект, и автозаполнение не работает.

Это то, что у меня было

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)

Никаких ошибок, но не то, что мне нужно, я понял, что включение одного файла в качестве источника даст мне автозаполнение, а также установит компоновщик на 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})
ебать
источник
Просто заметил, что вы используете CXX_FLAGS для установки стандартной версии C ++, и подумал, что упомянул бы переменную CXX_STANDARD, которая, я думаю, является рекомендуемым способом cmake.org/cmake/help/latest/prop_tgt/CXX_STANDARD.html и должна быть доступно в cmake 3.5
Chris Covert
2

Я также столкнулся с аналогичной ошибкой при компиляции моего кода на C. Я исправил проблему, исправив путь к исходному файлу в моем cmakeфайле. Пожалуйста, проверьте путь к исходному файлу каждого исходного файла, упомянутого в вашем cmakeфайле. Это может вам тоже помочь.

user2999709
источник
0

По умолчанию папка JNI Native называется jni . Переименование его в cpp устранило проблему

ГималайскийКодер
источник
0

Я хочу добавить еще одно решение на случай создания библиотеки без исходных файлов. Такие библиотеки также известны как библиотеки только для заголовков . По умолчанию add_libraryожидается добавление хотя бы одного исходного файла, в противном случае возникает указанная ошибка. Поскольку библиотеки только для заголовков довольно распространены, cmake имеет INTERFACEключевое слово для создания таких библиотек. INTERFACEИспользуется ключевое слово , как показано ниже , и это устраняет необходимость в пустых исходных файлов , добавленных в библиотеку.

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

В приведенном выше примере будет создана библиотека только для заголовков, включающая все файлы заголовков в том же каталоге, что и CMakeLists.txt. Замените {CMAKE_CURRENT_SOURCE_DIR}на путь, если ваши файлы заголовков находятся в другом каталоге, чем файл CMakeLists.txt.

Посмотрите это сообщение в блоге или документацию по cmake для получения дополнительной информации о библиотеках только для заголовков и cmake.

жм
источник
-2

Мне удалось решить мою, изменив

add_executable(file1.cpp)

к

add_executable(ProjectName file1.cpp)
AKJ
источник
-2

В моем случае реализация функции-члена класса в файле заголовка вызывает эту ошибку. Разделение интерфейса (в файле xh) и реализации (в файле x.cpp) решает проблему.

адембудак
источник