Windows + MinGW/MSVC 安装Boost程序库环境 踩坑指南
Windows + MinGW/MSVC 安装Boost程序库 踩坑指南
本文仅在博客园由aquawius发布,请在转载注明本链接,我这里就不写开源协议了,总之盗文章的马没了就完了。
0x00 关于MinGW-W64的安装
你可以自己选择, 我使用的来自github的w64devkit
, 这个工具内置了比较多的小工具,在linux中有许多工具windows用不了,w64devkit里边就有提供(甚至包括vim!!)
添加bin目录到环境变量就可以了.
0x01 关于Boost程序库
booststrap.bat
和b2.exe
需要通过源码自带的booststrap.bat工具编译b2.exe工具
如果你希望使用gcc来编译b2, 其中需要指定编译器为
gcc
, 如果没有指定gcc
工具链, 那么bootstrap.bat默认将会使用Visual Studio
的cl编译器.这里有一个前提, gcc需要在环境变量中, 也就是(0x00步骤).
cd boost_1_83_0 ./booststrap.bat gcc
你的目录下将会多出来一个b2.exe, 这个步骤是必须的.
这里是有坑的, 如果你的cl.exe(msvc编译工具集)或者gcc在没有在环境变量中, 你有可能在后续编译Boost的过程中发现, 你的编译器支持的c++特性将会全部是
no
(即使你通过toolset=xxx
指定了编译器, 也就是有坑(而且是大坑)).这里说一下坑, 其实也就是环境变量的问题, 一般我们安装完mingw的时候, 都会手动的配置环境变量, 所以说使用gcc构建的时候一般不会出现问题.
但是换成了msvc环境, 你的Visual Studio是通过Visual Studio Installer安装的, 他不会添加进环境变量, 理论上来说是不能在终端中直接编译的; 但是, 你会发现在编译b2.exe的时候使用的确实是msvc, 并切成功的生成了b2工具, 但是此时如果你输入cl, 命令又找不到, 在后续编译的时候, 你就出现了上述的c++的支持特性全部是no的情况, 最终你会花很大的时间排除错误.(甚至都不知道问题在哪了, 因为你VS是正常安装的)如果你想要使用msvc编译boost, 正确的姿势是在你的
开始 -> 所有程序 -> Visual Studio 2022 -> Developer PowerShell for VS 2022
这里你输入cl, 不会出现找不到命令的情况. 请你在这里进行编译boost的操作.
在这一步骤, 使用msvc或者使用gcc都是没有区别的, 他们的工作是为了构建出 构建boost程序库所需的 编译工具(也就是b2)
你可能有下面的问题, 我替你问了GPT老师:
./booststrap.bat gcc
说明一下为什么这样做, 为我做了什么?(ChatGPT回答):
在Boost库中,
bootstrap.bat
是用来初始化构建系统的脚本,而b2
则是Boost构建工具(Boost.Build)的可执行文件。Boost库使用Boost.Build作为其构建系统,用于管理库的编译和安装过程。
bootstrap.bat
主要用于生成b2
二进制文件,这是Boost.Build的一个组成部分,它将用于后续的编译过程。b2
实际上是Boost.Build的主要执行文件,通过运行它,您可以指定构建选项、目标等。
b2 install
命令则是使用Boost.Build来进行实际的编译和安装操作.
b2能构建除了boost以外的目标吗, 通常这样做吗
(ChatGPT回答):
b2
是Boost库特定的构建工具,主要用于构建和管理Boost库的编译过程。它通过使用Boost.Build系统来实现这些功能。Boost.Build是一个灵活的构建系统,实际上可以用于构建除了Boost库之外的其他项目。虽然
b2
和Boost.Build最初是为Boost库设计的,但它们也可以用于其他C++项目的构建。Boost.Build具有可扩展性和通用性,因此某些开发者可能选择在其他项目中使用它。使用
b2
和Boost.Build构建非Boost项目的一个常见做法是编写一个自定义的Jamroot
文件(类似于Makefile或CMakeLists.txt),其中包含项目的构建规则和依赖关系。然后,可以使用b2
命令执行构建。尽管可以这样做,但在实践中,很多项目更倾向于使用其他构建系统,如CMake、Makefile、或使用IDE(集成开发环境)的内置构建工具。这些工具更为通用,并且在整个C++社区中更广泛使用。
因此,虽然
b2
和Boost.Build可以用于非Boost项目,但在实际应用中,开发者可能更喜欢使用其他构建工具,特别是在非Boost项目中。
也就是说boost是通过b2读取已经写好的Jamroot进行构建并安装到我的机器上的
(ChatGPT回答):
是的,您的理解基本正确。Boost库通过
b2
命令和Boost.Build系统进行构建。构建过程通常是通过读取项目根目录下的Jamroot
文件(或者在旧版本中是Jamfile
)来定义构建规则、依赖关系和其他构建配置。
Jamroot
文件是一个文本文件,其中包含了描述构建过程的规则,指定了库的编译选项、源文件列表、依赖关系等。Boost.Build会解析Jamroot
文件并根据其中的规则执行构建操作。在执行构建之前,通常需要运行
bootstrap.bat
脚本来生成b2
二进制文件,它是Boost.Build系统的一部分,负责实际执行构建过程。最终,通过运行
b2 install
命令,Boost库将根据Jamroot
文件中的规则进行编译,并安装到您指定的目标目录中。总体而言,
b2
和Jamroot
文件是Boost库构建系统的核心组成部分,它们一起协同工作,使得Boost库可以在各种平台上进行自动化的构建和安装。
0x02 Boost的编译安装
boost官网是这样说的, Boost中的部分库有的可以不用编译直接使用, 但是有的必须进行编译才能够使用.
我选择是全部编译, 这样我就不用考虑需不需要编译的问题了.
在编译安装之前我希望你对b2构建工具有更深的印象.
./b2.exe --help
B2 4.10-git
Project-specific help:
Project has jamfile at Jamroot
Usage:
b2 [options] [properties] [install|stage]
Builds and installs Boost.
Targets and Related Options:
install Install headers and compiled library files to the
======= configured locations (below).
--prefix=<PREFIX> Install architecture independent files here.
Default: C:\Boost on Windows
Default: /usr/local on Unix, Linux, etc.
....................
我这里请GPT老师帮助我翻译.
请你翻译成中文, 对重要的内容进行解释.
(ChatGPT)
这段内容是
b2
的帮助信息,它列出了b2
的用法、目标、相关选项以及其他一些配置。让我为您解释其中的重要内容:
- Usage 部分:
b2 [options] [properties] [install|stage]
: 这是b2
的基本用法,它用于构建和安装Boost库。- Targets and Related Options 部分:
install
: 安装Boost库到配置的位置。--prefix=<PREFIX>
: 指定安装的根目录,默认在 Windows 下是C:\Boost
,在 Unix、Linux 下是/usr/local
。stage
: 仅构建和安装编译好的库文件到临时目录。- Other Options 部分:
--build-type=<type>
: 构建指定预定义变体的库。默认是minimal
,也可以选择complete
。--build-dir=DIR
: 指定构建的位置,推荐使用。--show-libraries
: 显示需要构建和安装的Boost库列表。--layout=<layout>
: 确定库名称和头文件位置的命名规则。可选值有versioned
、tagged
和system
。- Important Options 部分:
--clean
: 删除目标而不是构建。-a
: 重新构建所有。-n
: 仅打印命令而不执行。-d+2
: 显示执行命令时的详细信息。-q
: 在遇到第一个错误时停止。--reconfigure
: 重新运行所有配置检查。--durations[=N]
: 报告执行时间最长的前 N 个目标。--debug-configuration
: 诊断配置。--debug-building
: 报告使用哪些属性构建哪些目标。--debug-generator
: 诊断生成器搜索/执行。这些选项和目标可以帮助您配置和执行Boost库的构建和安装过程。
我们需要按照帮助命令中的要求补充b2的命令就可以了
我这里给出的命令是这样的
.\b2 --prefix="C:\boost" --build-type=complete threading=multi link=shared toolset=gcc install -j8
注意: 我这里指定了
toolset=gcc
(也就是MinGW-W64)作为编译工具集(你使用toolset=msvc也是可以的, 记得看看上面说的坑).-j8
指定了使用8个线程进行编译(加快编译速度).如果使用msvc构建boost, 请带上msvc的版本号.
.\b2 --prefix="C:\boost" --build-type=complete threading=multi link=shared toolset=msvc-14.3 install -j12
这里msvc-14.3表示的是Visual Studio 2022.
这里就不得不说说第二个坑了, 这是boost的问题不是我们的问题. 只有在特定的版本才会出现问题(我这里是VS2022 17.10.5 + boost 1.85.0). 详细请看issue https://github.com/boostorg/boost/issues/914 和 https://github.com/boostorg/boost/issues/931
我给一个总结, 以往的VS发布时候, 版本号都是14.1, 14.2 等等, boost通过检测是否存在匹配的字符串判定你使用的环境, 但是vs现在的版本命名规则有那么亿点迷惑, 以至于把b2搞糊涂了, 最终不能识别你的编译环境. 在issue中说明了修复的代码, 请根据issue提到的进行修复. (或者等等boost1.86.0(issue说是新的b2修复))
目前编译还是不成功的, 因为链接库的问题, 有可能链接的是vc143/vc170, 最终出现一些不确定的问题. 建议还是先使用mingw过度一下吧.
运行之后(我的电脑编译了接近20分钟), 配置不好的电脑可能更慢.
编译之后, --prefix
中设定的目录(我这里是C:\boost
目录) 如下所示:
C:\boost
.
├── include
│ └── boost-1_83
│ └── boost
│ ├── accumulators
│ ├── accumulators.hpp
│ ├── accumulators_fwd.hpp
│ ├── framework
│ │ ├── accumulator_base.hpp
│ │ ├── accumulator_concept.hpp
│ │ ├── accumulator_set.hpp
│ │ ├── accumulators
│ │ │ ├── droppable_accumulator.hpp
│ │ │ ├── external_accumulator.hpp
│ │ │ ├── reference_accumulator.hpp
│ ...................................................
└── lib
├── cmake
├── libboost_atomic-mgw13-mt-d-x32-1_83.a
├── libboost_atomic-mgw13-mt-d-x64-1_83.a
├── libboost_atomic-mgw13-mt-d-x64-1_83.dll
├── libboost_atomic-mgw13-mt-d-x64-1_83.dll.a
├── libboost_atomic-mgw13-mt-s-x32-1_83.a
├── libboost_atomic-mgw13-mt-s-x64-1_83.a
├── libboost_atomic-mgw13-mt-sd-x32-1_83.a
├── libboost_atomic-mgw13-mt-sd-x64-1_83.a
├── libboost_atomic-mgw13-mt-x32-1_83.a
├── libboost_atomic-mgw13-mt-x64-1_83.a
├── libboost_atomic-mgw13-mt-x64-1_83.dll
├── libboost_atomic-mgw13-mt-x64-1_83.dll.a
..................................................
0x03 关于使用Boost库
如果你想使用cmake作为构建工具, 我这里有一个调试好的CMakeList.txt.
主要用来编译chapter*/**.cpp
中的文件.
cmake_minimum_required(VERSION 3.20)
project(BoostLearning)
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
message(STATUS "Windows Detected!")
# 如果是 Windows,设置 Boost 根目录
set(Boost_ROOT "C:/boost")
message(STATUS "set Boost_ROOT to ${Boost_ROOT}")
endif()
find_package(Boost REQUIRED)
set(Boost_NO_SYSTEM_PATHS ON) # 只搜索上语句设置的搜索路径
if(Boost_FOUND)
message(STATUS "Boost found!")
message(STATUS "Boost_LIB_VERSION = ${Boost_LIB_VERSION}.")
endif()
set(Boost_ARCHITECTURE “-x64”)
# 遍历章节目录
file(GLOB CHAPTER_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/chapter*")
# 遍历每个章节
foreach(CHAPTER_DIR ${CHAPTER_DIRS})
# 获取文件夹名称
get_filename_component(CHAPTER_DIR_LAST_WORD ${CHAPTER_DIR} NAME)
# 获取章节中的所有CPP文件
file(GLOB CHAPTER_CPP_FILES "${CHAPTER_DIR}/*.cpp")
# 遍历每个CPP文件
foreach(CPP_FILE ${CHAPTER_CPP_FILES})
# 获取CPP文件名,假设文件名的命名规则为"filename.cpp"
get_filename_component(FILE_NAME ${CPP_FILE} NAME_WE)
set(EXECUTABLE_NAME "${FILE_NAME}")
# 添加可执行文件
add_executable(${EXECUTABLE_NAME} ${CPP_FILE})
# 链接Boost库
target_link_libraries(${EXECUTABLE_NAME} PUBLIC Boost::boost)
# 设置可执行文件的输出目录为相对路径
set_target_properties(${EXECUTABLE_NAME} PROPERTIES
OUTPUT_NAME ${FILE_NAME}
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CHAPTER_DIR_LAST_WORD}
)
endforeach()
endforeach()
如果你使用的是IDE, 请在include中包含你编译的那些hpp, 在我的例子中是C:\boost\include\boost-1_83
, 链接使用的目录为C:\boost\lib
, 之后你的IDE环境就能找到对应的头文件, 并且给出代码提示了.
请注意:IDE的include中请不要设置为
C:\boost\include\boost-1_83\boost
,因为通常在引入头文件的时候,是#include "boost/xxxxx/xxxx.hpp", 所以请设定为
C:\boost\include\boost-1_83
(不要后面的boost)
0xFF 后记
没有什么后记...吧, 就是折腾挺长时间的, 可算折腾明白这玩应怎么工作了.