CMake Error: Target contains relative path in its INTERFACE_INCLUDE_DIRECTORIES - cmake

I mean to compile example Advancing_front_surface_reconstruction from the CGAL package under Win10 + PortableApps Msys2.
For the library itself I use a precompiled package ($ pacman -Qs cgal gives local/mingw-w64-x86_64-cgal 4.14-1).
I used to be able to do that in my previous PC, see details below.
After transferring everything to a new PC (simply copying, it is PortableApps), I made a system update in Msys2 (required for other reasons).
I proceed as usual: mkdir build, cd build, ccmake ... Selecting Release mode, and verbosity ON, upon pressing g to generate files I got
CMake Error in CMakeLists.txt:
Imported target "CGAL::CGAL" includes non-existent path
"C:/building/msys64/mingw64/include"
in its INTERFACE_INCLUDE_DIRECTORIES. Possible reasons include:
* The path was deleted, renamed, or moved to another location.
* An install or uninstall procedure did not complete successfully.
* The installation package was faulty and references files it does not
provide.
Upon pressing e to exit the error message, the ccmake gui was exited and there were no files generated.
After googling a bit, this suggested creating the missing dirs, which seems merely a workaround (I did not try adapting this).
I created those dirs, and then I got
CMake Error in CMakeLists.txt:
Target "CGAL::CGAL" contains relative path in its
INTERFACE_INCLUDE_DIRECTORIES:
"C:/building/msys64/mingw64/include"
How can I fix this?
I found no suitable answers around.
Possibly related links, but which I found no way of relating to a suitable solution:
https://gitlab.kitware.com/cmake/cmake/commit/634bb33f3aa3b7f2181a896c025976b52171524a
https://cmake.org/cmake/help/v3.12/manual/cmake-buildsystem.7.html
NOTE:
The same happened with other examples.
EDIT:
I do not know what changed, but now upon pressing e to exit the error message (see above) all generated files are present, including the Makefile.
So I can proceed as described below in Previous state of affairs.
This happens either with or without the missing dirs (the error message changes, but I can generate my executables).
AFAICT, the only related change is that
I have just installed packages
, mingw-w64-x86_64-eigen3 (3.3.7-1)
, mingw-w64-x86_64-suitesparse (5.4.0-1)
, mingw-w64-x86_64-lapack (3.8.0-5)
, but I would not think this should matter.
Previous state of affairs
To compile and link CGAL examples, in my previous PC, some tweaking was needed.
Compilation went fine, but linking required a couple of tweaks.
An example command line produced for linking reads
/mingw64/bin/c++.exe -O3 -DNDEBUG -Wl,--enable-auto-import CMakeFiles/reconstruction_structured.dir/reconstruction_structured.cpp.o -o reconstruction_structured.exe -Wl,--out-implib,libreconstruction_structured.dll.a -Wl,--major-image-version,0,--minor-image-version,0 /mingw64/lib/lib/libmpfr.a /mingw64/lib/lib/libgmp.dll.a /mingw64/lib/lib/libCGAL.dll.a -lC:/building/msys64/mingw64/lib/libgmp.dll.a -lC:/building/msys64/mingw64/lib/libmpfr.a
The two types of required fixes are
Replacing /mingw64/lib/lib/ with /mingw64/lib/ in every (link.txt;build.make) file.
Replacing flag -lC:/building/msys64/mingw64/lib/libgmp.dll.a with -lgmp in every link.txt file. Similarly for -lmpfr.

