CMake не може визначити мову компонування за допомогою C ++


89

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

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

Я роблю a, cd buildпісля чого a 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 (генератор файлів 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. Це вирішило це!
бешкетник

Те саме для мене, файл .hpp, і це виправлено.
KulaGGin

68

У моєму випадку це було просто тому, що в цільовому файлі не було вихідного файлу. Вся моя бібліотека була шаблоном із вихідним кодом у заголовку. Додавання порожнього файлу. Cpp вирішило проблему.


6
Встановити цільові властивості також працює для файлу no cpp.
Деніз Скідмор

1
Похвала за підказку. Я також забув перенести свої джерела у відповідний srcпідкаталог мого новоствореного cmakeпроекту (спільна бібліотека), і це в основному було причиною цілої проблеми. У таких випадках справді вдячний наявність майстра, який подбає про структуру вашого cmakeпроекту. : D
rbaleksandar

Ту ж причину тут (помилка копіювання-вставлення). Дякую!
Вівіт

2
Корисна порада. Навіть якщо ваша "бібліотека" є лише заголовком, вам слід створити один файл .cpp, який робить a #includeдля кожного файлу. Незважаючи на те, що під час компіляції вашої бібліотеки не буде виходу, вона буде перевіряти синтаксис вашого файлу, а також перевіряти наявність залежностей заголовків (наприклад, заголовків системи), які ви могли пропустити.
Mark Lakata

Це так просто. Помилка в шляху не веде до файлів * .cpp у джерелах. Після цього все добре. Дякую!
Рахул Дас,

17

Як би не було заплутано, помилка також трапляється, коли файл cpp, включений до проекту, не існує.

Якщо ви перерахуєте вихідні файли в CMakeLists.txt і помилково введете ім'я файлу, ви отримаєте цю помилку.


Будь ласка, зробіть це, як у розділі коментарів.
Вірб,

1
Це працює як власна відповідь, оскільки не залежить від того, що сказали інші відповіді. Також це вирішило мою проблему.
Czarking

5

Трохи не пов'язана відповідь на OP, але для таких людей, як я, з дещо подібною проблемою.

Приклад використання: Ubuntu (C, Clion, автозавершення):

У мене була та ж помилка,

Помилка CMake: Не вдається визначити мову посилання для цільового "привіт".

set_target_properties(hello PROPERTIES LINKER_LANGUAGE C) допоможе вирішити цю проблему, але заголовки не входять до проекту, і автозавершення не працює.

Це те, що я мав

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файлу. Це може допомогти і вам.



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)

-2

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.