CMake output to build directory [duplicate] - c++

Is it possible to specify build directory within CMakeLists file? If yes, how.
My aim is to be able to call "cmake" within top level source directory and have cmake figure out the build directory.

Afaik, with CMake the build directory is always the directory from where you invoke the cmake or ccmake command. So if you want to change the build directory, you have to change directories before running CMake.
To control the location where executables, static and shared libraries are placed once finished, you can modifiy CMAKE_RUNTIME_OUTPUT_DIRECTORY, CMAKE_ARCHIVE_OUTPUT_DIRECTORY, and CMAKE_LIBRARY_OUTPUT_DIRECTORY respectively.

By design, there is not a way to specify that in CMakeLists.txt. It is designed for the user to be able to build the project in whatever directory they want. The typical workflow is:
Check out the project source code.
Go to desired build directory, or the source dir if you plan to do an in-source build.
Run cmake or ccmake to configure the project in that build directory.
Build your project.
All of the directories specified within your CMakeLists.txt should be relative to the ${PROJECT_BINARY_DIR} and ${PROJECT_SOURCE_DIR} variables. In this way, your code becomes buildable across different platforms, which is the goal of CMake.

Related

CMake run custom command with externalproject's target

I have a subproject in my project for generating code used in the project, however i want to include it using ExternalProject so it can be built and ran regardless of the toolchain i use for the main project.
It mostly works except i can't figure out how to use it in add_custom_command, since i want it to use the target rule specified in the docs:
If COMMAND specifies an executable target name (created by the add_executable() command), it will automatically be replaced by the location of the executable created at build time [...]
Simple example of my project setup that replicates the issue:
https://godbolt.org/z/of8G4c4Gf
Replacing the ExternalProject_Add with a simple add_subdirectory makes it work, but wouldn't do what i want in the case of using a different toolchain.
ExternalProject_Add will add the codegen target. However, CMake has no idea what that target is doing and what output it will provide, as that info is now hidden away in the external CMake run. So the outer CMake run has no idea about the codegen binary produced by that step and where it will be located. You need to provide the full path to the executable to add_custom_command manually.
ExternalProject_Add will build codegen and place the resulting binary in a subdirectory inside your build directory. The exact location is toolchain dependent, so it can be tricky to reconstruct the full target path. The most robust way to solve this is:
Add an install step to the codegen project. This will allow you to portably specify which path the installed binary will end up in relative to the install root directory.
Set the INSTALL_DIR option on ExternalProject_Add to a subdirectory inside your PROJECT_BINARY_DIR.
Hardcode the full path to the installed codegen binary in the custom command of the outer CMake project. To work on multiple platforms, you may need to make use of the CMAKE_EXECUTABLE_SUFFIX variable.

Makefile pass-through in a CMake project

I have a project which uses CMake. Most of the project builds with CMake, but there's one subdirectory with a complicated build procedure that doesn't work with CMake. For this one directory, we have a hand-written Makefile. To build this one special directory, we manually copy it over to the build directory and call make on it after we've called cmake && make to build the rest of the project.
What I want CMake to do is just copy over this one directory to the build directory as is, with its existing Makefile, without trying to generate a Makefile. Then when I call make on the top level build directory, it just invokes the hand-written Makefile for this one directory. Is this possible?
I short: Yes, this is possible.
Steps:
Copy the Directory
Add the Makefile as a build step using either add_custom_target or add_custom_command depending on the purpose of the makefile

What does cmake .. do?