Run this command to find all the places in the CGAL CMake files where the erroneous directory C:/building/ is mentioned:
grep -r '/building/' /mingw64/lib/cmake/CGAL
For each instance, either delete it or replace it with something more appropriate.
(Note: I haven't tried this myself.)
This erroneous directory is a general issue with MSYS2 which I attempted to fix at one point.

Related

pkg_check_modules cannot find *.pc.cmake

I am using a 3rd party library rbdl, which contains rbdl.pc.cmake, which 'I suppose' is included for using pkg_check_modules in a cmake file.
I update PKG_CONFIG_PATH to point at the rbdl folder
set(ENV{PKG_CONFIG_PATH} "$ENV{PKG_CONFIG_PATH}:${CMAKE_BINARY_DIR}/externals/rbdl")
pkg_check_modules(RBDL rbdl)
but pkg_check_modules says it cannot find the module.
When I manually duplicate rbdl.pc.cmake, rename the copy into rbdl.pc and run pkg-config --cflags --libs rbdl in terminal, then my cmake also start working!
Interestingly, now even if I delete rbdl.pc, rbdl module if perfectly found by rbdl.pc.cmake!
So my questions are:
What is the difference between *.pc and *.pc.cmake?
How do I correctly setup my cmake to work with original rbdl.pc.cmake?
Why rbdl.pc.cmake starts to be accepted by pkg_check_modules after that tweak with duplicating it, renaming the copy and running pkg-config manually?
You understand it wrong! rbdl.pc.cmake is just a template file. It is not supposed to be used by you! Take a look into CMakeLists.txt line 160 -- configure_file() used to render variables ("quoted" by # in template file) and produce a rbdl.pc (a real pkg-config) file. Latter should be installed (some way) and then will be available to pkg-config hence can be used in your project.
pkg-config is stupid do not interpret or validate compiler/linker flags any way, so your renamed file "works" (yeah, producing invalid command line for compiler/linker).
I wish you to read CMake documentation before trying to code something using it! It'll save your time and give you a necessary knowledge which stops you from doing stupid things like you described in your question ;-)

Cmake apparently ignoring CMAKE_BUILD_TYPE?

So I'm using CMake for a project.
It consists of a set of shared libraries linked to one executable. All are generated in the project (there are no external targets). Each sub project lives in its own directory, with its own cmakelists file.
So I make an out-of-source build, taking care to set CMAKE_BUILD_TYPE to Debug, and run cmake, and then make. I use GNU make 3.81, GCC 4.8.1, binutils 2.23.2 and CMake 3.2.3 on a Windows box using MSYS/MINGW.
The problem is that, when I load this executable in gdb (version 7.6), place a breakpoint on a function from one of the shared libraries, and then try to single step, gdb skips the whole function saying it has no line number information.
According to my understanding, line number information is a part of the debugging information, so I expected this to be generated during the compiling process (as per the CMAKE_BUILD_TYPE) which it didn't, so I would like to know how I can get CMake to generate this line number information properly (that is, without manually adding compiler-specific options in the cmake files, although I would take that if it's the only solution).
I've tried setting CMAKE_BUILD_TYPE from the command line (when invoking the cmake utility), inside the cmakelists, and even by modifying the CMakeCache.txt, and restarting the build from an empty directory with no success. I then made sure that CMAKE_BUILD_TYPE was effectively set to Debug by using the MESSAGE command to print it's value, and it was correctly set to Debug. So then I executed 'make VERBOSE=1' to see if the correct compiler option was added, and found it correctly used the "-g" option (although I would have expected -ggdb, but more on this later). The cmake documentation and Google did not bring me any answers.
My hypothesis is that the -g option only generates basic debugging information (such as the mappings between functions and their memory addresses, and how to access their arguments) whereas -ggdb would generate more in-detail debugging information in a gdb-specific format, including said line number informations), but a troubling fact is that, when running the executable in gdb, functions defined inside the executable do have line number information, only the shared libraries don't, hence my confusion.

When should I rerun cmake?

