How to make meson scan for new target - meson-build

I have meson project which have multiple targets in multiple subdirs.
When I add a new target into the project in a subdir, and try to compile that target, an error occurs:
ERROR: Can't invoke target `test`: target not found
The only way I have to compile the target is to setup again the project
meson setup builddir --wipe
Is the any command to make the build system scan for changes in subdirs' meson.build files?

You have two more options after you have changed subfiles:
run meson --reconfigure builddir to force reconfiguration. setup --wipe will remove the build directory, in case something corrupted the cache or builddir - and than creates a (new) configuration.
touch the root's meson.build (touch meson.build), then when you run ninja -C builddir again, it will reconfigure before building automatically since the time stamp of the root's meson.build doesn't match with the cache's anymore. The manual suggests, it's also possible to let the system send signals to a script which touches the main meson.build when change events are noticed.

Related

cmake add-custom-target doesn't create a target

I want to build a package that contains a list of files (configuration files that my main task uses). So I am adding these in my CMakeLists.txt
add_custom_target(my-configs)
install(
FILES
file1.cfg
DESTINATION data/task
COMPONENT my-configs
EXCLUDE_FROM_ALL)
...
But when I run :
make -C ../cmake-build/linux_64_static_make_RelWithDebInfo/task/ my-configs
I get :
make: Entering directory '/development/cmake-build/linux_64_static_make_RelWithDebInfo/task'
make: *** No rule to make target 'my-configs'. Stop.
Why is that? Shouldn't the above create the target?
EDIT
This component doesn't do anything apart from copying files into the specified location. In that case, do I need a custom_target at all?
Or could I just go ahead and do cmake install? If I do install I see :
cd ../cmake-build/linux_64_static_make_RelWithDebInfo && DESTDIR=../../cmake-install/linux_64_static_make_RelWithDebInfo cmake -DCOMPONENT=my_configs -P cmake_install.cmake
-- Install configuration: "RelWithDebInfo"
-- Install component: "my_configs"
but nothing gets installed in the DESTDIR as expected - which is why I thought I needed a target so I can regenerate the cmake-build tree? Otherwise how will it know about the new component?
One use case for add_custom_target() can be like a .PHONY target in a Makefile.
You need to add dependencies to your custom target so that CMake knows how to fill the order. Here some examples:
add_custom_target(libs DEPENDS library_1 library_2 ...)
So now you have a target libs that will build your set of libraries when you specify that target to be built or some other target depends on libs to be built.
Another example:
add_custom_target(unmount_server COMMAND "umount /mnt/deployment")
This would provide a target that would unmount a server drive. Very much a non-portable operation as I have written it.

Avoid creation of cmake_install.cmake file

I have several small personal projects that I execute directly from the build directory, and never are going "to be installed". Is there a way to avoid the creation of the cmake_install.cmake file in my build directory each time I run cmake?
I have seen the install documentation that explain how to configure install, but not how to disable the install procedure. Is there a cmake command line argument or cmake rule to avoid the creation of file cmake_install.cmake?
Add this line to your project's CMakeLists.txt:
set(CMAKE_SKIP_INSTALL_RULES True)
This is a documented CMake variable.

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.

CMake force install after add_subdirectory

We are converting a large Makefile based project to a CMake based system. I have numerous dependencies that I need to build prior to building our code. The first three dependencies are build using the following:
add_subdirectory(dependencies/libexpat/expat)
add_subdirectory(dependencies/libuuid-1.0.3)
add_subdirectory(dependencies/log4c-1.2.4)
expat has it's own CMakeLists.txt file and build with no problems. I would like to force expat to install to the staging directory before continuing. For libuuid I am using a ExternalProject_Add and as part of that process it does install into the staging directory.
Then when I build log4c, which needs expat, I can point it to the location of expat. Otherwise I would need to someone get access to the absolutely path for the temporary build location of expat.
I've tried to add the following after add_subdirectory:
add_subdirectory(dependencies/libexpat/expat)
add_subdirectory(dependencies/libuuid-1.0.3)
install(TARGETS expat LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/usr/lib)
add_subdirectory(dependencies/log4c-1.2.4)
Unfortunately CMake will not run expat's install code. How do I force expat to install after building but before it builds the rest of the project?
This looks like the primary use case for ExternalProject_Add, which is best used as a superbuild setup. 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.

Supress automatic messages in cmake custom targets

I want to add custom targets with cmake but, some of them must be "silent", because it isn't neccesary. For example, for clean custom commands:
// In CMakeLists.txt
add_custom_target(clean-temporaries
${CMAKE_COMMAND} -P clean-temporaries.cmake
COMMENT "Deleting temporary files"
)
// clean-temporaries.cmake
file(GLOB_RECURSE temporary_files "*[~#]")
file(REMOVE ${temporary_files})
$ cmake .
$ make clean-temporals
[100%] Deleting temporary files
[100%] Built target clean-temporaries
$ make clean
$
We can see that CMake prepares "make clean" to not show messages, but, how can I say to CMake I don't want messages in a custom target?
Try adding a minus at the beginning of the command you want to hide from the console.
-make clean
To deal with temporary files littering your source tree:
Encourage contributors to configure their editors so that temporary files end up in a common directory under their $HOME (eg: vim, emacs).
Encourage contributors to configure their global version control ignore files to always ignore the temporary files for their own work environment (eg. for git: vim, emacs).
Additionally exclude well known temporary file patterns in the version control's ignore file of each project, to be friendly to contributors who haven't yet implemented the two previous steps.
If you do that, it's likely that you don't have to put an additional 'optional' (ie. highly environment specific) step into your build system and you end up with a more generally applicable solution to the problem.
As an additional comment on your example code, I'd avoid building in the source tree and use out-of-source builds instead.