CMake/FindDoxygen: Path handling in MSYS2 - cmake

I'm trying to add a target to generate API doc with Doxygen to my CMake project by find_package(Doxygen ...) and doxygen_add_docs(). I'm in a MSYS2 environment on Windows 10. For some reason CMake and Doxygen seem to not handle paths in the expected way (see the example).
At first, Doxygen complains that it cannot create the output directory. The DOXYGEN_OUTPUT_DIRECTORY prepared by CMake is a Windows path with regular forward slashes. Doxygen seems to not recognize this as an absolute path and prepends it with its working directory in the Unix format (/c/Users/...). I tried this by executing the generated target as well as calling Doxygen manually with the generated Doxyfile.doc. It works if I convert the path to a Unix path with cygpath.
The second problem is about finding dot. I have GraphViz installed as a native Windows package and generally the MSYS2 CMake finds this. Then, in the FindDoxygen.cmake DOXYGEN_DOT_PATH is set as the path portion of the dot executable and is modified by file(TO_NATIVE_PATH ...) because I'm on Windows. Trying this manually I could see that it sets that path to "C:/Program Files (x86)/Graphviz/bin" and converts it to "C:/Program\ Files\ (x86)/Graphviz/bin". The latter ends up in Doxyfile.doc. If I remove the backslashes there, it works. I suppose Doxygen considers these backslashes which are meant to escape the spaces as path separators.
For the first problem I have a (hopefully) portable workaround, but the second I can only fix if I manually repeat the retrieval of DOXYGEN_DOT_PATH from the Find module without the conversion step. This doesn't feel like a good solution.
Do I miss something here about path handling in CMake, e.g. some documentation or setting/policy?
Is this anyways the expected behavior, esp. for file(TO_NATIVE_PATH ...), in MSYS2?
Example
Very basic example: Just a CMakeLists.txt to generate Makefiles and invoke Doxygen. The output of make doc shows the 2 problems described above - the error is for #1, the warning for #2.
CMakeLists.txt
cmake_minimum_required(VERSION 3.19)
project(DoxyTest VERSION 0.1)
find_package(Doxygen OPTIONAL_COMPONENTS dot)
doxygen_add_docs(doc)
Trying to build the doc target
$ cmake -G"MSYS Makefiles" ..
-- The C compiler identification is GNU 10.2.0
-- The CXX compiler identification is GNU 10.2.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/msys64/mingw64/bin/gcc.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/msys64/mingw64/bin/g++.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found Doxygen: C:/msys64/usr/bin/doxygen.exe (found version "1.9.1 (ec8203f43232e7e7b16b1c85351c7c48d128f924)") found components: doxygen dot
-- Configuring done
-- Generating done
-- Build files have been written to: C:/Users/myUser/tmp/foo/build
$ make doc
Scanning dependencies of target doc
[100%] Generate API documentation for doc
warning: the dot tool could not be found at C:/Program\ Files\ (x86)/Graphviz/bin
Doxygen version used: 1.9.1 (ec8203f43232e7e7b16b1c85351c7c48d128f924)
error: Could not create output directory /C/Users/myUser/tmp/foo/C:/Users/myUser/tmp/foo/build/html
Exiting...
make[3]: *** [CMakeFiles/doc.dir/build.make:78: CMakeFiles/doc] Error 1
make[2]: *** [CMakeFiles/Makefile2:95: CMakeFiles/doc.dir/all] Error 2
make[1]: *** [CMakeFiles/Makefile2:102: CMakeFiles/doc.dir/rule] Error 2
make: *** [Makefile:137: doc] Error 2

It turned out that the proper Doxygen package was not installed in the MSYS2 environment.
I use the MinGW64 shell, which uses the binaries from the mingw-w64-x86_64-* packages. The CMake output from the question shows that the binaries for the C and CXX compilers are under C:/msys64/mingw64/ (as well as the CMake binary) while Doxygen is in C:/msys64/usr/bin/.
Installing mingw-w64-x86_64-doxygen solved the issue. Now, the CMake output shows the mingw64 path also for Doxygen in the MSYS2 MinGW64-bit shell and API doc generation works flawlessly. Trying the MSYS2 MSYS shell also works fine with CMake using binaries from C:/msys64/usr/bin/.

