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