如何在Embarcadero C++Builder v10.4中使用yaml-cpp读取YAML?
在Embarcadero C++Builder 10.4中集成yaml-cpp的问题与解决
需求与疑问
- 使用Embarcadero CBuilder v10.4开发C VCL应用,需要读取YAML文件,计划采用yaml-cpp库
- 此前通过头文件+DLL方式集成过其他库,但对yaml-cpp的集成流程不熟悉,需明确:
- 如何为Embarcadero环境正确生成Makefile?
make执行完成后会得到哪些产物?- 如何将yaml-cpp集成到VCL项目中?
已尝试的方法
- 按照yaml-cpp官方GitHub说明构建并创建Borland Makefile,编译至2%时失败
- 参考Embarcadero官方文档使用CMake生成Makefile,编译至94%时出现链接错误,Turbo链接器提示未解析外部符号__Atomic_fetch_add_4,该符号来自yaml-cpp.lib的nodebuilder.cpp文件
完整错误日志
C:\git\Temp\yaml-cpp-master\build>cmake -DCMAKE_C_COMPILER=bcc32x.exe -DCMAKE_CXX_COMPILER=bcc32x.exe -DCMAKE_BUILD_TYPE_INIT=Release -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON -G "Borland Makefiles" .. -- CXX编译器标识为Embarcadero 7.50.37590 -- 检测CXX编译器ABI信息 -- 检测CXX编译器ABI信息 - 完成 -- 检查工作中的CXX编译器: C:/Program Files (x86)/Embarcadero/Studio/21.0/bin/bcc32x.exe - 跳过 -- 配置完成 (2.0s) -- 生成完成 (0.3s) CMake警告: 手动指定的变量未被项目使用: CMAKE_C_COMPILER -- 构建文件已写入: C:/git/Temp/yaml-cpp-master/build C:\git\Temp\yaml-cpp-master\build>make MAKE版本5.43 版权所有(c) 1987, 2019 Embarcadero Technologies, Inc. "C:\Program Files\CMake\bin\cmake.exe" -P C:\git\Temp\yaml-cpp-master\build\CMakeFiles\VerifyGlobs.cmake "C:\Program Files\CMake\bin\cmake.exe" -SC:\git\Temp\yaml-cpp-master -BC:\git\Temp\yaml-cpp-master\build --check-build-system CMakeFiles\Makefile.cmake 0 "C:\Program Files\CMake\bin\cmake.exe" -E cmake_progress_start C:\git\Temp\yaml-cpp-master\build\CMakeFiles C:\git\Temp\yaml-cpp-master\build\\CMakeFiles\progress.marks make -f CMakeFiles\Makefile2 -l -o all MAKE版本5.43 版权所有(c) 1987, 2019 Embarcadero Technologies, Inc. make -f CMakeFiles\yaml-cpp.dir\build.make -l -o CMakeFiles\yaml-cpp.dir\depend MAKE版本5.43 版权所有(c) 1987, 2019 Embarcadero Technologies, Inc. "C:\Program Files\CMake\bin\cmake.exe" -E cmake_depends "Borland Makefiles" C:\git\Temp\yaml-cpp-master C:\git\Temp\yaml-cpp-master C:\git\Temp\yaml-cpp-master\build C:\git\Temp\yaml-cpp-master\build C:\git\Temp\yaml-cpp-master\build\CMakeFiles\yaml-cpp.dir\DependInfo.cmake --color= make -f CMakeFiles\yaml-cpp.dir\build.make -l -o CMakeFiles\yaml-cpp.dir\build MAKE版本5.43 版权所有(c) 1987, 2019 Embarcadero Technologies, Inc. [ 2%] 编译CXX目标文件 CMakeFiles/yaml-cpp.dir/src/contrib/graphbuilder.cpp.obj C:\PROGRA~2\EMBARC~1\Studio\21.0\bin\bcc32x.exe -DYAML_CPP_STATIC_DEFINE @CMakeFiles/yaml-cpp.dir/includes_CXX.rsp -Wall -Wextra -Wshadow -Weffc++ -Wno-long-long -pedantic -pedantic-errors -oCMakeFiles\yaml-cpp.dir\src\contrib\graphbuilder.cpp.obj -P -c C:\git\Temp\yaml-cpp-master\src\contrib\graphbuilder.cpp Embarcadero C++ 7.50 for Win32 版权所有(c) 2012-2021 Embarcadero Technologies, Inc. .... [ 94%] 链接CXX可执行文件 parse.exe cd C:\git\Temp\yaml-cpp-master\build\util C:\PROGRA~2\EMBARC~1\Studio\21.0\bin\bcc32x.exe --rsp-quoting=windows -oparse.exe @MAKE0000.@@@ Embarcadero C++ 7.50 for Win32 版权所有(c) 2012-2021 Embarcadero Technologies, Inc. bcc32x.exe: 警告: 编译期间未使用的参数: '-nobuiltininc' [-Wunused-command-line-argument] Turbo增量链接器 6.95 版权所有(c) 1997-2021 Embarcadero Technologies, Inc. 错误: 未解析的外部符号__Atomic_fetch_add_4,引用自 C:\GIT\TEMP\YAML-CPP-MASTER\BUILD\YAML-CPP.LIB|nodebuilder.cpp 错误: 无法执行链接 bcc32x.exe: 错误: 链接器命令执行失败,退出码为2 (使用 -Xdriver -v 查看调用详情) ** 错误2 ** 删除 util\parse.exe ** 错误1 ** 删除 util\CMakeFiles\yaml-cpp-parse.dir\all ** 错误1 ** 删除 all
问题根源与解决方案
问题分析
__Atomic_fetch_add_4是C++11原子操作相关的符号,bcc32x编译器默认未链接对应原子操作库,且yaml-cpp默认编译自带工具(如parse.exe)时触发了该依赖。
步骤1:调整CMake编译参数,规避不必要的编译内容
运行CMake时添加以下参数,跳过yaml-cpp的工具、测试及额外模块编译,只构建核心库:
cmake -DCMAKE_CXX_COMPILER=bcc32x.exe ^ -DCMAKE_BUILD_TYPE=Release ^ -DYAML_CPP_BUILD_TOOLS=OFF ^ -DYAML_CPP_BUILD_TESTS=OFF ^ -DYAML_CPP_BUILD_CONTRIB=OFF ^ -DCMAKE_CXX_STANDARD=11 ^ -DCMAKE_CXX_STANDARD_REQUIRED=ON ^ -G "Borland Makefiles" ..
参数说明:
-DYAML_CPP_BUILD_TOOLS=OFF:取消编译parse.exe等工具,直接避免链接错误-DCMAKE_CXX_STANDARD=11:显式指定C++11标准,确保原子操作语法被正确识别- 其他OFF参数:减少编译负载,聚焦核心库构建
步骤2:执行编译并获取产物
运行make完成后,在build目录下会生成:
yaml-cpp.lib:静态链接库(yaml-cpp默认编译为静态库)- 核心头文件:位于源码根目录的
include/yaml-cpp文件夹
步骤3:集成到VCL项目中
- 添加头文件路径:
打开项目选项 →C++ Compiler→Include path,添加yaml-cpp源码中include目录的路径 - 添加库文件路径:
打开项目选项 →C++ Linker→Library path,添加生成的yaml-cpp.lib所在目录 - 定义静态库宏:
打开项目选项 →C++ Compiler→Defines,添加YAML_CPP_STATIC_DEFINE - 代码中使用:
在需要读取YAML的源文件中包含头文件:#include <yaml-cpp/yaml.h>
备选方案:保留原子操作支持
如果你的项目需要多线程场景下的yaml-cpp原子操作支持,需在CMake中添加链接选项,指定链接Embarcadero的crt库:
-DCMAKE_EXE_LINKER_FLAGS="-lcrt"
或者在C++Builder项目的链接选项中手动添加crt.lib。
内容的提问来源于stack exchange,提问作者Jay
相关产品推荐
相关产品推荐

