I'm currently constructing a project with a plugin structure. I'm using CMake to compile the project. The plugins are compiled in separate directories. My problem is that CMake compiles and saves the binaries and plugins, dynamic libraries, in the directory structure of the source. How do I make CMake save the files in something like a ./bin directory?
10 Answers
As in Oleg's answer, I believe the correct variable to set is CMAKE_RUNTIME_OUTPUT_DIRECTORY. We use the following in our root 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) You can also specify the output directories on a per-target basis:
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" ) In both cases you can append _[CONFIG] to the variable/property name to make the output directory apply to a specific configuration (the standard values for configuration are DEBUG, RELEASE, MINSIZEREL and RELWITHDEBINFO).
9 Comments
CMAKE_ARCHIVE_OUTPUT_DIRECTORY, considering that the command install(TARGETS <target_name>) still complains about "given no RUNTIME DESTINATION for executable target"? This variable supposedly provides a default value, therefore the install command should not complain about the absence of a RUNTIME DESTINATION.CMAKE_ARCHIVE_OUTPUT_DIRECTORY sets where static (archive) libraries (.a files on Linux) will be built. It doesn't affect where install puts files.Use set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "/some/full/path/to/bin")
4 Comments
${PROJECT_SOURCE_DIR}/some/path or ${CMAKE_BINARY_DIR}/some/path.Use the EXECUTABLE_OUTPUT_PATH CMake variable to set the needed path. For details, refer to the online CMake documentation:
Comments
As to me I am using cmake 3.5, the below(set variable) does not work:
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/" ) but this works(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/" ) 3 Comments
One more refinement to serg06's answer:
To force the three paths to be used as-is with all generators and for all build configurations, you can add an empty generator expression as in the following:
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 That has the side-effect of forcing the Visual Studio generator in particular to use the specified path as-is, instead of appending a configuration-specific subdirectory, with no need for a foreach loop.
1 Comment
Be careful about changing the OUTPUT_DIRECTORY like the answers above describe. It's not an ideal solution since it can make your CMake project less friendly to add_subdirectory users.
I'm currently constructing a project with a plugin structure. I'm using CMake to compile the project. The plugins are compiled in separate directories. My problem is that CMake compiles and saves the binaries and plugins, dynamic libraries, in the directory structure of the source.
Sounds like your real issue is trying to load dlls.
CMake 3.21 added functionality for this exact situation.
$<TARGET_RUNTIME_DLLS:tgt> New in version 3.21.
This generator expression can be used to copy all of the DLLs that a target depends on into its output directory in a POST_BUILD custom command using the cmake -E copy -t command. For example:
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 ) Link to official documentation:
Fundamentally this is a Windows issue CMake tries to provide a nice solution for since the MSVC compiler doesn't have RPATH support. Which makes this a trivial problem on almost all systems except for Windows.
Comments
To add on to this:
If you're using CMAKE to generate a Visual Studio solution, and you want Visual Studio to output compiled files into /bin, Peter's answer needs to be modified a bit:
# 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 ) Comments
Use this line config:
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/build/)
place your any CMakeLists.txt project.
This ${PROJECT_SOURCE_DIR} is your current source directory where project place .
and if wander why is ${EXECUTABLE_OUTPUT_PATH} check this file CMakeCache.txt then search the key word output path, all the variables define here, it would give a full explanation of the project all setting.
1 Comment
EXECUTABLE_OUTPUT_PATH is superseded by RUNTIME_OUTPUT_DIRECTORY.cat CMakeLists.txt project (hello) set(CMAKE_BINARY_DIR "/bin") set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}) add_executable (hello hello.c)
cmake --install. It will automatically copy executables to abinsubdirectory by default.