Как указать выходной каталог данной DLL? - PullRequest
0 голосов
/ 09 июня 2019

Я использую следующее src/CMakeLists.txt:

cmake_minimum_required(VERSION 3.1.0)
project(foo)
add_library(foo SHARED foo.cpp)
set_target_properties(foo
    PROPERTIES
        LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/$<CONFIG>/subdir
)

А в Windows я собираю библиотеку, используя:

mkdir build
cd build
cmake ../src
cmake --build .

Выходной файл: ~/build/Debug/foo.dll

Ожидаемый выходной файл: ~/build/Debug/subdir/foo.dll

Что я делаю не так?

Отлично работает на платформах, отличных от Windowsи, похоже, он должен работать в соответствии со следующей документацией:

1 Ответ

0 голосов
/ 09 июня 2019

Краткий ответ

В Windows, в отличие от других платформ, вы должны использовать RUNTIME_OUTPUT_DIRECTORY вместо LIBRARY_OUTPUT_DIRECTORY для указания выходного каталога общей библиотеки.

Длинный ответ

Это описано в документации CMake о Выходных артефактах :

Артефакты вывода во время выполнения

Выходной артефакт времени выполнения системы сборки цель может быть:

  • Исполняемый файл (например, .exe) исполняемой цели, созданной Команда add_executable ().
  • На платформах DLL: исполняемый файл (например, .dll) цели общей библиотеки , созданной командой add_library () с опцией SHARED. RUNTIME_OUTPUT_DIRECTORY и Свойства назначения RUNTIME_OUTPUT_NAME могут использоваться для контроля времени выполнения Вывод местоположений и имен артефактов в дереве сборки.

Артефакты вывода библиотеки

Выходной артефакт библиотеки системы сборки цель может быть:

  • Загружаемый файл модуля (например, .dll или .so) цели библиотеки модулей созданный командой add_library () с опцией MODULE.
  • С платформы, отличные от DLL: файл общей библиотеки (например, .so или .dylib) целевая библиотека , созданная командой add_library () с ОБЩАЯ опция LIBRARY_OUTPUT_DIRECTORY и Целевые свойства LIBRARY_OUTPUT_NAME могут использоваться для управления библиотекой Вывод местоположений и имен артефактов в дереве сборки.

Но почему CMake делает такое различие между платформами DLL (Windows) и платформами не-DLL (macOS, Linux и т. Д.)?

Я не смог найти источник, документирующий это проектное решение, но я считаю, что логическое обоснование состоит в том, что Windows не поддерживает концепцию rpath, то есть .exe файлы не могут внутренне хранить местоположение их зависимых .dll файлов. Поэтому в Windows файлы .dll часто хранятся в той же папке, что и файлы .exe, чтобы убедиться, что библиотеки DLL находятся во время выполнения. Вместо этого в системах Unix файлы общей библиотеки часто хранятся в отдельной папке lib, в то время как двоичные файлы приложений хранятся в папке bin, что не является проблемой, поскольку двоичные файлы могут хранить расположение своих зависимостей, используя rpath .

В заключение, для кроссплатформенной разработки имеет смысл определить и LIBRARY_OUTPUT_DIRECTORY и RUNTIME_OUTPUT_DIRECTORY, вот так:

cmake_minimum_required(VERSION 3.1.0)
project(foo)
add_library(foo SHARED foo.cpp)
set_target_properties(foo
    PROPERTIES
        LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/$<CONFIG>/lib
        RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/$<CONFIG>/bin
)
...