Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/155.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/22.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++ 无法将外部git CMake项目的输出(静态库)链接到CMake项目_C++_Git_Linker_Cmake_Static Libraries - Fatal编程技术网

C++ 无法将外部git CMake项目的输出(静态库)链接到CMake项目

C++ 无法将外部git CMake项目的输出(静态库)链接到CMake项目,c++,git,linker,cmake,static-libraries,C++,Git,Linker,Cmake,Static Libraries,我在尝试将最近推到Git上的库链接到我的CMake项目时遇到了问题 我已将该库命名为“八进制”(),并试图将其链接到我的另一个库bulletframe()。这两个项目都是由我创建的 我预计第一次链接库不会起作用,所以我只从octal中的几个源文件开始。octal的文件夹结构如下: .gitignore CMakeLists.txt .git/ build/ # generated project files go here, but right now it's empty src/ C

我在尝试将最近推到Git上的库链接到我的CMake项目时遇到了问题

我已将该库命名为“八进制”(),并试图将其链接到我的另一个库
bulletframe
()。这两个项目都是由我创建的

我预计第一次链接库不会起作用,所以我只从
octal
中的几个源文件开始。
octal
的文件夹结构如下:

.gitignore
CMakeLists.txt
.git/
build/ # generated project files go here, but right now it's empty
src/
    CMakeLists.txt
    octal.h # this is empty
    octal/
        vector/
            vector.h
            vector.cpp
octal/CMakeLists.txt

#...

set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_HOME_DIRECTORY}")

add_subdirectory("src")
macro(add_include)
    set(ALL_INCLUDES ${ALL_INCLUDES} ${ARGV})
endmacro(add_include)

add_include("octal.h")
add_include("octal/vector/vector.cpp" "octal/vector/vector.h")

add_library(${PROJECT_NAME} STATIC ${ALL_INCLUDES})

install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY})
macro(add_include)
    set(ALL_INCLUDES ${ALL_INCLUDES} ${ARGV})
endmacro(add_include)

add_include("entity.cpp")

add_library(${PROJECT_NAME} STATIC ${ALL_INCLUDES})

target_link_libraries(${PROJECT_NAME} "octal")
八进制/src/CMakeLists.txt

#...

set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_HOME_DIRECTORY}")

add_subdirectory("src")
macro(add_include)
    set(ALL_INCLUDES ${ALL_INCLUDES} ${ARGV})
endmacro(add_include)

add_include("octal.h")
add_include("octal/vector/vector.cpp" "octal/vector/vector.h")

add_library(${PROJECT_NAME} STATIC ${ALL_INCLUDES})

install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY})
macro(add_include)
    set(ALL_INCLUDES ${ALL_INCLUDES} ${ARGV})
endmacro(add_include)

add_include("entity.cpp")

add_library(${PROJECT_NAME} STATIC ${ALL_INCLUDES})

target_link_libraries(${PROJECT_NAME} "octal")
八进制/src/vector/vector.h

#pragma once

namespace octal
{
    class Vector
    {
        // ...
        Vector Add(Vector other);
        Vector Subtract(Vector other);
        Vector Multiply(Vector other);
        Vector Multiply(double x);
        Vector Divide(Vector other);
        Vector Divide(double x);
        // ...
    }
}

这些配置成功地构建了一个
liboctal.a
文件,但是我不确定它们是否与
bulletframe
正确链接。有多个文件使用来自
octal
的类,但这是它尝试编译第一个源文件
entity.cpp
后出现的第一个错误:

fatal error: octal/vector/vector.h: No such file or directory
 #include "octal/vector/vector.h"
                                 ^
compilation terminated.
src\CMakeFiles\bulletframe.dir\build.make:57: recipe for target 'src/CMakeFiles/bulletframe.dir/entity.cpp.obj' failed
mingw32-make.exe[3]: *** [src/CMakeFiles/bulletframe.dir/entity.cpp.obj] Error 1
CMakeFiles\Makefile2:121: recipe for target 'src/CMakeFiles/bulletframe.dir/all' failed
mingw32-make.exe[2]: *** [src/CMakeFiles/bulletframe.dir/all] Error 2
CMakeFiles\Makefile2:133: recipe for target 'src/CMakeFiles/bulletframe.dir/rule' failed
mingw32-make.exe[1]: *** [src/CMakeFiles/bulletframe.dir/rule] Error 2
Makefile:130: recipe for target 'bulletframe' failed
mingw32-make.exe: *** [bulletframe] Error 2
bulletframe
的文件夹结构与
octal

bulletframe/CMakeLists.txt

include(ExternalProject)
set(EXPROJ_DIR    "${CMAKE_HOME_DIRECTORY}/external")
set(LIB_DIR       "${CMAKE_HOME_DIRECTORY}/lib")

