CMake和Make需要运行两次才能成功构建代码

com*_*eak 5 c++ gcc cmake gnu-make

我在C ++ 14项目中使用CMake 3.8.2,GNU make 4.2.1和GCC 6.4.0,在构建时我注意到了一个奇怪的行为。我使用CMake在名为“ build”的子文件夹中进行源代码外构建,cmake ..然后运行make

CMake运行良好,没有任何错误,make会像我期望的那样构建所有源文件,直到完成编译并开始链接它们为止。然后它将失败并显示错误

[ 83%] ...
[100%] Linking CXX executable myproject
/usr/bin/ld: some-source-file.cc.o: undefined reference to symbol '_ZNKSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEE3strEv@@GLIBCXX_3.4.21'
Run Code Online (Sandbox Code Playgroud)

有趣的是,到目前为止,它不显示任何编译器警告,而仅显示上述链接器错误。

现在,当我忽略该错误并简单地运行cmake ..,然后make再次运行(就像我之前所做的那样)时,即使我没有更改任何代码或与CMake相关的文件,我也会得到我的代码应产生的所有编译器警告,并且所有链接都可以正常运行同时。

我可以build通过运行删除目录中的所有文件来重现此行为rm -r *

这是我的CMakeLists.txt文件:

# Define minimum required CMake version
cmake_minimum_required(VERSION 3.8.2)

# Setting compiler related settings
set(CMAKE_CXX_COMPILER "${CMAKE_SOURCE_DIR}/toolchain/binary/gcc-6.4.0/bin/gcc")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wconversion -O2 -lstdc++")
set(CMAKE_CXX_STANDARD 14)

# Define project name
project(MyProject)

# Find source files
file(GLOB_RECURSE SOURCES application/*.cc)

# Adding third-party sources
set(SOURCES ${SOURCES} "third-party/cpp-base64/base64.cpp")

# Executable to be built from which source files
add_executable(myproject ${SOURCES})

# Find and include and link Botan
find_library(BOTAN botan-2 "third-party/botan/build/lib")
include_directories("third-party/botan/build/include/botan-2")

# Includes that are part of the project
include_directories("${CMAKE_SOURCE_DIR}/application/include")

# Include nlohmann/json
include_directories("third-party/json/src")

# Include cpp-base64 by René Nyffenegger
include_directories("third-party/cpp-base64")

find_package(Boost REQUIRED COMPONENTS program_options)
if(Boost_FOUND)
  include_directories(${Boost_INCLUDE_DIRS})
endif()

# Link third-party libraries
target_link_libraries(myproject ${Boost_LIBRARIES} ${BOTAN})
Run Code Online (Sandbox Code Playgroud)

注意:我需要检入正在使用的编译器和库,这​​就是为什么我在CMake文件中指定它们的原因。

Flo*_*ian 3

如果它只在第二次起作用,则与缓存变量有关。

\n\n

所以我很确定如果您CMAKE_CXX_COMPILER通过添加来修改设置,它会第一次工作set(... CACHE INTERNAL ""通过添加) 来

\n\n
set(CMAKE_CXX_COMPILER "${CMAKE_SOURCE_DIR}/toolchain/binary/gcc-6.4.0/bin/gcc" CACHE INTERNAL "")\n
Run Code Online (Sandbox Code Playgroud)\n\n

set(CMAKE_CXX_FLAGS ...)在之后移动project()

\n\n

但也请注意,您不应该将编译器放入您的CMakeLists.txt.

\n\n

参考

\n\n\n