有可能用CMake构建Boost吗
Is it possible to build Boost with CMake?
我不想在交叉编译项目的源代码树中包含静态库,而是想直接将boost添加到cmake中并构建它。这可用吗?
在我的工作场所,我们也遇到过一些困难。虽然我当然不能声称知道"最好"的方式,但我可以就我的经历提出以下想法。
我们最初只是要求开发人员单独安装boost,并让CMake以find_package(Boost...)
调用的形式进行正常检查。这很容易,但不是自动化的,并且给已经安装了旧版本boost的开发人员带来了问题。
然后,我们改变了策略,添加了一份从您上面提到的一个项目中克隆的boost源的副本。我记不起具体情况了,但我认为这是Ryppl项目中目前正在进行的一项工作的前兆。主要的一点是,它已经得到了对CMake的支持;boost库是通过add_library
调用添加的实际CMake目标,这使它们更容易在CMake代码中使用。
虽然这通过在我们的项目中自动使用boost解决了以前的问题,但它最终成为了一场维护噩梦。我们克隆的boost项目发生了根本性的变化,现在非常依赖Ryppl特定的CMake功能。我们不想添加Ryppl作为依赖项,所以我们再次改变了策略!
我们查看了你在问题中提到的项目,同样发现它们都不可用。
我们目前的设置使用了CMake的ExternalProject
模块。这允许我们下载并构建boost到我们的构建树。
优点:
- 低维护
- 自动化,因此所有开发人员都使用相同的版本,使用相同的标志构建
- 保持我们自己的源代码树不受第三方代码的影响
- boost的多个副本可以愉快地共存(因此不会意外链接到使用不同编译器/stdlib组合构建的副本)
的缺点
- 删除构建树意味着必须从头开始下载和构建boost。这可以通过例如下载到固定位置(例如,系统临时目录)来改善,因此如果找到升压源的现有副本,则可以跳过下载/解压缩步骤
- boost库不是合适的CMake目标(即,它们尚未通过
add_library
调用添加)
这是我们的CMake代码的链接。有一些方法需要改进,但目前对我们来说效果相当好
我希望这个答案很快就会过时,一个像样的、模块化的、兼容CMake的解决方案就会出现。
我发现Fraser上面的答案是一个很好的起点,但在我们的系统上使用Boost 1.55.0时遇到了一些问题。
首先,我们希望为我们的应用程序提供一个自包含的源代码包,因此不希望使用CMake ExternalProject。我们只使用Boost中的线程和date_time库,所以我们使用bcp创建了Boost的一个子集,其中包括构建工具、线程和其他依赖库:
$ bcp tools/build thread system date_time ../boost_1_55_0_threads_only
并将其检查到我们的svn存储库中。
接下来,我可以调整Fraser的CMake文件以在Linux上构建,但在Windows上使用CMake的execute_process命令运行bootstrap.bat
文件时遇到了问题。要运行bootstrap.bat,我们首先需要运行相关的Visual Studio vcvarsall.bat
脚本来设置环境变量(我们可能可以确定需要设置哪些单独的变量,但运行整个脚本更容易)。为了使用execult_process在同一个shell中运行两个.bat文件,我们使用了cmd /c
并列出了用&
分隔的文件作为参数。
此外,bootstrap.bat
在失败的情况下没有将退出代码设置为非零,因此使用execute_process RESULT_VARIABLE检查成功与否是不起作用的。相反,我们检查b2.exe可执行文件是否已在命令运行后创建。
最后一个问题:bootstrap.sh
支持--prefix=
选项,而bootstrap.bat
不支持。我还发现在windows上为b2.exe
指定--prefix
选项是有效的,但是在Linux上为b2
使用--prefix
选项,而没有为bootstrap.sh
指定该选项,会出现错误。(我还不明白为什么)。
因此,我们的CMake文件的相关部分看起来像:
#
# run bootstrap
#
if(WIN32)
if(MSVC10)
set(VCVARS_CMD "C:\Program^ Files^ ^(x86^)\Microsoft^ Visual^ Studio^ 10.0\VC\vcvarsall.bat")
elseif(MSVC11)
set(VCVARS_CMD "C:\Program^ Files^ ^(x86^)\Microsoft^ Visual^ Studio^ 11.0\VC\vcvarsall.bat")
elseif(MSVC12)
set(VCVARS_CMD "C:\Program^ Files^ ^(x86^)\Microsoft^ Visual^ Studio^ 12.0\VC\vcvarsall.bat")
# elseif(...)
# add more options here
endif(MSVC10)
set(BOOTSTRAP_CMD "${VCVARS_CMD} & bootstrap.bat")
message("Executing command: ${BOOTSTRAP_CMD}")
execute_process(COMMAND cmd /c "${BOOTSTRAP_CMD}" WORKING_DIRECTORY ${APT_BOOST_SRC}
RESULT_VARIABLE BS_RESULT OUTPUT_VARIABLE BS_OUTPUT ERROR_VARIABLE BS_ERROR)
if(NOT EXISTS ${APT_BOOST_SRC}/b2.exe)
message(FATAL_ERROR "Failed running cmd /c ${BOOTSTRAP_CMD} in ${APT_BOOST_SRC}:n${BS_OUTPUT}n${BS_ERROR}n")
else(NOT EXISTS ${APT_BOOST_SRC}/b2.exe)
message("bootstrap output:n${BS_OUTPUT}")
endif(NOT EXISTS ${APT_BOOST_SRC}/b2.exe)
else(WIN32)
set(BOOTSTRAP_CMD "./bootstrap.sh")
set(BOOTSTRAP_ARGS "--prefix=${APT_BOOST_BIN}")
message("Executing command: ${BOOTSTRAP_CMD} ${BOOTSTRAP_ARGS}")
execute_process(COMMAND "${BOOTSTRAP_CMD}" ${BOOTSTRAP_ARGS} WORKING_DIRECTORY ${APT_BOOST_SRC}
RESULT_VARIABLE BS_RESULT OUTPUT_VARIABLE BS_OUTPUT ERROR_VARIABLE BS_ERROR)
if(NOT BS_RESULT EQUAL 0)
message(FATAL_ERROR "Failed running ${BOOTSTRAP_CMD} ${BOOTSTRAP_ARGS} in ${APT_BOOST_SRC}:n${BS_OUTPUT}n${BS_ERROR}n")
endif()
endif(WIN32)
#
# run b2
#
set(B2_ARGS "link=static" "threading=multi" "runtime-link=static" "variant=release")
foreach(COMP IN LISTS APT_BOOST_COMPONENTS)
set(B2_ARGS "--with-${COMP}" ${B2_ARGS})
endforeach(COMP IN LISTS APT_BOOST_COMPONENTS)
if(WIN32)
if(MSVC11)
set(B2_ARGS "--toolset=msvc-11.0" ${B2_ARGS})
elseif(MSVC12)
set(B2_ARGS "--toolset=msvc-12.0" ${B2_ARGS})
endif(MSVC11)
file(TO_NATIVE_PATH ${APT_BOOST_BIN} APT_BOOST_BIN_WIN)
set(B2_ARGS "--prefix=${APT_BOOST_BIN_WIN}" ${B2_ARGS} "architecture=x86" "address-model=64")
endif(WIN32)
set(B2_ARGS ${B2_ARGS} install)
set(B2_CMD "./b2")
message("Executing command: ${B2_CMD} ${B2_ARGS}")
execute_process(COMMAND ${B2_CMD} ${B2_ARGS} WORKING_DIRECTORY ${APT_BOOST_SRC}
RESULT_VARIABLE B2_RESULT OUTPUT_VARIABLE B2_OUTPUT ERROR_VARIABLE B2_ERROR)
if(NOT B2_RESULT EQUAL 0)
message(FATAL_ERROR "Failed running ${B2_CMD} in ${APT_BOOST_SRC}:n${B2_OUTPUT}n${B2_ERROR}n")
endif()
在上面的APT_BOOST_SRC
是我们源目录中Boost子目录的位置,APT_BOOST_BIN
是我们用于存储CMake构建目录中的库的位置,而APT_BOOST_COMPONENTS
是我们正在使用的Boost库的列表。
- 尝试将 boost::stacktrace 添加到 CMake 项目时出现构建错误
- 如何在 Linux for Windows 上通过 MinGW 构建静态 ICU 的 Boost
- 在 Boost::fiber 中引发的BOOST_ASSERT故障 Visual Studio "Debug" 构建
- 虽然我添加了boost库,但Eclipse并不是用C++构建的.为什么
- 如何使用VS 2015构建Boost 1.44
- 无法从 bazel 使用 boost/iostream 构建项目包
- 使用 python3 为 msvc 构建 boost python - 链接器错误
- C++ CMake 构建错误:未定义对"boost::throw_exception(std::exception const&)"的引用
- BOOST :: MUTEX版本与调试构建
- 将Windows上32位和64位的Boost构建到同一文件夹中
- 当我使用 boost 构建绝对路径时,无限递归
- 当我使用 boost 构建 CAGL 演示时,如何修复错误 1001
- 使用boost构建Python扩展
- boost构建中的多个构建目标
- 在Windows上使用SSL和预构建Boost构建Mongo-Cpp驱动程序
- 使用boost构建NodeJ模块(或任何其他库)
- 使用Boost构建单元测试时发生链接器错误
- 是否可以使用boost构建并发进程间消息队列
- 使用Boost.构建和提升.测试链接器错误
- 当使用(自定义)GCC 4时,Boost构建无法进行c++ 11特性检查.X或5