无法 link 外部 git CMake 项目的输出(静态库)到 CMake 项目
Unable to link the output (static library) of an external git CMake project to a CMake project
我在尝试 link 我最近推送到 Git 的库到我的 CMake 项目时遇到了问题。
我已将库命名为 octal
(GitHub) and am trying to link it to my other library bulletframe
(GitHub)。这两个项目都是我创建的。
我预料到 link 第一次使用库不会起作用,所以我只从 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")
octal/src/CMakeLists.txt
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})
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
文件,但是我不确定它们是否 link 与 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
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
) 吗?
- 我没有正确地 link 将其添加到我的项目 (
bulletframe
) 中吗?
看起来你正在构建八进制,但没有提供正确的源路径(为了 bulletframe 能够 #include
它),也没有提供到它的编译库。
修复包含问题很简单;只需将路径添加到导入库的 INTERFACE_INCLUDE_DIRECTORIES
属性。但是,修复库的路径有点棘手。
使用 MSVC,八进制库的完整路径将是
${OCTAL_SOURCE_DIR}/lib/<build type>/octal.lib
其中 <build type>
是 "Debug"、"Release" 等。但是,对于其他编译器,路径将是
${OCTAL_SOURCE_DIR}/lib/liboctal.a
为了解决这个问题,我会做类似的事情:
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()
我在尝试 link 我最近推送到 Git 的库到我的 CMake 项目时遇到了问题。
我已将库命名为 octal
(GitHub) and am trying to link it to my other library bulletframe
(GitHub)。这两个项目都是我创建的。
我预料到 link 第一次使用库不会起作用,所以我只从 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")
octal/src/CMakeLists.txt
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})
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
文件,但是我不确定它们是否 link 与 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
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
) 吗? - 我没有正确地 link 将其添加到我的项目 (
bulletframe
) 中吗?
看起来你正在构建八进制,但没有提供正确的源路径(为了 bulletframe 能够 #include
它),也没有提供到它的编译库。
修复包含问题很简单;只需将路径添加到导入库的 INTERFACE_INCLUDE_DIRECTORIES
属性。但是,修复库的路径有点棘手。
使用 MSVC,八进制库的完整路径将是
${OCTAL_SOURCE_DIR}/lib/<build type>/octal.lib
其中 <build type>
是 "Debug"、"Release" 等。但是,对于其他编译器,路径将是
${OCTAL_SOURCE_DIR}/lib/liboctal.a
为了解决这个问题,我会做类似的事情:
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()