Related

cmake . -B build - Compiling Neural Graphic Primitives

I trying compile NGP but after cmake . -B build I get this lines:
I've installed
Visual Studio 2019
CUDA Toolkit 11.6
CMake 3.22
Python 3.10
Optix 7.6
C:\NGP\instant-ngp>cmake . -B build
-- Building for: Visual Studio 16 2019
-- Selecting Windows SDK version 10.0.19041.0 to target Windows 10.0.19043.
-- The C compiler identification is MSVC 19.29.30147.0
-- The CXX compiler identification is MSVC 19.29.30147.0
-- The CUDA compiler identification is NVIDIA 11.6.124
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.29.30133/bin/Hostx64/x64/cl.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.29.30133/bin/Hostx64/x64/cl.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Detecting CUDA compiler ABI info
-- Detecting CUDA compiler ABI info - done
-- Check for working CUDA compiler: C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v11.6/bin/nvcc.exe - skipped
-- Detecting CUDA compile features
-- Detecting CUDA compile features - done
-- **Obtained CUDA architectures automatically from installed GPUs**
**CMake Error: The source directory "SOURCES/CMakeFiles/CMakeTmp" does not exist.**
Specify --help for usage, or press the help button on the CMake GUI.
CMake Error at dependencies/tiny-cuda-nn/CMakeLists.txt:107 (try_run):
Failed to configure test project build system.
Call Stack (most recent call first):
dependencies/tiny-cuda-nn/CMakeLists.txt:146 (TCNN_AUTODETECT_CUDA_ARCHITECTURES)
-- Configuring incomplete, errors occurred!
See also "C:/NGP/instant-ngp/build/CMakeFiles/CMakeOutput.log".
I am not coder I just want to try NERF. It ss possible download somewhere compiled NGP or it doesn't work that way?
EDIT: Noticed that OP is using the -S flag implicitly the issue seems to be elsewhere, hence the updated answer:
UPDATED ANSWER
Please bare in mind that with the limited information at my disposal. This is again only a wild guess, based on what I tried.
After re-examining the output of CMake I've noticed that the issue is within one of the dependencies i.e.
CMake Error at dependencies/tiny-cuda-nn/CMakeLists.txt:107 (try_run):
I was not able to completely replicate the problem, however I do believe I know how to debug these issues. My wild guess here is that either:
The individual dependencies were incorrectly pulled or
The CMake files were poorly generated due to some issue and you didn't clean them.
I would recommend trying the following:
Delete the build folder, and run cmake -S. -Bbuild again. And if that fails you can try the second option.
Remove the git repository (folder called instant-ngp) and clone it again using exactly this command:
git clone --recursive https://github.com/nvlabs/instant-ngp
Please note that the --recursive option is very important due to the fact that you need to pull the dependant repositories as well.
Now if all of that fails. You still have one more option and that is to go to the folder dependencies/tiny-cuda-nn/ and generate the CMake files yourself, however I do not recommend that due to the fact that if you have limited experience you may not know what exactly to do.
I've also checked the variables you wanted to set, and you may do that by running this in Powershell
$Env:CMAKE_CUDA_ARCHITECTURES=YOUR_VALUE_HERE (in my case it is 75 because I have a RTX2080). However bare in mind that
You shouldn't need it, because the architecture is discovered for you
You need to delete the build folder in order to clean up the cached CMake files
Hope it helps!

Is it possible to make CMake print one variable at the end from command line?

