Undefined reference when linking with googletest - makefile

When i try to build googletest (and googlemock) 1.8.0 i get an undefined reference to MakeAndRegisterTestInfo when i try to link with libgtest.a. It works fine with version 1.7.0 with the same cmake/make setup. I guess i could use 1.7.0 but then i need to download and build gmock separately.
CMakeFiles/unittest.dir/test/test_led.cpp.o: In function `__static_initialization_and_destruction_0(int, int)':
test_led.cpp:(.text+0x23d): undefined reference to `testing::internal::MakeAndRegisterTestInfo(char const*, char const*, char const*, char const*, void const*, void (*)(), void (*)(), testing::internal::TestFactoryBase*)'
collect2: error: ld returned 1 exit status
make[2]: *** [bin/unittest] Error 1
make[1]: *** [CMakeFiles/unittest.dir/all] Error 2
make[1]: *** Waiting for unfinished jobs....
Other symbols in the libgtest.a works perfectly fine (example ::testing::InitGoogleTest) but as soon as i try to add a test with the macro TEST_F i get this error.
This is my testcase setup:
#include "gtest/gtest.h"
namespace {
// The fixture for testing (used by TEST_F).
class Foo : public ::testing::Test {
protected:
Foo();
virtual ~Foo() {};
virtual void SetUp();
virtual void TearDown();
};
Foo::Foo() {
};
void Foo::SetUp()
{
};
void Foo::TearDown()
{
};
TEST_F(Foo, Init) {
};
} // namespace
int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv);
int ret = RUN_ALL_TESTS();
return ret;
}
Cmake google test snippet:
It downloads from a local folder. It builds and i get a libgtest.a file.
### Unit test ###
# Google test
ExternalProject_Add(EXT_googletest
PREFIX ${CMAKE_CURRENT_BINARY_DIR}
DOWNLOAD_COMMAND ""
SOURCE_DIR ${CMAKE_SOURCE_DIR}/../external/googletest
BUILD_COMMAND make all
# Disable install step
INSTALL_COMMAND "")
# Create a libgtest target to be used as a dependency by test programs
set(LIBGTEST_STATIC ${CMAKE_CURRENT_BINARY_DIR}/.../googlemock/gtest/libgtest.a)
add_executable(unittest
"test/test_foo.cpp")
target_link_libraries(unittest main_app_lib
${LIBGTEST_STATIC}
${CMAKE_THREAD_LIBS_INIT})
NM output libgtest.a 1.8.0
user#system$ nm .../libgtest.a |grep MakeAndRegisterTestInfo
000000000000743a T _ZN7testing8internal23MakeAndRegisterTestInfoEPKcS2_S2_S2_NS0_12CodeLocationEPKvPFvvES7_PNS0_15TestFactoryBaseE
NM output libgtest.a 1.7.0 (working file)
user#system$ nm .../libgtest.a |grep MakeAndRegisterTestInfo
0000000000005968 T _ZN7testing8internal23MakeAndRegisterTestInfoEPKcS2_S2_S2_PKvPFvvES6_PNS0_15TestFactoryBaseE
Solved:
There was an old version of google test installed on build machine which headers were used by cmake.

#user1178014 answered his own question but since there are no posted answers I am writing it up:
If you downloaded the gtest source directly and used the make install from the downloaded gtest repository it may have installed header files under /usr/local/include/gtest. If you later use apt-get to install the libgtest-dev debian package it installs the header files under /usr/include/gtest. If the version installed from the debian package is newer, your Makefile can pick up the older header files from /usr/include and give you link errors even though you
are correctly linking the new libgtest.a archive.
The solution is to look for /usr/local/include/gtest and /usr/include/gtest to see if they both exist. If they do then delete the older directory. If /usr/include/gtest is the older directory, you may want to remove it by uninstalling the libgtest-dev package.

Related

