本文介绍了CMake和Make需要运行两次才能成功构建代码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 我在C ++ 14项目中使用了CMake 3.8.2,GNU make 4.2.1和GCC 6.4.0,并且在构建时我注意到了一个奇怪的行为。我在运行 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 中。 参考文献 传递编译器选项cmake CMakeLists.txt中的CMake错误:30(项目):找不到CMAKE_C_COMPILER 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 versioncmake_minimum_required(VERSION 3.8.2)# Setting compiler related settingsset(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 nameproject(MyProject)# Find source filesfile(GLOB_RECURSE SOURCES application/*.cc)# Adding third-party sourcesset(SOURCES ${SOURCES} "third-party/cpp-base64/base64.cpp")# Executable to be built from which source filesadd_executable(myproject ${SOURCES})# Find and include and link Botanfind_library(BOTAN botan-2 "third-party/botan/build/lib")include_directories("third-party/botan/build/include/botan-2")# Includes that are part of the projectinclude_directories("${CMAKE_SOURCE_DIR}/application/include")# Include nlohmann/jsoninclude_directories("third-party/json/src")# Include cpp-base64 by René Nyffeneggerinclude_directories("third-party/cpp-base64")find_package(Boost REQUIRED COMPONENTS program_options)if(Boost_FOUND) include_directories(${Boost_INCLUDE_DIRS})endif()# Link third-party librariestarget_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.ReferencesCMake: In which Order are Files parsed (Cache, Toolchain, …)?Passing compiler options cmakeCMake Error at CMakeLists.txt:30 (project): No CMAKE_C_COMPILER could be found 这篇关于CMake和Make需要运行两次才能成功构建代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 10-30 09:20