CMake和Make需要运行两次才能成功构建代码 [英] CMake and Make need to be run twice in order to build code successfully

查看:1068
本文介绍了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 中。



参考文献




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和Make需要运行两次才能成功构建代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