CMake和Make需要运行两次才能成功构建代码 [英] CMake and Make need to be run twice in order to build code successfully
问题描述
cmake ..
然后是 make <>的子文件夹中使用CMake进行源代码构建。 / code>。
CMake运行良好,没有任何错误,并且会像我期望的那样构建所有源文件,直到完成编译并开始链接它们。然后它会失败,并出现错误。
[83%] ...
[100%]将CXX可执行文件myproject
/ usr / bin / ld:some-source-file.cc.o:未定义的符号引用'_ZNKSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEE3strEv @@ GLIBCXX_3.4.21'
有趣的是,到目前为止,它并没有显示任何编译器警告,只显示了上面提到的链接器错误。
现在当我忽略错误并简单运行 cmake ..
,然后 make
(就像我以前做的那样),我得到了所有编译器警告,我的代码应该产生,并且所有链接都很好,即使我没有在此期间更改任何代码或与CMake相关的文件。 我可以通过运行 rm删除
。 build
dir中的所有文件来重现此行为-r *
这是我的 CMakeLists.txt
文件:
#定义最低需求CMake版本
cmake_minimum_required(VERSION 3.8.2)
#设置编译器相关设置
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)
#定义项目名称
项目(MyProject)
#查找源文件
file( GLOB_RECURSE SOURCES application / *。cc)
#添加第三方来源
set(SOURCES $ {SOURCES}third-party / cpp-base64 / base64.cpp)
#可以从哪个源文件构建的可执行文件
add_executable(myproject $ {SOURCES})
#查找并包含并链接Botan
find_library(BOTAN botan- 2第三方/ botan / b
include_directories(第三方/ botan / build / include / botan-2)
#包含那些是项目的一部分
include_directories( $ {CMAKE_SOURCE_DIR} / application / include)
#包含nlohmann / json
include_directories(第三方/ json / src)
#包含cpp -base64 byRenéNyffenegger
include_directories(third-party / cpp-base64)
find_package(Boost必需组件program_options)
if(Boost_FOUND)
include_directories $ {$ Boost_INCLUDE_DIRS})
endif()
#链接第三方库
target_link_libraries(myproject $ {Boost_LIBRARIES} $ {BOTAN})
注意:我需要签入我正在使用的编译器和库,这就是我在CMake文件中指定它们的原因。
如果它只是第二次与缓存变量一起工作。
所以我非常确定,如果您通过添加 set(... CACHE)来修改
CMAKE_CXX_COMPILER
设置, (CMAKE_CXX_COMPILER$ {CMAKE_SOURCE_DIR} / toolchain / binary /)。
gcc-6.4.0 / bin / gccCACHE INTERNAL)
然后移动 set(CMAKE_CXX_FLAGS ...)
在项目()
命令之后
但是请注意,您不应该将编译器放入您的 CMakeLists.txt
中。
参考文献
I am using CMake 3.8.2, GNU make 4.2.1 and GCC 6.4.0 for my C++14 project and I noticed a strange behavior when building. I am using CMake for an out-of-source build in a sub-folder called "build" where I run cmake ..
followed by make
.
CMake runs fine without any errors and make will build all source files like I expect until it is done compiling and starts linking them. It will then fail with an error
[ 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'
Interestingly it doesn't show any compiler warnings up to this point and only shows the above mentioned linker error.
Now when I ignore the error and simply run cmake ..
and then make
again (just like I did before) I get all the compiler warnings that my code should produce and everything links perfectly fine, even though I didn't change any code or CMake-related files in the meantime.
I can reproduce this behavior by deleting all files in the build
dir by running rm -r *
.
Here is my CMakeLists.txt
file:
# 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})
Note: I am required to check-in the compiler and libraries I am using, which is why I specified them in the CMake file.
If it only works the second time it has to do with cached variables.
So I'm pretty sure that it will work the first time if you modify CMAKE_CXX_COMPILER
setting by adding set(... CACHE INTERNAL ""
) to:
set(CMAKE_CXX_COMPILER "${CMAKE_SOURCE_DIR}/toolchain/binary/gcc-6.4.0/bin/gcc" CACHE INTERNAL "")
And move set(CMAKE_CXX_FLAGS ...)
after the project()
command.
But please also be noted that you shouldn't put the compiler into your CMakeLists.txt
.
References
- CMake: In which Order are Files parsed (Cache, Toolchain, …)?
- Passing compiler options cmake
- CMake Error at CMakeLists.txt:30 (project): No CMAKE_C_COMPILER could be found
这篇关于CMake和Make需要运行两次才能成功构建代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!