Краткий ответ
В 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
)