We may start with the default option to link two libraries, however, the depedency between two library in the same projects can be classified as PRIVATEPUBLICINTERFACE.
Let’s start with a simple example to show how these things are differnet in cmake.
Assuming there is a main function call the hello, and the hello function calls the helloinner.
Before adding the constraints for the depedency, lets look at the static and daynamic link firstly.
There are four cases, we take down the main operations of make by using make VERBOSE=1
Case 1 Both helloinner and hello are static libraries
#1 create the object file for helloinner /usr/bin/c++ -I/home/zw/cworkspace/src/5MCST/cmake_example/Depedency -MD -MT hello/helloinner/CMakeFiles/helloinner.dir/helloinner.cpp.o -MF CMakeFiles/helloinner.dir/helloinner.cpp.o.d -o CMakeFiles/helloinner.dir/helloinner.cpp.o -c /home/zw/cworkspace/src/5MCST/cmake_example/Depedency/hello/helloinner/helloinner.cpp
#2 build the object file into the static library /usr/bin/ar qc libhelloinner.a CMakeFiles/helloinner.dir/helloinner.cpp.o /usr/bin/ranlib libhelloinner.a
#4 create the static library for hello /usr/bin/ar qc libhello.a CMakeFiles/hello.dir/hello.cpp.o /usr/bin/ranlib libhello.a
#5 build the object file for main /usr/bin/c++ -I/home/zw/cworkspace/src/5MCST/cmake_example/Depedency -MD -MT CMakeFiles/main.dir/main.cpp.o -MF CMakeFiles/main.dir/main.cpp.o.d -o CMakeFiles/main.dir/main.cpp.o -c /home/zw/cworkspace/src/5MCST/cmake_example/Depedency/main.cpp
#6 link the static libraris to main executable file /usr/bin/c++ -rdynamic CMakeFiles/main.dir/main.cpp.o -o main hello/libhello.a hello/helloinner/libhelloinner.a
Case 2 helloinner is shared library and hello is static library
# 1 build the shared object for helloinner # except the parameter used for shared library, it adds -Dhelloinner_EXPORTS as a preprocessor macro helloinner_EXPORTS
# 3 build the object of hello, this is same with previous situation /usr/bin/c++ -I/home/zw/cworkspace/src/5MCST/cmake_example/Depedency -MD -MT hello/CMakeFiles/hello.dir/hello.cpp.o -MF CMakeFiles/hello.dir/hello.cpp.o.d -o CMakeFiles/hello.dir/hello.cpp.o -c /home/zw/cworkspace/src/5MCST/cmake_example/Depedency/hello/hello.cpp
# 4 link to a static lib (same with prevoius situation) /usr/bin/ar qc libhello.a CMakeFiles/hello.dir/hello.cpp.o /usr/bin/ranlib libhello.a
# 5 build object for main (same with previous situation) /usr/bin/c++ -I/home/zw/cworkspace/src/5MCST/cmake_example/Depedency -MD -MT CMakeFiles/main.dir/main.cpp.o -MF CMakeFiles/main.dir/main.cpp.o.d -o CMakeFiles/main.dir/main.cpp.o -c /home/zw/cworkspace/src/5MCST/cmake_example/Depedency/main.cpp
# 6 link the shared object (helloinner) and static library (hello) to the main (two libraries are linked here) /usr/bin/c++ -rdynamic CMakeFiles/main.dir/main.cpp.o -o main -Wl,-rpath,/home/zw/cworkspace/src/5MCST/cmake_example/Depedency/build/hello/helloinner hello/libhello.a hello/helloinner/libhelloinner.so
Case 3 helloinner is static and hello is dynamic library
# 1 and 2 same with the case 1 # 3 build shared object for hello, there is also export macro
# 4 link the static library to the shared library /usr/bin/c++ -fPIC -shared -Wl,-soname,libhello.so -o libhello.so CMakeFiles/hello.dir/hello.cpp.o helloinner/libhelloinner.a
# 5 build the object for main, same with the case 1
# 6 link the shared lib to the main (two libraries are linked here) /usr/bin/c++ -rdynamic CMakeFiles/main.dir/main.cpp.o -o main -Wl,-rpath,/home/zw/cworkspace/src/5MCST/cmake_example/Depedency/build/hello hello/libhello.so hello/helloinner/libhelloinner.a
Case 4 Both helloinner and hello are dynamic libraries
# 6 link the shared executable for main (there are two shared files)
/usr/bin/c++ -rdynamic CMakeFiles/main.dir/main.cpp.o -o main -Wl,-rpath,/home/zw/cworkspace/src/5MCST/cmake_example/Depedency/build/hello:/home/zw/cworkspace/src/5MCST/cmake_example/Depedency/build/hello/helloinner hello/libhello.so hello/helloinner/libhelloinner.so
There are some discussion about the meaning of PRIVATE keyward PUBLIC keyword when link to the target here
If the hello library in our situation is the static library, we does not need to care about the private and public keyword, the static library does not contains the information about the shared library, so the shared library is added to the link path of the main even if we use the private key word here.
The thing that matters is when both helloinner and hello are shared libraries. In this case, when we use the private keyword, at the link stage of the main, we get:
# 1, 2 and 3 are same with the case 4 # 4 link the hello.so libraray, the path of the helloinner is added into the rpath based on the comma format, which is different with the previous case 4