My build system is optimizing out my google test functions - c++

I'm trying to make an application that runs some unit tests using GoogleTest but the tests in the test files outside of the main file are not discovered by GoogleTest.
I have 2 test files:
main_test.cpp:
#include <gtest/gtest.h>
TEST(MainTest, Test1) {
EXPECT_EQ(1,1);
}
int main(int argc, char* argv[]) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
external_test.cpp:
#include <gtest/gtest.h>
TEST(ExternalTest, Test1) {
EXPECT_EQ(1,1);
}
ExternalTest is never discovered and run when I try and build with my build system.
These are the commands that my build system uses to build this app and it seemingly optimizes out the functions in external_test.cpp:
clang++ -c googletest/googletest/src/gtest-all.cc -o build/gtest -Igoogletest/googletest/include/ -Igoogletest/googletest/ -std=c++17
clang++ -c external_test.cpp -o build/external_test -Igoogletest/googletest/include/ -Igoogletest/googletest/ -std=c++17
clang++ -c main_test.cpp -o build/main_test -Igoogletest/googletest/include/ -Igoogletest/googletest/ -std=c++17
cd build
libtool -o test_app.lib main_test gtest external_test
clang++ test_app.lib
Result:
./a.out
[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from MainTest
[ RUN ] MainTest.Test1
[ OK ] MainTest.Test1 (0 ms)
[----------] 1 test from MainTest (0 ms total)
[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (0 ms total)
[ PASSED ] 1 test.
If I build like so:
clang++ -c googletest/googletest/src/gtest-all.cc -o build/gtest -Igoogletest/googletest/include/ -Igoogletest/googletest/ -std=c++17
clang++ -c external_test.cpp -o build/external_test -Igoogletest/googletest/include/ -Igoogletest/googletest/ -std=c++17
clang++ -c main_test.cpp -o build/main_test -Igoogletest/googletest/include/ -Igoogletest/googletest/ -std=c++17
cd build
clang++ external_test gtest main_test
I get the expected result:
./a.out
[==========] Running 2 tests from 2 test suites.
[----------] Global test environment set-up.
[----------] 1 test from ExternalTest
[ RUN ] ExternalTest.Test1
[ OK ] ExternalTest.Test1 (0 ms)
[----------] 1 test from ExternalTest (0 ms total)
[----------] 1 test from MainTest
[ RUN ] MainTest.Test1
[ OK ] MainTest.Test1 (0 ms)
[----------] 1 test from MainTest (0 ms total)
[----------] Global test environment tear-down
[==========] 2 tests from 2 test suites ran. (0 ms total)
[ PASSED ] 2 tests.
But our build system needs to generate the lib file and then link. Also, if I create some function foo in external_test.cpp, and then declare that function as extern in main_test.cpp and call it in the main function - then all tests are discovered correctly.
My theory is that libtool and clang++ somehow preform some link time optimization and remove the tests. I've tried adding the -fno-lto flag to no avail.
Does anyone have any ideas? Any help would be greatly appreciated.

Try this command
clang++ -Wl,--whole-archive test_app.lib -Wl,--no-whole-archive
It will prevent discarding global initializers, that register test suites.
Try this on macOS
clang++ -Wl,-all_load test_app.lib

Related

I can't compile google test which telling linker input unused (macOS)

I have downloaded the google test with below command.
wget https://github.com/google/googletest/archive/release-1.8.0.zip
and I run the following command to install the libraries to my macOS 10.13.5
unzip release-1.8.0.zip
cd googletest-release-1.8.0
mkdir build
cd build
cmake ..
make
sudo make install
and i try to compile the test as below code with command g++ -c -std=c++11 -stdlib=libc++ -lgtest -lgtest_main -pthread -o cpptest test.cpp.
#include <iostream>
#include <gtest/gtest.h>
TEST(firstTest, abs)
{
EXPECT_EQ(1, abs( -1 ));
EXPECT_EQ(1, abs( 1 ));
}
int main(int argc, char **argv) {
std::cout << "Running main() from testmain.cc\n";
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
but i get below warnings
clang: warning: -lgtest: 'linker' input unused [-Wunused-command-lin-argument]
clang: warning: -lgtest_main: 'linker' input unused [-Wunused-command-line-argument]
Does anyone can fix this problems?
g++ -c is used to compile a source file to an object file. This stage does not link an executable, i.e. it does not use linker, thus linker flags -lgtest -lgtest_main are not used. If you want to compile an executable the proper compand will be without -c:
g++ -std=c++11 -lgtest -lgtest_main -pthread -o cpptest test.cpp
Note, I have removed not required use of -stdlib.

Generate multiple builds in one makefile

I want to have my unit test built along with my project every time I run make. I tried to do this with the following code in my Makefile:
DEPS = Parallel.cpp Resistor.cpp Series.cpp Source.cpp
TEST = Parallel.cpp Resistor.cpp Series.cpp Test.cpp
resistor: $(DEPS)
g++ -std=c++11 -o resistor $(DEPS) -I. -g
test: $(TEST)
g++ -std=c++11 -o test $(TEST) -I. -g
Yet when I look at the directory I only see ./resistor and not ./test.... BTW any advice for improving my makefile in other ways is welcome.
You could add the following rule as the first rule in your Makefile:
all: resistor test
Then run make:
$ make
g++ -std=c++11 -o resistor Parallel.cpp Resistor.cpp Series.cpp Source.cpp -I. -g
g++ -std=c++11 -o test Parallel.cpp Resistor.cpp Series.cpp Test.cpp -I. -g
Per the make documentation:
By default, make starts with the first target (not targets whose
names start with ‘.’).

jenkins does not recognize the errors when building the cpp code

I am using jenkins for my CI server but i have problems when i want to build the project because jenkins does not recognize the compilation errors.This is my problem:
creating objects directory obj
g++ -I../src -I third-party/cppunit-1.12.1/include -fPIC -g -Wall -c booktest.cpp -o obj/booktest.o
g++ -I../src -I third-party/cppunit-1.12.1/include -fPIC -g -Wall -c reader/bookreadertest.cpp -o obj/reader/bookreadertest.o
g++ -I../src -I third-party/cppunit-1.12.1/include -fPIC -g -Wall -c indexer/indexertest.cpp -o obj/indexer/indexertest.o
indexer/indexertest.cpp: In constructor ‘IndexerTest::IndexerTest()’:
indexer/indexertest.cpp:17:12: error: ‘failMethod’ was not declared in this scope
make: *** [obj/indexer/indexertest.o] Error 1
creating objects directory obj
g++ -I ../src -fPIC -g -Wall -c src/main.cpp -o obj/src/main.o
g++ -o oreallybooks -fPIC -g -Wall obj/src/main.o -L/user/local/lib -L../src/lib -loreally -lm
Finished: SUCCESS
I am using bash files to build and clean the cpp project
I "execute shell" for "build steps" in jenkins and this is the command:
/var/lib/jenkins/jobs/OreallyBooks/workspace/buildProject
"buildProject" is bash file and contains:
!/bin/bash
cd src;
make;
cd ../test;
make;
cd ../ui
make;
Someone can help me please? thanks all
If anything other than the final make fails then the bash script will ignore the error.
You need to set the script to fail on first error
#!/bin/bash -e
Stop on first error

Using exit() in c++

For one reason or another, I am messing around with the exit() function in c++. I am getting all kinds of strange errors from my mac running lion (64 bit). I am compiling using g++ -o -g -Wall.
Exhibit A:
#include <iostream>
int main(int arc, char *argv[]){
exit(1);
}
The Terminal output looks like this
$ g++ -o -g -Wall test main.cpp
ld: in test, can't link with a main executable for architecture x86_64
collect2: ld returned 1 exit status
but $ g++ -o test main.cpp compiles fine.
using #include<stdio.h> or #include<stdlib.h> result in the same compilation error.
I am just wondering if anyone might be able to see immediately what is going on here?
test is the name of the binary to produce, your first argument list should be:
> g++ -g -Wall -o test main.cpp
^^^^^^^ -o has test for an argument
-o is meant to be followed immediately by the name of the output file. It is probably trying to use your old binary 'test' as a source file, incorrectly.
Try this:
g++ -o test -g -Wall main.cpp

Embed python code in C++ (Windows + minGW + Python 2.7.2 + Eclipse)

I'm trying to embed python code in C++ (Windows 7 + minGW + Python 2.7.2 + Eclipse Indigo with CDT and PyDev).
So, this is the simple code:
#include <Python.h> //Python.h
#include <iostream> //iostream
using namespace std;
int main(int argc, char *argv[])
{
Py_Initialize();
PyRun_SimpleString("from time import time,ctime\n"
"print('Today is', ctime(time()))\n");
Py_Finalize();
return 0;
}
And I couldn't understant what am I doing wrong.
I include dirrctories C:\Python27\include and C:\Python27\libs but I can't build my project.
1) When I trying to build my project I got this error:
**** Internal Builder is used for build **** g++
-IC:\Python27\include -IC:\Python27\libs -O0 -g3 -Wall -c
-fmessage-length=0 -o main.o ..\main.cpp g++ -o testpy2.exe main.o
main.o: In function `main':
C:\Users\const\workspace\testpy2\Debug/../main.cpp:7: undefined
reference to `_imp__Py_Initialize'
C:\Users\const\workspace\testpy2\Debug/../main.cpp:9: undefined
reference to `_imp__PyRun_SimpleStringFlags'
C:\Users\const\workspace\testpy2\Debug/../main.cpp:10: undefined
reference to `_imp__Py_Finalize'
collect2: ld returned 1 exit status
Build error occurred, build is stopped Time consumed: 1507 ms.
2) And if I change current toolchain in Eclipse from "minGW" to "CrossGCC" .. I got this error:
**** Build of configuration Release for project testpy ****
make all Building file: ../main.cpp Invoking: Cross G++ Compiler g++
-I"C:\Python27\include" -I"C:\Python27\libs" -O3 -Wall -c
-fmessage-length=0 -MMD -MP -MF"main.d" -MT"main.d" -o "main.o"
"../main.cpp" Finished building: ../main.cpp Building target:
testpy.exe Invoking: Cross G++ Linker g++ -o "testpy.exe" ./main.o
-l"C:/Python27/libs/libpython27.a" -l"C:/Python27/libs/python27.lib"
c:/mingw/bin/../lib/gcc/mingw32/4.5.2/../../../../mingw32/bin/ld.exe:
cannot find -lC:/Python27/libs/libpython27.a
c:/mingw/bin/../lib/gcc/mingw32/4.5.2/../../../../mingw32/bin/ld.exe:
cannot find -lC:/Python27/libs/python27.lib collect2: ld returned 1
exit status make: *** [testpy.exe] Error 1
**** Build Finished ****
Could anybody tell me what's wrong with my code or settings or something else?
Thank you
That is a linker error, not a compiler error. You need to link to the python. As you can see, with the "CrossGCC" toolchain you are almost there:
-lC:/Python27/libs/libpython27.a
You need to change this to
-LC:/Python27/libs -lpython