How to fix "error: no member named 'fancy_abort' in namespace 'std::__1'; did you mean simply 'fancy_abort'? _VSTD::abort();"

Platform: Macos Catalina 10.15.2
Xcode version: Xcode 11
I have tried many times to make-all gcc to build my source code. However, I have encountered a problem:
In file included from ../.././gcc/c/c-objc-common.c:33:
In file included from /Applications/Xcode11.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/new:85:
/Applications/Xcode11.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/exception:181:5: error:
no member named 'fancy_abort' in namespace 'std::__1'; did you mean simply 'fancy_abort'?
_VSTD::abort();
^~~~~~~ /Applications/Xcode11.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__config:873:15: note:
expanded from macro '_VSTD' # _VSTD std::_LIBCPP_ABI_NAMESPACE
^ ../.././gcc/system.h:685:13: note: 'fancy_abort' declared here extern void fancy_abort (const char *, int, const char
*) ATTRIBUTE_NORETURN;
^
1 error generated.
make[1]: *** [c/c-objc-common.o] Error 1
make: *** [all-gcc] Error 2
I have tried to install another version of Xcode. I have installed Xcode6 but it still did not work, and I found a solution of this issue. But when I download Xcode8.3.3, it is not compatible with Catalina 10.15.2.
I ran in to this issue while using crosstools-ng on mac (mojave 10.14) to compile cross-platform toolchain with gcc 4.9.
Solution: Edit .build/src/gcc-4.9.4/gcc/system.h to add #include <map> in #ifdef __cplusplus block where other include statements are.
The problem is that is included (via ) after abort has been
defined as a macro to fancy_abort. And thus when the C++ standard headers try
to call std::abort, they end up calling std::fancy_abort, which of course
doesn't exist.
Source: https://gcc.gnu.org/legacy-ml/gcc-bugs/2017-09/msg00154.html

Linking problem with boost when building cpprest-sdk on MacOs

