How to set up googleTest as a shared library on Linux
Asked Answered
H

14

103

Debian does not provide any precompiled packages for gTest anymore. They suggest you integrate the framework into your project's makefile. But I want to keep my makefile clean. How do I set up gTest like the former versions (<1.6.0), so that I can link against the library?

Housemother answered 22/11, 2012 at 13:38 Comment(7)
BTW, gtest builds are managed using autotools so the standard ./configure && make && make install workflow should work just fine. I'm not sure if this warrants a post since it would be no different from compiling many other packages from source.Outoftheway
I guess not all users are as experienced as you. I recently came from Windows to Linux and I would have been happy to find something like this on StackOverflow.Housemother
Note that Google recommend that you DO NOT build a library, but instead include the GTest code into your project. See code.google.com/p/googletest/wiki/…Nodule
Thats the first note in the answer.Housemother
If you want to build from source, you may check out this answer on StackOverflow.Doublet
The link provided by @Nodule is broken (the wiki was removed), it seems to work but points to a page that isn't on topic anymore (quite confusing). The best that I can find as replacement are these build instructions: github.com/google/googletest/blob/master/googletest/README.md However that only explains how to build with cmake. For autotools, I found the following answer to work best: https://mcmap.net/q/211786/-how-can-i-use-google-test-with-my-project-that-builds-via-autotoolsTeleost
Wow!! That is weird !!! Thanks for pointing it outNodule
H
161

Before you start make sure your have read and understood this note from Google! This tutorial makes using gtest easy, but may introduce nasty bugs.

1. Get the googletest framework

wget https://github.com/google/googletest/archive/release-1.8.0.tar.gz

Or get it by hand. I won't maintain this little How-to, so if you stumbled upon it and the links are outdated, feel free to edit it.

2. Unpack and build google test

tar xf release-1.8.0.tar.gz
cd googletest-release-1.8.0
cmake -DBUILD_SHARED_LIBS=ON .
make

3. "Install" the headers and libs on your system.

This step might differ from distro to distro, so make sure you copy the headers and libs in the correct directory. I accomplished this by checking where Debians former gtest libs were located. But I'm sure there are better ways to do this.

sudo cp -a googletest/include/gtest /usr/include
sudo cp -a googlemock/gtest/libgtest_main.so googlemock/gtest/libgtest.so /usr/lib/

# The easiest/best way:
make install  # Note: before v1.11 this can be dangerous and is not supported

4. Update the cache of the linker

... and check if the GNU Linker knows the libs

sudo ldconfig -v | grep gtest

If the output looks like this:

libgtest.so.0 -> libgtest.so.0.0.0
libgtest_main.so.0 -> libgtest_main.so.0.0.0

then everything is fine.

gTestframework is now ready to use. Just don't forget to link your project against the library by setting -lgtest as linker flag and optionally, if you did not write your own test main() routine, the explicit -lgtest_main flag.

From here on you might want to go to Google's Googletest Primer documentation, and the old docs about the framework to learn how it works. Happy coding!

Edit: This works for OS X too! See "How to properly setup googleTest on OS X"

Housemother answered 22/11, 2012 at 13:38 Comment(11)
Is there no make install target that you can use instead of manually copying the library and headers?Outoftheway
Cite of the output of the makefile: 'make install' is dangerous and not supported. Instead, see README for how to integrate Google Test into your build system.Housemother
Have the files been renamed in the 1.8.0 version? There is no include/gtest as far as I can tell.Od
Your post is out-of-date. Please do not mislead people, sudo cp -a libgtest_main.so libgtest.so /usr/lib/ does not work anymore. The file isn't even there to begin with.Romito
I'd also like to know why debian removed a pre-installed shared library (they did so as per upstreams recommendations: bugs.debian.org/cgi-bin/bugreport.cgi?bug=802587). The wiki link given there does no longer exist though. So why was this the case?Teleost
your solution didn't work for me. The correct output of ldconfig didn't show up. sudo make instal worked for me.Myrmecophagous
Just run make install from 1.11 onward, this works on >=debian10Nich
Why use cp -a instead of just cp?Pentyl
Wouldn't it be safer and better to copy to /usr/local/include and /usr/local/lib instead of to /usr/include and /usr/lib, respectively?Pentyl
The "note from Google" you have at the top, which recommends not installing into /usr/local, no longer exists in the latest FAQ from Google. In fact, sudo make install now installs into /usr/local, as stated here. I think that warning can safely be removed.Pentyl
Here is the quote: sudo make install # Install in /usr/local/ by defaultPentyl
S
45

