CMake生成的MinGW Makefile有引用错误

时间:2017-07-21 23:19:34

标签: windows cmake mingw zlib mingw-w64

我正在尝试使用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,我可以为预先构建的二进制文件抓网,但这也发生在其他一些版本中。

2 个答案:

答案 0 :(得分:0)

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"
                        VERBATIM)
    set(ZLIB_DLL_SRCS "${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj")
endif(MINGW)

答案 1 :(得分:0)

这似乎是MinGW版本windres.exe中的一个错误,尽管我也要把一些责备归咎于CMake,因为它是一种令人震惊的调用风向标的方法,这是导致失败的原因。

问题

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假设我想默认使用它,尽管没有设置任何环境变量并且它不在路径中(在正常使用中,必须调用vcvars64.bat文件,然后再使用MSVC,此行为早于CMake)。因此,我必须使用-G "MinGW Makefiles",除了我的路径中还有sh.exe(由于Git),而且这让CMake感到震惊,所以我需要命令...

cmake .. -G"MSYS Makefiles" -DCMAKE_RC_COMPILER=windres