Have cmake check version at install time - cmake

I have a cmake script that add a "add_custom_command" that generate a program version anytime the program is compiled. That creates a Header File. It works fine...
Now, what I want to do is to have cmake use value from said file during installation and packaging.
Parsing the file is of no worry. What I don't know is how do I ask cmake to parse it just before installing, since it would have been modified during the compilation.

You should check out some of the capabilities of the INSTALL command
INSTALL(CODE "CMAKE_CODE_THAT_PARSES_FILE")
or
INSTALL(SCRIPT CMAKE_Parsing_Script.cmake)
These will be executed at install time.

Related

Trigger CMake code version check routine while running make cmd

When I run the cmake command to generate the Makefile of my projet, a dedicated CMake routine polls the latest git tagged version of my code. This tagged version code is then passed to the C++ executable codes as a preprocessor definition to be displayed in runtime.
The problem is that when the git repository is updated, we usually only run the make command without pre-running cmake again. Is there a way to check if the git version has been updated (using CMakeFileList.txt) while running make?

Compiling latest release of CppUTest (3.7) with MinGw, pthreads missing

I'm trying to use CppUTest in Windows, first step is to get it to work and I already have problems. These are the things I've tried:
First Approach
With CMake, using the cmake GUI I can do the configure and generate command and I get something in the output directory, but no binaries and no libraries, just a bunch of cmakefiles. The CMake GUI says everything went OK during the configuration and generation steps, however the libraries (.lib files) are not generated in the output directory... is there something I am missing? I've never used CMake before.
Second approach
With MinGW and msys alone, running cmd in Windows and executing a MinGW shell by typing sh in the Windows terminal, afterwards I execute the following commands:
cd <CppUTest folder>
mount c:\mingw /mingw
./autogen.sh
./configure
make
The build process starts but it fails with a message indicating that pthread.h was not found in MinGW directory. If I install the pthread-win32 package with the MinGW package manager and repeat the same steps as above the build process starts but fails with a message indicating that the structure timespec is defined in time.h and pthread.h.
I've tried to follow this same procedure with CppUTest 3.6 and it works perfectly fine, I get the .lib files, so I guess I will have to continue with this for now.
Does anyone know how to build CppUTest 3.7 (latest release) with MinGW or CMake?
In the end I used Cygwin to compile it, I couldn't find a way to compile it with MinGW properly, I added a dirty trick to make it compile under MinGW (handled the timespec redifinition) but chances are that is going to cause issues.
Just make sure that you use Cygwin aswell to compile your tests, something that I found out after making this question (https://www.youtube.com/watch?v=oVmd0P85D8o).

CMake rpm installing a file in /etc/init.d

I want to install a file in
/etc/init.d directory
I have written code
INSTALL(FILES ${CMAKE_SOURCE_DIR}/app/script/appd DESTINATION /etc/init.d/appd)
but when I run packing code using cmake I get error
CMake Error at /home/vivek/workspace/app/build/standalone/cmake_install.cmake:54 (FILE):
file cannot create directory: /etc/init.d/appd. Maybe need
administrative privileges.
How can I set cmake to install a file inside /etc/init.d directory ?
You can do this, but you may need to explicitly set:
set(CPACK_SET_DESTDIR ON)
prior to:
include(CPack)
in your CMakeLists.txt file. (You will need to do this only for older versions on CMake/CPack, prior to 2.8.3)
The reason you need to do this is that you are specifying a full path name as the DESTINATION of one of your installed files. In order to do that properly in the packing phase, CPack needs to use a DESTDIR environment variable in its "make install" call.
We didn't do this automatically by default for backwards compatibility reasons.
But then, this bug was fixed in version 2.8.3 so that it could be done transparently and automatically with install rules that use full path names:
http://public.kitware.com/Bug/view.php?id=7000
Hopefully, you can use either CPACK_SET_DESTDIR to ON for your rpm packages, OR use a more recent version of CMake/CPack that includes the automatic fix.
You can't. Only thing you can do is to ask user to run make install for your app with administrative priveleges.
Also, you can try detecting presense of sudo command and add_custom_command() which would install your files with sudo.

Compile-time wildcards in cmake install targets

I'm new to cmake and I'm finding it very frustrating. I am trying to use wildcards in file paths that are evaluated when the build runs, not when the build is generated.
I have created a build that uses SWIG to generate Java wrappers for some C++ code. I can write the commands to generate the native code, compile it, and produce a working shared library, and even use the INSTALL command to install that shared library correctly. What I can't figure out how to do is to write an INSTALL command that can copy all *.java files generated by SWIG into that same install location.
It seems that cmake's FILE GLOB command does the globbing when cmake is executed, and not when the build actually runs. Of course, when cmake is executed, SWIG hasn't run yet, and the Java files don't exist.
Is there a way to do what I want? Am I going about things wrong? It seems like this is such a fundamental part of what Makefiles need to do, I'm really surprised not to find an easy way to do it.
Assuming that the Java wrappers are located in the current binary directory, you can use the following install command to copy the Java files upon install:
install(
CODE "file( GLOB _GeneratedJavaSources \"${CMAKE_CURRENT_BINARY_DIR}/*.java\" )"
CODE "file( INSTALL \${_GeneratedJavaSources} DESTINATION \"$ENV{HOME}\" )"
)
The CODE form of the install command is used to execute two CMake commands upon running the install target. The first one collects all generated Java files in a helper variable. The second one uses the INSTALL form of the file command to copy the files.
you can use install(SCRIPT swigInstaller.cmake) or install(DIRECTORY) both of which supports doing file globing at install time. You can read more about the install command at:
http://cmake.org/cmake/help/cmake-2-8-docs.html#command:install

CMake Configure File Build Rule

I'm using CMake for my build system and in the project, we will have a bunch of configuration files. Some of them will just need to be copied over, some will need to be modified per computer. I'm currently using CMake's "configure_file" command to copy/replace parts of the file. This works great, and I love how I can use any variable from CMake in the configure routine.
But if you change the original file, CMake will not pick this up and you have to rerun cmake for it to configure the directory. When I run "make", I want it to pick up that I've changed the file and rerun configure.
It will also reconfigure files always, even if the file it is overwriting is newer. I want it to act like a custom target.
I think I can do this with add_custom_command, but I don't think I can run a CMake command from add_custom_command. So is there anyway to duplicate the behaviour that configure_file does in CMake?
I recently upgraded to CMake 2.8. It seems like it automatically has the exact behavior I wanted.
I do not think this has an easy answer. I see two options:
To trigger a re-run of cmake if an input changes, you might be able to make your input file depend on CMakeLists.txt.
To run a cmake command as part of and add_custom_command, there is the variable ${CMAKE_COMMAND}, which will give you the path to the running cmake. You could, as part of the configure step, generate a fragment of CMake code (that calls configure_file) that is invoked using the -P option. Either pass substitutions on the command line using -D, or write them to the CMake fragment.