How to use external libraries with find_package in CMake
As a continuation on the previous blogs about CMake and especially the one about linking to an external library. I have done some experimenting with different ways and figured out that it is also possible with the find_package() command.
As a reminder the following project structure is used. This is the same as in the previous posts.
├── build dir
├── CMakeLists.txt
├── src
| ├── CMakeLists.txt
| ├── main.cpp
| ├── example.h
| ├── example.cpp
| ├── example2.h
| └── example2.cpp
├── test
| ├── CMakeLists.txt
| ├── exampleTest.cpp
| └── example2Test.cpp
├── ui
| ├── CMakeLists.txt
| ├── exampleView.h
| └── exampleView.cpp
└── lib/thirdparty
├── CMakeLists.txt
├── UI dir
| ├── exampleUi.h
| └── exampleUi.cpp
└── Test dir
├── exampleTest.h
└── exampleTest.cpp
So it is really important that the following steps are executed first. If these steps are forgotten the find_package() command will not work! Another point that should be mentioned, the projects that I build are developed on Linux. This might also work on Windows, but I haven’t tried it out yet. Be my guest to try it out, but let me know if it works!
So to get started, go to the lib or third party/googletest directory. Create a directory called build. Change directories to the build directory and execute the cmake command on the CMakeLists.txt file in googletest.
# Create a directory within the googletest dir
mkdir build
cd build
# Call cmake command on parent directory googletest
cmake ../
After CMake generates the make file that is needed to build and install the google test project. Execute the following commands:
# Use the make install command in the build directory
sudo make install
Installing is nothing more than putting an executable, binaries or include files on a certain location in the Operating System, so that it can be used by an application or a user. In case of Linux it is important to use sudo because the googletest files are installed in /usr/local/include. This is a root directory and the administrator needs to give access in order to make changes here.
Now that the googletest files have been installed, it is possible to adjust the CMakeLists.txt files. The CMakeLists.txt file in the root directory of the project will have some small adjustments.
# Root project directory CMakeLists.txt
cmake_minimum_required(VERSION 3.10.0 FATAL_ERROR)
project(example)
find_package(GTest Required)
add_subdirectory(src)
add_subdirectory(test)
add_subdirectory(ui)
add_subdirectory(lib)
Only the find_package command is added to the configuration file in the root directory. When the files are installed, this command will find and load the settings of the external project. When the files are not installed, CMake won’t be able to find the external project and will give you errors while running the cmake command.
Setting up the project with find_package() makes a slight difference for the configuration file in the test directory. Because of this it is not longer needed to use the include_directories command for the include files of the googletest project. However, there still needs to be linked to the library. This is done in the target_link_libraries() command with the GTest::GTest and GTest::Main.
# Test directory CMakeLists.txt
cmake_minimum_required(VERSION 3.10.0 FATAL_ERROR)
project(example)
# Include the directories so there is access
# to the header files.
include_directories(${PROJECT_DIR})
set(TEST_FILES
exampleTest.cpp
exampleTest2.cpp
)
add_executable(Unit_tests ${TEST_FILES})
target_link_libraries(Unit_tests
GTest::GTest
GTest::Main
SrcFiles)
There you have it! Using an external library with the find_package() command in CMake. I still want write a blog about using CTest in CMake, but this will be featured in the other post.
I hope you find this blogpost useful! Happy coding!