I got the Box2D project source and want to compile the testbed portion of it.
The project folder contains folders like: freeglu glui testbed(a demo) helloword(a demo)
Box2D Build CMakeFiles
There are many CMakeLists.txt in all the different folders.
I was thinking that I should cmake all those files so that make files are created in all places required.
I read this (as instructions to do do want I want) :
wget http://box2d.googlecode.com/files/Box2D_v2.2.1.zip
unzip Box2D_v2.2.1.zip
cd Box2D_v2.2.1/Build
cmake ..
make
What does the cmake .. do?
There is no CMakeLists.txt in the build folder.
cmake is a Makefile generator.
When you call cmake [path], you ask it to generate a Makefile in the current directory following instructions given in [path]/CMakeLists.txt
Usually cmake output some messages while it is working, and after it is done without errors, you can type "make" to execute your newly created Makefile.
CMakeLists.txt files can reference other CMakeLists.txt file in sub-directories, so you are usually only interested by the CMakeLists.txt of the top directory, not the other ones.
Using an empty "build" directory is a technique called "out-of-source build", in which all your generated files (.o, executable, Makefile, .anything) are generated in the separate "build" directory and not mixed with source files. If you want to clean all, you can delete all the content of the build directory.
In fact, you can put your "build" directory in any place, as long as you give cmake the correct path of the top CMakeLists.txt. You can even have several build directories. It is very useful if you need several different builds at the same time (with different options, different versions of gcc, etc.)
In old programs, you generate the Makefile too, but using ./configure (this is called auto-tools. You may have encountered that already). cmake is considered a successor of the auto-tools.
cmake .. generates makefiles in the current directory, using ../CMakeLists.txt file as starting point. make command, executed after this, builds the program, using generated makefile(s) as an input. This is convenient to keep a source code and build results in different folders. General syntax is: cmake source-dir (of course, there are a lot of other switches).
Well, .. is shorthand for the parent folder, so it will presumably act upon whatever it finds in Box2D_v2.2.1.

Working with Multiple Projects in CMake

I am currently working on transitioning over a Visual C++ project (that has multiple subprojects inside of it) over to CMake.
There is one thing that I am not sure about – basically, to include the subprojects from the top level CMakeLists.txt file, I just utilize the add_subdirectory command, and reference the directories that these various subprojects are stored under.
However, I have one project that is in the same directory as my top level CMakeLists.txt file, and so I am wondering if it is still possible to include this file somehow? CMake does not allow me to call add_subdirectory on the existing PROJECT_BINARY_DIR (see below):
add_subdirectory(${PROJECT_BINARY_DIR}) #not allowed in CMake
I cannot think of another way for me to include this subproject into my CMake build. Any ideas?
All add_subdirectory does is add a subdirectory with a CMakeLists.txt file in it, and so it would not make sense to allow you to add the current directory. You can simply add the CMake logic to build that part of your project in the CMakeLists.txt file. If you would like to separate the logic, then you could put it in build_project.cmake, and then use include,
include(build_project.cmake)
You can include as many other CMake files as you like, and that CMake code will be evaluated as if it was pasted inline. So all the normal add_executable and similar commands would work.

cmake to place the intermediate files to a certain directory

I am pretty new to cmake and wonder how I can do this is cmake. I want to place all the intermediate files (like the .o files) to be placed in a certain directory (say "build") and then once the build is done I want copy certain files I need (e.g., the .exe, .dll like the end product) from build directory to "stage" directory. how can I specify the path to these two directories (build and stage)? Cmake will also check if the build/stage directory exists or not. If does not exist, it will create the directories for me.
Any help will be appreciated.
What are you asking is the most often CMake use case.
To make whole build process to occur in arbitary dir, you should run cmake /path/to/your/project from that dir (or use cmake-gui).
Your source dir would be untouched until you explicitly tell CMake to output some files there.
As for point 2:
You should place install() invocations into your CMakeLists.txt (see documentation on install()) and set CMAKE_INSTALL_PREFIX to the dir where you wish files to be copied. After that you can run make install or cmake -P cmake_install.cmake from your build dir to install these files.
I would suggest another approach.
make out-of-source builds see here, so that all your build stuff is in an own folder
copy your executables from your build directory in an own folder with explicit copying see here
Or instead of choosing step 2 you also can provide an install routine where the needed executables are installed in a give path. see here