If you're on Windows, you can run Bash and gcc
and g++
build commands inside an MSYS2 terminal. See my full setup and installation instructions here: Installing & setting up MSYS2 from scratch, including adding all 7 profiles to Windows Terminal. git
commands, however, should still be run inside the Git Bash terminal in Windows which comes with Git for Windows.
For Linux, just use your regular Bash-based terminal for everything.
For my brand-new answer 1 year later, see here: The "easy" way: install gtest's headers and .a static library files system-wide into /usr/local/include
and /usr/local/lib
, respectively
The "hard" way: manually build everything from scratch, using g++
directly without a build system
I finally figured it out! The key reference is this one, which has some excellent build command examples I studied to figure it all out: https://ethz-adrl.github.io/ct/ct_core/doc/html/md__home_adrl_code_src_control-toolbox_ct_core_build_test_googletest-src_googletest_README.html
Here are the steps:
Tested on Linux Ubuntu.
I first documented this entire process, and more, in my eRCaGuy_hello_world repo in my main C++ readme file here: cpp/README.md.
1. Build all of gtest and gmock as static library archive *.a
files
# Clone the repo
git clone https://github.com/google/googletest.git
# Build all of gtest and gmock as static library archive `*.a` files
time g++ -Wall -Wextra -Werror -O3 -std=c++17 -pthread -c \
-I"googletest/googletest/include" -I"googletest/googletest" \
-I"googletest/googlemock/include" -I"googletest/googlemock" \
googletest/googletest/src/gtest-all.cc \
googletest/googletest/src/gtest_main.cc \
googletest/googlemock/src/gmock-all.cc \
googletest/googlemock/src/gmock_main.cc
# move all of the object files just created to a "bin" dir
mkdir -p bin
mv -t bin gtest-all.o gtest_main.o gmock-all.o gmock_main.o
# Use the `ar` "archive" utility to create the *.a static library archive files
# from the 4 object files above
time ar -rv bin/libgtest.a bin/gtest-all.o
time ar -rv bin/libgtest_main.a bin/gtest_main.o
time ar -rv bin/libgmock.a bin/gmock-all.o
time ar -rv bin/libgmock_main.a bin/gmock_main.o
You now have:
bin/libgtest.a
bin/libgtest_main.a
bin/libgmock.a
bin/libgmock_main.a
2. Build and run some of the samples which come with googletest
See these sample tests here: https://github.com/google/googletest/tree/main/googletest/samples.
- For
googletest/googletest/samples/sample1_unittest.cc
:
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 \
)
- For
googletest/googletest/samples/sample2_unittest.cc
:
time ( \
time g++ -Wall -Wextra -Werror -O3 -std=c++17 -pthread \
-I"googletest/googletest/include" -I"googletest/googlemock/include" \
googletest/googletest/samples/sample2_unittest.cc \
googletest/googletest/samples/sample2.cc \
bin/libgtest.a bin/libgtest_main.a \
-o bin/a \
&& time bin/a \
)
etc.
Sample build and run command and output of building sample1_unittest.cc
above:
eRCaGuy_hello_world/cpp$ 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 \
> )
real 0m1.787s
user 0m1.375s
sys 0m0.165s
Running main() from 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
real 0m1.790s
user 0m1.375s
sys 0m0.166s
Notes
- Q: Why is the include dir
-I"googletest/googletest"
required when building the googletest library?
- A: Because
googletest/googletest/src/gtest-all.cc
includes all other source files as src/name_of_file.cc
, here: https://github.com/google/googletest/blob/main/googletest/src/gtest-all.cc#L41-L49. That means that the parent dir which contains the src
dir must be an "include folder". That parent dir is googletest/googletest
, so we mark it as an include dir with -I"googletest/googletest"
.
- You can test C code with gtest too, using the
extern "C" { }
trick when including C headers in C++ to prevent name-mangling. You then link to the C-built object *.o
files, while including the non-name-mangled headers in the C++ googletest unit tests.
Happy building! Now I/we can finally use gtest easily in our own personal projects!
Other references
- my own answer where I figured out the
time
cmd wrapper things to time sub-components of a larger multi-line command, as well as the entire multi-line command: How to run time on multiple commands AND write the time output to file?
See also
- My Q&A: Meaning of
-l
(lowercase "L") flags in gcc/g++
- And the answer by @KamilCuk
- My answer: How to install Google Test (
gtest
) and Google Mock (gmock
) as shared, static .a
libraries, system-wide, on Linux/Unix:
This includes a lot about gcc/g++ libraries, installing libraries, naming .a statically-linked library files, where g++ searches for includes, etc.
c
tag too because technically you can test C code with gtest too, using theextern "C" { }
trick when including C headers in C++ to prevent name-mangling. You then link to the C-built object*.o
files, while including the non-name-mangled headers in the C++ googletest unit tests. But, removing thec
tag is probably not a big deal either. – Jezreel