Configuring a library to be included with C++ test - c++

I would like to utilize the UnitTest++ library in a testing file. However, I am having some difficulty getting the library to be included at compile time. So here is my current directory structure:
tests/
UnitTests++/
libUnitTest++.a
src/
UnitTests++.h
unit/
test.cpp
I have just used the UnitTest++ getting started guide to just get the library setup. Here is test.cpp:
// test.cpp
#include <UnitTest++.h>
TEST(FailSpectacularly)
{
CHECK(false);
}
int main()
{
return UnitTest::RunAllTests();
}
And I am currently trying to compile with:
gcc -lUnitTest++ -L../UnitTest++/ -I../UnitTest++/src/ test.cpp
I am currently getting a bunch output with ld: symbol(s) not found at the end. So how would I be able to get the UnitTest++ library properly included when this program is compiled? I am on a Mac and I'd also like for there to be an easy way for people on a Linux machine to run these same tests.
Whew, I hope this provides enough information, if not please let me know.

I was able to build it in the following manner
gcc -L../UnitTest++/ -I../UnitTest++/src/ test.cpp -lUnitTest++ -lstdc++
or
g++ -L../UnitTest++/ -I../UnitTest++/src/ test.cpp -lUnitTest++
that links to libstdc++ automatically.
GCC documentation says:
-llibrary
-l library
Search the library named library when linking. (The second alternative with the library as a separate argument is only for POSIX compliance and is not recommended.)
It makes a difference where in the command you write this option; the linker searches and processes libraries and object files in the order they are specified.
Thus, foo.o -lz bar.o' searches libraryz' after file foo.o but before bar.o. If bar.o refers to functions in `z', those functions may not be loaded.
I guess that's why the library symbols are not found when you first specify -lUnitTest++ and then test.cpp

Compile test.cpp to get test.o
and use
g++ test.o libUnitTest++.a -o ./exectest
to get the ./exectest executable
libUnitTest++.a is just an archive of all the object files of UnitTest++. You just need to link all the object files (your test object file + libUnitTest++.a)
Try editing the makefile that came with unittest++ and make it suitable for your case

The message ld: symbol(s) not found means you haven't compiled the library. So you need to go in the UnitTest++ folder, compile and install it.
I've never worked on a MAC, but in linux, libraries are usually compiled and installed with:
./configure
make
make install
In the UnitTest++ link you posted, you should simply:
make install
Then you will have the UnitTest++.so library in the libraries folder of your OS. Now the library can be linked with your program with the -lUnitTest++ command.

Usually you have to put -Lsomething before the -lsomething that requires it.

Related

Linking to a static library with a makefile and g++

I want to link my C++ executable to both a static (libStatic.a) and a shared (libShared.so) library, using a makefile.
The makefile so far has the following content:
myExe: main.cpp libStatic.a libShared.so
g++ main.cpp libStatic.a libShared.so
I'm fairly sure that the static linking is correct, as I have seen similar things elsewhere. What I am unsure of is the shared linking part. Is this correct? Or is linking to a static library done differently?
If I run make, then it seems to be ok, and creates the executable. However, when I execute this, I reveive the error:
/usr/bin/ld: cannot find -lShared
However, my executable and libShared.so are in the same directory.
You need to set LD_LIBARY_PATH to this directory where the shared object is sitting before you run your program.
You can read up on 'rpath' in man ld for other possibilities.

Statically linking matio library using g++

How do you statically link matio, a library for reading mat-files, mainly used by matlab and octave into an executable?
If the file main.cpp holds matio functionality the compiler call
g++ -o main main.cpp -Imatio/include matio/lib/libmatio.a
fails with a bunch of error messages like: undefined reference to `inflateEnd'. This can be resolved by also adding zlib to the compiler call:
g++ -o main main.cpp -Imatio/include matio/lib/libmatio.a -lz
Now the error messages differ with something like undefined reference to `__intel_sse2_strlen'. So it appears that the zlib library is necessary for the comilation.
I now have the following questions:
What do you need to do to statically link the matio library in an executable?
Why do I need to add the zlib library even though I configured and compiled matio with ./configure --without-libz?
To build matio without zlib you apparently need to invoke configure with
./configure --with-zlib=no
(Checked this from configure.ac and config/matio_zlib.m4.)
In case you want to build matio with icc, Intel's developer pages tell that __intel_sse2_strlen is defined in libirc.a on Linux and libirc.lib on Windows.
To compile matio with the gcc do
./configure --with-zlib=no CC=gcc
afterwards, the matio library is statically linkable with the call posted in the question

Building code that uses EVP_* functions in Ubuntu

I am trying to build some code that uses the EVP_* functions in Ubuntu, however when I build, I get the dreaded "undefined reference" errors.
I am using Ubuntu 11.10.
The following line is how I compile:
g++ -lcrypto -lssl *.cpp -o IOService
[...]
crypto.cpp:(.text+0x8): undefined reference to `EVP_md5'
[...]
The cpp files include openssl/evp.h.
I have installed the libssl1.0.0-dbg package, but those libraries get installed in /usr/lib/debug/lib/i386-linux-gnu/ where my linker doesn't seem to find them. I tried softlinking and copying the .so files, to no avail (and I have the feeling this is not the way to go).
ld is a one-pass linker, meaning that you have to add libraries after the object files that use them: g++ *.cpp -o IOService -lcrypto (I think libssl is not needed if all you need is md5)

