我想澄清一下如何正确连接共享库



让我们举一个真实的例子——我有两个原生的android lib模块(CMake(。第一个模块名称为-libtetdecoder(此处为-A(,另一个模块名称是-libtetplayer(此处为-B(。因此,库A使用opencv,库B使用库A。然后,opencv是共享库,这意味着为了使其在库A中工作,我需要包括头文件和.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(shared)。问题是,在这种情况下,我是否需要在lib B中包含opencv配置(CMake(?因为据我所知,如果lib B将使用lib A,那么这意味着lib B应该实现与lib A相同的所有依赖项。

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

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

如果您通过target_link_libraries将其全部链接,并将它们链接到PUBLICly,则依赖关系应该是可传递的,请查看此处。

目录结构:

- 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
)

test/CMakeLists.txt:

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

我认为CMake应该想清楚。首先,确保在引用OpenCV之前调用find_package。我相信你可以坚持使用target_link_libraries,而不必像现在这样修改PROPERTIES。在幕后,我相信target_link_libraries也修改了一些属性,但我相信这样会更清楚。

最新更新