How to Make Cmake Output into a 'Bin' Dir

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

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

How to make cmake output to the build directory?

The usual way to do this, rather than changing variables to set the path, is simply to create the output directory, change to it, and run cmake from there. So instead of cmake . you usually have cmake .. or similar.

I understand the initial impulse to say "But I expect my build system to write output somewhere else." But CMake is not usually used in the way you were initially expecting, and other people who run your CMake build won't expect what you were expecting, so it's probably best to just use the built-in, default behavior, which is to put the output wherever cmake was run.

Put another way: You are fighting against the tool. Don't do that.

CMake output/build directory

There's little need to set all the variables you're setting. CMake sets them to reasonable defaults. You should definitely not modify CMAKE_BINARY_DIR or CMAKE_CACHEFILE_DIR. Treat these as read-only.

First remove the existing problematic cache file from the src directory:

cd src
rm CMakeCache.txt
cd ..

Then remove all the set() commands and do:

cd Compile && rm -rf *
cmake ../src

As long as you're outside of the source directory when running CMake, it will not modify the source directory unless your CMakeList explicitly tells it to do so.

Once you have this working, you can look at where CMake puts things by default, and only if you're not satisfied with the default locations (such as the default value of EXECUTABLE_OUTPUT_PATH), modify only those you need. And try to express them relative to CMAKE_BINARY_DIR, CMAKE_CURRENT_BINARY_DIR, PROJECT_BINARY_DIR etc.

If you look at CMake documentation, you'll see variables partitioned into semantic sections. Except for very special circumstances, you should treat all those listed under "Variables that Provide Information" as read-only inside CMakeLists.

CMake output directory by platform

One way would be to set the bin directories for the project:

math(EXPR platform_bits "${CMAKE_SIZEOF_VOID_P} * 8")
set(platform_dir ${CMAKE_SYSTEM_NAME}${platform_bits}-${CMAKE_CXX_COMPILER_ID}${CMAKE_CXX_COMPILER_VERSION})

foreach(config DEBUG RELEASE RELWITHDEBINFO MINSIZEREL)

foreach(var CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${config} CMAKE_LIBRARY_OUTPUT_DIRECTORY_${config} CMAKE_RUNTIME_OUTPUT_DIRECTORY_${config})
set(${var} "${CMAKE_BINARY_DIR}/${platform_dir}-${config}")
string(TOLOWER "${${var}}" ${var})
endforeach()

endforeach()

This won't give you the exact directory names you are looking for, but is a good start. You can look at the CMake variables list for a list of platform specific configuration information. You would then need to apply some logic that will transform the CMake defined values into the specific ones you are looking for.

how to make Cmake output relative path?

(1)Solution to the first problem:Add the following code to your outermost CMakeLists.txt:

set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CMAKE_SOURCE_DIR}/custom_output.sh")

The global RULE_LAUNCH_COMPILE property is set to a custom launch script named custom_output.sh which needs to be added to the root of the CMake source tree:

  #!/bin/bash

# shell script invoked with the following arguments
# $(CXX) $(CXX_DEFINES) $(CXX_FLAGS) -o OBJECT_FILE -c SOURCE_FILE

# extract parameters
SOURCE_FILE="${@: -1:1}"
OBJECT_FILE="${@: -3:1}"

# invoke compiler
{ "$@" 2> >(sed 's@^/mnt/d/demo/@@'|sed "s/warning/${esc}[32m&${esc}[0m/g"|sed "s/error/${esc}[31m&${esc}[0m/g" >&3); } 3>&2

it would output stderr messages also on stderr and transform it to relative path.Where "/mnt/d/demo/" is the string to be deleted. What to delete depends on the source code relative path.

(2)You can use the following command from gdb for remapping to solve the second problem:

set substitute-path old_path new_path

You need add follow code to you launch.json

 "customLaunchSetupCommands": [
{
"text": "set substitute-path /mnt/d d:/",
"description": "change directory to workspace",
"ignoreFailures": false
}
]

If you debug with Cortex Debug you should add follw code to you launch.json

"postLaunchCommands": ["set substitute-path /mnt/d d:/"]

CMake: write executables to multiple subdirectories

You may set CMAKE_RUNTIME_OUTPUT_DIRECTORY variable as many times as you want. Each setting will affect only on the executables created since that setting until the next one.

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
# Futher executables will be placed under 'bin/'
add_executable(my_program <sources>...)

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin/tests)
# Futher executables will be placed under 'bin/tests/' instead
add_executable(test1 <sources>...)
add_executable(test2 <sources>...)

If you are creating the tests in the separate CMakeLists.txt, the settings can be made modular:

CMakeLists.txt:

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
# Futher executables will be placed under 'bin/'
add_executable(my_program <sources>...)

add_subdirectory(tests)

tests/CMakeLists.txt:

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin/tests)
# Executables created below will be placed under 'bin/tests/' instead
add_executable(test1 <sources>...)
add_executable(test2 <sources>...)

Actually, when you call add_executable, it just uses the current value of the CMAKE_RUNTIME_OUTPUT_DIRECTORY variable. This fact can be found in the documentation about RUNTIME_OUTPUT_DIRECTORY target property, which is affected by the variable.



Related Topics



Leave a reply



Submit