使用自己的库使用cmake进行未定义的引用

rob*_*ert 4 c++ cmake

我有以下目录结构:

-project

  -helper
    -build
    -include
      -h_a.h
      -h_b.h
    -src
      -h_a
        -h_a.cpp
        -CMakeLists.txt
      -h_b
        -h_b.cpp
        -CMakeLists.txt
      -CMakeLists.txt

  -proj_c
    -build
    -src
      -main.cpp
      -CMakeLists.txt
Run Code Online (Sandbox Code Playgroud)

helper项目中生成两个库:libh_a.alibh_b.a.libh_a.a用来建立libh_b.a.文件如下:

helper/src/CMakeLists.txt:

cmake_minimum_required(VERSION 2.6)

project(helper)

set(CMAKE_CXX_FLAGS "-Wall -g -std=c++11")

add_subdirectory(h_a)
add_subdirectory(h_b)
Run Code Online (Sandbox Code Playgroud)

helper/src/h_a/CMakeLists.txt:

project(h_a)

add_library(h_a h_a.cpp)
Run Code Online (Sandbox Code Playgroud)

helper/src/h_a/h_a.cpp

void func_a(){}
Run Code Online (Sandbox Code Playgroud)

helper/src/h_b/CMakeLists.txt:

project(h_b)

add_library(h_b h_b.cpp)

target_link_libraries(
    h_b STATIC
    h_a
)
Run Code Online (Sandbox Code Playgroud)

helper/src/h_b/h_b.cpp:

#include "../../include/h_a.h"

void func_b(){
    func_a();   
}
Run Code Online (Sandbox Code Playgroud)

proj_c/src/CMakeLists.txt:

cmake_minimum_required(VERSION 3.2)

project(proj_c)

find_library(h_a PATHS ../../helper/build/h_a)
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../helper/build/h_a)

find_library(h_b PATHS ../../helper/build/h_b)
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../helper/build/h_b)

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "../bin/")

add_executable(proj_c main.cpp)

target_link_libraries(
    proj_c
    h_a
    h_b
)
Run Code Online (Sandbox Code Playgroud)

proj_c/src/main.cpp:

#include "../../helper/include/h_b.h"

int main(){
    func_b();
}
Run Code Online (Sandbox Code Playgroud)

首先,我cmake ../srchelper/build(没有错误消息)运行而不是cmake ../srcproj_c/build我得到

proj_c/src/../../helper/build/h_b/libh_b.a(h_b.cpp.o): In function `func_b()':
helper/src/h_b/h_b.cpp:4: undefined reference to `func_a()'
Run Code Online (Sandbox Code Playgroud)

似乎问题在于h_b.cpp,但libh_b.a之前已经构建没有错误.

Dev*_*lar 5

第一个问题是找不到您的库.在proj_c/build/CMakeCache.txt:

//Path to a library.
h_a:FILEPATH=h_a-NOTFOUND

//Path to a library.
h_b:FILEPATH=h_b-NOTFOUND
Run Code Online (Sandbox Code Playgroud)

(使用DOC选项来find_library()获取通用的"库的路径"替换为更有用的东西.)

find_library()以下情况之后添加支票可以克服这种"无声失败" :

if ( NOT h_a )
    message( FATAL_ERROR "Library h_a not found in ${CMAKE_CURRENT_SOURCE_DIR}/../../helper/build/h_a" )
endif()
Run Code Online (Sandbox Code Playgroud)

(对于较大的项目,您将FindXyz.cmake设置一个用于查找依赖项的模块,您可以通过该模块调用find_package( Xyz REQUIRED )以避免静默失败.但是,在编写此类模块时,您可以使用的辅助函数是一个独立的主题.)

失败本身是由于您使用以下问题find_library:

find_library(h_a PATHS ../../helper/build/h_a)
Run Code Online (Sandbox Code Playgroud)

您告诉CMake在哪里查看,以及在哪个变量中存储结果,但不知道要查找的内容.

使用:

find_library(h_a NAMES h_a PATHS ../../helper/build/h_a)
Run Code Online (Sandbox Code Playgroud)

这将解决-NOTFOUND.(也申请h_b.)

你仍然会得到链接器错误,因为......

target_link_libraries(
    proj_c
    h_a
    h_b
)
Run Code Online (Sandbox Code Playgroud)

...链接订单.proj_c寻找func_b(),没有找到它h_a,找到它h_b,这反过来要求func_a(),未发现因为链接正在上只有库列表中的一个通行证.

它与-lh_a -lh_b命令行中的指定相同.

根据依赖链切换库(proj_c取决于h_b取决于h_a):

target_link_libraries(
    proj_c
    h_b
    h_a
)
Run Code Online (Sandbox Code Playgroud)

那可行.