繁体   English   中英

使用CMake和C ++处理共享库依赖关系

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM