How to parse whole project but build only subfolder that have dependancies on other subfolder, using cmake - cmake

I'm porting a project to linux and cmake. It is part of a huge project, each subproject in a folder. I want to build only my project and its dependencies.
I can comment the other projects from the main CMakeList.txt file, but that doesn't work because there are a few dependencies to other projects (which may also depend on other projects...)
I don't want to modify all the cmake files from other projects to build only the small pieces that I need because is very error prone and time consuming. I could checkin something by mistake which I was not supposed to, for example.
My main problem is that the other projects break continuisly (almost everybody else is just working in windows, so the linux build is not taken good care of) and is slowing me down a lot.
My question is: Is there a way to tell cmake: run through all the project, but compile only what is needed to compile certain subfolder?

You can do:
add_subdirectory(dir EXCLUDE_FROM_ALL)
and then all targets within that subdirectory (and recursive) are by default marked with EXCLUDE_FROM_ALL, that way they will not build by default.
You may also specify the specific targets to be build with:
cmake --build the_build_dir --target this_target -t another_target

Related

How do you make CMake skip an ExternalProject on subsequent runs?

I'm using CMake for a project where I want to bundle Clang. I use ExternalProject_Add to build clang from source. However, since Clang and LLVM is huge, a make with nothing changed takes 45 seconds.
Is there a way to make CMake just build the ExternalProject once, and then not even check if anything has changed on subsequent runs if it has already been built successfully?
The best way to use ExternalProject_Add() is to structure your project as a superbuild. This means that your top-level project (the "superbuild") does not build any actual code and instead consists only of ExternalProject_Add calls. Your "real" project is added as one of these "external" projects. This allows you to set up the superbuild with all dependencies, ordering, etc.
The workflow is then as follows:
Generate the superbuild project.
Build the superbuild project. This will build and install all dependencies, and also generate (and build) your real project.
Switch to the buildsystem generated for your real project and start doing further development using that. Your dependencies are already correctly set up and installed by the build of the superbuild project in the previous step, and will never be checked for out-of-dateness by the build.
If you ever need to change the setup of your dependencies, do it and build the superbuild again.

Automatic recompilation: if a CMake client project depends on a separate CMake library, how to have the client project re build its dependency?

With a growing codebase, it makes sense to organize it between separate repositories, each repo being a separate CMake-managed project.
Because of modularity, this usually means you end up in a situation where a CMake-managed project Application depends on another CMake-managed project Library, while both are internal code (i.e., code owned and maintained by your structure).
The automatic dependency recompilation issue
Then, if some sources in Library are modified, it needs to be recompiled in order to build Application. The question being:
Is it possible to have the "build Application" command (a button in an IDE, or a call to make on the command line) to first rebuild Library if Library files changed ?
I'd suggest to use the ExternalProject_Add command.
The documentation has slightly changed for the different versions:
CMake v2.8.9 ExternalProject
CMake v3.0. ExternalProject
CMake v3.3 ExternalProject
In case you encounter problems with getting the dependencies right, this thread might help you.
By looking at how the OpenChemistry parent-project does it, and with the confirmation by normanius's answer, it turns out this can be achieved with relatively few CMake script code.
It turns out that CMake CLI is offering an abstraction over the "build" action of the targeted build systems. See --build option.
ExternalProject_Add can be seen as a wrapper to use this CLI interface directly from CMake scripts.
Imagine there is a CMake-managed repository, building libuseful, and a separate CMake-managed repo, building appawesome with a dependency on libuseful.
find_package(libuseful CONFIG) # The usual way to find a dependency
# appawesome is the executable we are building, it depends on libuseful
add_executable(appawesome main.cpp)
target_link_libraries(appawesome libuseful)
 Adding automatic rebuild
