Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ CMake 3.8.0在makefiles中生成错误的链接命令 问题:_C++_Cmake_Mingw W64_Ninja - Fatal编程技术网

C++ CMake 3.8.0在makefiles中生成错误的链接命令 问题:

C++ CMake 3.8.0在makefiles中生成错误的链接命令 问题:,c++,cmake,mingw-w64,ninja,C++,Cmake,Mingw W64,Ninja,在我运行cmake生成一个带有静态库的项目并成功完成后,ninja和mingw32都未能实现链接的目标。对于共享库或可执行文件,同样的设置效果很好。我在“忍者”和“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"

在我运行cmake生成一个带有静态库的项目并成功完成后,ninja和mingw32都未能实现链接的目标。对于共享库或可执行文件,同样的设置效果很好。我在“忍者”和“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生成输出:

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\u root\build\CMakeFiles\hello\u wsl.dir\link.txt”:


分步骤复制“MinGW makefile”问题的示例项目:
  • 安装CMake 3.8.0
  • 安装MinGWx64 6.3 windows二进制文件()
  • 为这个项目创建一个根文件夹,在这个示例中我将它称为project\u root
  • 在内部创建以下子文件夹:
  • 项目\u根目录\build
  • 项目\u根目录\include
  • 项目\u root\include\lib\u hello\u world
  • 创建以下文件:

  • project\u root\include\lib\u hello\u world\lib\u hello\u world.cpp:

  • project\u root\toolchain.cmake:

  • project\u root\configure.bat:

  • project\u root\build.bat:

  • 最后,打开CMD并运行以下命令:

    project_root\configure.bat
    project_root\build.bat
    

这是我发现的一个粗略的修复/解决方法:
  • 创建此文件: project\u root\fix.bat:

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

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

  • mingw32修复后生成(已成功链接):


我做了几件事试图解决这个问题:
  • 在应用修复程序并重新运行configure and build之前,我备份了CMakeCache.txt(CMakeCache.txt.before\u fix)。在重新配置并成功构建项目后,修复之前的CMakeCache.txt文件与CMakeCache.txt文件之间没有差异

  • 我还备份了“rules.ninja”,然后将它们与FC进行了比较。这是FC“project\u root\rules.ninja.before\u fix”“project\u root\build\rules.ninja”的输出:

  • 对“MinGW Makefiles”也是如此。这是FC“project\u root\link.txt.before\u fix”“project\u root\build\cmakfiles\lib\u hello\u world.dir\link.txt”的输出:


  • 关于CMAKE_AR和CMAKE_RUNLIB变量有一些特定的定义:根据这些定义,它们应该声明为缓存的

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

    CMake不知道变量CMake_链接器。请参阅关于设置链接器。@Tsyvarev如果我在“project_root\toolchain.CMAKE”(最后一行)中定义它,它怎么会不知道CMAKE_链接器?“#链接器集(CMAKE_链接器“$ENV{MINGW_W64_BIN_DIR}/ld.bfd.exe”)?我应该能够在工具链文件中指定链接器,对吗?我的意思是,CMake在内部不使用CMake_链接器变量:该名称并不表示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")
    
    @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
    
    @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
    
    project_root\configure.bat
    project_root\build.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
    
    project_root\fix.bat
    project_root\configure.bat
    project_root\build.bat
    
    [2/2] Linking CXX static library hello_wsl.lib
    
    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
    
    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
    *****
    
    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
    *****
    
    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")