set(OCTAL_NAME          "octal-git")
set(OCTAL_GIT           "https://github.com/TheOctopod/octal-cpp.git")
set(OCTAL_PREFIX        "${EXPROJ_DIR}/${OCTAL_NAME}")
set(OCTAL_SOURCE_DIR    "${EXPROJ_DIR}/${OCTAL_NAME}")
set(OCTAL_BUILD_DIR     "${EXPROJ_DIR}/${OCTAL_NAME}/build")
set(OCTAL_INSTALL_DIR   "${LIB_DIR}")

ExternalProject_Add(${OCTAL_NAME}
    PREFIX          ${OCTAL_PREFIX}
    TMP_DIR         ${OCTAL_PREFIX}-tmp
    STAMP_DIR       ${OCTAL_PREFIX}-stamp
    # - Download Step ------------------
    GIT_REPOSITORY  ${OCTAL_GIT}
    # - Update Step --------------------
    UPDATE_COMMAND  ""
    # - Configure Step -----------------
    SOURCE_DIR      ${OCTAL_SOURCE_DIR}
    # - Build Step ---------------------
    BINARY_DIR      ${OCTAL_BUILD_DIR}
    # - Install Step ------------------
    INSTALL_COMMAND ""
    CMAKE_ARGS
    "-DCMAKE_BUILD_TYPE=Release"
)

add_library("octal" STATIC IMPORTED)
set_target_properties("octal" PROPERTIES
    # this is where ExternalProject built liboctal.a at
    IMPORTED_LOCATION "${OCTAL_BUILD_DIR}/src"
)

add_subdirectory(src)
bulletframe/src/CMakeLists.txt

#...

set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_HOME_DIRECTORY}")

add_subdirectory("src")
macro(add_include)
    set(ALL_INCLUDES ${ALL_INCLUDES} ${ARGV})
endmacro(add_include)

add_include("octal.h")
add_include("octal/vector/vector.cpp" "octal/vector/vector.h")

add_library(${PROJECT_NAME} STATIC ${ALL_INCLUDES})

install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY})
macro(add_include)
    set(ALL_INCLUDES ${ALL_INCLUDES} ${ARGV})
endmacro(add_include)

add_include("entity.cpp")

add_library(${PROJECT_NAME} STATIC ${ALL_INCLUDES})

target_link_libraries(${PROJECT_NAME} "octal")

目前,我的当前配置无法使用
Visual Studio 10 2013
MinGW Makefiles
生成器生成
bulletframe

当我看到编译器每次都给出类似的错误时,我想到了几个问题:

  • 我没有正确构建静态库(
    octal
    )吗?
  • 我没有正确地将它链接到我的项目(
    bulletframe
    )吗?

看起来您正在构建octal OK,但没有提供到其源代码(bulletframe能够
#包含它)或其编译库的正确路径

解决包含问题很简单;只需将路径添加到导入库的属性。然而,修复库的路径有点棘手

使用MSVC,八进制库的完整路径将是

${OCTAL_SOURCE_DIR}/lib/<build type>/octal.lib
为了解决这个问题,我会做如下事情:

add_library(octal STATIC IMPORTED)
if(MSVC)
  set_target_properties(octal PROPERTIES
      IMPORTED_LOCATION_DEBUG "${OCTAL_SOURCE_DIR}/lib/Debug/octal.lib"
      IMPORTED_LOCATION_RELEASE "${OCTAL_SOURCE_DIR}/lib/Release/octal.lib"
      INTERFACE_INCLUDE_DIRECTORIES "${OCTAL_SOURCE_DIR}/src")
else()
  set_target_properties(octal PROPERTIES
      IMPORTED_LOCATION "${OCTAL_SOURCE_DIR}/lib/liboctal.a"
      INTERFACE_INCLUDE_DIRECTORIES "${OCTAL_SOURCE_DIR}/src")
endif()

有趣的是,你提到了if语句——实际上我刚刚添加了一个检查
MSVC
。然而,有一件事让我感到困惑,那就是为什么我需要定义
octal
的源文件。拥有
octall.lib
liboctall.a
是不够的?如果我可以直接包含源代码,为什么还要费心编译一个库呢?不管怎样,谢谢你的回答,我稍后会尝试这个解决方案。你的解决方案奏效了——不过我还是希望你能澄清一下之前评论中提到的问题。除非你想让我再问一个问题?实际上我们想公开的只是八进制的公共标题,而不是源代码的完整列表。请参阅示例,其中给出了我对如何构造库源文件的看法。由于octal的公共头文件与源文件位于同一路径中,因此我们需要给出该路径。将octal作为一个自包含库的一个主要优点是,即使它被多个目标包含,也不需要多次编译。是否因为链接库是导入的
,我需要像使用
设置目标属性
那样显式定义包含目录,还是这只是惯例?比如说,我不能将include目录已经放在
octal.lib
中,因为
target\u include\u目录在您的链接答案中似乎暗示了这一点?是的,因为它是导入的。文章的第一段试图解释理由。