In the previous part This entertaining story talked about the organization of the header library within the framework of the CMake build system generator.
This time we will add a compiled library to it, and also talk about linking modules with each other.
As before, those who are impatient can immediately go to updated repository and touch everything with your hands.
The first thing to do to achieve our lofty goal is to divide the developed software into universal isolated blocks that are uniform from the user's point of view.
In the first part, such a building block was described - a project with a header library. Now let's add a compiled library to our project.
To do this, we will take out the implementation of the function myfunc into a separate .cpp-file:
Then we define the library to be compiled (myfeature), which will consist of the obtained at the previous step .cpp-file. The new library obviously needs the existing headers, and in order to provide this, it can and should be linked to the existing goal. mylib. Moreover, the binding between them is public, which means that everything to which the target will be connected myfeature, will automatically receive the load and target mylib (more about tying methods).
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 108045c..0de77b8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -64,6 +64,17 @@ target_compile_features(mylib INTERFACE cxx_std_17)
add_library(Mylib::mylib ALIAS mylib)
+###################################################################################################
+##
+## ΠΠΎΠΌΠΏΠΈΠ»ΠΈΡΡΠ΅ΠΌΠ°Ρ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ°
+##
+###################################################################################################
+
+add_library(myfeature src/mylib/myfeature.cpp)
+target_link_libraries(myfeature PUBLIC mylib)
+
+add_library(Mylib::myfeature ALIAS myfeature)
+
Next, we will make sure that the new library is also installed on the system:
It should be noted that for the purpose myfeature, as for mylib an alias was created with a prefix Mylib::. The same is written for both purposes when exporting them for installation on the system. This makes it possible to work uniformly with goals for any binding scheme.
After that, it remains to tie unit tests with the new library (function myfunc moved out of the header, so now you need to link):
Titles (Mylib::mylib) now you donβt need to connect separately, because, as already mentioned, they are automatically connected together with the library (Mylib::myfeature).
And let's add a couple of nuances to ensure coverage measurements taking into account the newly arrived library:
You can add more libraries, executables, etc. It does not matter how exactly they are knitted together within the framework of the project. The only important thing is which targets are the interface of our module, that is, stick out.
Now we have standard modules-blocks, and we can rule over them: compose a structure of any complexity from them, installing them into the system or linking them together within a single assembly system.
System installation
One of the options for using the module is to install our module on the system.
After that, it is connected to any other project using the command find_package.
find_package(Mylib 1.0 REQUIRED)
Connecting as a submodule
Another option is to connect the folder with our project to another project as a submodule using the command add_subdirectory.
Using
The binding methods are different, but the result is the same. In both cases, in the project using our module, goals will be available Mylib::myfeature ΠΈ Mylib::mylib, which can be used, for example, like this:
Specifically, in our case, the library Mylib::myfeature you need to connect when you need to link with the library libmyfeature. If there are enough headers, then you should use the library Mylib::mylib.
CMake targets can be tricky, for example, intended only to forward some properties, dependencies, etc. At the same time, they work in the same way.