【问题标题】:How to make Boost DLLs accessible to an executable built with CMake?如何使使用 CMake 构建的可执行文件可以访问 Boost DLL?
【发布时间】:2011-12-20 04:05:06
【问题描述】:

我在 Windows 上使用 CMake 来构建基于 Boost.Test 的测试套件。当我动态链接到 Boost.Test 时,我的可执行文件需要能够找到 DLL(位于 ../../../boost/boost_1_47/lib 或与可执行文件相关的类似内容下)。

所以我需要将 DLL 复制到可执行文件所在的文件夹中,或者以其他方式使其可找到。使用 CMake 实现这一目标的最佳方法是什么?

-- 附加信息--

我的 CMakeLists.txt 目前有这个 Boost 相关配置:

set(Boost_ADDITIONAL_VERSIONS "1.47" "1.47.0")
set(BOOST_ROOT "../boost")

find_package(Boost 1.47 COMPONENTS unit_test_framework REQUIRED)
include_directories(${Boost_INCLUDE_DIR})
link_directories(${Boost_LIBRARY_DIR})

add_executable(test-suite test-suite.cpp)
target_link_libraries(test-suite ${Boost_LIBRARIES})

【问题讨论】:

标签: windows dll boost cmake


【解决方案1】:

假设您通过在 Visual Studio 中构建 RUN_TESTS 目标来运行测试:

  1. 我总是将 .../boost/boost_1_47/lib 添加到我的命令 PATH 环境变量中,因此可以在运行时找到 boost unit_test_framework dll。这就是我的建议。

  2. 如果由于某种原因无法更改 PATH,您可以使用 cmake 复制文件。

(未经测试)

get_filename_component(LIBNAME "${Boost_UNIT_TEST_FRAMEWORK_LIBRARY_RELEASE}" NAME)
add_custom_command(TARGET test-suite POST_BUILD
    COMMAND ${CMAKE_COMMAND} -E copy "${Boost_UNIT_TEST_FRAMEWORK_LIBRARY_RELEASE}" "${CMAKE_CURRENT_BINARY_DIR}/${LIBNAME}"
)

3。如果您仅在构建时运行测试(正如我上面假设的那样),那么您需要一系列 INSTALL 命令,就像 Hans Passant 建议的那样。在您的 sn-p 中,您的可执行文件没有 INSTALL 命令;因此,即使您的可执行文件也不会最终出现在“可执行文件夹中”。首先添加一个 cmake INSTALL 命令将您的可执行文件放在某个位置以响应 cmake INSTALL 目标。一旦你完成了这项工作,我们就可以研究如何添加另一个 INSTALL 命令来将 boost unit_test_framework 库放入相同的位置。之后,如果您想使用 CPACK 制作安装程序,该库将自动与可执行文件一起安装。

【讨论】:

    【解决方案2】:

    我最终使用install 命令将 Boost DLL 复制到可执行文件的文件夹:

    get_filename_component(UTF_BASE_NAME ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY_RELEASE} NAME_WE)
    get_filename_component(UTF_PATH ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY_RELEASE} PATH)
    install(FILES ${UTF_PATH}/${UTF_BASE_NAME}.dll
      DESTINATION ../bin
      CONFIGURATIONS Release RelWithDebInfo
    )
    
    get_filename_component(UTF_BASE_NAME_DEBUG ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY_DEBUG} NAME_WE)
    install(FILES ${UTF_PATH}/${UTF_BASE_NAME_DEBUG}.dll
      DESTINATION ../bin
      CONFIGURATIONS Debug
    )
    

    【讨论】:

      【解决方案3】:

      我有一个非常相似的问题,但这里提出的解决方案并不令人满意。 像原始海报一样,我想基于 boost::test 运行单元测试。

      我有多个测试项目,一个针对我们产品的每个主要组件。 必须在每次测试之前运行安装目标意味着重新编译整个东西只是为了运行属于核心组件的测试。这就是我想要避免的。

      如果我更改核心组件中的某些内容,我想编译该核心组件和相关的测试。然后运行测试。当测试成功时,我才想编译并最终安装它的其余部分。

      为了在调试器中运行测试,我在以下位置找到了一些非常有用的 cmake 脚本: https://github.com/rpavlik/cmake-modules

      有了这个,我可以指定所需dll的所有目录,并为新进程设置PATH环境变量:

      # for debugging
      INCLUDE(CreateLaunchers)
      
      create_target_launcher(PLCoreTests 
          ARGS  "--run-test=Core1"
          RUNTIME_LIBRARY_DIRS ${PL_RUNTIME_DIRS_DEBUG} ${PROJECT_BINARY_DIR}/bin/Debug 
          WORKING_DIRECTORY ${PL_MAIN_DIR}/App/PL/bin
      )
      

      其中 ${PL_RUNTIME_DIRS_DEBUG} 包含可以找到来自 boost 和所有其他库的 dll 的目录。

      现在我正在寻找如何使用 ADD_CUSTOM_COMMAND() 实现类似的功能

      更新:

      ADD_CUSTOM_COMMAND() 可以有多个 cmake 写入批处理文件的命令。因此,您可以先设置所有运行时目录的路径,然后执行测试可执行文件。为了能够轻松地手动执行测试,我让 cmake 在构建目录中创建了一个额外的批处理文件:

      MACRO(RunUnitTest TestTargetName)
          IF(RUN_UNIT_TESTS)
              SET(TEMP_RUNTIME_DIR ${PROJECT_BINARY_DIR}/bin/Debug)
              FOREACH(TmpRuntimeDir ${PL_RUNTIME_DIRS_DEBUG})
                  SET(TEMP_RUNTIME_DIR  ${TEMP_RUNTIME_DIR}  ${TmpRuntimeDir})
              ENDFOREACH(TmpRuntimeDir)
      
              ADD_CUSTOM_COMMAND(TARGET ${TestTargetName} POST_BUILD 
                  COMMAND echo "PATH=${TEMP_RUNTIME_DIR};%PATH%" > ${TestTargetName}_script.bat
                  COMMAND echo ${TestTargetName}.exe --result_code=no --report_level=no >> ${TestTargetName}_script.bat
                  COMMAND ${TestTargetName}_script.bat
                  WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Debug
              )
          ENDIF(RUN_UNIT_TESTS)
      ENDMACRO()
      

      这样,单元测试可以尽快捕获错误,而无需先编译全部内容。

      【讨论】:

        猜你喜欢
        • 2017-11-12
        • 1970-01-01
        • 2013-08-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-09-08
        • 1970-01-01
        • 2021-07-17
        相关资源
        最近更新 更多