xref: /freebsd/contrib/googletest/docs/pkgconfig.md (revision 28f6c2f292806bf31230a959bc4b19d7081669a7)
1*28f6c2f2SEnji Cooper## Using GoogleTest from various build systems
2*28f6c2f2SEnji Cooper
3*28f6c2f2SEnji CooperGoogleTest comes with pkg-config files that can be used to determine all
4*28f6c2f2SEnji Coopernecessary flags for compiling and linking to GoogleTest (and GoogleMock).
5*28f6c2f2SEnji CooperPkg-config is a standardised plain-text format containing
6*28f6c2f2SEnji Cooper
7*28f6c2f2SEnji Cooper*   the includedir (-I) path
8*28f6c2f2SEnji Cooper*   necessary macro (-D) definitions
9*28f6c2f2SEnji Cooper*   further required flags (-pthread)
10*28f6c2f2SEnji Cooper*   the library (-L) path
11*28f6c2f2SEnji Cooper*   the library (-l) to link to
12*28f6c2f2SEnji Cooper
13*28f6c2f2SEnji CooperAll current build systems support pkg-config in one way or another. For all
14*28f6c2f2SEnji Cooperexamples here we assume you want to compile the sample
15*28f6c2f2SEnji Cooper`samples/sample3_unittest.cc`.
16*28f6c2f2SEnji Cooper
17*28f6c2f2SEnji Cooper### CMake
18*28f6c2f2SEnji Cooper
19*28f6c2f2SEnji CooperUsing `pkg-config` in CMake is fairly easy:
20*28f6c2f2SEnji Cooper
21*28f6c2f2SEnji Cooper```cmake
22*28f6c2f2SEnji Cooperfind_package(PkgConfig)
23*28f6c2f2SEnji Cooperpkg_search_module(GTEST REQUIRED gtest_main)
24*28f6c2f2SEnji Cooper
25*28f6c2f2SEnji Cooperadd_executable(testapp)
26*28f6c2f2SEnji Coopertarget_sources(testapp PRIVATE samples/sample3_unittest.cc)
27*28f6c2f2SEnji Coopertarget_link_libraries(testapp PRIVATE ${GTEST_LDFLAGS})
28*28f6c2f2SEnji Coopertarget_compile_options(testapp PRIVATE ${GTEST_CFLAGS})
29*28f6c2f2SEnji Cooper
30*28f6c2f2SEnji Cooperenable_testing()
31*28f6c2f2SEnji Cooperadd_test(first_and_only_test testapp)
32*28f6c2f2SEnji Cooper```
33*28f6c2f2SEnji Cooper
34*28f6c2f2SEnji CooperIt is generally recommended that you use `target_compile_options` + `_CFLAGS`
35*28f6c2f2SEnji Cooperover `target_include_directories` + `_INCLUDE_DIRS` as the former includes not
36*28f6c2f2SEnji Cooperjust -I flags (GoogleTest might require a macro indicating to internal headers
37*28f6c2f2SEnji Cooperthat all libraries have been compiled with threading enabled. In addition,
38*28f6c2f2SEnji CooperGoogleTest might also require `-pthread` in the compiling step, and as such
39*28f6c2f2SEnji Coopersplitting the pkg-config `Cflags` variable into include dirs and macros for
40*28f6c2f2SEnji Cooper`target_compile_definitions()` might still miss this). The same recommendation
41*28f6c2f2SEnji Coopergoes for using `_LDFLAGS` over the more commonplace `_LIBRARIES`, which happens
42*28f6c2f2SEnji Cooperto discard `-L` flags and `-pthread`.
43*28f6c2f2SEnji Cooper
44*28f6c2f2SEnji Cooper### Help! pkg-config can't find GoogleTest!
45*28f6c2f2SEnji Cooper
46*28f6c2f2SEnji CooperLet's say you have a `CMakeLists.txt` along the lines of the one in this
47*28f6c2f2SEnji Coopertutorial and you try to run `cmake`. It is very possible that you get a failure
48*28f6c2f2SEnji Cooperalong the lines of:
49*28f6c2f2SEnji Cooper
50*28f6c2f2SEnji Cooper```
51*28f6c2f2SEnji Cooper-- Checking for one of the modules 'gtest_main'
52*28f6c2f2SEnji CooperCMake Error at /usr/share/cmake/Modules/FindPkgConfig.cmake:640 (message):
53*28f6c2f2SEnji Cooper  None of the required 'gtest_main' found
54*28f6c2f2SEnji Cooper```
55*28f6c2f2SEnji Cooper
56*28f6c2f2SEnji CooperThese failures are common if you installed GoogleTest yourself and have not
57*28f6c2f2SEnji Coopersourced it from a distro or other package manager. If so, you need to tell
58*28f6c2f2SEnji Cooperpkg-config where it can find the `.pc` files containing the information. Say you
59*28f6c2f2SEnji Cooperinstalled GoogleTest to `/usr/local`, then it might be that the `.pc` files are
60*28f6c2f2SEnji Cooperinstalled under `/usr/local/lib64/pkgconfig`. If you set
61*28f6c2f2SEnji Cooper
62*28f6c2f2SEnji Cooper```
63*28f6c2f2SEnji Cooperexport PKG_CONFIG_PATH=/usr/local/lib64/pkgconfig
64*28f6c2f2SEnji Cooper```
65*28f6c2f2SEnji Cooper
66*28f6c2f2SEnji Cooperpkg-config will also try to look in `PKG_CONFIG_PATH` to find `gtest_main.pc`.
67*28f6c2f2SEnji Cooper
68*28f6c2f2SEnji Cooper### Using pkg-config in a cross-compilation setting
69*28f6c2f2SEnji Cooper
70*28f6c2f2SEnji CooperPkg-config can be used in a cross-compilation setting too. To do this, let's
71*28f6c2f2SEnji Cooperassume the final prefix of the cross-compiled installation will be `/usr`, and
72*28f6c2f2SEnji Cooperyour sysroot is `/home/MYUSER/sysroot`. Configure and install GTest using
73*28f6c2f2SEnji Cooper
74*28f6c2f2SEnji Cooper```
75*28f6c2f2SEnji Coopermkdir build && cmake -DCMAKE_INSTALL_PREFIX=/usr ..
76*28f6c2f2SEnji Cooper```
77*28f6c2f2SEnji Cooper
78*28f6c2f2SEnji CooperInstall into the sysroot using `DESTDIR`:
79*28f6c2f2SEnji Cooper
80*28f6c2f2SEnji Cooper```
81*28f6c2f2SEnji Coopermake -j install DESTDIR=/home/MYUSER/sysroot
82*28f6c2f2SEnji Cooper```
83*28f6c2f2SEnji Cooper
84*28f6c2f2SEnji CooperBefore we continue, it is recommended to **always** define the following two
85*28f6c2f2SEnji Coopervariables for pkg-config in a cross-compilation setting:
86*28f6c2f2SEnji Cooper
87*28f6c2f2SEnji Cooper```
88*28f6c2f2SEnji Cooperexport PKG_CONFIG_ALLOW_SYSTEM_CFLAGS=yes
89*28f6c2f2SEnji Cooperexport PKG_CONFIG_ALLOW_SYSTEM_LIBS=yes
90*28f6c2f2SEnji Cooper```
91*28f6c2f2SEnji Cooper
92*28f6c2f2SEnji Cooperotherwise `pkg-config` will filter `-I` and `-L` flags against standard prefixes
93*28f6c2f2SEnji Coopersuch as `/usr` (see https://bugs.freedesktop.org/show_bug.cgi?id=28264#c3 for
94*28f6c2f2SEnji Cooperreasons why this stripping needs to occur usually).
95*28f6c2f2SEnji Cooper
96*28f6c2f2SEnji CooperIf you look at the generated pkg-config file, it will look something like
97*28f6c2f2SEnji Cooper
98*28f6c2f2SEnji Cooper```
99*28f6c2f2SEnji Cooperlibdir=/usr/lib64
100*28f6c2f2SEnji Cooperincludedir=/usr/include
101*28f6c2f2SEnji Cooper
102*28f6c2f2SEnji CooperName: gtest
103*28f6c2f2SEnji CooperDescription: GoogleTest (without main() function)
104*28f6c2f2SEnji CooperVersion: 1.11.0
105*28f6c2f2SEnji CooperURL: https://github.com/google/googletest
106*28f6c2f2SEnji CooperLibs: -L${libdir} -lgtest -lpthread
107*28f6c2f2SEnji CooperCflags: -I${includedir} -DGTEST_HAS_PTHREAD=1 -lpthread
108*28f6c2f2SEnji Cooper```
109*28f6c2f2SEnji Cooper
110*28f6c2f2SEnji CooperNotice that the sysroot is not included in `libdir` and `includedir`! If you try
111*28f6c2f2SEnji Cooperto run `pkg-config` with the correct
112*28f6c2f2SEnji Cooper`PKG_CONFIG_LIBDIR=/home/MYUSER/sysroot/usr/lib64/pkgconfig` against this `.pc`
113*28f6c2f2SEnji Cooperfile, you will get
114*28f6c2f2SEnji Cooper
115*28f6c2f2SEnji Cooper```
116*28f6c2f2SEnji Cooper$ pkg-config --cflags gtest
117*28f6c2f2SEnji Cooper-DGTEST_HAS_PTHREAD=1 -lpthread -I/usr/include
118*28f6c2f2SEnji Cooper$ pkg-config --libs gtest
119*28f6c2f2SEnji Cooper-L/usr/lib64 -lgtest -lpthread
120*28f6c2f2SEnji Cooper```
121*28f6c2f2SEnji Cooper
122*28f6c2f2SEnji Cooperwhich is obviously wrong and points to the `CBUILD` and not `CHOST` root. In
123*28f6c2f2SEnji Cooperorder to use this in a cross-compilation setting, we need to tell pkg-config to
124*28f6c2f2SEnji Cooperinject the actual sysroot into `-I` and `-L` variables. Let us now tell
125*28f6c2f2SEnji Cooperpkg-config about the actual sysroot
126*28f6c2f2SEnji Cooper
127*28f6c2f2SEnji Cooper```
128*28f6c2f2SEnji Cooperexport PKG_CONFIG_DIR=
129*28f6c2f2SEnji Cooperexport PKG_CONFIG_SYSROOT_DIR=/home/MYUSER/sysroot
130*28f6c2f2SEnji Cooperexport PKG_CONFIG_LIBDIR=${PKG_CONFIG_SYSROOT_DIR}/usr/lib64/pkgconfig
131*28f6c2f2SEnji Cooper```
132*28f6c2f2SEnji Cooper
133*28f6c2f2SEnji Cooperand running `pkg-config` again we get
134*28f6c2f2SEnji Cooper
135*28f6c2f2SEnji Cooper```
136*28f6c2f2SEnji Cooper$ pkg-config --cflags gtest
137*28f6c2f2SEnji Cooper-DGTEST_HAS_PTHREAD=1 -lpthread -I/home/MYUSER/sysroot/usr/include
138*28f6c2f2SEnji Cooper$ pkg-config --libs gtest
139*28f6c2f2SEnji Cooper-L/home/MYUSER/sysroot/usr/lib64 -lgtest -lpthread
140*28f6c2f2SEnji Cooper```
141*28f6c2f2SEnji Cooper
142*28f6c2f2SEnji Cooperwhich contains the correct sysroot now. For a more comprehensive guide to also
143*28f6c2f2SEnji Cooperincluding `${CHOST}` in build system calls, see the excellent tutorial by Diego
144*28f6c2f2SEnji CooperElio Pettenò: <https://autotools.io/pkgconfig/cross-compiling.html>
145