Как сделать библиотеки Boost доступными для исполняемого файла, созданного с помощью CMake? - PullRequest
9 голосов
/ 02 ноября 2011

Я использую CMake в Windows для создания набора тестов на основе 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})

Ответы [ 3 ]

6 голосов
/ 30 ноября 2011

Предполагается, что вы выполняете свои тесты, создавая цель RUN_TESTS в Visual Studio:

  1. Я всегда добавляю ... / boost / boost_1_47 / lib в мою переменную среды PATH, поэтомуDLL-файлы boost unit_test_framework можно найти во время выполнения.Это то, что я рекомендую.

  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, как предложил Ханс Пассант.В вашем фрагменте у вас нет команды INSTALL для вашего исполняемого файла;так что даже ваш исполняемый файл не окажется "в папке с исполняемыми файлами".Сначала добавьте команду cmake INSTALL, чтобы поместить исполняемый файл куда-нибудь в ответ на цель cmake INSTALL.Когда у вас все получится, мы сможем разобраться, как добавить еще одну команду INSTALL, чтобы поместить библиотеку boost unit_test_framework в то же место.После этого, если вы хотите создать установщик с использованием CPACK, библиотека будет автоматически установлена ​​вместе с исполняемым файлом.

4 голосов
/ 01 марта 2012

Я закончил тем, что использовал команду 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
)
2 голосов
/ 28 августа 2012

У меня очень похожая проблема, но представленное здесь решение не является действительно удовлетворительным.Как и оригинальный постер, я хочу запустить модульные тесты на основе boost :: test.

У меня есть несколько тестовых проектов, по одному для каждого компонента мэра нашего продукта.Необходимость запуска цели установки перед каждым тестом означает перекомпиляцию всего, чтобы запустить тесты, относящиеся к основному компоненту.Вот чего я хочу избежать.

Если я что-то изменю в основном компоненте, я хочу скомпилировать этот основной компонент и связанные с ним тесты.А затем запустите тесты.Когда тесты пройдут успешно, только тогда я захочу скомпилировать и в конце концов установить оставшуюся часть.

Для запуска тестов в отладчике я нашел несколько очень полезных скриптов cmake по адресу: https://github.com/rpavlik/cmake-modules

С этим я могу указать все каталоги необходимых библиотек, и переменная окружения 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} содержит каталоги, в которых библиотек 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()

При этом модульные тесты отлавливают ошибки как можно скорее, без необходимости компилироватьсначала весь лот.

...