C++ 我想澄清如何正确连接共享LIB

C++ 我想澄清如何正确连接共享LIB,c++,dll,shared-libraries,C++,Dll,Shared Libraries,让我们举一个真实的例子——我有两个本机android lib模块(CMake)。第一个模块名为-libtetdecker(此处进一步为-A),另一个模块名为-libtetplayer(此处进一步为-B)。因此,liba使用opencv,libb使用liba。然后,opencv是共享lib,这意味着为了使它在liba中工作,我需要包括头文件和.So文件 我用CMakeList.txt这样做 ... include_directories(${pathToOpenCv}/sdk/native/jni

让我们举一个真实的例子——我有两个本机android lib模块(
CMake
)。第一个模块名为-
libtetdecker
(此处进一步为-A),另一个模块名为-
libtetplayer
(此处进一步为-B)。因此,liba使用
opencv
,libb使用liba。然后,opencv是共享lib,这意味着为了使它在liba中工作,我需要包括头文件和.So文件

我用
CMakeList.txt
这样做

...
include_directories(${pathToOpenCv}/sdk/native/jni/include)
add_library(lib_opencv SHARED IMPORTED)
set_target_properties(lib_opencv PROPERTIES IMPORTED_LOCATION
        ${pathToOpenCv}/sdk/native/libs/${CMAKE_ANDROID_ARCH_ABI}/libopencv_java3.so)
...
正如我在上面所说的,lib B使用lib A(但不是opencv),所以链看起来像这样
B->A->opencv(共享)
。问题是——在这种情况下,我是否需要在libb中包含opencv配置(CMake)?因为据我所知,如果libb要使用liba,那么这意味着libb应该实现与liba相同的所有依赖项

为什么我要问,因为今天我在库A和库B中有这个实现,如果我试图清理库B
CMakeList.txt
并删除opencv配置行,它将不起作用


所以,问题是-如果我真的需要在所有派生库中包含这个opencv依赖项?

如果您通过
target\u link\u库
链接它并将它们链接到
PUBLIC
ly,依赖项应该是可传递的,请看这里

目录结构:

- src
-- CMakeLists.txt
-- ecu.cpp
-- engine_ecu.cpp
-- ...
- test
-- CMakeLists.txt
-- integration_test.cpp
src/CMakeLists.txt:

project(EngineController)

add_library(Lib1 SHARED
    ecu.cpp
)

add_library(Lib2 SHARED
    engine_ecu.cpp
    load_detector.cpp
    math_helper.cpp
    temperature_sensor.cpp
)

target_link_libraries(Lib1
    PUBLIC
        EngineControllerApi
)

target_link_libraries(Lib2
    PUBLIC
        EngineControllerApi
        Lib1
)
project(EngineControllerTest)

add_executable(${PROJECT_NAME}
    integration_test.cpp
)

target_link_libraries(${PROJECT_NAME}
    PUBLIC
        Lib2
)
test/CMakeLists.txt:

project(EngineController)

add_library(Lib1 SHARED
    ecu.cpp
)

add_library(Lib2 SHARED
    engine_ecu.cpp
    load_detector.cpp
    math_helper.cpp
    temperature_sensor.cpp
)

target_link_libraries(Lib1
    PUBLIC
        EngineControllerApi
)

target_link_libraries(Lib2
    PUBLIC
        EngineControllerApi
        Lib1
)
project(EngineControllerTest)

add_executable(${PROJECT_NAME}
    integration_test.cpp
)

target_link_libraries(${PROJECT_NAME}
    PUBLIC
        Lib2
)
结果如下:

-- Build files have been written to: /diaggen/example/engine_controller/build
[ 11%] Building CXX object src/CMakeFiles/Lib1.dir/ecu.cpp.o
[ 22%] Linking CXX shared library libLib1.so
[ 22%] Built target Lib1
[ 33%] Building CXX object src/CMakeFiles/Lib2.dir/engine_ecu.cpp.o
[ 44%] Building CXX object src/CMakeFiles/Lib2.dir/load_detector.cpp.o
[ 55%] Building CXX object src/CMakeFiles/Lib2.dir/math_helper.cpp.o
[ 66%] Building CXX object src/CMakeFiles/Lib2.dir/temperature_sensor.cpp.o
[ 77%] Linking CXX shared library libLib2.so
[ 77%] Built target Lib2
[ 88%] Building CXX object test/CMakeFiles/EngineControllerTest.dir/integration_test.cpp.o
[100%] Linking CXX executable EngineControllerTest
[100%] Built target EngineControllerTest
我相信克马克应该能弄明白。首先,确保在引用OpenCV之前调用
find_package
。我相信您可以坚持使用
target\u link\u库
,而不必像您那样更改
属性。在幕后,我相信
target\u link\u libraries
也会修改一些属性,但我相信这样做更清楚。

我相信答案是“是”,因为这个调用会进行一些特定库实例本地的幕后初始化。在编程系统中遇到这种情况是很常见的。所以–“如果可行,就去做。”