Scenario
I'm in the process of debugging a CMake script.
In order to produce usable output for me to inspect, I use the following invocation:
cmake -S . -B build -DENABLE_MODULE_A=OFF -DENABLE_MODULE_B=OFF -DENABLE_MODULE_C=OFF --trace-source=CMakeLists.txt --trace-expand |& grep VARIABLE_IM_INTERESTED_IN > build/testout.utf8
Problem
This approach is sub-par, because I'm really only interested in one variable that is expanded in the CMake script in question. grep-ing for that after running it in trace-mode seems to be quite cumbersome, especially since the variable gets expanded multiple times, however I'm interested only in the last, full expansion of said variable.
Desired result
Ideally, there is a command line option for CMake, to print/expand only the one variable I'm interested in. I can filter for the last occurrence of that variable with external tools (for instance tail), but grepping the entire trace output for just one file, seems excessive. In essence I'm looking for a command line option to inspect an arbitrary variable, instead of tracing the entirety of the CMake script.
It is however, not an option to change the CMakeFiles.txt such that this one variable is printed. That is for external reasons, of which I have no control of.
Use variable_watch and CMAKE_PROJECT_INCLUDE_BEFORE as a debugging tool. Create a file called watch_var.cmake with the following contents:
cmake_minimum_required(VERSION 3.24)
variable_watch("${watch_var}")
Now here's an example project:
cmake_minimum_required(VERSION 3.24)
project(example)
set(VARIABLE_IM_INTERESTED_IN foo)
string(APPEND VARIABLE_IM_INTERESTED_IN " bar")
At the command line:
$ cmake -G Ninja -S . -B build -DCMAKE_PROJECT_INCLUDE_BEFORE=$PWD/watch_var.cmake -Dwatch_var=VARIABLE_IM_INTERESTED_IN
-- The C compiler identification is GNU 10.2.1
-- The CXX compiler identification is GNU 10.2.1
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
CMake Debug Log at CMakeLists.txt:4 (set):
Variable "VARIABLE_IM_INTERESTED_IN" was accessed using MODIFIED_ACCESS
with value "foo".
CMake Debug Log at CMakeLists.txt:5 (string):
Variable "VARIABLE_IM_INTERESTED_IN" was accessed using READ_ACCESS with
value "foo".
CMake Debug Log at CMakeLists.txt:5 (string):
Variable "VARIABLE_IM_INTERESTED_IN" was accessed using MODIFIED_ACCESS
with value "foo bar".
-- Configuring done
-- Generating done
-- Build files have been written to: /home/reinking/test2/build
Docs: https://cmake.org/cmake/help/latest/command/variable_watch.html

CMake Setup for Dual Environment Builds

