Makefile pass-through in a CMake project - c++

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

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.

CMake output to build directory [duplicate]

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.

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.

What is nmake equivalent of 'configure --prefix=DIR && make all install '?

I would like my nmake output to go to a particular directory.
The short bit is that there isn't such a thing as Make and configure do two different things. The configure is what creates a Makefile, and a Makefile is what actually contains the compiler commands to build the software. Together they create what is called a build system. To specify the target directory, you'll need to review what creates that makefile for you. However, if you do not generate a Makefile, it is likely that there is a variable which you can override with your target directory, something like:nmake DESTDIR="Path"
With your added comment regarding your file, if it's set-up like this project, then you'll can use nmake PREFIX="Path"

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