After running the cmake command once to generate a build system, when, if ever, should I rerun the cmake command?
The generated build systems can detect changes in the associated CMakeLists.txt files and behave accordingly. You can see the logic for doing so in generated Makefiles. The exact rules for when this will happen successfully are mysterious to me.
When should I rerun cmake? Does the answer depend on the generator used?
This blog post (under heading: "Invoking CMake multiple times") points out the confusion over this issue and states that the answer is actually 'never', regardless of generator, but I find that surprising. Is it true?
The answer is simple:
The cmake binary of course needs to re-run each time you make changes to any build setting, but you wont need to do it by design; hence "never" is correct regarding commands you have to issue.
The build targets created by cmake automatically include checks for each file subsequently [=starting from the main CMakeLists.txt file] involved or included generating the current set of Makefiles/VS projects/whatever. When invoking make (assuming unix here) this automatically triggers a previous execution of cmake if necessary; so your generated projects include logic to invoke cmake itself! As all command-line parameters initially passed (e.g. cmake -DCMAKE_BUILD_TYPE=RELEASE .. will be stored in the CMakeCache.txt, you dont need to re-specify any of those on subsequent invocations, which is why the projects also can just run cmake and know it still does what you intended.
Some more detail:
CMake generates book-keeping files containing all files that were involved in Makefile/Project generation, see e.g. these sample contents of my <binary-dir>/CMakeFiles/Makefile.cmake file using MSYS makefiles:
# The top level Makefile was generated from the following files:
set(CMAKE_MAKEFILE_DEPENDS
"CMakeCache.txt"
"C:/Program Files (x86)/CMake/share/cmake-3.1/Modules/CMakeCCompiler.cmake.in"
"C:/Program Files (x86)/CMake/share/cmake-3.1/Modules/RepositoryInfo.txt.in"
"<my external project bin dir>/release/ep_tmp/IRON-cfgcmd.txt.in"
"../CMakeFindModuleWrappers/FindBLAS.cmake"
"../CMakeFindModuleWrappers/FindLAPACK.cmake"
"../CMakeLists.txt"
"../CMakeScripts/CreateLocalConfig.cmake"
"../Config/Variables.cmake"
"../Dependencies.cmake"
"CMakeFiles/3.1.0/CMakeCCompiler.cmake"
"CMakeFiles/3.1.0/CMakeRCCompiler.cmake")
Any modification to any of these files will trigger another cmake run whenever you choose to start a build of a target. I honestly dont know how fine-grained those dependencies tracking goes in CMake, i.e. if a target will just be build if any changes somewhere else wont affect the target's compilation. I wouldn't expect it as this can get messy quite quickly, and repeated CMake runs (correctly using the Cache capabilities) are very fast anyways.
The only case where you need to re-run cmake is when you change the compiler after you started a project(MyProject); but even this case is handled by newer CMake versions automatically now (with some yelling :-)).
additional comment responding to comments:
There are cases where you will need to manually re-run cmake, and that is whenever you write your configure scripts so badly that cmake cannot possibly detect files/dependencies you're creating. A typical scenario would be that your first cmake run creates files using e.g. execute_process and you would then include them using file(GLOB ..). This is BAD style and the CMake Docs for file explicitly say
Note: We do not recommend using GLOB to collect a list of source files from your source tree. If no CMakeLists.txt file changes when a source is added or removed then the generated build system cannot know when to ask CMake to regenerate.
Btw this comment also sheds light on the above explained self-invocation by the generated build system :-)
The "proper" way to treat this kind of situations where you create source files during configure time is to use add_custom_command(OUTPUT ...), so that CMake is "aware" of a file being generated and tracks changes correctly. If for some reason you can't/won't use add_custom_command, you can still let CMake know of your file generation using the source file property GENERATED. Any source file with this flag set can be hard-coded into target source files and CMake wont complain about missing files at configure time (and expects this file to be generated some time during the (first!) cmake run.
Looking into this topic for reading the version information from a debian/changelog file (generation phase), I ran in the topic that cmake execution should be triggered as debian/changelog is modified. So I had the need to add debian/changelog to CMAKE_MAKEFILE_DEPENDS.
In my case, debian/changelog is read through execute_process. Execute_process unfortunately gives no possibility to add files processed to CMAKE_MAKEFILE_DEPENDS. But I found that running configure_file will do it. Actually I am really missing something like DEPENDENCIES in execute_process.
However, as I had the need to configure the debian/changelog file for my needs, the solution came implicitly to me.
I actually also found a hint about this in the official documentation of configure_file:
"If the input file is modified the build system will re-run CMake to re-configure the file and generate the build system again."
So using configure_file should be a safe to trigger the re-run of cmake.
From a user perspective, I would expect other commands to extend CMAKE_MAKEFILE_DEPENDS, too. E.g. execute_process (on demand) but also file(READ) (implicitly like configure_file). Perhaps there are others. Each read file is likely to influence the generation phase. As an alternative it would be nice to have a command to just extend the dependency list (hint for the cmake developers, perhaps one comes along).

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

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
$#

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.