strange mingw linker errors with boost?

I've been working on this for a while now, and can't seem to make sense of the situation - partly bceause I don't fully understand what's going on (which is why I came here).
I'm doing a sort of boost hello world as follows:
#include <boost/thread/thread.hpp>
#include <cstdio>
void helloworld() {
std::printf("HELLO FROM A BOOST THREAD!");
}
int main(int argc, char **argv) {
boost::thread t(&helloworld);
t.join();
}
This is on Windows. I stored the Boost directory in C:\Boost. I ran bootstrap and bjam, and now have a stage/lib folder that contains all the .lib files. The lib files relating to the boost/thread library are:
libboost_thread-vc100-mt.lib
libboost_thread-vc100-mt-1_46_1.lib
libboost_thread-vc100-mt-gd.lib
libboost_thread-vc100-mt-gd-1_46_1.lib
Now I compile:
g++ -c main.cpp -I/Boost
that line works fine, I get main.o. Then:
g++ -o test.exe main.o -L/Boost/stage/lib -llibboost_thread-vc100-mt
And that's where the trouble happens. First of all, If I didn't type the -l argument the way I did, MinGW couldn't even find the file. Meaning, if I tried:
-lboost_thread-vc100-mt
instead of the way I typed it above (and how I thought it should be done), ld would exit with no such file. Anyway, this is now the output I'm getting from that line:
main.o:main.cpp:(.text+0x47): undefined reference to `_imp___ZN5boost6thread4joinEv'
main.o:main.cpp:(.text+0x55): undefined reference to `_imp___ZN5boost6threadD1Ev'
main.o:main.cpp:(.text+0x70): undefined reference to `_imp___ZN5boost6threadD1Ev'
main.o:main.cpp:(.text$_ZN5boost6threadC1IPFvvEEET_NS_10disable_ifINS_14is_convertibleIRS4_NS_6detail13thread_move_tIS4_EEEEPNS0_5dummyEE4typeE[boost::thread::thread<void (*)()>(void (*)(), boost::disable_if<boost::is_convertible<void (*&)(), boost::detail::thread_move_t<void (*)()> >, boost::thread::dummy*>::type)]+0x23): undefined reference to `_imp___ZN5boost6thread12start_threadEv'
collect2: ld returned 1 exit status
Now somewhere in there, I can tell that these are apparently the functions I'm supposed to be getting from boost/thread, and apparently it does find the lib file, so why isn't it linking correctly?
Thank you very much for any help!
EDIT:
I've rebuilt boost using the bjam "stage" option
bjam toolset=gcc stage
Now, after the build completes, I'm left with a stage/lib folder with .a files, as is to be expected. These are the boost/thread related libraries:
libboost_thread-mgw45-mt-1_46_1.a
libboost_thread-mgw45-mt-d-1_46_1.a
However, linking as follows:
g++ -o test.exe main.o -L/Boost/stage/lib -lboost_thread-mgw45-mt-1_46_1
outputs the exact same errors. Also tried:
g++ -o test.exe main.o -L/Boost/stage/lib -lboost_thread-mgw45-mt-1_46_1 -static
I'm at a loss, still.
Solved the problem. Boost's headers are configured to be dynamically linked, but the dynamic libraries (dll's) are not built unless you specify:
--build-type=complete
when invoking bjam. After that, copy the appropriate dll to your application directory, but still use the
-L/BOOST_DIR/stage/lib -lname
when linking.
This set of library files:
libboost_thread-vc100-mt.lib
libboost_thread-vc100-mt-1_46_1.lib
libboost_thread-vc100-mt-gd.lib
libboost_thread-vc100-mt-gd-1_46_1.lib
are for the Visual Studio 2010 compiler. They won't work with GCC. If you want to use gcc/MinGW, you'll need to download/build a set of boost libraries for that compiler. Alternatively you can install VS 2010 and use that compiler (the free VC++ 2010 Express version should work fine if cost is an issue).
You can get a MinGW distribution with Boost already in the package from http://nuwen.net/mingw.html (32-bit target only, I believe).
To answer about getting the errors with using the MinGW libs:
The _imp_ prefixes on the symbols is an indication that g++ is looking to link to a a dll/shared library. The .lib file you have are for static libraries (which is what also what I get when doing a straightforward bjam build of the libraries). If you look in boost/thread/detail/config.hpp you'll see that for Win32 builds it defaults to building against a DLL library unless the MSVC or Intel compiler is being used.
I'm not even sure exactly how to build the DLL libraries - I'll have to look it up. In the meantime, you can use the following command to build your example such that it'll link against the static library. The BOOST_THREAD_USE_LIB macro build the .cpp file such that it'll expect to link against the static library:
g++ -I/Boost -DBOOST_THREAD_USE_LIB -c main.cpp