Let me answer this specifically for ubuntu users. First start by installing the gtest development package.

sudo apt-get install libgtest-dev

Note that this package only install source files. You have to compile the code yourself to create the necessary library files. These source files should be located at /usr/src/gtest. Browse to this folder and use cmake to compile the library:

sudo apt-get install cmake # install cmake
cd /usr/src/gtest
sudo mkdir build
cd build
sudo cmake ..
sudo make
sudo make install

Now to compile your programs that uses gtest, you have to link it with:

-lgtest -lgtest_main -lpthread

This worked perfectly for me on Ubuntu 14.04LTS.

Sandy answered 31/1, 2017 at 9:43 Comment(6)
Actually you don't have to copy libraries manually, there is a target for that in Makefile. You can just do it like that: sudo apt-get install cmake # install cmake cd /usr/src/gtest sudo cmake CMakeLists.txt sudo make install That should be built and copy /usr/local/lib/Altissimo
@AlexanderZinovyev I get "make: *** No rule to make target 'install'. Stop." when I execute the "sudo make install"Few
"sudo make install" worked on Ubuntu 18.04, but didn't work on Ubuntu 16.04.Rockyrococo
@AhmedNassar: "sudo make install" does just the same thing as "sudo cp *.a /usr/lib". So, if install option is not available in generated Makefile, you just copy them manuallySandy
There is no need to manually sudo cp *.a /usr/lib, just repalce it with sudo make install should be fine.Frisk
I had to compile with -lgtest -lgtest_main -lpthread to make it work.Jessiejessika
P
29

It took me a while to figure out this because the normal "make install" has been removed and I don't use cmake. Here is my experience to share. At work, I don't have root access on Linux, so I installed the Google test framework under my home directory: ~/usr/gtest/.

To install the package in ~/usr/gtest/ as shared libraries, together with sample build as well:

$ mkdir ~/temp
$ cd ~/temp
$ unzip gtest-1.7.0.zip 
$ cd gtest-1.7.0
$ mkdir mybuild
$ cd mybuild
$ cmake -DBUILD_SHARED_LIBS=ON -Dgtest_build_samples=ON -G"Unix Makefiles" ..
$ make
$ cp -r ../include/gtest ~/usr/gtest/include/
$ cp lib*.so ~/usr/gtest/lib

To validate the installation, use the following test.c as a simple test example:

    #include <gtest/gtest.h>
    TEST(MathTest, TwoPlusTwoEqualsFour) {
        EXPECT_EQ(2 + 2, 4);
    }

    int main(int argc, char **argv) {
        ::testing::InitGoogleTest( &argc, argv );
        return RUN_ALL_TESTS();
    }

To compile:

    $ export GTEST_HOME=~/usr/gtest
    $ export LD_LIBRARY_PATH=$GTEST_HOME/lib:$LD_LIBRARY_PATH
    $ g++ -I $GTEST_HOME/include -L $GTEST_HOME/lib -lgtest -lgtest_main -lpthread test.cpp 
Portraiture answered 23/1, 2014 at 16:33 Comment(2)
With the last line I get error: /usr/bin/ld: /tmp/cczG727X.o: undefined reference to symbol '_ZN7testing4TestC2Ev'. I fixed this placing test.cpp before the libraries. i.e: g++ test.cpp -I $GTEST_HOME/include -L $GTEST_HOME/lib -lgtest -lgtest_main -lpthreadRadiolocation
If linking against gtest_main (lgtest_main), there is no need to define your own main in the test file.Grover
E
11

If you happen to be using CMake, you can use ExternalProject_Add as described here.

This avoids you having to keep gtest source code in your repository, or installing it anywhere. It is downloaded and built in your build tree automatically.

Embonpoint answered 22/11, 2012 at 13:51 Comment(0)
A
3

Update for Debian/Ubuntu

Google Mock (package: google-mock) and Google Test (package: libgtest-dev) have been merged. The new package is called googletest. Both old names are still available for backwards compatibility and now depend on the new package googletest.

So, to get your libraries from the package repository, you can do the following:

