On Windows/MSys2/MinGW, execute_process(), exec_program() do not work as expected if the executable name contains "." followed by at least one more character
I noticed this behavior when trying to compile gmic-qt (https://github.com/c-koi/gmic-qt), which copntains entries in CMakeLists.txt like the following:
execute_process(COMMAND gimptool-2.0 --libs-noui OUTPUT_VARIABLE GIMP2_LIBRARIES OUTPUT_STRIP_TRAILING_WHITESPACE)
After some trial and error, I established that the execute calls would only work if one of the following was true (I created a few new executables under /mingw64/bin to test some of these cases):
- The executable suffix ".exe" was added to "gimptool-2.0"
- If the executable suffix was not added, then the ".0" had to be removed from the end.
More generally, I suspect, the point of failure is the "." separator, which causes these functions to interpret the string that follows ("0") as a file type -- although I only tested this by changing "0" to "executable" (i.e. "gimptool-2.executable") and having this fail as well.
To be clear, I set up the following hard links to /mingw64/bin/gimptool-2.0
and tested these from Bash (although Bash already had no trouble with the original "gimptool-2.0", either): /mingw64/bin/gimptool2.0.exe*
/mingw64/bin/gimptool-2.exe*
/mingw64/bin/gimptool-2.executable.exe*
I'm a novice when it comes to CMake, so I don't know how to properly obtain debug information. I did however notice that if I changed the execute_process lines to the following and ran cmake with --trace-expand, only in that case did it produce some kind of error message.
For example, these worked (same as the changes above):
exec_program(gimptool-2 ARGS --libs-noui OUTPUT_VARIABLE GIMP2_LIBRARIES)
exec_program(gimptool-2 ARGS --cflags-noui OUTPUT_VARIABLE GIMP2_INCLUDE_DIRS)
Whereas if I used:
exec_program(gimptool-2.0 ARGS --libs-noui OUTPUT_VARIABLE GIMP2_LIBRARIES)
exec_program(gimptool-2.0 ARGS --cflags-noui OUTPUT_VARIABLE GIMP2_INCLUDE_DIRS)
then the following appeared in the --trace-expand output:
set(CMAKE_CXX_FLAGS -fopenmp Process failed because: The system cannot find the file specified
target_link_libraries(gmic_gimp_qt PRIVATE Process failed because: The system cannot find the file specified
To clarify: if I used the original execute_process() and left the executable name as "gimptool-2.0" then the equivalent output line generated by --trace-expand was:
set(CMAKE_CXX_FLAGS -fopenmp )
target_link_libraries(gmic_gimp_qt PRIVATE Qt5::Core;Qt5::Widgets;Qt5::Gui;Qt5::Network;C:/msys64/mingw64/lib/libpng.dll.a;C:/msys64/mingw64/lib/libz.dll.a;C:/msys64/mingw64/lib/libfftw3.dll.a;C:/msys64/mingw64/lib/libz.dll.a;C:/msys64/mingw64/lib/libcurl.dll.a;pthread;psapi;gdi32 )
I.e. there were no errors generated, but the variable assignments were also missing the entries normally added by gimptool. Here's the output from a successful run for each of the execute statements:
set(CMAKE_CXX_FLAGS -fopenmp -pthread -mms-bitfields -IC:/msys64/mingw64/include/gimp-2.0 -IC:/msys64/mingw64/include/gdk-pixbuf-2.0 -IC:/msys64/mingw64/include/libpng16 -IC:/msys64/mingw64/include -IC:/msys64/mingw64/include/cairo -IC:/msys64/mingw64/include/pixman-1 -IC:/msys64/mingw64/include -IC:/msys64/mingw64/include/freetype2 -IC:/msys64/mingw64/include -IC:/msys64/mingw64/include/harfbuzz -IC:/msys64/mingw64/include/libpng16 -IC:/msys64/mingw64/include/gegl-0.4 -IC:/msys64/mingw64/include -IC:/msys64/mingw64/include/json-glib-1.0 -IC:/msys64/mingw64/include/gio-win32-2.0 -IC:/msys64/mingw64/include -IC:/msys64/mingw64/lib/libffi-3.2.1/include -IC:/msys64/mingw64/include/glib-2.0 -IC:/msys64/mingw64/lib/glib-2.0/include -IC:/msys64/mingw64/include -IC:/msys64/mingw64/include/babl-0.1 )
and
target_link_libraries(gmic_gimp_qt PRIVATE -LC:/msys64/mingw64/lib -lgimp-2.0 -lgimpmath-2.0 -lgimpconfig-2.0 -lgimpcolor-2.0 -lgimpbase-2.0 -lgdk_pixbuf-2.0 -lcairo -lgegl-0.4 -lgegl-npd-0.4 -ljson-glib-1.0 -pthread -lgmodule-2.0 -lgio-2.0 -lgobject-2.0 -lintl -lglib-2.0 -lbabl-0.1 Qt5::Core;Qt5::Widgets;Qt5::Gui;Qt5::Network;C:/msys64/mingw64/lib/libpng.dll.a;C:/msys64/mingw64/lib/libz.dll.a;C:/msys64/mingw64/lib/libfftw3.dll.a;C:/msys64/mingw64/lib/libz.dll.a;C:/msys64/mingw64/lib/libcurl.dll.a;pthread;psapi;gdi32 )
I did finally test "gimptool-2." as well, for completeness. I.e. I added /mingw64/bin/gimptool-2..exe, tested by running "gimptool-2. --libs" from Bash (it worked), then changing the execute statements to "... gimptool-2. ...". This did in fact also work, but notice how the execute statements show up in the trace-expand output:
CMakeLists.txt(477): execute_process(COMMAND gimptool-2 --libs-noui OUTPUT_VARIABLE GIMP2_LIBRARIES OUTPUT_STRIP_TRAILING_WHITESPACE )
CMakeLists.txt(479): execute_process(COMMAND gimptool-2 --cflags-noui OUTPUT_VARIABLE GIMP2_INCLUDE_DIRS OUTPUT_STRIP_TRAILING_WHITESPACE )
So in effect, this is the same as the "gimptool-2" testcase above.
I think this constitutes unexpected behavior because the same command lines work both from Bash and Windows' native CL.