How cmake supports third-party libraries

1. Introduction

In the process of program development, libraries (dynamic libraries and static libraries) are often introduced. Sometimes only one of them, sometimes a mix of both. In this case, a question arises, how to support the library in the project (this does not involve the version management of the library, that is, it does not deal with problems such as DLL HELL). There are many ways to do this, and different platforms and different development tools have different processing methods. For example, there are differences between VS and Idea, and different languages ​​may handle it differently, all of which need to be handled by developers themselves according to the actual situation.
Here we only mention some methods of using Cmake on Linux for third-party library management.

Two, four forms

The ways to use the third library in Linux, if you use Cmake to build and manage, mainly include the following:
1. Direct compilation and compilation
This is the most commonly used method, and developers have used it. The old way of using it is generally:

mkdir build
cd build 
cmake ..
make -j5
make install

However, higher versions of CMake support the following simpler methods:

cmake -B build -DCMAKE_PREFIX_PATH=/home/fpc/Qt65/6.5.0/gcc_64   (通过 -S 可以 指定编译路径 -G指定构造方式 如Ninja)
cmake --build build -j5(--parallel 5)

The big brother on station B called this modern CMake, which makes sense.
This method is more suitable for beginners or places where project management is simple. The advantage is that it is easy to understand and easy to operate; the disadvantage is that you need to manually control and manage the compilation and linking of the library in the CMake file of the project. Similar to the following:

find_package (库名称 1.6.0 REQUIRED)

add_executable (myapp main.cpp)
target_link_libraries (myapp 库名称)

If there are development environments with different versions or different machines, some unexpected problems may arise when teams cooperate. The characteristics of this kind of problem are random and not easy to find, so if this method is adopted in a slightly larger project, there must be strict library version management and dependency management instructions. But everyone understands that relying on people is often unreliable.

2. CMake cooperates with git submodules submodule control

This method is suitable for effective management at the source code level between teams, and is not suitable for third parties who only provide libraries. Moreover, the third-party library is in parallel with other projects, that is, the third library does not belong to a certain project, so be sure to pay attention. Use the appropriate path:

增加子模块:
cd examples
git submodule add http://xxx.xxx/libname.git
下载子模块:
git clone --recursive   git@xxxxxx/parent_libname.git
或者没有使用 --recursive 下载完成后,进入子目录执行:
git submodule update --init

Then add to the total CMakeLists.txt file of the project:

add_subdirectory(${CMAKE_SOURCE_DIR}/examples/libname)

Add in the project CMakeLists.txt of the application third-party library:

add_dependencies(SUPRA_Lib libname)
TARGET_INCLUDE_DIRECTORIES(SUPRA_Lib
        PUBLIC ${SUPRA_Lib_INCLUDEDIRS} libname_include
)

target_link_libraries(SUPRA_Lib ${SUPRA_Lib_LIBRARIES} libname_path)

In this way, the library can be tightly bound without external influence. Source level management for easy control. The disadvantage is also obvious. It is troublesome to upgrade with a lot of external libraries. At the same time, every project used has to add the above dependent projects.

3. Add directly to the project subdirectory
The difference from the above is that this third-party library really has to become a subdirectory of a certain project, that is to say add_subdirectory is under the CMakeLists.txt of a certain project, such as Google's glog provides This way:

add_subdirectory(${CMAKE_SOURCE_DIR}/examples/libname)
target_link_libraries(firt libname)

It's so simple and unrestrained, you can use it directly, you don't need to deal with any header files and add_dependencies, find_package and the like. The disadvantage is that it may not be as clear as the division into modules, and large projects may be a bit inconvenient to maintain.

4. The method of using an external project For
the detailed method of using this method, please refer to the CMake documentation. Here is an example:

include(ExternalProject)

SET(NodeEditor_DIR "${CMAKE_CURRENT_BINARY_DIR}/NodeEditor")
SET(NodeEditor_GIT_REPOSITORY "https://github.com/goeblr/nodeeditor.git" CACHE STRING "")
SET(NodeEditor_GIT_TAG "3bcba3740d68932f3ffaa4b3dc73e624fe51e2db" CACHE STRING "")
ExternalProject_Add( 
	NodeEditor
	PREFIX "${NodeEditor_DIR}"
	
	LOG_DOWNLOAD TRUE
	LOG_UPDATE TRUE
	LOG_CONFIGURE TRUE
	LOG_BUILD TRUE
	LOG_INSTALL TRUE
	
	SOURCE_DIR "${NodeEditor_DIR}"
	BINARY_DIR "${NodeEditor_DIR}_build"
	STAMP_DIR "${NodeEditor_DIR}_stamp"
	TMP_DIR "${NodeEditor_DIR}_tmp"
	#--Download step--------------
	GIT_REPOSITORY ${NodeEditor_GIT_REPOSITORY}
	GIT_TAG ${NodeEditor_GIT_TAG}
	#--Configure step-------------
	CMAKE_ARGS
	  -DCMAKE_RUNTIME_OUTPUT_DIRECTORY:PATH=${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
	  -DCMAKE_LIBRARY_OUTPUT_DIRECTORY:PATH=${CMAKE_LIBRARY_OUTPUT_DIRECTORY}
	  -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY:PATH=${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}
	  -DCMAKE_BUILD_TYPE=Release
	  -DBUILD_EXAMPLES=OFF
	  -DQt5_DIR=${Qt5_DIR}
	  -DCMAKE_INSTALL_PREFIX=${NodeEditor_DIR}_install
	  -DNODE_EDITOR_STATIC=
	#--Build step-----------------
	#BUILD_ALWAYS 0
	#--Install step-----------------
	INSTALL_DIR=${NodeEditor_DIR}_install
)
SET(NodeEditor_LIBRARIES "nodes")
INCLUDE_DIRECTORIES(SUPRA_GUI "${NodeEditor_DIR}_install/include")
LINK_DIRECTORIES(SUPRA_GUI "${NodeEditor_DIR}_install/lib")

Then still in the current project:

TARGET_LINK_LIBRARIES(SUPRA_GUI
	${NodeEditor_LIBRARIES})
add_dependencies(SUPRA_GUI SUPRA_Lib NodeEditor)

This method is not simple, but it is flexible in application. It can be said that any code that can be used can be operated in this way. The shortcomings are also obvious, it is complicated, and it has to deal with a lot of things that have nothing to do with compilation.

3. Summary

At present, CMake should be the mainstream mode in C++ engineering applications. The advantage of using it is that it is much simpler than writing MakeFile, and it is more suitable for developers to understand, and it is relatively simple. The disadvantage is that this thing has too many macro definitions, and various errors are not easy to understand. If you encounter some weird problems, veterans may have to cry. Flaws do not conceal advantages, study hard and use more, and take the initiative to avoid some pitfalls, you will find that CMake is still a very good tool.

Guess you like

Origin blog.csdn.net/fpcc/article/details/131582753