我有以下目录结构:
-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
在helper
项目中,会生成两个库:libh_a.a
和libh_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)
helper/src/h_a/CMakeLists.txt:
project(h_a)
add_library(h_a h_a.cpp)
helper/src/h_a/h_a.cpp
void func_a(){}
helper/src/h_b/CMakeLists.txt:
project(h_b)
add_library(h_b h_b.cpp)
target_link_libraries(
h_b STATIC
h_a
)
helper/src/h_b/h_b.cpp:
#include "../../include/h_a.h"
void func_b(){
func_a();
}
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
)
proj_c/src/main.cpp:
#include "../../helper/include/h_b.h"
int main(){
func_b();
}
首先我从cmake ../src
helper/build
运行cmake ../src
(没有错误消息),而proj_c/build
的{{1}}运行
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()'
问题似乎是h_b.cpp
,但libh_b.a
之前已经构建而没有错误。
答案 0 :(得分: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
(使用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()
(对于较大的项目,您将设置一个FindXyz.cmake
模块来查找依赖项,您可以通过find_package( Xyz REQUIRED )
调用它来避免静默失败。但是这样,以及写入时可用的帮助函数这样一个模块,是一个独立的主题。)
故障本身是由于您使用find_library
:
find_library(h_a PATHS ../../helper/build/h_a)
你告诉CMake在哪里查看,以及在哪个变量中存储结果,而不是
使用:
find_library(h_a NAMES h_a PATHS ../../helper/build/h_a)
这将解决-NOTFOUND
。 (也适用于h_b
。)
然而,由于......
,您仍会收到链接器错误target_link_libraries(
proj_c
h_a
h_b
)
...链接订单。 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
)
):
[HttpPost]
[ODataRoute("PostUpdate")]
public async Task<string> PostUpdate(HttpRequestMessage eventsToUpdate)
{
//Do something
}
这将有效。