CMake : Compile only one subdirectory with preset - cmake

I have a project with this structure, where Components are subdirectories :
CMakeList.txt
CMakePresets.json
|
---Component1/CMakeList.txt
|
---Component2/CMakeList.txt
|
---Component3/CMakeList.txt
I would like to compile only Component1 with the root preset. (I mean compile all targets under Component1).
Normally, to configure and compile all the project i use this commands :
#Configuration
cd myBuildDir
cmake mySourcedDir --preset=myPreset
#Compilation
cd mySourcedDir
cmake --build --preset=myPreset
Problems :
With ninja, after configuration, the myBuildDir/Component1 directory doesn't contain build.ninja file
If i try to do cmake --build in the mySourcedDir/Component1 directory, i have an error message : CMake Error: Could not read presets from...

Try editing Component1/CMakeList.txt with:
get_property(ALL_BUILDSYSTEM_TARGETS DIRECTORY PROPERTY BUILDSYSTEM_TARGETS)
add_custom_target(Component1 DEPENDS ${ALL_BUILDSYSTEM_TARGETS})
And then do:
cmake --build --preset=myPreset --target component1

Related

How to use CMake to build sources with ghdl as custom target?

I would like to build VHDL sources with CMake. For this I have a directory structure:
<root>
- CMakeLists.txt
- src/CMakeLists.txt
- src/mymodule.vhdl
- build
Inside the root CMakeLists.txt I have:
cmake_minimum_required(VERSION 3.12)
project(vhdlsdb LANGUAGES NONE)
add_subdirectory(src)
In the src/CMakeLists.txt I have:
set(filelist mymodule.vhdl )
add_custom_target(vhdlize COMMAND ghdl -a ${filelist})
However, when I run cd build && cmake .. -GNinja && cmake --build . --target vhdlize I get:
error: cannot open mymodule
C:\Users\pm\git\GHDL\0.36-mingw64-llvm\bin\ghdl.exe: compilation error
How can I tell CMake to copy or look for the sources in the src folder?

How does project(...) affect variables?

I stumbled upon the following nice cmake feature recently:
https://cmake.org/cmake/help/latest/variable/CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT.html
Save the following snippet as CMakeLists.txt, run mkdir build; cd build:
cmake_minimum_required(VERSION 3.12)
message(STATUS "CMID: ${CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT}")
project( test )
Executing that snippet does not output a true variable:
➜ build /usr/bin/rm -rf *; cmake ../ | grep CMID
-- CMID:
Now if you change that snippet:
cmake_minimum_required(VERSION 3.12)
project( test )
message(STATUS "CMID: ${CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT}")
Execution yields the result, I expect from the documentation:
➜ build /usr/bin/rm -rf *; cmake ../ | grep CMID
-- CMID: 1
So I wonder, how does the relative position of the project( ... ) command change that variable?
project() call sets many CMake variables, and CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT is one of such variables.
So, for many CMake commands and variables' accesses placing them before or after the project() call is crusial.
In most cases, project() call should be before the using of the other commands and variables.
If you are looking for a way of changing default install prefix from the CMakeLists.txt, see that my answer: https://stackoverflow.com/a/39485990/3440745.

CMake Export Package Not Working As Expected