sudo apt-get install googletest -y
cd /usr/src/googletest
sudo mkdir build
cd build
sudo cmake ..
sudo make
sudo cp googlemock/*.a googlemock/gtest/*.a /usr/lib

After that, you can link against -lgmock (or against -lgmock_main if you do not use a custom main method) and -lpthread. This was sufficient for using Google Test in my cases at least.

If you want the most current version of Google Test, download it from github. After that, the steps are similar:

git clone https://github.com/google/googletest
cd googletest
sudo mkdir build
cd build
sudo cmake ..
sudo make
sudo cp lib/*.a /usr/lib

As you can see, the path where the libraries are created has changed. Keep in mind that the new path might be valid for the package repositories soon, too.

Instead of copying the libraries manually, you could use sudo make install. It "currently" works, but be aware that it did not always work in the past. Also, you don't have control over the target location when using this command and you might not want to pollute /usr/lib.

Alberik answered 30/3, 2020 at 9:41 Comment(0)
D
1

I was similarly underwhelmed by this situation and ended up making my own Ubuntu source packages for this. These source packages allow you to easily produce a binary package. They are based on the latest gtest & gmock source as of this post.

Google Test DEB Source Package

Google Mock DEB Source Package

To build the binary package do this:

tar -xzvf gtest-1.7.0.tar.gz
cd gtest-1.7.0
dpkg-source -x gtest_1.7.0-1.dsc
cd gtest-1.7.0
dpkg-buildpackage

It may tell you that you need some pre-requisite packages in which case you just need to apt-get install them. Apart from that, the built .deb binary packages should then be sitting in the parent directory.

For GMock, the process is the same.

As a side note, while not specific to my source packages, when linking gtest to your unit test, ensure that gtest is included first (https://bbs.archlinux.org/viewtopic.php?id=156639) This seems like a common gotcha.

Disappear answered 26/3, 2015 at 13:32 Comment(5)
Your package gives me errors when I try to compile. Any reason why?? here is my log test.cpp:(.text+0x57): undefined reference to testing::Message::Message()' test.cpp:(.text+0x84): undefined reference to testing::internal::AssertHelper::AssertHelper(testing::TestPartResult::Type, char const*, int, char const*)' test.cpp:(.text+0x97): undefined reference to `testing::internal::AssertHelper::operator=(testing::Message const&) const' ... its so long that I can't post the entire thing. I did this in a brand new Ubuntu 14.04 VM so nothing else was installed except the necessary dependencies.Demilitarize
@Demilitarize Yeah i ran into this little google test gem too. Apparently the order of the shared libraries is important. When linking gtest to your unit test, try including gtest before other libraries. When i hit this problem, this link solved it for me: bbs.archlinux.org/viewtopic.php?id=156639Disappear
@ddelnano, also if your test suite does not have a 'main' defined then don't forget to link against 'gtest_main'.Disappear
I didn't include any other libraries. this is all i had in my file #include <gtest/gtest.h> TEST(MathTest, TwoPlusTwoEqualsFour) { EXPECT_EQ(2 + 2, 4); } int main(int argc, char **argv) { ::testing::InitGoogleTest( &argc, argv ); return RUN_ALL_TESTS(); }Demilitarize
nevermind I didn't read the blog post until after I posted that comment. It is now finally working!Demilitarize
H
1

Just in case somebody else gets in the same situation like me yesterday (2016-06-22) and also does not succeed with the already posted approaches - on Lubuntu 14.04 it worked for me using the following chain of commands:

git clone https://github.com/google/googletest
cd googletest
cmake -DBUILD_SHARED_LIBS=ON .
make
cd googlemock
sudo cp ./libgmock_main.so ./gtest/libgtest.so gtest/libgtest_main.so ./libgmock.so /usr/lib/
sudo ldconfig
Hopple answered 23/6, 2016 at 14:30 Comment(0)
M
1

This answer from askubuntu is what worked for me. Seems simpler than other options an less error-prone, since it uses package libgtest-dev to get the sources and builds from there: https://askubuntu.com/questions/145887/why-no-library-files-installed-for-google-test?answertab=votes#tab-top

Please refer to that answer, but just as a shortcut I provide the steps here as well:

sudo apt-get install -y libgtest-dev
sudo apt-get install -y cmake
cd /usr/src/gtest
sudo cmake .
sudo make
sudo mv libg* /usr/lib/

After that, I could build my project which depends on gtest with no issues.

Mada answered 24/12, 2016 at 7:9 Comment(0)
C
1

This will build and install both gtest and gmock 1.7.0:

mkdir /tmp/googleTestMock
tar -xvf googletest-release-1.7.0.tar.gz -C /tmp/googleTestMock
tar -xvf googlemock-release-1.7.0.tar.gz -C /tmp/googleTestMock
cd /tmp/googleTestMock
mv googletest-release-1.7.0 gtest
cd googlemock-release-1.7.0
cmake -DBUILD_SHARED_LIBS=ON .
make -j$(nproc)
sudo cp -a include/gmock /usr/include
sudo cp -a libgmock.so libgmock_main.so /usr/lib/
sudo cp -a ../gtest/include/gtest /usr/include
sudo cp -a gtest/libgtest.so gtest/libgtest_main.so /usr/lib/
sudo ldconfig
Castrate answered 4/1, 2017 at 10:50 Comment(0)
B
1

The following method avoids manually messing with the /usr/lib directory while also requiring minimal change in your CMakeLists.txt file. It also lets your package manager cleanly uninstall libgtest-dev.

The idea is that when you get the libgtest-dev package via

sudo apt install libgtest-dev

The source is stored in location /usr/src/googletest

You can simply point your CMakeLists.txt to that directory so that it can find the necessary dependencies

Simply replace FindGTest with add_subdirectory(/usr/src/googletest gtest)

At the end, it should look like this

add_subdirectory(/usr/src/googletest gtest)
target_link_libraries(your_executable gtest)
Bookrack answered 28/6, 2019 at 6:37 Comment(0)
W
1

With buster and bullseye one can install the following three packages without compiling anything:

sudo apt-get install libgtest-dev libgmock-dev googletest

This includes gmock.

Westernism answered 1/1, 2023 at 18:54 Comment(0)
P
1

Looking at the excellent answers from @ManuelSchneid3r here and @amritkrs here, I have finally been able to put together (over more than 1 year of effort now) a more up-to-date set of instructions, as well as additional insight and information not provided by any other answer here, and which I have been trying to figure out for 5 years.

This includes a lot about gcc/g++ libraries, installing libraries, naming .a statically-linked library files, where g++ searches for includes, etc.

How to install Google Test (gtest) and Google Mock (gmock) as shared, static .a libraries, system-wide, on Linux/Unix

Tested on Ubuntu 20.04 with the latest (unreleased, git pulled) version of googletest (more recent than v1.13.0).

If in a hurry, just run the several commands in the install section, then look at the "Example usage" shortly after.

Note: googletest has undergone a variety of changes over the last few years. For example, gtest and gmock are now packaged under the same repo, here: https://github.com/google/googletest. So, following my instructions will install both for you.

1. Install the latest gtest and gmock from source

If you want the latest released version, find it here: https://github.com/google/googletest/releases.

You can download it with wget like this, for instance:

# Download release v1.13.0
wget https://github.com/google/googletest/archive/refs/tags/v1.13.0.tar.gz

I prefer to just get the most-up-to-date content from the repo itself, however. Here are my full instructions, doing that:

sudo apt update
sudo apt install cmake

# You can find some of these instructions, here: 
# https://github.com/google/googletest/tree/main/googletest
time git clone https://github.com/google/googletest.git
cd googletest        # "Main directory of the cloned repository."
mkdir build          # "Create a directory to hold the build output."
cd build
time cmake ..        # "Generate native make build scripts for GoogleTest."
                        # Takes ~2 seconds.
time make            # Run those makefiles just autogenerated by cmake above.
                        # Takes ~10 seconds.
sudo make install    # Install the .a library files, and headers, into 
                        # /user/local/.

Done!

You can now include the necessary headers into your files as shown above.

Note: here is the full output of what was copied over, or "installed", into /usr/local when you ran sudo make install:

googletest/build$ sudo make install
[ 25%] Built target gtest
[ 50%] Built target gmock
[ 75%] Built target gmock_main
[100%] Built target gtest_main
Install the project...
-- Install configuration: ""
-- Up-to-date: /usr/local/include
-- Installing: /usr/local/include/gmock
-- Installing: /usr/local/include/gmock/gmock.h
-- Installing: /usr/local/include/gmock/gmock-actions.h
-- Installing: /usr/local/include/gmock/gmock-more-matchers.h
-- Installing: /usr/local/include/gmock/gmock-spec-builders.h
-- Installing: /usr/local/include/gmock/gmock-function-mocker.h
-- Installing: /usr/local/include/gmock/internal
-- Installing: /usr/local/include/gmock/internal/gmock-pp.h
-- Installing: /usr/local/include/gmock/internal/gmock-internal-utils.h
-- Installing: /usr/local/include/gmock/internal/gmock-port.h
-- Installing: /usr/local/include/gmock/internal/custom
-- Installing: /usr/local/include/gmock/internal/custom/gmock-port.h
-- Installing: /usr/local/include/gmock/internal/custom/gmock-matchers.h
-- Installing: /usr/local/include/gmock/internal/custom/gmock-generated-actions.h
-- Installing: /usr/local/include/gmock/internal/custom/README.md
-- Installing: /usr/local/include/gmock/gmock-cardinalities.h
-- Installing: /usr/local/include/gmock/gmock-more-actions.h
-- Installing: /usr/local/include/gmock/gmock-matchers.h
-- Installing: /usr/local/include/gmock/gmock-nice-strict.h
-- Installing: /usr/local/lib/libgmock.a
-- Installing: /usr/local/lib/libgmock_main.a
-- Installing: /usr/local/lib/pkgconfig/gmock.pc
-- Installing: /usr/local/lib/pkgconfig/gmock_main.pc
-- Installing: /usr/local/lib/cmake/GTest/GTestTargets.cmake
-- Installing: /usr/local/lib/cmake/GTest/GTestTargets-noconfig.cmake
-- Installing: /usr/local/lib/cmake/GTest/GTestConfigVersion.cmake
-- Installing: /usr/local/lib/cmake/GTest/GTestConfig.cmake
-- Up-to-date: /usr/local/include
-- Installing: /usr/local/include/gtest
-- Installing: /usr/local/include/gtest/gtest-param-test.h
-- Installing: /usr/local/include/gtest/gtest-printers.h
-- Installing: /usr/local/include/gtest/gtest-test-part.h
-- Installing: /usr/local/include/gtest/internal
-- Installing: /usr/local/include/gtest/internal/gtest-port.h
-- Installing: /usr/local/include/gtest/internal/gtest-death-test-internal.h
-- Installing: /usr/local/include/gtest/internal/gtest-filepath.h
-- Installing: /usr/local/include/gtest/internal/custom
-- Installing: /usr/local/include/gtest/internal/custom/gtest-printers.h
-- Installing: /usr/local/include/gtest/internal/custom/gtest-port.h
-- Installing: /usr/local/include/gtest/internal/custom/gtest.h
-- Installing: /usr/local/include/gtest/internal/custom/README.md
-- Installing: /usr/local/include/gtest/internal/gtest-string.h
-- Installing: /usr/local/include/gtest/internal/gtest-type-util.h
-- Installing: /usr/local/include/gtest/internal/gtest-param-util.h
-- Installing: /usr/local/include/gtest/internal/gtest-port-arch.h
-- Installing: /usr/local/include/gtest/internal/gtest-internal.h
-- Installing: /usr/local/include/gtest/gtest_pred_impl.h
-- Installing: /usr/local/include/gtest/gtest-assertion-result.h
-- Installing: /usr/local/include/gtest/gtest-typed-test.h
-- Installing: /usr/local/include/gtest/gtest-spi.h
-- Installing: /usr/local/include/gtest/gtest_prod.h
-- Installing: /usr/local/include/gtest/gtest.h
-- Installing: /usr/local/include/gtest/gtest-message.h
-- Installing: /usr/local/include/gtest/gtest-death-test.h
-- Installing: /usr/local/include/gtest/gtest-matchers.h
-- Installing: /usr/local/lib/libgtest.a
-- Installing: /usr/local/lib/libgtest_main.a
-- Installing: /usr/local/lib/pkgconfig/gtest.pc
-- Installing: /usr/local/lib/pkgconfig/gtest_main.pc

2. Background: the above installation instructions have just:

  1. Installed gtest and gmock *.a static library files into /usr/local/lib so that you can build and run your gtest and gmock programs using these simple g++ build flags (used by the linker, ld):

    1. -lgtest Link against the /usr/local/lib/libgtest.a static library file, which provides general googletest functionality.
    2. -lgtest_main Link against the /usr/local/lib/libgtest_main.a static library file, which provides a default main() function needed by googletest.
    3. -lgmock Link against the /usr/local/lib/libgmock.a static library file, which provides general googlemock functionality.
    4. -lgmock_main Link against the /usr/local/lib/libgmock_main.a static library file, which provides a default main() function needed by googlemock.
    5. -pthread Required by googletest, since it uses POSIX threads under the hood.

    Notes:

    1. Order matters. Ensure your flags above come after the files which need them.
    2. If you were to set the necessary CMake define to build shared dynamically-linked .so libraries instead of the static .a libraries we are building, then the -l flags above would cause the run-time linker to link against those instead, at run-time. See @amritkrs's answer for more info. on that. Following my instructions, however, will cause those same -l flags to link at build-time instead, placing the entire pre-built .a static library file binaries into your executables.
  2. Installed all gtest and gmock header files that you need to include in your programs into /usr/local/include/gtest and /usr/local/include/gmock, respectively.

    This allows you to includes the necessary files in your programs, like this:

    // Include in your unit tests
    #include <gtest/gtest.h>
    #include <gmock/gmock.h>
    
    // Include in your production code to give gtest access to private members
    // in your classes, as friends, via the 
    // `FRIEND_TEST(TestSuiteName, TestName);` macro, for instance.
    #include <gtest/gtest_prod.h>
    

3. Example usage:

# Build and run an example googletest unit test that comes in the repo:
# - required in this case: `-pthread`, `-lgtest`, and `-lgtest_main`

mkdir -p bin

time g++ -Wall -Wextra -Werror -O3 -std=c++17 -pthread \
    googletest/googletest/samples/sample1_unittest.cc \
    googletest/googletest/samples/sample1.cc \
    -lgtest -lgtest_main -o bin/a && time bin/a

4. Run an example unit test

Manually test-build and run a sample test included in the repo:

# (run while still in the googletest/build dir)
time g++ -Wall -Wextra -Werror -O3 -std=c++17 -pthread \
    ../googletest/samples/sample1_unittest.cc \
    ../googletest/samples/sample1.cc \
    -lgtest -lgtest_main -o bin/a && time bin/a

Sample run and output:

googletest/build$ time g++ -Wall -Wextra -Werror -O3 -std=c++17 -pthread \
>     ../googletest/samples/sample1_unittest.cc \
>     ../googletest/samples/sample1.cc \
>     -lgtest -lgtest_main -o bin/a && time bin/a

real    0m1.879s
user    0m1.740s
sys 0m0.135s
Running main() from /home/gabriel/GS/dev/temp/googletest/googletest/src/gtest_main.cc
[==========] Running 6 tests from 2 test suites.
[----------] Global test environment set-up.
[----------] 3 tests from FactorialTest
[ RUN      ] FactorialTest.Negative
[       OK ] FactorialTest.Negative (0 ms)
[ RUN      ] FactorialTest.Zero
[       OK ] FactorialTest.Zero (0 ms)
[ RUN      ] FactorialTest.Positive
[       OK ] FactorialTest.Positive (0 ms)
[----------] 3 tests from FactorialTest (0 ms total)

[----------] 3 tests from IsPrimeTest
[ RUN      ] IsPrimeTest.Negative
[       OK ] IsPrimeTest.Negative (0 ms)
[ RUN      ] IsPrimeTest.Trivial
[       OK ] IsPrimeTest.Trivial (0 ms)
[ RUN      ] IsPrimeTest.Positive
[       OK ] IsPrimeTest.Positive (0 ms)
[----------] 3 tests from IsPrimeTest (0 ms total)

[----------] Global test environment tear-down
[==========] 6 tests from 2 test suites ran. (0 ms total)
[  PASSED  ] 6 tests.

real    0m0.003s
user    0m0.000s
sys 0m0.002s

5. Uninstall

To remove/uninstall gtest and gmock, just manually remove all of the files that were copied over by sudo make install. Hare are the commands to do that:

# remove the main libraries
sudo rm /usr/local/lib/libgtest.a \
        /usr/local/lib/libgtest_main.a \
        /usr/local/lib/libgmock.a \
        /usr/local/lib/libgmock_main.a

# remove the include dirs
sudo rm -r /usr/local/include/gtest \
           /usr/local/include/gmock

# extras

# remove the package config (whatever that is)
sudo rm /usr/local/lib/pkgconfig/gtest.pc \
        /usr/local/lib/pkgconfig/gtest_main.pc \
        /usr/local/lib/pkgconfig/gmock.pc \
        /usr/local/lib/pkgconfig/gmock_main.pc

# remove cmake GTest stuff
sudo rm -r /usr/local/lib/cmake/GTest

Going further: general information about libraries; debugging; gcc/g++ compiler flags; etc.

  1. When compiling, g++ searches your include directories for all header files your code includes. The default C++ system-wide include paths can be found by running $(gcc -print-prog-name=cc1plus) -v and then pressing Ctrl + C after a second to kill it (see here: Where does gcc look for C and C++ header files?). They include primarily:

    /usr/include        # system-added includes
    /usr/local/include  # user-added includes
    
    # as well as some more include paths to pull in compiler includes
    

    Include directories also include any that you have passed to g++ via -I flags, such as -I"path/to/some/personal/include_dir1" -I"path/to/include_dir2", etc.

    Storing gtest's includes in /usr/local/include directly means that you never have to pass custom -I flags to specify where they will be. The compiler just always has them available now!

  2. Similar to the above "include" concept, library files, such as statically-linked .a files (or dynamically-linked .so files) can be linked to your executable by passing them as inputs to g++.

    Example: this command, from my answer here, manually specifies the gtest and gmock include directories, as well as the pre-built .a files, and builds the googletest/googletest/samples/sample1_unittest.cc example program:

    # Note: the specified .a files here must actually be locally stored in
    # a local "bin" path, as specified in this command
    time ( \
        time g++ -Wall -Wextra -Werror -O3 -std=c++17 -pthread \
        -I"googletest/googletest/include" -I"googletest/googlemock/include" \
        googletest/googletest/samples/sample1_unittest.cc \
        googletest/googletest/samples/sample1.cc \
        bin/libgtest.a bin/libgtest_main.a \
        -o bin/a \
        && time bin/a \
    )
    

    Or, by copying the includes to /usr/local/include and the .a static library files to /usr/local/lib, you can simplify that command greatly and run this instead! The include directories no longer need to be specified at all, and instead of passing path/to/libgtest.a and path/to/libgtest_main.a, you simply pass -lgtest and -lgtest_main, respectively, instead:

    time g++ -Wall -Wextra -Werror -O3 -std=c++17 -pthread \
        googletest/googletest/samples/sample1_unittest.cc \
        googletest/googletest/samples/sample1.cc \
        -lgtest -lgtest_main -o bin/a && time bin/a
    
  3. Instead of running sudo make install to install the gtest and gmock headers and libraries into /usr/local/include and /usr/local/lib, respectively, you can manually install the header files and libraries by copying them like this if you want:

    # manually install the .a libraries, and header files
    
    # give access to g++ flags `-lgtest`, `-lgtest_main`, `-lgmock`, and
    # `-lgmock_main`, by copying over the .a static library files
    sudo cp -i -t /usr/local/lib \
        lib/libgtest.a lib/libgtest_main.a lib/libgmock.a lib/libgmock_main.a
    # give access to include header files `<gtest/gmock.h>` `<gtest/gtest.h>`, 
    # `<gtest/gtest_prod.h>`, etc.
    # 1. gtest header file includes
    sudo cp -a path/to/googletest/googletest/include/gtest /usr/local/include
    # 2. gmock header file includes
    sudo cp -a path/to/googletest/googlemock/include/gmock /usr/local/include 
    

    I first learned that concept in @ManuelSchneid3r's answer here. I tested it myself.

  4. Without header files installed or a -I path specified to them, you'll see failures to include your desired headers, such as fatal error: gtest/gtest.h: No such file or directory here:

    eRCaGuy_hello_world/cpp$ time g++ -Wall -Wextra -Werror -O3 -std=c++17 -pthread  googletest/googletest/samples/sample1_unittest.cc     googletest/googletest/samples/sample1.cc     -lgtest -lgtest_main     -o bin/a      && time bin/a
    googletest/googletest/samples/sample1_unittest.cc:46:10: fatal error: gtest/gtest.h: No such file or directory
       46 | #include "gtest/gtest.h"
          |          ^~~~~~~~~~~~~~~
    compilation terminated.
    
    real    0m0.046s
    user    0m0.039s
    sys 0m0.007s
    
  5. Without libraries (.a or .so files) installed, and if you try to use -lgtest for example instead of passing path/to/libgtest.a directly, you'll see failures to link via the ld linker, such as cannot find -lgtest here:

    eRCaGuy_hello_world/cpp$ time g++ -Wall -Wextra -Werror -O3 -std=c++17 -pthread  googletest/googletest/samples/sample1_unittest.cc     googletest/googletest/samples/sample1.cc     -lgtest -lgtest_main     -o bin/a      && time bin/a
    /usr/bin/ld: cannot find -lgtest
    /usr/bin/ld: cannot find -lgtest_main
    collect2: error: ld returned 1 exit status
    
    real    0m1.895s
    user    0m1.776s
    sys 0m0.119s
    
  6. If you copy your library files to a known g++ system-wide library path, such as /usr/local/lib (recommended for user-installed .a and .so libraries) or /usr/lib (for system-installed .a and .so libraries), the .a files must be named libwhatever.a, for instance, in order to be used as -lwhatever.

    You cannot call them lwhatever.a, or libwhatever. They must be named libwhatever.a.

    So, having file /usr/local/lib/libgtest.a enables the -lgtest library linker flag, but /usr/local/lib/lgtest.a does not.

    If your name is wrong and then try to use the -lgtest flag, you'll see the /usr/bin/ld: cannot find -lgtest linker error as previously shown above, since this library is not properly named and "installed".

    Again, this means if you call it /usr/local/lib/libwhatever.a, then you must use -lwhatever as the linker flag to that library.

    Note that per ld --help, the -l (lowercase "L") flags are apparently passed to the ld linker, and presumably the l stands for library. See my question here: Meaning of -l (lowercase "L") flags in gcc/g++. From ld --help:

    -l LIBNAME, --library LIBNAME  
                                Search for library LIBNAME
    
  7. Looking at library files inside /usr/local/lib and /usr/lib, the linker naming convention for libraries, whether static .a or dynamic .so files, seems to require that the library file name must be prefixed with lib!

  8. Gtest uses POSIX threads (pthreads) under the hood, so you must always pass the -pthread flag to g++ too.

  9. A google search for g++ "-lpthread" vs "-pthread" reveals this answer: Difference between -pthread and -lpthread while compiling, which says that the difference between -lpthread and -pthread is historical, so on today's gcc/g++ and clang compilers, you should always just use -pthread to bring in POSIX threads.

    The -lpthread library is now an empty binary apparently and doesn't do anything except satisfy ancient requirements where that library must still be included in some places. But, -pthread handles that all for you, so just use -pthread alone and be done!

That about covers it. I now know more about g++, libraries, and gtest.

References:

  1. Answer by @ManuelSchneid3r
  2. Answer by @amritkrs
  3. https://github.com/google/googletest
    1. https://github.com/google/googletest/tree/main/googletest
  4. My Q&A: How do I build and use googletest (gtest) and googlemock (gmock) with gcc/g++ or clang?
  5. MY Q: Meaning of -l (lowercase "L") flags in gcc/g++
Pentyl answered 13/3, 2023 at 6:58 Comment(0)
W
0

This will install google test and mock library in Ubuntu/Debian based system:

sudo apt-get install google-mock

Tested in google cloud in debian based image.

Wagoner answered 11/11, 2016 at 22:42 Comment(1)
Hmm, no, I think this only installs googlemock, but it does not install googletest (gtest). At least that's what happened to me.Mada
B
-1

For 1.8.1 based on @ManuelSchneid3r 's answer I had to do:

wget github.com/google/googletar xf release-1.8.1.tar.gz 
tar xf release-1.8.1.tar.gz
cd googletest-release-1.8.1/
cmake -DBUILD_SHARED_LIBS=ON .
make

I then did make install which seemed to work for 1.8.1, but following @ManuelSchneid3r it would mean:

sudo cp -a googletest/include/gtest /usr/include
sudo cp -a googlemock/include/gmock /usr/include
sudo cp `find .|grep .so$` /usr/lib/
Boarhound answered 22/2, 2019 at 14:44 Comment(1)
Its been a while that I wrote this answer, let me know what is the problem with it if you think it has no value / is invalid.Boarhound

© 2022 - 2024 — McMap. All rights reserved.