Why doesn't CMake-generated make clean delete files created with configure_file - cmake

I'm using CMake for a project, and generating some configuration .h files with a configure_file() command. This works well enough, but - if I make clean, the generated file is not deleted - nor is it overwritten when I invoke cmake again with different parameters (or ccmake and so on).
Why is this the case, and how can I force re-generation of configure_file output files - when necessary / always?

It seems this may happen if the files are generated under the source folder rather than under the build folder. I think CMake treated the (generated) files it found as source files - or at least, not build files (see #Tsyvarev's comment), so they must not be deleted/altered.

Related

How do I generate a clean (ready to release) build in CMake?

For the record, because this seems like there should be an obvious, well-known way to do it: I can't find any docs on how to do this - all I find is people looking to do a "clean" of their built files when I search for this.
When you build out-of-source in CMake, the resulting directory does not exclusively contain your built executable and other files. CMake leaves all its cache and makefiles, as well as other intermediate files, lying around - for example, the CMakeFiles directory, the CMakeCache.txt, Makefiles, .cbp, .ilk, .pdb, etc. - meaning if I wanted to release the results of said build, I'd need to (automatically or manually) either remove excess cmake files, or copy all my generated files elsewhere manually, before I am ready to release. This would be tedious for projects that require a specific structure in the output directory, or have many output files (e.g. an assets folder full of dozens of built asset files - now polluted with CMakeFiles et al.)
When building with CMake, can I not only perform an out-of-source build where intermediate files (as seen above) end up out-of-source, but where the resulting cmake binary directory is also separate and kept free of polluting by CMake and extra compiler output? (e.g. resulting in a build/output directory that cleanly contains all the actual built files with proper directory structure.)

CMake generation requiring generated files

I'm building a project using CMake in multiple subdirectories. There is a parent directory containing a parent CMakeLists file, and each subdirectory contains its own CMakeLists file. As such, I'm using the add_subdirectory command to run the subdirectories.
My issue is that one of the subdirectories generates code that another subdirectory needs in order to build. Specifically, it's Google Protocol Buffers. The CMakeLists file in that subdirectory will generate the pb.cc and pb.h files if run independently, but until I do so, I cannot generate the cache of the parent CMake file as it complains it's missing those source files.
Directory structure is as follows:
/
--CMakeLists.txt
--protobuf/
----CMakeLists.txt
----src/
--main/
----CMakeLists.txt
----src/
Where the main subdirectory requires files generated by the protobuf subdirectory.
Is there a way I can have the parent CMakeLists file build the subdirectory as part of its generation step? Or somehow mark the protobuf files as required, but missing, so the generation does not fail?
You can try running this particular cmake file as execute_process before including the main file. But this goes against the designed cmake usage.
The correct answer would be to make your generation step a part of build process. If you can post a minimal, reproducible example of your problem I could give you concrete ways to solve your problem directly instead of making your workaround work.

'Cannot determine link language for target...' issue in sub directory

In the main folder of my project, I have a CMakeLists.txt file. Inside this file, I include (using add_subdirectory) another CMakeLists.txt file located in my header file directory. The responsibility of this second file is to add all of my header files to the project:
file(GLOB gl_nbody_HEADERS "*.h")
add_executable(gl_nbody ${gl_nbody_HEADERS})
However, this files causes an error:
CMake Error: CMake can not determine linker language for target:gl_nbody
CMake Error: Cannot determine link language for target "gl_nbody".
What is strange is that when I include the two lines causing this error in my main CMakeLists.txt file (modified to work correctly for the change in directory), it works fine.
What is going wrong here?
add_executable causes the creation of an executable target, meaning the compilation of a list of source code files into an executable binary.
In order for this to work, and have CMake select a suitable compiler, the list of source files must contain at least one file with a "compilable" extension, ie. .c, or .cpp, or .cxx....
I don't see why you are trying to compile an executable here, since you only seem to try to list header files for inclusion into a project (which only makes sense for IDE-based generators, such as Visual Studio).
Also, it is not recommended to use globbing of files in CMake, because if you add more files to your project, CMake cannot detect them automatically, and will not regenerate build files. Please list all files explicitely.
The proper solution here is to list the header files in the proper add_executable command call where you list the actual source files that you want to compile.
You might also want to use the source_group() command, that allows you to group files into folders in the generated Visual Studio solution, for example:
source_group(header_files ${gl_nbody_HEADERS})

Add file dependencies to a custom target

I would like to set up CMake to build qresource files when the contents of files referenced in the .qrc file change. For example I have some qml files that are packaged into a qrc file and the qrc needs to be recompiled if the qml files are changed.
I have the following macro to run the resource compiler but it will only rebuild it if the resource file itself changes.
MACRO(PYQT5_WRAP_RC outfiles)
FOREACH(it ${ARGN})
GET_FILENAME_COMPONENT(outfile ${it} NAME_WE)
GET_FILENAME_COMPONENT(infile ${it} ABSOLUTE)
SET(outfile ${CMAKE_CURRENT_SOURCE_DIR}/${outfile}_rc.py)
ADD_CUSTOM_TARGET(${it} ALL
DEPENDS ${outfile}
)
ADD_CUSTOM_COMMAND(OUTPUT ${outfile}
COMMAND ${PYRCC5BINARY} ${infile} -o ${outfile}
MAIN_DEPENDENCY ${infile}
)
SET(${outfiles} ${${outfiles}} ${outfile})
ENDFOREACH(it)
ENDMACRO (PYQT5_WRAP_RC)
The macro is used like this:
PYQT5_WRAP_RC(rc_gen file1.qrc file2.qrc ...)
How can I make it so the qrc file gets recompiled if one of files that it refers to changes?
Do I need to do something convoluted like this?
It seems to me that the command you are looking for is add_custom_command:
This defines a command to generate specified OUTPUT file(s). A target
created in the same directory (CMakeLists.txt file) that specifies any
output of the custom command as a source file is given a rule to
generate the file using the command at build time.
Configuring the dependencies correctly you should be able to get the file recompiled only when it is really needed.
If I understand correctly your situation, the problem is that CMake does not know anything about what qrc file is and it does not know, that qrc file references some other files. This dependency is implicit for CMake (compare with C++ includes; but for those cmake have special mechanisms to detect dependencies).
So, as I understand, what you can do is to use add_custom_target (which is executed always) but not only add qrc file to its depends, but also write some script, which whould check that files referenced in qrc are also up to date and if they are not, then touch qrc file).
Of course you can use methods from the other answer, which you reference above, to touch qrc file, but you have to develop your own script to extract paths of files referenced in qrc files. Then you can use CMake scripting facilities to check if they are up to date and to touch qrc file.

