CMake 生成的 MinGW Makefile 有引用错误
CMake-generated MinGW Makefile has quoting errors
我试图用 CMake 3.9.0 构建 zlib,输出设置为 MinGW Makefiles,并在尝试调用输出目录中的 mingw32-make
时注意到有一条奇怪的错误消息,看起来很像对我来说是一个引用错误。
D:\zlib-1.2-11> mingw32-make
[ 2%] Generating zlib1rc.obj
'C:\Program' is not recognized as an internal or external command,
operable program or batch file.
C:\Program Files\mingw-w64\x86_64-7.1.0-win32-seh-rt_v5-rev0\mingw64\bin\windres.exe: preprocessing failed.
CMakeFiles\zlib.dir\build.make:60: recipe for target 'zlib1rc.obj' failed
mingw32-make[2]: *** [zlib1rc.obj] Error 1
CMakeFiles\Makefile2:103: recipe for target 'CMakeFiles/zlib.dir/all' failed
mingw32-make[1]: *** [CMakeFiles/zlib.dir/all] Error 2
Makefile:139: recipe for target 'all' failed
mingw32-make: *** [all] Error 2
此错误可能是什么原因造成的,我该如何解决?如果它只是 zlib,我可以在网络上搜索预构建的二进制文件,但其他一些构建也发生过这种情况。
CMake 文件作者应该引用包含未知文件系统路径的字符串,即变量和 VERBATIM 选项也避免了麻烦:
if(MINGW)
# This gets us DLL resource information when compiling on MinGW.
if(NOT CMAKE_RC_COMPILER)
set(CMAKE_RC_COMPILER windres.exe)
endif()
add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj"
COMMAND "${CMAKE_RC_COMPILER}"
-D GCC_WINDRES
-I "${CMAKE_CURRENT_SOURCE_DIR}"
-I "${CMAKE_CURRENT_BINARY_DIR}"
-o "${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj"
-i "${CMAKE_CURRENT_SOURCE_DIR}/win32/zlib1.rc"
<b>VERBATIM</b>)
set(ZLIB_DLL_SRCS "${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj")
endif(MINGW)
这似乎是 MinGW 版本 windres.exe
中的一个错误,尽管我也将一些责任归咎于 CMake,因为它调用 windres 的方法令人震惊,这就是导致失败的原因。
问题
CMake 理解 Windows 资源 .rc
文件是一个东西,它们是用 Windows 资源编译器(又名 windres.exe
)编译的,它包装了在默认变量 CMAKE_RC_COMPILER
.
问题是,CMake 并不像普通人那样调用 windres
,而是认为这样调用它很聪明...
cmd.exe /C "cd /D C:\Users\username\zlib-1.2.11\build && "C:\Program Files\mingw-w64\x86_64-7.2.0-posix-seh-rt_v5-rev0\mingw64\bin\windres.exe" -D GCC_WINDRES -I C:/Users/username/zlib-1.2.11 -I C:/Users/username/zlib-1.2.11/build -o C:/Users/username/zlib-1.2.11/build/zlib1rc.obj -i C:/Users/username/zlib-1.2.11/win32/zlib1.rc"
显然它不理解当前工作目录或系统路径变量(它首先用于查找 windres)的概念。如果我们要简化命令,它看起来像这样...
windres -D GCC_WINDRES -I.. -I. -ozlib1rc.obj -i ../win32/zlib1.rc
这两个命令具有完全相同的含义,除了第二个命令确实有效。
解决方案
我们必须介入并阻止 CMake 耍小聪明。
cmake .. -DCMAKE_RC_COMPILER=windres
我已经安装了 MSVC 2017,并且 CMake 假设我想默认使用它,尽管设置了 none 的环境变量并且它不在路径中(在正常使用中,必须调用vcvars64.bat
文件之前使用 MSVC,此行为早于 CMake)。所以我必须使用 -G "MinGW Makefiles"
,除了我的路径中还有 sh.exe
(因为 Git),这让 CMake 大吃一惊,所以我需要命令...
cmake .. -G"MSYS Makefiles" -DCMAKE_RC_COMPILER=windres
我试图用 CMake 3.9.0 构建 zlib,输出设置为 MinGW Makefiles,并在尝试调用输出目录中的 mingw32-make
时注意到有一条奇怪的错误消息,看起来很像对我来说是一个引用错误。
D:\zlib-1.2-11> mingw32-make
[ 2%] Generating zlib1rc.obj
'C:\Program' is not recognized as an internal or external command,
operable program or batch file.
C:\Program Files\mingw-w64\x86_64-7.1.0-win32-seh-rt_v5-rev0\mingw64\bin\windres.exe: preprocessing failed.
CMakeFiles\zlib.dir\build.make:60: recipe for target 'zlib1rc.obj' failed
mingw32-make[2]: *** [zlib1rc.obj] Error 1
CMakeFiles\Makefile2:103: recipe for target 'CMakeFiles/zlib.dir/all' failed
mingw32-make[1]: *** [CMakeFiles/zlib.dir/all] Error 2
Makefile:139: recipe for target 'all' failed
mingw32-make: *** [all] Error 2
此错误可能是什么原因造成的,我该如何解决?如果它只是 zlib,我可以在网络上搜索预构建的二进制文件,但其他一些构建也发生过这种情况。
CMake 文件作者应该引用包含未知文件系统路径的字符串,即变量和 VERBATIM 选项也避免了麻烦:
if(MINGW)
# This gets us DLL resource information when compiling on MinGW.
if(NOT CMAKE_RC_COMPILER)
set(CMAKE_RC_COMPILER windres.exe)
endif()
add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj"
COMMAND "${CMAKE_RC_COMPILER}"
-D GCC_WINDRES
-I "${CMAKE_CURRENT_SOURCE_DIR}"
-I "${CMAKE_CURRENT_BINARY_DIR}"
-o "${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj"
-i "${CMAKE_CURRENT_SOURCE_DIR}/win32/zlib1.rc"
<b>VERBATIM</b>)
set(ZLIB_DLL_SRCS "${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj")
endif(MINGW)
这似乎是 MinGW 版本 windres.exe
中的一个错误,尽管我也将一些责任归咎于 CMake,因为它调用 windres 的方法令人震惊,这就是导致失败的原因。
问题
CMake 理解 Windows 资源 .rc
文件是一个东西,它们是用 Windows 资源编译器(又名 windres.exe
)编译的,它包装了在默认变量 CMAKE_RC_COMPILER
.
问题是,CMake 并不像普通人那样调用 windres
,而是认为这样调用它很聪明...
cmd.exe /C "cd /D C:\Users\username\zlib-1.2.11\build && "C:\Program Files\mingw-w64\x86_64-7.2.0-posix-seh-rt_v5-rev0\mingw64\bin\windres.exe" -D GCC_WINDRES -I C:/Users/username/zlib-1.2.11 -I C:/Users/username/zlib-1.2.11/build -o C:/Users/username/zlib-1.2.11/build/zlib1rc.obj -i C:/Users/username/zlib-1.2.11/win32/zlib1.rc"
显然它不理解当前工作目录或系统路径变量(它首先用于查找 windres)的概念。如果我们要简化命令,它看起来像这样...
windres -D GCC_WINDRES -I.. -I. -ozlib1rc.obj -i ../win32/zlib1.rc
这两个命令具有完全相同的含义,除了第二个命令确实有效。
解决方案
我们必须介入并阻止 CMake 耍小聪明。
cmake .. -DCMAKE_RC_COMPILER=windres
我已经安装了 MSVC 2017,并且 CMake 假设我想默认使用它,尽管设置了 none 的环境变量并且它不在路径中(在正常使用中,必须调用vcvars64.bat
文件之前使用 MSVC,此行为早于 CMake)。所以我必须使用 -G "MinGW Makefiles"
,除了我的路径中还有 sh.exe
(因为 Git),这让 CMake 大吃一惊,所以我需要命令...
cmake .. -G"MSYS Makefiles" -DCMAKE_RC_COMPILER=windres