C++ - building static library question

I built libbz2 (static variant) using MinGW (GCC 4.5.0) compilation system and now try to import this library into my MSVS2008 project.
I've done these things already and everything worked fine, for example, with zlib (which means that created C libraries are actually interchangeable).
However, when doing the same with libbz2, I face some unknown troubles - when I compile my MSVS2008-project I receive the following error on linking stage:
unresolved external symbol ___chkstk referenced in function _bzopen_or_bzdopen
I don't know why this happens (I think it's because some basic C runtimes are not fully compatible), but maybe someone knows how to fix this kind of error?
Maybe there is a manual way to somehow merge the implementation of MinGW-based ___chkstk into libbz2 static library?
Thank you.
I read your answer, but I think there's an easier (automatic) way of doing the manual merging of object files: use the CFLAG -static-libgcc, which will link in the necessary functions (what you are describing and doing manually).
Thanks everyone, I found the answer.
Basically, you can simply link to libgcc.a / libgcc.lib which was used when building the library.
The more convenient way that deals with the ___chkstk problem only means doing something like ar x libgcc.a (which produces many .o files) and then merging your libbz2 object files with __chkstk.o file.
I think it should be in linker options e.g. LDFLAGS=-static, while LDFLAGS=-static-libgcc still gives dynamically linked binaries...with any test.c:
gcc -c test.c
gcc -static-libgcc test.o
ldd a.out
libc.so.6 => /lib64/libc.so.6
/lib64/ld-linux-x86-64.so.2
gcc -c test.c
gcc -static test.o
ldd a.out
not a dynamic executable
For librarian, simply use ar
ar q libtest.a <path>/libgcc.a