FindDoxygen: Path handling in MSYS2

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 usig CMake 3.19.3. 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

The root of the problem is a mix of incompatibles environments.

You cannot use MSYS2 tools in a Windows environment. Only MINGW64 or MINGW32 tools can be used.

For example, for Doxygen, you have to install package mingw-w64-x86_64-doxygen and work in mingw64 subsystem by using dedicated console or ensure correct setting of environment variables (i.e. MSYSTEM variable).

1 Like

Thanks a lot @marc.chevrier! This was the missing piece of the puzzle.

I have to admit that I’m using MSYS2 since a short time only and I absolutely didn’t consider these ‘modes’. So your answer even improved my general knowledge about it. :+1: