ChatGPT解决这个技术问题 Extra ChatGPT

How do I make CMake output into a 'bin' dir?

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?


P
Peter Mortensen

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).


You can also override this on a per-target basis by setting the RUNTIME_OUTPUT_DIRECTORY target property. See documentation here: cmake.org/cmake/help/…
DLRdave's link is dead. Try cmake.org/cmake/help/v2.8.8/…
How to make it apply to all configurations at once?
What is the purpose of setting 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.
G
Guy Avraham

Use set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "/some/full/path/to/bin")


Use the full path name to the directory as the variable value, and do not put a trailing "/" in the value... as in Adam Bowen's answer.
Why do you need to add the full path? It seems like an annoyance when you move your project...
maybe change the path "/some/full/path/to/bin" to something relative to the root CMakeLists.txt which will have its path set in ${CMAKE_SOURCE_DIR}
P
Peter Mortensen

Use the EXECUTABLE_OUTPUT_PATH CMake variable to set the needed path. For details, refer to the online CMake documentation:

CMake 2.8.8 Documentation


EXECUTABLE_OUTPUT_PATH still works right now, but is the "old" way of achieving this result. Adam Bowen's answer is the recommended approach.
m
mcandre
$ cat CMakeLists.txt
project (hello)
set(EXECUTABLE_OUTPUT_PATH "bin")
add_executable (hello hello.c)

J
Jayhello

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/"
)

I am using Adam's answer with set (CMAKE_... and it works, but only when you do it before adding libraries, executables etc. I think it's an important note for beginners like me.
Wow. @ashrasmun saved me from going insane after a few hours. Absolutely nothing was working until coming to the realization that the order of these commands is very relevant.
CMake version 3.19, this worked: set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "/some/full/path/to/bin"). Also you can specify path relative to the current directory (directory from which the cmake command is being executed).
u
user438383

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.


s
serg06

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 )

P
Paul Floyd
cat CMakeLists.txt
project (hello)
set(CMAKE_BINARY_DIR "/bin")
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR})
add_executable (hello hello.c)

Could you add some explanation to your answer?
J
Jerry Miller

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.


B
BTJ

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.