Then it is possible to make building appawesome systematically first try to rebuild libuseful with some code looking like:
ExternalProject_Add(EP_libuseful)
SOURCE_DIR <libuseful_sourcedir> # containing libuseful's root CMakeLists.txt
BINARY_DIR <libuseful_binarydir> # containing libuseful's CMakeCache.txt
BUILD_ALWAYS 1 # Always rebuild libuseful
)
add_dependencies(libuseful EP_libuseful)
The last line is quite important: find_package() in config mode should make a libuseful imported targed available. The call to ExternalProject_Add made a build target EP_libuseful available (which is a custom build step, building libuseful). The last line just makes sure that libuseful depends on its build step.

CMake for Code::Blocks -- how to NOT get a Makefile

Here is my setup:
Windows 7 x64, MingW, Msys, CMake, Freescale Kinetis SDK, Code::Blocks
I'm trying to get the project settings established by CMake into a proper Code::Blocks project. When I modify the provided build_debug.bat file with -G "CodeBlocks - Unix Makefiles", it indeed produces a .cbp file, as well as the normal Makefile (and it builds the project). However when I open this .cbp file in Code::Blocks, it basically just points to the Makefile, and building the project just runs make on the Makefile.
If I deselect "This is a custom Makefile" from Project Options, and add a source file to the project tree like a normal IDE, it doesn't get built correctly, ie the include files, libraries, linker stuff, compile options, etc., are not imported into the project itself. It seems the project is basically just a holder for the Makefile, so there is not much benefit to this as an IDE.
Of course if I add the source file to the original CMakeLists.txt which is part of the distribution, and rerun cmake (via the build_debug.bat file), then it works fine.
So is there any way to get a "real" IDE configuration out of CMake? I'm guessing the answer is No, since a "real" IDE configuration is a static thing, and a Makefile is a general (Turing complete) program, so there is no way in general to create this automatically, although I suspect for 99% of cases you're just specifying include directories, lib files, and compiler options, so no general programmability is truly needed.
I can probably try to figure out where the deeply obscured gcc calls are getting their include files from, what libs are being linked in, and what compile options are being used, and add all that stuff manually into a native Code::Blocks project, but this seems to defeat the purpose of having this already done for me by the package providers, and gets very tedious when building for a different CPU or development board.
Thanks
"Real configuration" is a CMakeLists.txt, and you need to modify CMakeLists when you editing project configuration. Both makefiles and IDE settings generated by CMake are temporary and you should not edit them.
Some IDEs are able to manage project configuration directly in the CMakeLists.txt

CMake build and project directories

I wonder to know why projects structures has folders like bin and lib but normally (at least in tutorials I saw), people creates a folder named build and use cmake ...
Is it the right way to use ${CMAKE_BINARY_DIR}/bin or ${CMAKE_SOURCE_DIR}/bin to build a project?
You're right, people using CMake often do build in a different directory (e.g. one called build). That's called "out of source" building, and it's useful because it helps keep built artifacts out of your source tree so you don't check them in.
As for bin and lib, those are the conventional names on Unix-like systems for directories storing executable files and libraries respectively. It's good to keep your build artifacts separated this way because it makes it clear where to look for things you can run vs. things you can build against. A common setup in CMake would be to have a build directory containing bin and lib within--if your build rules are set up properly, CMake will create bin and lib when you run your build.

CMake: automatically find target dependencies in other CMake projects

If we have a case of highly decentralized development environment, where there are many repositories and projects, is there an existing functionality in CMake that automatically finds dependencies between targets without a top level CMake file?
The workflow is something like this, you specify a directory and all targets are default-configured in the given tree. Then you can go and build any of the projects. I am looking for a behavior similar to that when you build the Android OS.
There is no build-time dependency tracking in CMake across different projects. For this case you need to have a project on the top-level which adds all the subdirectories, so that the target names are available inside a single CMake project.
I am aware of one helper script around CMake which provides the required inter-project dependencies: https://github.com/aldebaran/qibuild
I would say that is getting close to a mature code base. However, it requires additional descriptor files for each project. Might be worth to have a look at it.