Как мне сделать вывод CMake в директорию bin?
В настоящее время я строю проект со структурой плагина. Я использую CMake для компиляции проекта. Плагины скомпилированы в отдельных каталогах. Моя проблема в том, что CMake компилирует и сохраняет двоичные файлы и плагины, динамические библиотеки, в структуре каталогов исходного кода. Как сделать так, чтобы CMake сохранял файлы в директории ./bin?
11 ответов
Как и в ответе Олега, я считаю, что правильная переменная для установки - CMAKE_RUNTIME_OUTPUT_DIRECTORY. Мы используем следующее в нашем корневом CMakeLists.txt:
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
Вы также можете указать выходные каталоги для каждой цели:
set_target_properties( targets...
PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
)
В обоих случаях вы можете добавить _[CONFIG]
к имени переменной / свойства, чтобы сделать выходной каталог применимым к конкретной конфигурации (стандартные значения для конфигурации: DEBUG
, RELEASE
, MINSIZEREL
а также RELWITHDEBINFO
).
Использование set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "/some/full/path/to/bin")
Использовать EXECUTABLE_OUTPUT_PATH
Переменная CMake для установки необходимого пути. За подробностями обращайтесь к онлайн-документации CMake:
Что касается меня, я использую cmake 3.5, ниже (set variable
) не работает:
set(
ARCHIVE_OUTPUT_DIRECTORY "/home/xy/cmake_practice/lib/"
LIBRARY_OUTPUT_DIRECTORY "/home/xy/cmake_practice/lib/"
RUNTIME_OUTPUT_DIRECTORY "/home/xy/cmake_practice/bin/"
)
но это работает (set set_target_properties
):
set_target_properties(demo5
PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY "/home/xy/cmake_practice/lib/"
LIBRARY_OUTPUT_DIRECTORY "/home/xy/cmake_practice/lib/"
RUNTIME_OUTPUT_DIRECTORY "/home/xy/cmake_practice/bin/"
)
$ cat CMakeLists.txt
project (hello)
set(EXECUTABLE_OUTPUT_PATH "bin")
add_executable (hello hello.c)
Английский не мой родной язык; пожалуйста, извините за ошибки при печати.
используйте эту строку конфигурации:set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/build/)
разместите любой ваш проект CMakeLists.txt.
this $ {PROJECT_SOURCE_DIR} - это ваш текущий каталог исходных текстов, в котором находится проект.
и если бродить почему ${EXECUTABLE_OUTPUT_PATH}
проверить этот файл CMakeCache.txt
затем поиск по ключевому слову output path
,
все переменные определяют здесь, это дало бы полное объяснение проекта все setting·
Чтобы добавить к этому:
Если вы используете CMAKE для создания решения Visual Studio и хотите, чтобы Visual Studio выводила скомпилированные файлы в /bin, ответ Питера необходимо немного изменить:
# set output directories for all builds (Debug, Release, etc.)
foreach( OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES} )
string( TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIG )
set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_SOURCE_DIR}/lib )
set( CMAKE_LIBRARY_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_SOURCE_DIR}/lib )
set( CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_SOURCE_DIR}/bin )
endforeach( OUTPUTCONFIG CMAKE_CONFIGURATION_TYPES )
Еще одно уточнение к ответу serg06 :
Чтобы принудительно использовать три пути как есть со всеми генераторами и для всех конфигураций сборки, вы можете добавить пустое выражение генератора, как показано ниже:
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "$<0:>${CMAKE_BINARY_DIR}/bin") # .exe and .dll
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "$<0:>${CMAKE_BINARY_DIR}/lib") # .so and .dylib
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "$<0:>${CMAKE_BINARY_DIR}/lib") # .lib and .a
Побочным эффектом этого является принуждение генератора Visual Studio, в частности, к использованию указанного пути как есть, вместо добавления подкаталога, специфичного для конфигурации, без необходимости в
foreach
петля.
Будьте осторожны при измененииOUTPUT_DIRECTORY
как описано в ответах выше. Это не идеальное решение, поскольку оно может сделать ваш проект CMake менее дружелюбным для пользователей add_subdirectory .
В настоящее время я создаю проект со структурой плагинов. Я использую CMake для компиляции проекта. Плагины собраны в отдельные каталоги. Моя проблема в том, что CMake компилирует и сохраняет двоичные файлы и плагины, динамические библиотеки, в структуре каталогов источника.
Похоже, ваша настоящая проблема заключается в попытке загрузить библиотеки DLL.
В CMake 3.21 добавлена функциональность именно для этой ситуации.
$<TARGET_RUNTIME_DLLS:tgt> New in version 3.21.
Это выражение генератора можно использовать для копирования всех DLL, от которых зависит цель, в выходной каталог с помощью пользовательской команды POST_BUILD с помощью команды cmake -E copy -t. Например:
find_package(foo CONFIG REQUIRED) # package generated by install(EXPORT)
add_executable(exe main.c)
target_link_libraries(exe PRIVATE foo::foo foo::bar)
add_custom_command(TARGET exe POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy -t $<TARGET_FILE_DIR:exe> $<TARGET_RUNTIME_DLLS:exe>
COMMAND_EXPAND_LISTS
)
Ссылка на официальную документацию:
По сути, это проблема Windows, для которой CMake пытается предложить хорошее решение, поскольку компилятор MSVC не имеетRPATH
поддерживать. Это делает эту проблему тривиальной практически для всех систем, кроме Windows.
cat CMakeLists.txt
project (hello)
set(CMAKE_BINARY_DIR "/bin")
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR})
add_executable (hello hello.c)
Независимо от того, определяю ли я это в основном файле CMakeLists.txt или в отдельных файлах, он по-прежнему предполагает, что я хочу, чтобы все библиотеки и бункеры находились вне основного пути, что является наименее полезным предположением из всех.