Generating a 'clean' target for a subdirectory in CMake - cmake

I want to generate a clean target for a subdirectory.
My project structure is like this:
app/
A
B
lib/
A
B
C
Sometimes I want to run clean on just app/A and don't want to clean the library.
Is it possible to tell CMake to generate a clean target for each directory?
Or a custom target like app-clean which will call clean on each application sub-directory?

You can just cd to ${CMAKE_BINARY_DIR}/app/A and run make clean there.
Of course, you can add_custom_target(app-A-clean ...) which would do this for you.
macro(add_clean_target dir)
add_custom_target(clean-${dir} COMMAND ${CMAKE_MAKE_PROGRAM} clean WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${dir})
endmacro(add_clean_target)
Now you can use it in such way:
add_clean_target(app-A)

Perhaps try to set up your CMakeLists.txt to have a project in each directory, and a "root" CMakeLists.txt which simply does add_subdirectory for all the sub-projects... then CMake will generate a solution-file or makefile in each project-directory. You can then "step into" such a directory and build and and clean one project.
For example, in one of my projects I have the following structure:
projectroot/
applications/
appA
libraries/
libA
libB
In projectroot I set up a CMakeLists.txt like this:
project(MyProject)
add_subdirectory(libraries)
add_subdirectory(applications)
In libraries/, I do the following:
project(Libraries)
add_subdirectory(libA)
add_subdirectory(libB)
add_subdirectory(libC)
And then in applications/:
project(Applications)
add_subdirectory(appA)
In this case, I can step into projectroot/applications/appA and call make or msbuild appA.sln and it will start building libA, B, C and then appA. Similarly you can call make clean or msbuild /t:Clean appA.sln.
The added benefit of an extra directory for all libraries is that I can build them at once by running make or msbuild libraries.sln in the libraries/ dir.

Related

CMakeLists Equivalent of -B CL Argument [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.

Install add_subdirectory(A) header files before building add_subdirectory(B)

I am new to cmake and I am trying to build my code on UNIX and Windows platforms. I have add_subdirectory(A) and add_subdirectory(B). If I build only add_subdirectory(A), it installs headers files to some xyz location and next when I build add_subdirectory(B), it uses headers files from previously installed xyz location. But when I try to build both add_subdirectory(A) and add_subdirectory(B) together, it fails with missing header files from xyz location, as they are not installed. So my question is, is there a way that I can tell cmake to build and install add_subdirectory(A) and then start building add_subdirectory(B).
I tried to look online but no luck.
My master CMakeLists.txt:
add_subdirectory(TradeFlowCommonFrameworkLib/cpp/src)
add_subdirectory(TradeFlowCommonDataLib/cpp/src)
install(EXPORT Findfotmc DESTINATION ${INSTALL_FOTMC}/cmake)
----------------------------------------------------------------
Adding subdirectories does not specify dependancies between them. You have to explicitly link your second executable/library to your first library.
In the sub CMakeLists of your B project (TradeFlowCommonDataLib/cpp/src) you have to add something like this :
target_link_libraries(B A)

CMAKE : Build only one directory of an downloaded external project

CMAKE : I only want to build part of a downloadable external project
The external project I want to use has the following structure :
- ExternalProject
- Subproject A <- this i care for
- Subproject B
It's all in the same archive that is available for download. The problem is that Subproject B has more dependencies that I don't want in my project, also it's not relevant for what I'm doing. The subprojects are buildable on their own, so for now I just took Subproject A out of the archive and put it in my main project which is working fine, but I'd like to not deploy the external project with my project but allow the user to download the external project on his own when running cmake. Sadly there is no archive for each of the subprojects on their own so all I can download is the full external project.
What I want is to tell CMAKE to download and unpack the whole archive ExternalProject but then only add Subproject A to my project. I read all the documentation on ExternalProject_add but it mostly allows for detailed configuration of the build parameters of the project. Maybe I'm just looking for the wrong keyword and my question is really simple to answer - or it is just not possible.
If someone could point me towards the right approach here I'd be very thankful.
Actual project :
The mentioned archive has two subfolders "octomap" and "octovis". octomap is the one I want to build while octovis will create a lot of errors if the dependencies are not met.
ExternalProject_Add(octomap-1.6.5
URL https://github.com/OctoMap/octomap/archive/v1.6.5.tar.gz
URL_MD5 de09b1189a03ac8cbe4f813951e86605
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/octomap/
CMAKE_ARGS "-DCMAKE_INSTALL_PREFIX=${EXTERNAL_INSTALL_DIR}"
)
You can define all commands explicitly. For instance you have a directory structure:
FooBar/
- CMakeLists.txt
- Foo/
- - CMakeLists.txt # You wanna build
- Bar/
- - CMakeLists.txt # You wanna ignore
Example with hardcoded paths:
set(ext_dir "${CMAKE_BINARY_DIR}/third-party-activities/ExternalProject/")
set(foobar_dir "${ext_dir}/FooBar")
ExternalProject_Add(
FooBar
URL "your-url-here"
SOURCE_DIR "${foobar_dir}/Source"
CONFIGURE_COMMAND
"${CMAKE_COMMAND}"
"-H${foobar_dir}/Source/Foo"
"-B${foobar_dir}/Builds"
"-DCMAKE_INSTALL_PREFIX=${EXTERNAL_INSTALL_DIR}"
BUILD_COMMAND
"${CMAKE_COMMAND}" --build "${foobar_dir}/Builds"
INSTALL_COMMAND
"${CMAKE_COMMAND}" --build "${foobar_dir}/Builds" --target install
)
Update
Note that it's much easier to patch parent project like this:
# FooBar/CMakeLists.txt
option(BUILD_BAR_SUBPROJECT "Build targets from subproject Bar" ON)
...
add_subdirectory(Foo)
if(BUILD_BAR_SUBPROJECT)
add_subdirectory(Bar)
endif()
... and now you don't need to hack ExternalProject_Add so much:
ExternalProject_Add(
FooBar
URL "your-url-here"
CMAKE_ARGS -DBUILD_BAR_SUBPROJECT=OFF "-DCMAKE_INSTALL_PREFIX=${EXTERNAL_INSTALL_DIR}"
)

Specifying build directory within CMakeLists file

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.

cmake creates a ton of files

I'm new to cmake and have just started playing around with it. My problem is that when I invoke cmake like in the tutorial it generates a massive amount of files.
Is there a way to invoke cmake so that all is left after is one unix makefile in the root directory of my project?
The files CMake generates are all useful and shouldn't be deleted.
You could probably write a script which deletes these at the end of running CMake, but I'd strongly recommend that you let CMake work the way it's designed to.
If you keep your source tree separate from your build tree (do an "out of source build" as CMake calls it), there should be no problems. So e.g.
- project_root_dir
|
|- CMakeLists.txt
|- src_dir
- build_dir
If you cd build_dir, then do cmake ../project_root_dir, all the files CMake generates will be in build_dir and won't pollute your source tree.