I am working through learning CMake's install commands. I have it pretty much figured out for executables. For libraries there are few additional steps to build and install the required CMake scripts so the library can be used in the following scenarios.
Find and link the library from the local build generated by the current CMake project.
Find and link the library from a common installation location. This is required by 3rd party CMake projects that don't build the library.
I want to build a library called FooBar. FooBar is linked to an executable called App, that is defined in the same CMake project as FooBar.
Here are my CMake files and project structure.
<project-root>
|-app
| |-src
| | |-main.cpp
| |
| |-CMakeLists.txt
|
|-lib
| |-include
| | |-FooBar.h
| |
| |-src
| | |-FooBar.cpp
| |
| |-CMakeLists.txt
|
|-CMakeLists.txt
# File: <project-root>/CMakeLists.txt
cmake_minimum_required(VERSION 3.8 FATAL_ERROR)
project(SampleProject VERSION 0.0.1 LANGUAGES CXX)
add_subdirectory(lib)
add_subdirectory(app)
# File: <project-root>/app/CMakeLists.txt
cmake_minimum_required(VERSION 3.8 FATAL_ERROR)
set(TARGET_NAME "App")
find_package(FooBar REQUIRED)
set(IMPL_FILES
${CMAKE_CURRENT_SOURCE_DIR}/src/main.cpp
)
add_executable(
${TARGET_NAME}
${IMPL_FILES}
)
target_link_libraries(
${TARGET_NAME}
PRIVATE
FooBar
)
install(
TARGETS
${TARGET_NAME}
DESTINATION
bin
)
# File: <project-root>/lib/CMakeLists.txt
set(LIB_NAME FooBar)
set(CMAKE_CXX_VERSION 11)
set(IMPL_FILES
${CMAKE_CURRENT_SOURCE_DIR}/src/Lib.cpp
)
set(PUBLIC_DEFI_FILES
${CMAKE_CURRENT_SOURCE_DIR}/include/Lib.h
)
add_library(
${LIB_NAME}
STATIC
${IMPL_FILES}
)
target_include_directories(
${LIB_NAME}
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
)
set_target_properties(
${LIB_NAME}
PROPERTIES
PUBLIC_HEADER
${PUBLIC_DEFI_FILES}
)
install(
TARGETS
${LIB_NAME}
EXPORT
${LIB_NAME}Targets
PUBLIC_HEADER DESTINATION include
ARCHIVE DESTINATION lib
)
install(
EXPORT
${LIB_NAME}Targets
FILE
${LIB_NAME}Config.cmake
DESTINATION
lib/cmake/${LIB_NAME}
)
# I am under the impression these are needed for other targets in the
# current project to be able to use "find_package(FooBar)". I also
# think that "CMAKE_EXPORT_NO_PACKAGE_REGISTRY" needs to not be set.
message(STATUS "CMAKE_EXPORT_NO_PACKAGE_REGISTRY: ${CMAKE_EXPORT_NO_PACKAGE_REGISTRY}")
export(
EXPORT
${LIB_NAME}Targets
FILE
${CMAKE_CURRENT_BINARY_DIR}/${LIB_NAME}Config.cmake
)
export(PACKAGE ${LIB_NAME})
To generate build files I run
# Clean project directory.
mkdir _build
cd _build
cmake .. -DCMAKE_INSTALL_PREFIX=<project-root>/_dist
and I get the following error.
-- CMAKE_EXPORT_NO_PACKAGE_REGISTRY:
CMake Error at app/CMakeLists.txt:5 (find_package):
By not providing "FindFooBar.cmake" in CMAKE_MODULE_PATH this project has
asked CMake to find a package configuration file provided by "FooBar", but
CMake did not find one.
Could not find a package configuration file provided by "FooBar" with any
of the following names:
FooBarConfig.cmake
foobar-config.cmake
Add the installation prefix of "FooBar" to CMAKE_PREFIX_PATH or set
"FooBar_DIR" to a directory containing one of the above files. If "FooBar"
provides a separate development package or SDK, be sure it has been
installed.
-- Configuring incomplete, errors occurred!
Running the above command a second time yields the same error message. I should not see that message because these two lines
export(
EXPORT
${LIB_NAME}Targets
FILE
${CMAKE_CURRENT_BINARY_DIR}/${LIB_NAME}Config.cmake
)
export(PACKAGE ${LIB_NAME})
should generate _build/FooBar/FooBarConfig.cmake and add it to the search path for packages seen by App.
If I remove the app sub-directory, build and install FooBar to _dist, and then re-add app, I do not get the error. Even if I clear out _build and generate build files from scratch, I don't get the error. How is CMake finding my local install config script, but not the one in the build directory? Am I doing something wrong or does anyone have any idea why this might not work?

cmake, how to specify the output directory

I'm using cmake to generate a VS2017 solution (and projects...), I try to generate everything in a different folder.
I used both the command line and different variables, but no way, it generate in the "source" folder !
Here are some examples of what I tried:
cd source
cmake -B../build ...
cd build
cmake ../source
cmake --build "../build"
cmake -Dxxx=../build
Any idea ? all theses solutions are expected to generate in the build folder !
Once you have performed in-source build (in source directory), it is impossible to build the project out-of-source: every such attempt will modify in-source build.
You need to clear build files (CMakeCache.txt, probably some other ones) in source directory before using out-of-source builds.
I fixed with:
cd VSBuild
cmake ../
instead of
cd VSBuild
cmake ..
Have you tried this? This will put all the build files under "out"
$ cmake -H. -Bout
To execute:
$ cmake --build out

How do I change the directory to which CMake outputs solution and project files?

I have a build/ directory where I'd like CMake to put the *.sln, *.proj, etc. files it generates when I type cmake CMakeLists.txt. How do I do this?
You run cmake in the directory you want to build in with the path from the build directory to the source directory. So say your parent directory is called project and it contains src and build you would:
cd build
cmake ../src
That will put the makefiles and the objects in build while leaving the CMakeLists.txt files in src. The one pitfall is that if there is already a CMakeCache.txt in src then you must delete before running cmake.