I'm trying to create an HTTP client for a rest API using the cpprest-sdk library: https://github.com/Microsoft/cpprestsdk
I'm using a MacBook Pro with the latest version of MacOs (10.14.2).
I use brew as a package manager and have installed boost with:
brew install boost
Versions of dependencies:
clang: Apple LLVM version 10.0.0 (clang-1000.11.45.5)
cmake: 3.13.2
boost: stable 1.68.0 (bottled), HEAD
First I tried to follow this:
https://github.com/Microsoft/cpprestsdk/wiki/How-to-build-for-Mac-OS-X
So I also installed cpprestsdk with boost:
boost install cpprestsdk
Then I used the code from the tutorial in one main.cpp:
#include <cpprest/http_client.h>
#include <cpprest/filestream.h>
using namespace utility; // Common utilities like string conversions
using namespace web; // Common features like URIs.
using namespace web::http; // Common HTTP functionality
using namespace web::http::client; // HTTP client features
using namespace concurrency::streams; // Asynchronous streams
int main(int argc, char* argv[])
{
auto fileStream = std::make_shared<ostream>();
// Open stream to output file.
pplx::task<void> requestTask = fstream::open_ostream(U("results.html")).then([=](ostream outFile)
{
*fileStream = outFile;
// Create http_client to send the request.
http_client client(U("http://www.bing.com/"));
// Build request URI and start the request.
uri_builder builder(U("/search"));
builder.append_query(U("q"), U("cpprestsdk github"));
return client.request(methods::GET, builder.to_string());
})
// Handle response headers arriving.
.then([=](http_response response)
{
printf("Received response status code:%u\n", response.status_code());
// Write response body into the file.
return response.body().read_to_end(fileStream->streambuf());
})
// Close the file stream.
.then([=](size_t)
{
return fileStream->close();
});
// Wait for all the outstanding I/O to complete and handle any exceptions
try
{
requestTask.wait();
}
catch (const std::exception &e)
{
printf("Error exception:%s\n", e.what());
}
return 0;
}
And I created a CMake build file CMakeLists.txt as they describe in the README of cpprestsdk:
cmake_minimum_required(VERSION 3.13)
project(cpprest-example)
set(CMAKE_CXX_STANDARD 14)
find_package(cpprestsdk REQUIRED)
add_executable(cpprest-example main.cpp)
target_link_libraries(cpprest-example PRIVATE cpprestsdk::cpprest)
First I had a problem with CMake not fining openssl, so I had to add two env parameters like described here:
CMake not able to find OpenSSL library
Then it compiles but then fails during linking, with errors:
Scanning dependencies of target cpprest-example
[ 50%] Building CXX object CMakeFiles/cpprest-example.dir/main.cpp.o
[100%] Linking CXX executable cpprest-example
Undefined symbols for architecture x86_64:
"boost::this_thread::interruption_point()", referenced from:
boost::condition_variable::wait(boost::unique_lock<boost::mutex>&) in main.cpp.o
boost::condition_variable::do_wait_until(boost::unique_lock<boost::mutex>&, boost::detail::real_platform_timepoint const&) in main.cpp.o
"boost::chrono::steady_clock::now()", referenced from:
bool boost::condition_variable::wait_for<long long, boost::ratio<1l, 1000l>, pplx::details::event_impl::wait(unsigned int)::'lambda0'()>(boost::unique_lock<boost::mutex>&, boost::chrono::duration<long long, boost::ratio<1l, 1000l> > const&, pplx::details::event_impl::wait(unsigned int)::'lambda0'()) in main.cpp.o
bool boost::condition_variable::wait_until<boost::chrono::steady_clock, boost::chrono::duration<long long, boost::ratio<1l, 1000000000l> >, pplx::details::event_impl::wait(unsigned int)::'lambda0'()>(boost::unique_lock<boost::mutex>&, boost::chrono::time_point<boost::chrono::steady_clock, boost::chrono::duration<long long, boost::ratio<1l, 1000000000l> > > const&, pplx::details::event_impl::wait(unsigned int)::'lambda0'()) in main.cpp.o
"boost::detail::get_current_thread_data()", referenced from:
boost::detail::interruption_checker::interruption_checker(_opaque_pthread_mutex_t*, _opaque_pthread_cond_t*) in main.cpp.o
"boost::system::detail::system_category_instance", referenced from:
boost::system::system_category() in main.cpp.o
"boost::system::detail::generic_category_instance", referenced from:
boost::system::generic_category() in main.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [cpprest-example] Error 1
make[1]: *** [CMakeFiles/cpprest-example.dir/all] Error 2
make: *** [all] Error 2
Strange thing is that if I build the cpprestsdk codebase with CMake it works fine and one of the samples is the same code:
https://github.com/Microsoft/cpprestsdk/tree/master/Release/samples/BingRequest
That sample project has then been built successfully and runs fine.
I also tried uninstalling cpprestsdk from brew and did a CMake build of the cloned repository and then "make -j4 && make install". That installs cpprestsdk headers and libraries locally but in the end, results in the same errors.
It looks like it's not finding the boost libraries and I have tried using find_package(BOOST 1.68.0) and similar things but it fails with the same errors.
Can anyone see what I'm doing wrong?

Trying to get stasm to work on Ubuntu

