How to find the CMake command line I used for the build? - cmake

This is what typically happens. I get source code that has cmake build scripts. I create a build subdirectory, change to it, run cmake <options> ... Depending upon the project and its dependencies I have to repeat the last step until it finds all necessary dependencies and generates makefiles. I successfully build and use the project. Few days pass, I forget about this installation. Then one day I'm trying to setup the same project on another machine and now I can't recall what exact CMake command line I used in the past to get things working.
I still have the old build directory on the old machine. Can I find the cmake command line I used in the past, by looking into some of the autogenerated files in the build directory? I was expecting CMake would just put the exact command line I used in one of these files in commented form. But if it does so, I haven't found it yet.
How can I find the original CMake command line I used?

You can't.
Original CMake command can be guessed from analysis of CMakeCache.txt
As a workaround, you could always create a simple wrapper to store the original command line used. Something along these lines:
#!/bin/bash
echo "$#" > cmake_command.log
$#

Related

CMake Error (configure_file): configure_file error configuring file

I am working on a project on c++ and need to execute a CMakeLists.txt file to run it. I installed cmake, doxygen, cmake-curses-gui and make using sudo. Then I tried running the file.
The following is a part of the cmake code -
if (BUILD_DOC)
find_package(Doxygen)
configure_file(${PROJECT_SOURCE_DIR}/doc/Doxyfile.in
${PROJECT_SOURCE_DIR}/doc/Doxyfile #ONLY)
add_custom_target(${PROJECT_NAME}_doc ALL ${DOXYGEN_EXECUTABLE}
${PROJECT_SOURCE_DIR}/doc/Doxyfile)
endif ()
Here, it gave me an error message saying that
CMake Error at CMakeLists.txt:77 (configure_file): configure_file
Problem configuring file
Just so that you know, line 77 is configure_file(${PROJECT_SOURCE_DIR}/doc/Doxyfile.in .
If I add AND DOXYGEN_FOUND to the if condition, it doesn't execute anything at all which means that it couldn't find a doxygen executable. But as I already told, I already installed doxygen.
I am new to cmake. So, could anyone please help me with this
Edit:
The OS I am using is Ubuntu 16.04
After I put if(DOXYGEN_FOUND) after the command find_package(doxygen) it executed, but I got the same cmake error in line 78 instead of line 77
Also, now since I got enough information from the comments, I just realized that my problem is more towards finding where the Doxyfile.in file lies than configuring the file. Could anyonee help me with it?
The error is clear
configure_file Problem configuring file
CMake's configure_file(<input> <output>) command is used to copy input file to ouput and replacing #VARIABLES# in input by the corresponding value.
configure_file(${PROJECT_SOURCE_DIR}/doc/Doxyfile.in ${PROJECT_SOURCE_DIR}/doc/Doxyfile #ONLY)
You have to find why this process failed:
Make sure ${PROJECT_SOURCE_DIR} contains the correct path to your project, and make sure the file Doxyfile.in is is the right folder (<project dir>/doc)
Make sure content of Doxyfile.in does not contains any syntax error, in particular with #VARIABLES# that needs to be replaced by their CMake value.
Note that this error has nothing to do with Doxygen on your system, and the fact that CMake actually found it or not.

In CMake how do I create a file needed at configure time?

Edit: my question targets the early configure stage where CMake input files are still being parsed and thus have to be present before include() is being called. So the answer found here: Force CMake to generate configure_file target every build does not solve my problem since it generates files after include() statements have been interpreted.
I have a CMakeLists.txt that includes a file which is generated in the configure stage:
execute_process(COMMAND "my-generator -o generated.cmake")
include(generated.cmake)
Apart from the fact that this approach doesn't feel right (not to say elegant) I now need to re-generate that file before every build (my-generator produces output that incorporates the current time).
My assumption is that I can't use add_custom_command() or add_custom_target() because the file would be generated at compile time but needed in the configure-step.
This very old post suggests to touch the input file so I did this:
execute_process(
COMMAND "my-generator -o generated.cmake"
COMMAND cmake -E touch "${CMAKE_CURRENT_LIST_FILE}")
.. which does not produce errors but calling make multiple times won't run the configure step more than once.
What do I do wrong? Is there a better approach?

Is there a way to get errors when a CMake command fails?

I am writing a script and started working with the install command (for copying files) and it is not working. CMake configure/generate does not show any errors (i.e. it does not stop and no warnings/errors show related to this command) and the command does not seem to be working, because I don't see any files being copied.
Since I am new, I am wondering:
How can I tell that install failed (perhaps the source directory was wrong, or the destination directory was wrong)? It appears to be failing silently.
Are there error codes I can check to see what went wrong?
When is install called? When I click configure? Or when the project is built?
I am on Windows.
To the general question, there are a number of ways to get more verbose output from CMake - I just learned a third for gnarly errors:
to debug CMake recipes, I like using the message command and you can even iterate over directories and issue messages*
e.g. message( STATUS "SQLITE3_LIB: ${SQLITE3_LIB} SQLITE3_PATH: ${SQLITE3_PATH}") # prints SQLITE3_LIB and SQLITE3_PATH variables
perform verbose builds to troubleshoot your build itself
run make VERBOSE=1 (with make, ninja -v with ninja, etc.) to help you troubleshoot the process, such as cmake -DYOUR_OPTION="insert values" ~/path/to/files/ && make VERBOSE=1
if you ever find an inscrutable error, I just learned that we can run strace on the failing command - this can be a bit overwhelming, but can help when you have exhausted #1 and #2
I just used strace /usr/bin/cmake -E copy_directory $MY_SOURCE_PATH $MY_DEST_PATH to try to understand why a copy was failing
*I have used DLRdave's answer to a different question to print out the INCLUDE_DIRS:
get_property(dirs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES)
foreach(dir ${dirs})
message(STATUS "dir='${dir}'")
endforeach()
When you add an install command to your CMakeLists.txt, you get a new target created called "install".
In order to actually install the chosen files/targets, you need to build this install target. It's not automatically built as part of the "ALL" target.
For example, if you're using Visual Studio, the "INSTALL" target should appear in the "CMakePredefinedTargets" folder of the Solution Explorer. Just selecting this target and building it will cause the solution to be built and the selected items installed.
If any part of the build or install process fails, the notifications should then be apparent.

CMake install dynamic generated list of files

I have a cmake project that upon installing it will invoke a python script which will output for me a list of files that I must also install.
I use this output and pass it to FILE(INSTALL ${output}) but this command doesnt put the files at the right place.
How can I install a list of file that is a output of a command? (Note that the command depends on the built target)
Make a target which generates this list to get it during the build step. With the list of files written somewhere, use install(SCRIPT <file>) to run a CMake script which uses the file to copy/modify/whatever the files into the right place. The script itself will likely need to have configure_file used to get the install directory and the generated file path correct (I don't see a way to pass arguments to the cmake command which runs the script).

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.