gpt4 book ai didi

c++ - CMake 3.8.0 在 makefile 中生成错误的链接命令

转载 作者:搜寻专家 更新时间:2023-10-31 00:09:21 34 4
gpt4 key购买 nike

问题:

在我运行 cmake 生成一个带有 STATIC 库的项目并成功完成后,ninja 和 mingw32-make 都无法在链接时建立它们的目标。对于 SHARED 库或可执行文件,同样的设置工作正常。我已经为“Ninja”和“MinGW Makefiles”生成器尝试过这个:

忍者输出:

[2/2] Linking CXX static library hello_wsl.lib
FAILED: hello_wsl.lib
cmd.exe /C "cd . && "C:\Program Files\CMake\bin\cmake.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
CMakeFiles\hello_wsl.dir\build.make:93: recipe for target 'hello_wsl.lib' failed
mingw32-make.exe[2]: *** [hello_wsl.lib] Error 2
CMakeFiles\Makefile2: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

另请查看“MinGW Makefiles”生成的“project_root\build\CMakeFiles\hello_wsl.dir\link.txt”:

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

示例项目,分步重现“MinGW Makefiles”的问题:

  • 安装CMake 3.8.0
  • 安装 MinGWx64 6.3 windows 二进制文件 ( I've downloaded them from here )
  • 为此项目创建一个根文件夹,我将在本示例中将其称为 project_root。
  • 在里面创建这些子文件夹:
    1. project_root\build
    2. project_root\include
    3. project_root\include\lib_hello_world
  • 创建这些文件:

    1. project_root\include\lib_hello_world\lib_hello_world.cpp:

      #include <iostream>

      class HelloWorldClass{
      HelloWorldClass(){
      std::cout << "Hello, world!" << std::endl;
      }
      };
    2. project_root\include\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 Files\CMake\bin\cmake.exe"
      SET "MINGW_W64_BIN_DIR=C:/Program Files/MinGWx64/bin"
      CD "%~dp0\build"
      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 "%~dp0\build"
      CALL "%MINGW_W64_BIN_DIR%/mingw32-make.exe"
      ENDLOCAL
  • 最后,打开CMD并运行命令:

    project_root\configure.bat
    project_root\build.bat

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

  • 创建这个文件:project_root\fix.bat:

    @ECHO OFF
    SETLOCAL
    @ECHO OFF

    MOVE "%~dp0\build\CMakeCache.txt" ".\"
    RMDIR "%~dp0\build" /S /Q
    MKDIR "%~dp0\build"
    MOVE "%~dp0\CMakeCache.txt" ".\build\"

    ENDLOCAL
  • 重现错误后,打开 CMD 并运行:

    project_root\fix.bat
    project_root\configure.bat
    project_root\build.bat
  • 修复后的 ninja 输出(成功链接):

    [2/2] Linking CXX static library hello_wsl.lib
  • 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
    [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""project_root\build\rules.ninja"的输出:

    Comparando archivos .\rules.ninja.before_fix y .\BUILD\RULES.NINJA
    ***** .\rules.ninja.before_fix
    rule CXX_STATIC_LIBRARY_LINKER__lib_hello_world
    command = cmd.exe /C "$PRE_LINK && "C:\Program Files\CMake\bin\cmake.exe" -E remove $TARGET_FILE && "" qc $TARGET_FILE $LINK_
    FLAGS $in && $POST_BUILD"
    description = Linking CXX static library $TARGET_FILE
    ***** .\BUILD\RULES.NINJA
    rule CXX_STATIC_LIBRARY_LINKER__lib_hello_world
    command = cmd.exe /C "$PRE_LINK && "C:\Program Files\CMake\bin\cmake.exe" -E remove $TARGET_FILE && C:\PROGRA~1\MinGWx64\bin\
    ar.exe qc $TARGET_FILE $LINK_FLAGS $in && C:\PROGRA~1\MinGWx64\bin\ranlib.exe $TARGET_FILE && $POST_BUILD"
    description = Linking CXX static library $TARGET_FILE
    *****
  • 并为“MinGW Makefiles”做了同样的事情。这是 FC "project_root\link.txt.before_fix""project_root\build\CMakeFiles\lib_hello_world.dir\link.txt"的输​​出:

    Comparando archivos .\link.txt.before_fix y .\BUILD\CMAKEFILES\LIB_HELLO_WORLD.DIR\LINK.TXT
    ***** .\link.txt.before_fix
    "" qc hello_wsl.lib CMakeFiles/hello_wsl.dir/lib_hello_world.cpp.obj
    ***** .\BUILD\CMAKEFILES\LIB_HELLO_WORLD.DIR\LINK.TXT
    C:\PROGRA~1\MinGWx64\bin\ar.exe qc lib_hello_world.lib CMakeFiles/lib_hello_world.dir/lib_hello_world.cpp.obj
    C:\PROGRA~1\MinGWx64\bin\ranlib.exe lib_hello_world.lib
    *****

最佳答案

关于 CMAKE_ARCMAKE_RUNLIB 变量有一些具体说明:根据 bugreport它们应该声明为缓存:

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")

关于c++ - CMake 3.8.0 在 makefile 中生成错误的链接命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43751132/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com