GoogleTest: CLang error compiling ASSERT_FALSE(false) - c++

I downloaded googletest and built it in a subdirectory named build.
Then, I wrote the following code in a file named main.cpp:
#include <gtest/gtest.h>
TEST(FOO, BAR) { ASSERT_FALSE(false); }
Quite simple indeed.
It relies on the fact that a main function is already provided with googletest if you link the libgtestmain.a library.
GCC (v5.3.1) compiles it using the following command:
g++ -L./googletest/build/googlemock/gtest -L./googletest/build/googlemock -I./googletest/googletest/include/ -lgmock -lgtest -lgtest_main -lgmock_main -pthread -std=c++11 main.cpp
Anyway, clang (v3.6.2) does not compile using the same command:
clang++ -L./googletest/build/googlemock/gtest -L./googletest/build/googlemock -I./googletest/googletest/include/ -lgmock -lgtest -lgtest_main -lgmock_main -pthread -std=c++11 main.cpp
The error is the following one:
/tmp/main-4127ae.o: In function 'FOO_BAR_Test::TestBody()':
main.cpp:(.text+0x7b): undefined reference to `testing::internal::GetBoolAssertionFailureMessage(testing::AssertionResult const&, char const*, char const*, char const*)'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
The code contains almost the sole ASSERT_FALSE(false) statement (that's a minimal, complete example and still it doesn't compile), so I'd say that the problem is not in the code itself.
The same problem arises also from the following statement:
TEST(FOO, BAR) { ASSERT_TRUE(true); }
Is that an issue due to googletest, to clang or whatever?
I'm trying to figure it out, but I'm a little bit in trouble while looking at the code of googletest.
NOTE
I've not been able to find neither an open nor a closed issue for googletest, so I'm to open also a ticket for it on github.
In a while I'll probably post the link to the issue.

As of GCC 5.1, g++ is not ABI-compatible with clang++. Some
bug reports: clang++ no longer ABI-compatible with g++
and Add support for gcc's attribute abi_tag (needed for compatibility with gcc 5's libstdc++).
Till this is fixed you need to link googletest-ing projects
with googletest libraries built with the same compiler.

Related

How to link libcxx application to a C++ library compiled with gcc

I am trying to link an application that is compiled with clang/libc++ to the v8-devel system library on Fedora. However the latter is compiled with gcc/libstdc++ which leads to a linking error for std::unique_ptr, I think due to inlining.
Is there anything I can change in eiher my application code, or the compiler/linker flags (other than -stdlib) , such that my program can be linked to v8-devel while being still compiled with clang+libcxx?
Below a minimal toy example to reproduce the problem on Fedora (in reality, the only compiler that I have available is a custom clang version with libcxx, so switching to libstdc++ is not an option):
#include <libplatform/libplatform.h>
#include <v8.h>
using namespace v8;
int main(){
std::unique_ptr<Platform> platform = platform::NewDefaultPlatform();
V8::InitializePlatform(platform.get());
}
Then on Fedora we do:
# Install dependencies
yum install -y clang libcxx-devel v8-devel
# Try to compile test program
clang++ test.cpp -std=gnu++17 -stdlib=libc++ -lv8 -lv8_libplatform
Which gives the following linker error:
/usr/bin/ld: /tmp/test-9925a1.o: in function `main':
test.cpp:(.text+0x24): undefined reference to `v8::platform::NewDefaultPlatform(int, v8::platform::IdleTaskSupport, v8::platform::InProcessStackDumping, std::__1::unique_ptr<v8::TracingController, std::__1::default_delete<v8::TracingController> >)'
clang-14: error: linker command failed with exit code 1 (use -v to see invocation)
You can automatically run the steps above using this Dockerfile.

Set openmp in MKL Library

I am trying to compile a minimal C++ code
#include <iostream>
#include <mkl.h>
#include <omp.h>
int main(int argc, char *argv[])
{
omp_set_num_threads(4);
return 0;
}
using the MKL library (icc version 17.0.4) in a MacOSX Sierra 10.12.5, using the command
icc main.cpp -o main.o -DMKL_ILP64 -I/opt/intel/compilers_and_libraries_2017.4.181/mac/mkl/include \
-L/opt/intel/compilers_and_libraries_2017.4.181/mac/mkl/lib -Wl,-rpath,/opt/intel/compilers_and_libraries_2017.4.181/mac/mkl/lib -lmkl_intel_ilp64 \
-lmkl_intel_thread -lmkl_core -liomp5 -lpthread -lm -ldl
However I receive the following error when I run the program
dyld: Library not loaded: #rpath/libiomp5.dylib
Referenced from: /Users/user/C++/MKL1/./main.o
Reason: image not found
/bin/sh: line 1: 8898 Abort trap: 6 ./main.o
make: *** [run] Error 134
How to set up properly the openmpi with the MKL library? I tried to follow the instruction in https://software.intel.com/en-us/articles/dyld-library-not-loadedlibiomp5dylib?page=1#comment-1905809
by adding
source /opt/intel/compilers_and_libraries_2017.4.181/mac/mkl/bin/mklvars.sh intel64
However I still get the same error during runtime.
I have tried a few ways to solve this issue. It literally took an entire day. But here are the results,
Project Files
I created a very simple Project with just one file, named,
test.c
1. The Easiest Solution
Fixing this can be as simple as,
icc -qopenmp -qopenmp-link=static test.c
This method just tells the compiler to link to static OpenMP run-time libraries.
Interestingly, the docs at Intel C++ Compiler Docs v.15 say that this is deprecated while Intel C++ Compiler Docs v.17 do not even mention about this argument, BUT it works. Probably they forgot to take it out.
2. Another method (which I do not recommend, nor do folks at Intel)
To compile the file you can use the normal "-qopenmp" flag
icc -qopenmp test.c
This creates the "a.out" file.
This method of fixing the error makes use of command-line utility called,
install_name_tool
Using this method we can change the path of #rpath/libiomp5.dylib
install_name_tool -change #rpath/libiomp5.dylib /opt/intel/compilers_and_libraries_2018.1.126/mac/compiler/lib/libiomp5.dylib a.out
Note: In place of compilers_and_libraries_2018.1.126 it should be your version of the compiler.
3. One of the BEST (correct) ways
You can just add
export DYLD_LIBRARY_PATH="/opt/intel/compilers_and_libraries_2018.1.126/mac/compiler/lib"
To your ~/.bash_profile
And then use the normal way of compiling,
icc -qopenmp test.c
Everything works perfectly.
Quick tip: You can use the otool command line utility to check the libraries your file links to.
otool -L a.out
I found the answer on https://software.intel.com/en-us/forums/intel-fortran-compiler-for-linux-and-mac-os-x/topic/645194
Basically one has to add
-Wl,-rpath,/opt/intel/compilers_and_libraries_2017.4.181/mac/compiler/lib
during compilation. Now openmp with icc works perfectly

Embedding SpiderMonkey JS

I'm working on a C++ application. I would like to embed SpiderMonkey in the application.
I'm working with CMake, but I couldn't get that build. So, in an attempt to reduce complications, I tried the example code on this page. This wouldn't link using cmake or gcc from the command line.
So, even simpler, just to ensure I can link properly I am trying to get the following to work.
From the command line with gcc:
g++ --std=c++11
-I/home/thetasinner/moz/js/src/build_DBG.OBJ/dist/include
-L/home/thetasinner/moz/js/src/build_DBG.OBJ/js/src -DDEBUG
-Wl,--verbose -lmozjs-54a1 -lm -lz -ldl test.cpp -o test
On the following minimal code example:
#include <iostream>
#include <stdexcept>
#include "jsapi.h"
#include "js/Initialization.h"
int main(int argc, char** args) {
if (!JS_Init()) {
throw std::runtime_error("failed to initialise.");
}
std::cout << "It's alive!\n";
JS_ShutDown();
return 0;
}
Even this doesn't link. I get the errors
/tmp/ccqjx5RY.o: In function `main':
custom.cpp:(.text+0xf2): undefined reference to `JS_ShutDown()'
/tmp/ccqjx5RY.o: In function `JS_Init()':
custom.cpp:(.text._Z7JS_Initv[_Z7JS_Initv]+0xa): undefined reference to
'JS::detail::InitWithFailureDiagnostic(bool)'
collect2: error: ld returned 1 exit status
The headers are found and the linker is finding the mozjs library
attempt to open /home/thetasinner/moz/js/src/custom_build_DBG.OBJ/js/src
/libmozjs-54a1.so succeeded
-lmozjs-54a1 (/home/thetasinner/moz/js/src/custom_build_DBG.OBJ/js/src
/libmozjs-54a1.so)
I am working on Linux (Ubuntu 16.04 and Debian 8.7 tried) because that's where the build tools are. I don't even want to touch Window's yet.
The 'js' executable built in the spidermonkey build works fine, which I assume has the lib I'm trying to link inside it. So I would have thought the lib itself is built okay.
Can anybody help me resolve these linker errors? There are lots of answers to questions about much older versions of SpiderMonkey, but there's nothing for more recent versions. I'm interested in version 45 (which I've tried with very similar errors) or the tip version 52.
I'm comfortable enough digging around in the code working out how to do what I want with it once it builds, hence the interest in the latest version which isn't properly documented, I'm just completely stumped with the building step.
I suspect it's just an ordering problem on the command line:
g++ --std=c++11
-I/home/thetasinner/moz/js/src/build_DBG.OBJ/dist/include
-L/home/thetasinner/moz/js/src/build_DBG.OBJ/js/src -DDEBUG
test.cpp -o test
-Wl,--verbose -lmozjs-54a1 -lm -lz -ldl
Compilation first, followed by linking, with libraries in order of dependency. (My first guess was you'd neglected to mention mozjs on the command line. It took a second look to see it was just in the wrong place.)

Undefined reference to boost::random::random_device constructor and destructor on MinGW-w64 gcc

My OS is Windows 7 64-bit and C++ compiler I'm using is:
g++ (i686-posix-dwarf-rev0, Built by MinGW-W64 project) 5.3.0
And I installed Boost version 1.60 using:
bootstrap.bat mingw
b2 install target=gcc
Then I tested is it working, using examples from Boost.Random tutorial.
With the first two everything was fine, but the third one gave linker errors about boost::random::random_device. I minimized the code to have only this:
// Compiled with:
// g++ -IC:/Boost/include/boost-1_60
// -LC:/Boost/lib -lboost_random-mgw53-mt-1_60
// main.cpp
#include "boost/random/random_device.hpp"
int main() {
boost::random::random_device rng;
}
And I get the following errors:
C:\Users\Daniel\AppData\Local\Temp\cc5DfdjZ.o:main.cpp:(.text+0x15):
undefined reference to `boost::random::random_device::random_device()'
C:\Users\Daniel\AppData\Local\Temp\cc5DfdjZ.o:main.cpp:(.text+0x20):
undefined reference to `boost::random::random_device::~random_device()'
collect2.exe: error: ld returned 1 exit status
Here, on SO, I found that someone with similar problem added -lboost_system to flags, but for me it didn't helped.
Does anyone have any idea, why it isn't working? I checked, and I have random_device.hpp header in my Boost folder, with declarations of random_device() and ~random_device() in it.
I found what was wrong - the g++ command syntax, that I wanted to use to compile and link my code.
As I wrote in my question, I do this that way:
g++ -IC:/Boost/include/boost-1_60 -LC:/Boost/lib -lboost_random-mgw53-mt-1_60 main.cpp
While the correct one is with main.cpp (or any other source code file(s), that we want to include in compiling process) before the -L and -l flags.
For example:
g++ -IC:/Boost/include/boost-1_60 main.cpp -LC:/Boost/lib -lboost_random-mgw53-mt-1_60
or even
g++ main.cpp -IC:/Boost/include/boost-1_60 -LC:/Boost/lib -lboost_random-mgw53-mt-1_60
Hope it will help anyone, who will make such silly mistake too.

How to compile boost unit test module with clang++?

I'm trying to compile a boost unit test module with cmake and clang but ran into a linker error. I was able to produce the following minimal test case:
$ cat boost_test_test.cc
#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE scanio
#include <boost/test/unit_test.hpp>
BOOST_AUTO_TEST_CASE(foo) { BOOST_CHECK(1); }
This compiles fine with g++:
$ g++ boost_test_test.cc -lboost_unit_test_framework
$ echo $?
0
But it does not with clang++:
$ /usr/bin/clang++-3.7 boost_test_test.cc -lboost_unit_test_framework
/tmp/boost_test_test-7e4892.o: In function `boost::unit_test::make_test_case(boost::unit_test::callback0<boost::unit_test::ut_detail::unused> const&, boost::unit_test::basic_cstring<char const>)':
boost_test_test.cc:(.text._ZN5boost9unit_test14make_test_caseERKNS0_9callback0INS0_9ut_detail6unusedEEENS0_13basic_cstringIKcEE[_ZN5boost9unit_test14make_test_caseERKNS0_9callback0INS0_9ut_detail6unusedEEENS0_13basic_cstringIKcEE]+0x58): undefined reference to `boost::unit_test::ut_detail::normalize_test_case_name(boost::unit_test::basic_cstring<char const>)'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
So during the linker stage I get an undefined reference error and this problem persists no matter the order of arguments to clang++.
Since it works fine with g++ I suppose there is something clang++ specific going on here?
This is with g++ 5.2.1, clang++ 3.7 and boost 1.58 on Debian Sid.
In Ubuntu Willy, Boost 1.58 Unit Test library is compiled with GCC 5.0. The library file libboost_unit_test_framework.a contains the mangled function _ZN5boost9unit_test9ut_detail24normalize_test_case_nameB5cxx11ENS0_13basic_cstringIKcEE that resolves to boost::unit_test::ut_detail::normalize_test_case_name[abi:cxx11](boost::unit_test::basic_cstring<char const>)
However, CLang does not seem to use the new ABI, so it searches for _ZN5boost9unit_test9ut_detail24normalize_test_case_nameENS0_13basic_cstringIKcEE, which is boost::unit_test::ut_detail::normalize_test_case_name(boost::unit_test::basic_cstring<char const>).
In order to overcome this, define your own function in the test file:
namespace boost { namespace unit_test { namespace ut_detail {
std::string normalize_test_case_name(const_string name) {
return ( name[0] == '&' ? std::string(name.begin()+1, name.size()-1) : std::string(name.begin(), name.size() ));
}
}}}
This should resolve the issue. If compiled with the same version of the compiler as Boost, it should be no problem, as the linker will simply ignore the library version of the function.