Cmake 3.8.0在makefiles中生成错误的链接命令

CMake 3.8.0 generates wrong link command in makefiles

本文关键字:错误 链接 命令 makefiles Cmake      更新时间:2023-10-16

问题:

我运行cmake以生成一个使用静态库生成一个项目,该项目成功地完成了,忍者和mingw32-make都无法实现链接的目标。对于共享库或可执行文件,相同的设置工作正常。我尝试了"忍者"answers" mingw makefiles"发电机的尝试:

忍者输出:

[2/2] Linking CXX static library hello_wsl.lib
FAILED: hello_wsl.lib
cmd.exe /C "cd . && "C:Program FilesCMakebincmake.exe" -E remove hello_wsl.lib && "" qc hello_wsl.lib  CMakeFiles/hello_wsl.dir/lib_hello_world.cpp.obj && cd ."
"""" no se reconoce como un comando interno o externo,
programa o archivo por lotes ejecutable.
ninja: build stopped: subcommand failed.

mingw32-make输出:

Scanning dependencies of target hello_wsl
[ 50%] Building CXX object CMakeFiles/hello_wsl.dir/lib_hello_world.cpp.obj
[100%] Linking CXX static library hello_wsl.lib
Error running link command: El parámetro no es correcto
CMakeFileshello_wsl.dirbuild.make:93: recipe for target 'hello_wsl.lib' failed
mingw32-make.exe[2]: *** [hello_wsl.lib] Error 2
CMakeFilesMakefile2:66: recipe for target 'CMakeFiles/hello_wsl.dir/all' failed
mingw32-make.exe[1]: *** [CMakeFiles/hello_wsl.dir/all] Error 2
Makefile:82: recipe for target 'all' failed
mingw32-make.exe: *** [all] Error 2

还查看" project_root build cmakefiles hello_wsl.dir link.txt",由" mingw makefiles"生成:

"" qc hello_wsl.lib  CMakeFiles/hello_wsl.dir/lib_hello_world.cpp.obj

示例项目,以便重现" mingw makefiles"的问题:

  • 安装Cmake 3.8.0
  • 安装Mingwx64 6.3 Windows二进制文件(我从这里下载了它们(
  • 为此项目创建一个根文件夹,我将其称为project_root。
  • 在内部创建这些子文件夹:
    1. project_root build
    2. project_root include
    3. project_root include lib_hello_world
  • 创建这些文件:

    1. project_root includs lib_hello_world lib_hello_world.cpp:

      #include <iostream>
      class HelloWorldClass{
          HelloWorldClass(){
              std::cout << "Hello, world!" << std::endl;
          }
      };
      
    2. project_root includs lib_hello_world cmakelists.txt:

      cmake_minimum_required(VERSION 3.8.0)
      project(lib_hello_world)
      add_library(lib_hello_world STATIC lib_hello_world.cpp)
      
    3. project_root toolchain.cmake:

      # Target system (cross compile)
      set(CMAKE_SYSTEM_NAME WindowsStore)
      set(CMAKE_SYSTEM_VERSION 10.0)
      # BIN utils
      SET(CMAKE_AR      "$ENV{MINGW_W64_BIN_DIR}/ar.exe")
      SET(CMAKE_OBJCOPY "$ENV{MINGW_W64_BIN_DIR}/objcopy.exe")
      SET(CMAKE_OBJDUMP "$ENV{MINGW_W64_BIN_DIR}/objdump.exe")
      SET(CMAKE_RANLIB  "$ENV{MINGW_W64_BIN_DIR}/ranlib.exe")
      SET(CMAKE_NM      "$ENV{MINGW_W64_BIN_DIR}/nm.exe")
      SET(CMAKE_STRIP   "$ENV{MINGW_W64_BIN_DIR}/strip.exe")
      # C compiler
      SET(CMAKE_C_COMPILER "$ENV{MINGW_W64_BIN_DIR}/gcc.exe")
      # CXX compiler
      SET(CMAKE_CXX_COMPILER "$ENV{MINGW_W64_BIN_DIR}/g++.exe")
      # LINKER
      SET(CMAKE_LINKER "$ENV{MINGW_W64_BIN_DIR}/ld.bfd.exe")
      
    4. project_root configure.bat:

      @ECHO OFF
      SETLOCAL
      @ECHO OFF
      REM Change these variables to the corresponding paths on your own system
      SET "CMAKE_EXECUTABLE=C:Program FilesCMakebincmake.exe"
      SET "MINGW_W64_BIN_DIR=C:/Program Files/MinGWx64/bin"
      CD "%~dp0build"
      CALL "%CMAKE_EXECUTABLE%" "-DCMAKE_EXPORT_COMPILE_COMMANDS=ON" "-DCMAKE_BUILD_TYPE=Debug" -G "MinGW Makefiles" "-DCMAKE_MAKE_PROGRAM='%MINGW_W64_BIN_DIR%/mingw32-make.exe'" "-DCMAKE_TOOLCHAIN_FILE='%~dp0/toolchain.cmake'" "%~dp0/include/lib_hello_world"
      ENDLOCAL
      
    5. project_root build.bat:

      @ECHO OFF
      SETLOCAL
      @ECHO OFF
      REM Change this variable to the corresponding path on your own system
      SET "MINGW_W64_BIN_DIR=C:/Program Files/MinGWx64/bin"
      CD "%~dp0build"
      CALL "%MINGW_W64_BIN_DIR%/mingw32-make.exe"
      ENDLOCAL
      
  • 最后,打开CMD并运行命令:

    project_rootconfigure.bat
    project_rootbuild.bat
    

这是我发现的粗略修复/解决方法:

  • 创建此文件: project_root fix.bat:

    @ECHO OFF
    SETLOCAL
    @ECHO OFF
    MOVE "%~dp0buildCMakeCache.txt" "."
    RMDIR "%~dp0build" /S /Q
    MKDIR "%~dp0build"
    MOVE "%~dp0CMakeCache.txt" ".build"
    ENDLOCAL
    
  • 再现错误后,打开CMD并运行:

    project_rootfix.bat
    project_rootconfigure.bat
    project_rootbuild.bat
    
  • 修复后的忍者输出(成功链接(:

    [2/2] Linking CXX static library hello_wsl.lib
    
  • mingw32 make fix(成功链接(:

    Scanning dependencies of target hello_wsl
    [ 50%] Building CXX object CMakeFiles/hello_wsl.dir/lib_hello_world.cpp.obj
    [100%] Linking CXX static library hello_wsl.lib
    [100%] Built target hello_wsl
    

我尝试弄清楚这一点:

  • 我在应用修复程序和重新固定配置和构建之前,在cmakecache.txt(cmakecache.txt.before_fix(进行了备份。在重新配置和成功构建项目后,cmakecache.txt.before_fix和cmakecache.txt文件之间没有区别。

  • 我还备份了" rules.ninja",然后将它们与FC进行了比较。这是fc" project_root rules.ninja.before_fix"的输出

    Comparando archivos .rules.ninja.before_fix y .BUILDRULES.NINJA
    ***** .rules.ninja.before_fix
    rule CXX_STATIC_LIBRARY_LINKER__lib_hello_world
    command = cmd.exe /C "$PRE_LINK && "C:Program FilesCMakebincmake.exe" -E remove $TARGET_FILE && "" qc $TARGET_FILE $LINK_
    FLAGS $in && $POST_BUILD"
    description = Linking CXX static library $TARGET_FILE
    ***** .BUILDRULES.NINJA
    rule CXX_STATIC_LIBRARY_LINKER__lib_hello_world
    command = cmd.exe /C "$PRE_LINK && "C:Program FilesCMakebincmake.exe" -E remove $TARGET_FILE && C:PROGRA~1MinGWx64bin
    ar.exe qc $TARGET_FILE $LINK_FLAGS $in && C:PROGRA~1MinGWx64binranlib.exe $TARGET_FILE && $POST_BUILD"
    description = Linking CXX static library $TARGET_FILE
    *****
    

  • ,并为" mingw makefiles"做了同样的事情。这是fc" project_root link.txt.before_fix"的输出

    Comparando archivos .link.txt.before_fix y .BUILDCMAKEFILESLIB_HELLO_WORLD.DIRLINK.TXT
    ***** .link.txt.before_fix
    "" qc hello_wsl.lib  CMakeFiles/hello_wsl.dir/lib_hello_world.cpp.obj
    ***** .BUILDCMAKEFILESLIB_HELLO_WORLD.DIRLINK.TXT
    C:PROGRA~1MinGWx64binar.exe qc lib_hello_world.lib  CMakeFiles/lib_hello_world.dir/lib_hello_world.cpp.obj
    C:PROGRA~1MinGWx64binranlib.exe lib_hello_world.lib
    *****
    

关于 cmake_ar cmake_runlib 变量有一些具体的特定内容:根据该Bugreport,应将其声明为 cached strong>:

SET(CMAKE_AR      "$ENV{MINGW_W64_BIN_DIR}/ar.exe" CACHE FILEPATH "Arhiver")
SET(CMAKE_RANLIB  "$ENV{MINGW_W64_BIN_DIR}/ranlib.exe" CACHE FILEPATH "Runlib")
相关文章: