[英]Handling Shared Library Dependencies with CMake and C++
我有一个利用共享库的c ++项目,其中一些具有自己的依赖性。 但是,我被迫在main.cpp文件中包括共享库依赖项的头文件。 我假设这与我的项目结构有关,但我不确定。
项目结构:
- myproject
|-> foo1
|-> include
|-> foo1_stuff.hpp
|-> src
|-> main.cpp
|-> build
|-> CMakeLists.txt
|-> foo2
|-> include
|-> foo2_stuff.hpp
|-> src
|-> main.cpp
|-> build
|-> CMakeLists.txt
|-> lib
|-> bar
|-> include
|-> bar.hpp
|-> src
|-> bar.cpp
|-> bar_tool
|-> include
|-> bar_tool.hpp
|-> src
|-> bar_tool.cpp
|-> CmakeLists.txt
foo1的main.cpp:
#include <bar_tool.hpp>
int main()
{
bar_tool tool;
tool.doStuff();
return 0;
}
bar_tool.hpp:
#include <bar.hpp>
class bar_tool
{
public:
bar_tool();
~bar_tool();
int var;
void doStuff();
};
bar_tool.cpp:
#include <iostream>
#include <bar_tool.hpp>
bar_tool::bar_tool() : var(0) {}
bar_tool::~bar_tool() {}
void bar_tool::doStuff()
{
std::cout << barFunction(var) << std::endl;
}
bar.cpp:
int barFunction(int value)
{
return value + 2;
}
Foo1 CMake列表:
cmake_minimum_required(VERSION 3.10.2)
project(foo)
set(PROJECT_ROOT ~/myproject/)
set(
CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_ROOT}/bin/
)
link_directories(
/usr/local/lib
/usr/lib
${PROJECT_ROOT}/lib
)
include_directories(
include
${PROJECT_ROOT}/lib/bar_tool/include
)
file(GLOB SOURCES "src/*.cpp")
add_executable(${PROJECT_NAME} ${SOURCES})
target_link_libraries(
${PROJECT_NAME}
bar_tool
)
共享库CMakeLists:
cmake_minimum_required(VERSION 3.10.2)
project(myproject)
set(PROJECT_ROOT ~/myproject/)
set(
CMAKE_LIBRARY_OUTPUT_DIRECTORY
${PROJECT_ROOT}/lib/
)
link_directories(
/usr/local/lib
/usr/lib
${PROJECT_ROOT}/lib
)
include_directories(
include
${PROJECT_ROOT}/lib/bar/include
${PROJECT_ROOT}/lib/bar_tool/include
)
# bar library
set(LIB_NAME "bar")
file(GLOB LIB_SRC "${LIB_NAME}/src/*.cpp")
add_library(${LIB_NAME} SHARED ${LIB_SRC})
# bar_tool library
set(LIB_NAME "bar_tool")
file(GLOB LIB_SRC "${LIB_NAME}/src/*.cpp")
add_library(${LIB_NAME} SHARED ${LIB_SRC})
target_link_libraries(
${LIB_NAME}
bar
)
我希望使用已编译的bar_tool共享库( libbar_tool.so
)不需要在foo1的CMakeLists的include_directories
部分中包含bar.hpp
。 但是,如果没有,则会出现以下错误:
In file included from /home/mrd/Development/compile_test/foo/src/main.cpp:1:0:
/home/mrd/Development/compile_test/lib/bar_tool/include/bar_tool.hpp:1:10: fatal error: bar.hpp: No such file or directory
#include <bar.hpp>
^~~~~~~~~
compilation terminated.
我没有正确使用共享库或CMake(或两者)吗?
固定:
更新的共享库CMakeLists:
cmake_minimum_required(VERSION 3.10.2)
project(myproject)
set(PROJECT_ROOT ~/myproject/)
set(
CMAKE_LIBRARY_OUTPUT_DIRECTORY
${PROJECT_ROOT}/lib/
)
# bar library
set(LIB_NAME "bar")
file(GLOB LIB_SRC "${LIB_NAME}/src/*.cpp")
add_library(${LIB_NAME} SHARED ${LIB_SRC})
target_include_directories(
${LIB_NAME} PUBLIC
${PROJECT_ROOT}/lib/bar/include
)
# bar_tool library
set(LIB_NAME "bar_tool")
file(GLOB LIB_SRC "${LIB_NAME}/src/*.cpp")
add_library(${LIB_NAME} SHARED ${LIB_SRC})
target_include_directories(
${LIB_NAME} PUBLIC
${PROJECT_ROOT}/lib/bar_tool/include
)
target_link_libraries(
${LIB_NAME} PUBLIC
bar
)
不知道这是否有效果,但是我也更改了它:
更新的 Foo1 CMakeLists:
cmake_minimum_required(VERSION 3.10.2)
project(foo)
set(PROJECT_ROOT /home/mrd/Development/compile_test)
set(
CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_ROOT}/bin/
)
add_subdirectory(${PROJECT_ROOT}/lib/ bin)
file(GLOB SOURCES "src/*.cpp")
add_executable(${PROJECT_NAME} ${SOURCES})
target_link_libraries(
${PROJECT_NAME}
bar_tool
)
任何其他建议都值得欢迎!
由于您具有已编译的库,因此无需添加源文件的路径。 所有函数调用,外部变量访问等都将链接到此预编译的库。
而当您包含头文件时,情况并非如此。 Make会在编译之前尝试创建所有依赖项的列表,以查找所有标头。 因此,必须提供直接或间接包括的所有标题的路径。
在您的共享库CMakeLists.txt
文件中,考虑添加PUBLIC
关键字以确保可传递依赖项(即bar
库)可以传播到最终目标。 另外,现代CMake鼓励使用target_include_directories()
而不是include_directories()
。 同样,您还应该在此处添加PUBLIC
关键字:
target_include_directories(bar PUBLIC
${PROJECT_ROOT}/lib/bar/include
)
target_include_directories(bar_tool PUBLIC
${PROJECT_ROOT}/lib/bar_tool/include
)
target_link_libraries(
${LIB_NAME} PUBLIC
bar
)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.