Goal
I am using CMake to make the build for my project which is an embedded firmware based on ARM Cortex platform built using arm-none-eabi-gcc-6.3.1 compiler, using VSCode Editor, and on Windows host. I am trying to make a second build for testing on the Windows system I am using for the same project.
The First Solution Problem
The issue I am having is that whenever I need to switch my build from production to test, I have to delete the build files and rerun the CMake command with the test argument, when I do not do that, the build does not change the ARM compiler to the one I intend to use (I am guessing it is a caching problem). I have tried make clean and make rebuild_cache thinking that it may clean the cache and solve the problem for me, and did not work.
A fresh build Example:
Project\build> cmake -G"MinGW Makefiles" -DTARGET_GROUP=test ..
You have changed variables that require your cache to be deleted.
Configure will be re-run and you may have to reset some variables.
The following variables have changed:
CMAKE_C_COMPILER= C:/MinGW/bin/gcc.exe
CMAKE_CXX_COMPILER= C:/MinGW/bin/g++.exe
-- The C compiler identification is GNU 6.3.0
-- The CXX compiler identification is GNU 6.3.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/MinGW/bin/gcc.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/MinGW/bin/g++.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: Path\to\Project\build
Project\build>make
(successful make)
The second build:
Project\build> cmake -G"MinGW Makefiles" -DTARGET_GROUP=production ..
You have changed variables that require your cache to be deleted.
Configure will be re-run and you may have to reset some variables.
The following variables have changed:
CMAKE_C_COMPILER= Path/to/arm-gnu-toolchain/bin/arm-none-eabi-gcc.exe
CMAKE_CXX_COMPILER= Path/to/arm-gnu-toolchain/bin/arm-none-eabi-g++.exe
-- The C compiler identification is GNU 6.3.0
-- The CXX compiler identification is GNU 6.3.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/MinGW/bin/gcc.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/MinGW/bin/g++.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: Path\to\Project\build
Project\build>make
(Cached make -did not change the compiler or the files to be built)
The CMakeLists.txt:
set(TARGET_GROUP test CACHE STRING "Group to build")
if(TARGET_GROUP STREQUAL production)
# ARM Lib
include("arm-gnu.cmake")
else()
include("win-gcc-for-testing.cmake")
endif()
# include the files based on the TARGET_GROUP value
# ...
Current Solution
Currently, I have a temporary solution by making a separate folder for each building type and they work perfectly.
The question
Is the current solution (making two build directories each is for a different environment) right in terms of best practices? If not, what could be a better one?
As #Tsyvarev says, you have to use different directories if you want different builds. Here you are trying to build both in the same build directory. Instead, create a subdirectory test to build the -DTARGET_GROUP=test, and a different subdirectory prod to build the -DTARGET_GROUP=production:
Project> mkdir test
Project> cd test
Project\test> cmake -G"MinGW Makefiles" -DTARGET_GROUP=test ..
Project\test> cd ..
Project> mkdir prod
Project> cd prod
Project\prod> cmake -G"MinGW Makefiles" -DTARGET_GROUP=production ..
Of course you can call the directories whatever you like.
Since you'd like this to integrate into VSCode, do the configuration change with the CMake build kits, which is what sets the compiler prior to calling CMake. You can specify additional user kit definitions, and in the VSCode interface choose between compiler kits.
Rewrite the CMake files just enough to condition everything else on the selection of compiler.
THEN, the VSCode cmake-tools extension supports variable expansion for the name of the build directory. Among the options are ${buildKit} and ${buildKitTargetArch}. Make this suffix part of the Build Directory setting (your choice of whether to set this only in your workspace, or more globally on your system).
Now, when you switch kits, CMake will pick up the directory change and happily exist with two different build directories.
Alternatively, cmake-tools now provides variants, which could be used to add additional Production and Test to the normal Release, Debug, RelWithDebInfo, etc. There are additional build directory expansion variables for information from the currently selected variant.

Qt-Cretor + CMake insists on using MSVC when I want to use MinGW