I have the below in a Cmake file:
add_library(stasm STATIC IMPORTED)
set_property(TARGET stasm PROPERTY
IMPORTED_LOCATION /media/Data/sdks/stasm3.1/linux/libstasm.a)
target_link_libraries( StasmOpencvExample ${OpenCV_LIBS} stasm)
I generated the libstasm.a by doing:
How to create a static library with g++? , the first answer, taking all of the .o files from the linux folder and putting it into an archive.
but when i run make on my project i get:
Scanning dependencies of target StasmOpencvExample
[100%] Building CXX object CMakeFiles/StasmOpencvExample.dir/stasm_opencv_example.cpp.o
Linking CXX executable StasmOpencvExample
CMakeFiles/StasmOpencvExample.dir/stasm_opencv_example.cpp.o: In function `main':
stasm_opencv_example.cpp:(.text+0x9a): undefined reference to `AsmSearchDll(int*, int*, char const*, char const*, int, int, int, char const*, char const*)'
collect2: ld returned 1 exit status
has anyone gotten a cmake project to work with stasm on linux before? I also had to remove a n include "windows.h" from stasm_dll.cpp, and other windows specific code that wasn't properly done to allow working on linux.
I have already gotten the linux folder to generate the binaries and they work great, now I just need to incorporate this functionality into my own project..
It seems that the reason was that Stasm was created to make executables on Windows that did Image processing. Stasm DOES NOT act like a library, I'm currently making my own static and shared library that will act like a library that you can use to import into a random project and specify the parameters.
Basically modifiying main.cpp to another class and taking out the testing/unecessary code and get a thin processing version.

Why can't I compile this command-line OpenCV Mac application?

Following is my step:
1)create a command line tool project "OpenCV"
2)add files to the project which are in /usr/local/lib with suffix 2.4.2, such as
"libopencv_calib3d.2.4.2.dylib"
3)add "/usr/local/include" to project's Header Search Path
4)type this program:
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv/cvaux.hpp>
int main(int argc, char** argv)
{
IplImage * pInpImg = 0;
// Load an image from file - change this based on your image name
pInpImg = cvLoadImage("my_image.jpg", CV_LOAD_IMAGE_UNCHANGED);
if(!pInpImg)
{
fprintf(stderr, "failed to load input image\n");
return -1;
}
// Write the image to a file with a different name,
// using a different image format -- .png instead of .jpg
if( !cvSaveImage("my_image_copy.png", pInpImg) )
{
fprintf(stderr, "failed to write image file\n");
}
// Remember to free image memory after using it!
cvReleaseImage(&pInpImg);
return 0;
}
However, I get error :
ld: library not found for -lopencv_calib3d.2.4.2
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Where is the problem?
I'm using mountain lion and Xcode 4.4
You don't need to add the opencv libs to your project but you do need to link to the libraries and set the library search path. I was able to compile and run your program with these settings:
Search paths:
Link to libraries:

Linking to an external library with Premake

I can't get an external library link with the main program using premake. For instance I've simplified the problem to this example:
./_external/ext.cpp
#include "ext.h"
int foo()
{
return 4;
}
./_external/ext.h
#pragma once
int foo();
./main.cpp
#include "stdio.h"
#include "_external/ext.h"
int main()
{
printf("%d", foo());
return 0;
}
./premake4.lua
solution "Test"
configurations { "Release", "Debug" }
project "TestMain"
language "C++"
kind "ConsoleApp"
files "main.cpp"
links
{
"_external/libfoo.a"
}
I create the GNU makefiles under Cygwin environment:
$ ./premake4.exe gmake
Building configurations...
Running action 'gmake'...
Generating Makefile...
Generating TestMain.make...
Done.
and I get the following error when I make:
$ make
==== Building TestMain (release) ====
Linking TestMain
/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../../i686-pc-cygwin/bin/ld: cannot find -lD:/test/_external/libfoo.a
collect2: ld returned 1 exit status
TestMain.make:93: recipe for target `TestMain.exe' failed
make[1]: *** [TestMain.exe] Error 1
Makefile:16: recipe for target `TestMain' failed
make: *** [TestMain] Error 2
The only workaround I found is to use "linkoptions" instead of "links" to get rid of the "-l" but for me it's more like a hack than a solution.
You are doing it right, but Premake is getting it wrong. There was a bug in Premake's makefile generator that prevented things from linking properly. It is now fixed in both the stable (will become version 4.4) and dev (will become 5.0) repositories.
Nice to get that fixed—hope it helps.

Resources