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?
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
).
Use set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "/some/full/path/to/bin")
Use the EXECUTABLE_OUTPUT_PATH
CMake variable to set the needed path. For details, refer to the online CMake documentation:
$ cat CMakeLists.txt
project (hello)
set(EXECUTABLE_OUTPUT_PATH "bin")
add_executable (hello hello.c)
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/"
)
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.
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 )
cat CMakeLists.txt
project (hello)
set(CMAKE_BINARY_DIR "/bin")
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR})
add_executable (hello hello.c)
Regardless of whether I define this in the main CMakeLists.txt or in the individual ones, it still assumes I want all the libs and bins off the main path, which is the least useful assumption of all.
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.
Success story sharing
CMAKE_ARCHIVE_OUTPUT_DIRECTORY
, considering that the commandinstall(TARGETS <target_name>)
still complains about "given no RUNTIME DESTINATION for executable target"? This variable supposedly provides a default value, therefore theinstall
command should not complain about the absence of aRUNTIME DESTINATION
.CMAKE_ARCHIVE_OUTPUT_DIRECTORY
sets where static (archive) libraries (.a files on Linux) will be built. It doesn't affect whereinstall
puts files.