I am trying to build a CMake project with MinGW. I have installed MinGW 8.1 through the Qt installer. The CMakeList is unchanged from how Qt Creator created it when creating the project.
When running CMake, I can see how Qt Creator passes the compiler and linker's paths to CMake and how CMake completely ignores them.
Führe C:\Program Files\CMake\bin\cmake.exe -S [snip] -B [snip] "-DCMAKE_BUILD_TYPE:String=Debug" "-DQT_QMAKE_EXECUTABLE:STRING=C:/Qt/5.15.1/mingw81_64/bin/qmake.exe" "-DCMAKE_PREFIX_PATH:STRING=C:/Qt/5.15.1/mingw81_64" "-DCMAKE_C_COMPILER:STRING=C:/Qt/Tools/mingw810_64/bin/gcc.exe" "-DCMAKE_CXX_COMPILER:STRING=C:/Qt/Tools/mingw810_64/bin/g++.exe" in [snip] aus.
-- Building for: Visual Studio 16 2019
-- Selecting Windows SDK version 10.0.18362.0 to target Windows 10.0.19041.
-- The CXX compiler identification is MSVC 19.24.28314.0
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.24.28314/bin/Hostx64/x64/cl.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
CMake Warning:
Manually-specified variables were not used by the project:
CMAKE_BUILD_TYPE
CMAKE_C_COMPILER
QT_QMAKE_EXECUTABLE
Here I am using a system install of CMake, but the output is unchanged when using the CMake installed with Qt Creator. The CMake generator for the selected kit is set to MinGW Makefiles in the Qt Creator settings. Running CMake manually, without Qt Creator, allows me to configure the project. (although it still doesn't compile because of a linker error, that I expect to be independent of this problem)
It seems there is a caching issue. The caching is done by CMake (CMakeCache.txt) and by QtCreator (CMakeLists.txt.user) itself.
Maybe this helps:
Close QtCreator (by closing QtCreator the CMakeLists.txt.user file is saved or generated if the file don't exist)
delete QtCreator's CMakeLists.txt.user
the build folder
Open the project again and select the desired kit.

Cmake: how to force it to use colormake?

in order to use colormake I did set this alias in my .bashrc
alias make="/usr/bin/colormake"
It works, as if I try to compile (with qmake) a simple C++ example code with errors (just a main.cpp with a cout ), they are correctly coloured.
However, if I compile the same code with cmake, colormake is not used. What can I do to force cmake to use it?
my minimal CMakeList.txt example is
CMAKE_MINIMUM_REQUIRED(VERSION 3.0.2)
ADD_DEFINITIONS(-std=c++11)
ADD_EXECUTABLE(exe main.cpp)
System: Debian 8.8 jessie
Thanks, Valerio
Update:
I modified the CMakeLists.txt in this way, but no success:
CMAKE_MINIMUM_REQUIRED(VERSION 3.0.2)
ADD_DEFINITIONS(-std=c++11)
set(CMAKE_MAKE_PROGRAM /usr/bin/colormake)
ADD_EXECUTABLE(exe main.cpp)
message("CMAKE_MAKE_PROGRAM: " ${CMAKE_MAKE_PROGRAM})
Update 2:
I modified the CMakeList in this way:
CMAKE_MINIMUM_REQUIRED(VERSION 3.0.2)
ADD_DEFINITIONS(-std=c++11)
#set(CMAKE_COLOR_MAKEFILE OFF)
#set(CMAKE_MAKE_PROGRAM /usr/bin/colormake)
ADD_EXECUTABLE(exe main.cpp)
message("CMAKE_MAKE_PROGRAM: " ${CMAKE_MAKE_PROGRAM})
message("CMAKE_COLOR_MAKEFILE: " ${CMAKE_COLOR_MAKEFILE})
then launched cmake with this argument from command line:
cmake -DCMAKE_MAKE_PROGRAM=/usr/bin/colormake -DCMAKE_COLOR_MAKEFILE=OFF ../
But again, the main.cpp synthax error after make is not coloured.
This is the output of cmake, note the messages about CMAKE_MAKE_PROGRAM and CMAKE_COLOR_MAKEFILE
-- The C compiler identification is GNU 4.9.2
-- The CXX compiler identification is GNU 4.9.2
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
CMAKE_MAKE_PROGRAM: /usr/bin/colormake
CMAKE_COLOR_MAKEFILE: OFF
-- Configuring done
-- Generating done
-- Build files have been written to: /home/valeriosperati/Desktop/VALERIO_SPERATI/prova_codice_c/colormake/cmake/build
Some additional (maybe helpful) info: this is the output
I obtain when compiling with qmake, the error 'hjskf' is in red.
this is the output when comiling with cmake:
It should be enough to set the CMAKE_MAKE_PROGRAM cache variable to point at the build tool you want to use. You can do this by running cmake with a -D option like so:
cmake -DCMAKE_MAKE_PROGRAM=/usr/bin/colormake path/to/src
For the benefit of others, this technique can be used with other generators too, not just make. Just be aware that it is your responsibility to make sure the build tool specified matches the generator type CMake is using (i.e. don't pass a make tool if you've told CMake to use Ninja with -G Ninja instead).
Note, however, that this only really matters if you are invoking the build via CMake like so:
cmake --build path/to/build/dir
Some IDE tools may invoke the build that way. Most of the time, however, developers invoke the tool directly. In your case, you can simply invoke colormake instead of make. If you are still not getting colored output after doing that, then your problem must be elsewhere (check your terminal type settings perhaps).