CMake retrieve output path - build

In my Application the user can click on a "Build" button. This will invoke a file dialogue where the user selects the folder with the CmakeCache. After that I'll invoke the cmake --build command with system(command) and the executeable will be built.
Now I'd like to know the path where the executeable was built. I need to copy files into that path.
I know that the file located at /CMakeCacheFolder/projectname/projectname.dir/Release/projectname.log contains the compiler log with the output path in the last line. But is there some other way?

Output directory of the executable/library target tgt can be obtained with generator expression
$<TARGET_FILE_DIR:tgt>
Because this is a generator expression, it can be used only in limited cases. (CMake documents every command and parameter, for which a generator expression can be used).
If you know, that output directory for the target is set via assigning CMAKE_RUNTIME_OUTPUT_DIRECTORY variable, then you may read either this variable or the target's property RUNTIME_OUTPUT_DIRECTORY. Unlike to the generator expressions, the variable's and the property's values can be used everywhere.
But note, that in case of multi-configuration generators (like Visual Studio), configuration name is appended to the variable's (or property's) value for obtain real output directory.

Not a full answer but too much for a comment:
You can define the output directories for executables, shared objects, and libraries for a project as follows:
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
And as you determine where to build you now have a common output directory under a well known path.
The directories could also be given on a configuration basis (Debug/Release/RelWithDebInfo/...) as follows
CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG
CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE
CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO
Hope that helps you further.

Related

Retrieve Path by Wildcard in custom taget CmakeLists.txt

