C++ 无法将外部git CMake项目的输出(静态库)链接到CMake项目
我在尝试将最近推到Git上的库链接到我的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
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
#包含它)或其编译库的正确路径
解决包含问题很简单;只需将路径添加到导入库的属性。然而,修复库的路径有点棘手
使用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目录在您的链接答案中似乎暗示了这一点?是的,因为它是导入的。文章的第一段试图解释理由。