CMake无法使用C++确定链接器语言

Chr*_*ert 70 c c++ cmake

我正在尝试使用Visual Studio 2010和Cygwin在Windows 7 x64上运行cmake hello world程序,但似乎无法运行.我的目录结构如下:

HelloWorld
-- CMakeLists.txt
-- src/
-- -- CMakeLists.txt
-- -- main.cpp
-- build/
Run Code Online (Sandbox Code Playgroud)

我做了一个cd build跟随a cmake ..,并得到一个错误说明

CMake Error: CMake can not determine linker language for target:helloworld
CMake Error: Cannot determine link language for target "helloworld".
Run Code Online (Sandbox Code Playgroud)

但是,如果我在我的filsystem上将main.cpp的扩展名更改为main.c,并且src/CMakeLists.txt所有内容都按预期工作.这是从Visual Studio命令提示符(Visual Studio解决方案生成器)和Cygwin终端(Unix Makefile文件生成器)运行的情况.

知道为什么这段代码不起作用?

的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)
Run Code Online (Sandbox Code Playgroud)

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 })
Run Code Online (Sandbox Code Playgroud)

SRC/main.cpp中

int main()
{
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

Joa*_*kim 143

我也提到你提到的错误:

CMake Error: CMake can not determine linker language for target:helloworld
CMake Error: Cannot determine link language for target "helloworld".
Run Code Online (Sandbox Code Playgroud)

在我的情况下,这是由于具有.cc扩展名的C++文件.

如果CMake无法正确确定代码的语言,您可以使用以下内容:

set_target_properties(hello PROPERTIES LINKER_LANGUAGE CXX)
Run Code Online (Sandbox Code Playgroud)

接受的答案建议将语言附加到project()语句中,只是增加了对使用何种语言的更严格检查(根据文档),但它对我没有帮助:

您可以选择指定项目支持的语言.示例语言是CXX(即C++),C,Fortran等.默认情况下启用C和CXX.例如,如果您没有C++编译器,则可以通过显式列出要支持的语言(例如C)来禁用对它的检查.通过使用特殊语言"NONE",可以禁用所有语言的所有检查.如果存在名为CMAKE_PROJECT__INCLUDE_FILE的变量,则该变量指向的文件将作为项目命令的最后一步包含在内.

  • 就我而言,我的文件具有 .hpp 扩展名。这解决了! (3认同)

Moe*_*ius 52

就我而言,这只是因为目标中没有源文件.我的所有库都是模板,标题中包含源代码.添加一个空的file.cpp解决了这个问题.

  • set target properties也适用于no cpp文件问题. (5认同)
  • 有用的提示。即使您的“库”只有标头,您也应该创建一个 .cpp 文件,为每个文件执行“#include”。即使编译库时不会有输出,它也会对文件进行语法检查,并检查您可能错过的头依赖项(例如系统头)。 (3认同)
  • 我认为理论上正确的方法是将您的仅标头库配置为 INTERFACE 库,并将该目标上的接口包含目录设置为您的标头位置。然后,当您想在应用程序(例如您的测试应用程序,这将是可执行目标)中使用它时,您可以“链接”它。这样做的优点是使安装变得简单,CMake 甚至会为您生成导出的目标,其他项目可以使用 find_package() 找到这些目标。 (3认同)
  • 为小费点赞。我也确实忘记将我的源移动到我新创建的 `cmake` 项目(一个共享库)的相应 `src` 子目录中,这基本上是整个问题的原因。在这种情况下,你真的很感激有一个向导来处理你的 `cmake` 项目的结构。:D (2认同)

olo*_*ovb 38

尝试改变

PROJECT(HelloWorld C)
Run Code Online (Sandbox Code Playgroud)

PROJECT(HelloWorld C CXX)
Run Code Online (Sandbox Code Playgroud)

要不就

PROJECT(HelloWorld)
Run Code Online (Sandbox Code Playgroud)

请参阅:http://www.cmake.org/cmake/help/v2.8.8/cmake.html#command : project

  • 这对我没有帮助.链接器错误仍然存​​在,请参阅我的回答有助于修复它的问题. (6认同)

Jol*_*ger 12

虽然可能令人困惑,但当项目中包含的cpp文件不存在时,也会发生错误.

如果您在CMakeLists.txt中列出源文件并错误地键入文件名,则会出现此错误.

  • 这可以作为它自己的答案,因为它独立于其他答案所说的内容。这也解决了我的问题。 (2认同)

fay*_*ayz 7

对 OP 的回答有点不相关,但对于像我这样有类似问题的人来说。

用例:Ubuntu(C、Clion、自动完成):

我有同样的错误,

CMake 错误:无法确定目标“hello”的链接语言。

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)
Run Code Online (Sandbox Code Playgroud)

没有错误,但不是我需要的,我意识到将单个文件作为源文件将使我自动完成并将链接器设置为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})
Run Code Online (Sandbox Code Playgroud)

  • 只是注意到您正在使用 CXX_FLAGS 来设置 C++ 标准版本,并认为我会提到 CXX_STANDARD 变量,我认为这是推荐的方式 https://cmake.org/cmake/help/latest/prop_tgt/CXX_STANDARD。 html 并且应该在 cmake 3.5 中可用 (2认同)

zhm*_*zhm 6

我想添加另一个解决方案,以防构建没有任何源文件的库。此类库也称为仅标头库。默认情况下add_library,至少需要添加一个源文件,否则会发生上述错误。由于仅标头库很常见,因此 cmake 具有INTERFACE构建此类库的关键字。所述INTERFACE关键字被用作如下所示,并将其消除了对添加到库中空源文件的需要。

add_library(myLibrary INTERFACE)
target_include_directories(myLibrary INTERFACE {CMAKE_CURRENT_SOURCE_DIR})
Run Code Online (Sandbox Code Playgroud)

上面的示例将构建一个仅包含头文件的库,包括与 CMakeLists.txt 位于同一目录中的所有头文件。{CMAKE_CURRENT_SOURCE_DIR}如果您的头文件与 CMakeLists.txt 文件位于不同的目录中,请替换为路径。

查看此博客文章cmake 文档,了解有关仅标头库和 cmake 的更多信息。