How to best handle data files with CMake?

I've got a CMake project that contains code and a few data files (images to be precise).
My directory structure is like this:
src
data
src contains the source code, data the data files. CMake suggests out of source builds, so when I invoke make, I have the executable program, but not the data files, thus I cannot execute the program.
Of course, make install would copy my data files to the required location and make it work, therefore I develop like this right now:
cmake -DCMAKE_INSTALL_DIR=dist
<edit source code>
make install
dist/myprogram.exe
That's okay if I'm working with the command line and an editor, but I recently decided to move to Eclipse CDT. Generating an Eclipse project from CMake works great, but manually executing the install target from Eclipse is not so nice.
How do you people tackle this problem? Does your program have some clever algorithms to try and find its data directory even if it's not where the binary is? Or do you not use out of source builds?
configure_file should solve that problem.
I have a CMakeLists.txt file in my data directory which contains the following:
configure_file(data_file ${CMAKE_CURRENT_BINARY_DIR}/data_file COPYONLY)
This copies the specified file into the build directory when cmake is invoked, so it is available in the same location even in out of source builds.
configure_file does not support directories however while the file command does:
file(COPY assets DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
And if copying the files takes too much time (they are images...) you could make it even better by creating a "custom" data_header.h with configure_file which contains the paths to the data still in your source-directory.
This is what I do: I have a file "global_build_config.h.in" in my source, containing the following:
const char* const global_testdatapath = "#Test_Data_Path#";
and then use configure_file in CMake:
# Assume CMake knows a variable Test_Data_Path, it will be filled in automatically
# in the generated config/Global_Build_Config.h
configure_file( Global_Build_Config.h.in ${CMAKE_BINARY_DIR}/config/Global_Build_Config.h )
# The config directory should be added as a include-searchpath
include_directories( ${CMAKE_BINARY_DIR}/config/ )
I can then #include "Global_Build_Config.h" in my cpp files and refer to the fixed path.
Your question is a bit old, but in case you're still interested (or someone else), I have a similar scenario where I copy testdata for a unit-test target:
add_custom_command( TARGET ${UTEST_EXE_NAME}
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E echo "Copying unit test data.."
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_HOME_DIRECTORY}/utest/testdata ${CMAKE_BINARY_DIR}
)
So the main idea is to use a post-build target, and it is executed after each build. For me, it's not much data, and the filesystem caches it, so I don't feel the copy process at all. You could probably enhance this by copying with copy_if_different. In that case, however, you have to create a list of your image files and write a loop, because the command is file based. With the GLOB command, this shouldn't be hard to do if you need to.