I'm trying to create a custom target in a CmakeList.txt which I'm planning to execute during the build process with Conan. When executing the build with conan build the sources are compiled and built, creating an output file with a dynmic name and a .a file extensions. Now my question is how is it possible to retrieve the path to this .a file?
I've tried things like this:
set(A_FILE ${CMAKE_BINARY_DIR}/*.a) or file(GLOB A_FILE ${CMAKE_BINARY_DIR}/*.a)
But unfortunately both variants do not resolve the wildcard character and I end up with a path that is not usable. Is there any way to retrieve a path with the file extensions and some wildcards in a custom target?
This target would be executed after the build process has finished and produced the *.a file.
If you want to manipulate created library after it is built, you can use add_custom_command with generator expressions:
#create library
add_library(my_lib STATIC my_lib.cpp)
# list the contents of a newly created library
add_custom_command(
TARGET my_lib
POST_BUILD
COMMAND ar -t $<TARGET_FILE:my_lib>
)
Note the $<TARGET_FILE:my_lib>; it is a generator expression that will retrieve the full path to the target my_lib.
BTW, trying to guess/figure-out library path in a configure phase (i.e. during cmake run) is wrong, and will almost never work correctly. Instead, use "generator expressions" to retrieve the required data.
At the end, here is the documentation about add_custom_command(build_events), and generator expressions (target queries).

Custom CMake target that uses only CMake functions [duplicate]

I have a project under CMake with some files generated with python generator from XML files. I cannot specify all files generated by this generator in CMakeLists.txt so I use file globbing for this.
The problem is that when I update my XML files or generator sources (which are in the same repository) I would like to have my build system reconfigured so changed files are taken into account when rebuilding the code (via make for example).
Is it possible to make CMake treat some files like it treats CMakeLists.txt files and to make it regenerate build system when those file are changed?
It doesn't require any kind of workarounds. The standard way is to use CMAKE_CONFIGURE_DEPENDS property:
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS <filename>)
Yes, you should be able to do that by (ab)using configure_file(). Configuring a file makes the source a dependency of the CMake run, so that any changes in it cause a reconfiguration. Simply like this:
configure_file(MyInputFile.xml DummyOutput.xml)
Since it has been a while I will add to #roolebo's answer.
There's actually a better command to add a dependency on a file:
set_directory_properties(PROPERTIES CMAKE_CONFIGURE_DEPENDS <relative_or_full_path_to_file>)
What might be confusing is that this command adds a property to the current directory. Well, it does not matter since you can set a full path to a file that resides outside of the current directory's scope, for instance: ../../config.json

Why aren't binaries placed in CMAKE_CURRENT_BINARY_DIR?

It is my understanding that CMAKE_CURRENT_BINARY_DIR should point to the directory where binaries for the current CMakeLists.txt file will be placed. However, this doesn't seem to be the case.
Consider this file structure:
CMakeTest
+- CMakeLists.txt
+- main.cpp
CMakeLists.txt
cmake_minimum_required(VERSION 3.2)
add_executable(CMakeTest main.cpp)
message(STATUS "CMAKE_CURRENT_BINARY_DIR = ${CMAKE_CURRENT_BINARY_DIR}")
main.cpp
#include <iostream>
int main() {
std::cout << "Hello, World!";
return 0;
}
On the (Windows) command line, I run the following commands:
md build
cd build
cmake .. -G "Visual Studio 14 2015"
cmake --build .
The first cmake command prints (among other things) the line
CMAKE_CURRENT_BINARY_DIR = X:/dev/projects/CMakeTest/build
So I'd expect the resulting binary file CMakeTest.exe to end up there. Really, however, it is placed in X:/dev/projects/CMakeTest/build/Debug.
Why isn't the binary file placed into CMAKE_CURRENT_BINARY_DIR, but in a sub-directory? And is there any CMake variable that tells me what that subdirectory is?
Edit:
I'm not trying to change the directory where binaries are placed. I'm trying to determine it. The reason is this:
During build, a number of additional resource files are created in the same directory as the executable file. (This part works.) I'd like to use the install(FILES, ...) command to then add these files to the resulting package. So I need to pass the actual path where the binaries are placed to install(FILES, ...).
Variable CMAKE_CURRENT_BINARY_DIR denotes "binary directory currently being processed" by CMake. Usually, this directory and its subdirectories contains build artifacts, like executables, libraries or other generated files.
If you want to control location of executable being built, you need to set variable CMAKE_RUNTIME_OUTPUT_DIRECTORY.
Note, that multiconfiguration build tools, like Visual Studio, for each specific configuration will create subdirectory (named as configuration itself) under CMAKE_RUNTIME_OUTPUT_DIRECTORY. Otherwise, executables created for different configurations would overwrite themselves.
For precise control of per-configuration directory used for built executables, use variable CMAKE_RUNTIME_OUTPUT_DIRECTORY_<CONFIG>. (Instead of <CONFIG> name of specific configuration should be inserted, so CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG variable will affect Debug builds).
For just determine directory with executable, use $<TARGET_FILE_DIR:tgt> generator expression (instead of tgt a name of the target created the executable should be used).
Note, that generator expressions can be used only in specific places. E.g., list of files for install(FILES) command can use generator expression, but message() command cannot.
Yes, the executables are often stored at a level below the CMAKE_CURRENT_BINARY_DIR, based on the build type. You can navigate to this directory directly by using ${CMAKE_BUILD_TYPE} (which is typically has value of Debug or Release) by building a full path like:
${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}

cannot change cmake executable output directory on windows

I have a project that builds on both Linux and Windows.
In that, I have in a subfolder somedir/modules/MyModule a CMakeLists.txt which should add some test executables. cmake wants to put them in some subdirectory binary folder, but I want to place them in the common binary folder under ${CMAKE_BINARY_DIR}/x64
So what I'm doing is this (in the CMakeLists.txt in the somedir/modules/MyModules directory):
ADD_EXECUTABLE(MyTest MyTest.cpp)
set_target_properties(MyTest PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/x64")
TARGET_LINK_LIBRARIES(MyTest SomeLibraries...)
ADD_TEST(MyTest ${CMAKE_BINARY_DIR}/x64/MyTest)
Under Linux this works nicely, but under Windows I simply cannot get it to build into the ${CMAKE_BINARY_DIR}/x64 folder. I've checked via MESSAGE, the ${CMAKE_BINARY_DIR}/x64 does point to the right folder. I also tried changing the CMAKE_RUNTIME_OUTPUT_DIRECTORY (or even the per-target variables, e.g. CMAKE_MyTest_OUTPUT_DIRECTORY, MyTest_OUTPUT_DIRECTORY_Release, MyTest_OUTPUT_DIRECTORY_Debug, as mentioned here: https://stackoverflow.com/a/25328001/671366). Tested both before or after ADD_EXECUTABLE, doesn't change anything. The output directory stays fixed on somedir/modules/x64/.
I'm out of ideas what I need to do, or even where the output directory it insists on using is coming from. Any ideas? At which point in time is the output directory decided in cmake? How does this relate to subdirectories? The executables specified in the parent folder CMakeLists.txt files get built in the desired directory, but if that is by mere chance I can't really say.
Config-specific property RUNTIME_OUTPUT_DIRECTORY_<CONFIG> has priority over common one RUNTIME_OUTPUT_DIRECTORY. Both types of properties are initialized from corresponded CMAKE_* variable(if it is set) when executable target is created.
So, having e.g CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG config-specific variable being set makes this variable to be used for Debug configuration even if RUNTIME_OUTPUT_DIRECTORY property is explicitely set. The only way to redefine output directory in that case is to set RUNTIME_OUTPUT_DIRECTORY_DEBUG config-specific property.

Set C++ object file output location with CMake

I would like to use CMake for a project, but I have the following two requirements:
The final output of the project should be a set of object files (*.o).
The location of the object files is important. I want to select which directory the files are outputted.
Does CMake support this type of behavior? If so, how? Can I do it with move commands after the object file is build?
First create an object library.
Now the problem is that:
Object libraries cannot be imported, exported, installed, or linked.
http://www.cmake.org/cmake/help/v2.8.11/cmake.html#command:add_library
I would try to use the install(DIRECTORY ...).
Using the options:
DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} #Probably you have to check more precisely where the object files are built
DESTINATION #it's something relative to DESTDIR, if set, or CMAKE_INSTALL_PREFIX otherwise
FILES_MATCHING
PATTERN "*.o"
A flaw of this solution will be in the output directory name, that will be basically decided by cmake, I wonder if anything can be done in that respect.