install a library so that c++ compiler can directly access it - c++

I installed libmcrypt on my system by using the following commands:-
avinash#ak-pc:~/Documents/network_lab/tut7$ cd libmcrypt-2.5.8
avinash#ak-pc:~/Documents/network_lab/tut7/libmcrypt-2.5.8$ ./configure --prefix=/usr --disable-posix-threads
avinash#ak-pc:~/Documents/network_lab/tut7/libmcrypt-2.5.8$ make
avinash#ak-pc:~/Documents/network_lab/tut7/libmcrypt-2.5.8$ sudo make install
As a result headers went to /usr/include and the libraries to /usr/lib. Now, when I include < mcrypt.h> into a .cpp file and use functions provided by libmcrypt, the compiler announces
/tmp/ccCot4nH.o: In function `main':
q3.cpp:(.text+0x64): undefined reference to `mcrypt_module_open'
q3.cpp:(.text+0xb9): undefined reference to `mcrypt_generic_init'
q3.cpp:(.text+0xd6): undefined reference to `mcrypt_generic'
q3.cpp:(.text+0x110): undefined reference to `mdecrypt_generic'
q3.cpp:(.text+0x13a): undefined reference to `mcrypt_generic_deinit'
q3.cpp:(.text+0x147): undefined reference to `mcrypt_module_close'
collect2: ld returned 1 exit status
Can anybody tell me where the problem is? Was there something wrong with the installation procedure?

Including the header files of a library only provides declarations so that the compiler is aware of function signatures and global variable types, but you also need to indicate to the linker the library your program is to be dynamically linked with.
With most compilers, use the -l flag followed by the library's name, without the lib prefix. For example, your linking command may look something like this:
g++ -o myprogram obj1.o obj2.o ... obj.o -lmcrypt

Related

Can't link against static library with Mingw on Linux

I have installed the GMP library and try to cross-compile with mingw-w64-posix.
My Library is in /usr/local/lib.
My compile command looks like the following:
x86_64-w64-mingw32-g++-posix src/factorial.cpp -o bin/factorial.win.o -I/usr/local/include -L/usr/local/lib -lgmp -lgmpxx
It throws an undefined reference error:
(I can remove the whole block from -L...., same error. Seems like the library doesnt link for some reason)
/usr/bin/x86_64-w64-mingw32-ld: /tmp/ccxY03WS.o:factorial.cpp:(.text$_ZN23__gmp_binary_multiplies4evalEP12__mpz_structPKS0_S3_[_ZN23__gmp_binary_multiplies4evalEP12__mpz_structPKS0_S3_]+0x27): undefined reference to `__gmpz_mul'
/usr/bin/x86_64-w64-mingw32-ld: /tmp/ccxY03WS.o:factorial.cpp:(.text$_ZN23__gmp_binary_multiplies4evalEP12__mpz_structPKS0_l[_ZN23__gmp_binary_multiplies4evalEP12__mpz_structPKS0_l]+0x26): undefined reference to `__gmpz_mul_si'
/usr/bin/x86_64-w64-mingw32-ld: /tmp/ccxY03WS.o:factorial.cpp:(.text$_ZN10__gmp_exprIA1_12__mpz_structS1_E7init_siEl[_ZN10__gmp_exprIA1_12__mpz_structS1_E7init_siEl]+0x1a): undefined reference to `__gmpz_init_set_si'
/usr/bin/x86_64-w64-mingw32-ld: /tmp/ccxY03WS.o:factorial.cpp:(.text$_ZN10__gmp_exprIA1_12__mpz_structS1_EC1EOS2_[_ZN10__gmp_exprIA1_12__mpz_structS1_EC1EOS2_]+0x2e): undefined reference to `__gmpz_init'
/usr/bin/x86_64-w64-mingw32-ld: /tmp/ccxY03WS.o:factorial.cpp:(.text$_ZN10__gmp_exprIA1_12__mpz_structS1_ED1Ev[_ZN10__gmp_exprIA1_12__mpz_structS1_ED1Ev]+0x14): undefined reference to `__gmpz_clear'
collect2: error: ld returned 1 exit status
However if i change my compiler to g++ instead everything works fine.
OK -
The link errors (__gmpz_init, __gmpz_clear, etc.) are GMP "internals". They're supposed to come from libgmp, the C-language base library.
The code that's referencing them (.text$ZN23__gmp_binary_multiplies4evalEP12__mpz_structPKS0_S3[ZN23__gmp_binary_multiplies4evalEP12__mpz_structPKS0_S3], etc.) is "name mangled" C++.
I suspect the problem is that your "gmpxx" library was built with a different C++ compiler, that has a different "name mangling" convention than MinGW.
SOLUTION:
Download the complete libGMP source (e.g. from https://gmplib.org/, and rebuild EVERYTHING (including libgmpxx) with your libmingw-w64-posix++ C++ cross-compiler.
ADDENDUM:
I downloaded gmp-6.2.1 source, and found __gmpz_clear here:
gmp-6.2.1\gmp-h.in
#define mpz_clear __gmpz_clear
__GMP_DECLSPEC void mpz_clear (mpz_ptr);
"gmp-h.in" is a template used by the project's "autoconf", to generate the libGMP source files for the specified target environment.
Which, in turn, means:
The project you started out with (in your original question) wasn't configured for MinGW
... and ...
You didn't run "configure" correctly when you tried building from source.
SUGGESTION:
Try building libGMP from source again. DELETE everything, re-extract from the libGMP tarball, and carefully follow the INSTALL instructions:
./configure
make
make check <= VERY IMPORTANT!!
make install
I'm curious about your build environment (Windows? Linux?), compiler (exact MinGW version) and target (if you're building on a Windows workstation, do you want to run your GMP app as a Windows .exe)?

Resolving Linker error MySQL Connector/C++

I would like to be able to connect from my c++ program to a local MySQL instance, but the following minimal file testfile.cpp does not compile and returns undefined references:
#include <mysqlx/xdevapi.h>
using namespace ::mysqlx;
int main()
{
printf("Hello world!\n");
return 0;
}
I suspect to not use the right compile flags. When I use the command
c++ -o test1 -std=c++11 -lmysqlcppconn8 -I /usr/include/mysql-cppconn-8/ testfile.cpp
I am getting the following error messages (translated to English):
/tmp/cc02ZbBr.o: In the function "mysqlx::abi2::r0::string::traits<char>::to_str[abi:cxx11](mysqlx::abi2::r0::string const&)":
testfile.cpp:(.text._ZN6mysqlx4abi22r06string6traitsIcE6to_strB5cxx11ERKS2_[_ZN6mysqlx4abi22r06string6traitsIcE6to_strB5cxx11ERKS2_]+0x2e): undefined reference to "mysqlx::abi2::r0::string::Impl::to_utf8[abi:cxx11](mysqlx::abi2::r0::string const&)"
/tmp/cc02ZbBr.o: In the function "mysqlx::abi2::r0::DbDoc::DbDoc()":
testfile.cpp:(.text._ZN6mysqlx4abi22r05DbDocC2Ev[_ZN6mysqlx4abi22r05DbDocC5Ev]+0x1b): undefined reference to "vtable for mysqlx::abi2::r0::DbDoc"
/tmp/cc02ZbBr.o: In the function "mysqlx::abi2::r0::DbDoc::~DbDoc()":
testfile.cpp:(.text._ZN6mysqlx4abi22r05DbDocD2Ev[_ZN6mysqlx4abi22r05DbDocD5Ev]+0xf): undefined reference to "vtable for mysqlx::abi2::r0::DbDoc"
/tmp/cc02ZbBr.o: In the function "mysqlx::abi2::r0::Value::print(std::ostream&) const":
testfile.cpp:(.text._ZNK6mysqlx4abi22r05Value5printERSo[_ZNK6mysqlx4abi22r05Value5printERSo]+0x88): undefined reference to "mysqlx::abi2::r0::common::Value::print(std::ostream&) const"
/tmp/cc02ZbBr.o:(.data.rel.ro._ZTCN6mysqlx4abi22r05ValueE0_NS1_6common5ValueE[_ZTVN6mysqlx4abi22r05ValueE]+0x18): undefined reference to "typeinfo for mysqlx::abi2::r0::common::Value"
/tmp/cc02ZbBr.o:(.data.rel.ro._ZTCN6mysqlx4abi22r05ValueE0_NS1_6common5ValueE[_ZTVN6mysqlx4abi22r05ValueE]+0x20): undefined reference to "mysqlx::abi2::r0::common::Value::print(std::ostream&) const"
/tmp/cc02ZbBr.o:(.data.rel.ro._ZTIN6mysqlx4abi22r05ValueE[_ZTIN6mysqlx4abi22r05ValueE]+0x28): undefined reference to "typeinfo for mysqlx::abi2::r0::common::Value"
collect2: error: ld returned 1 exit status
The header from this file comes from a sample code on MySQL Connector/C++'s Github.
This question on SO seems relevant but the syntax/directories might be outdated. In any case, I do not know how to adjust the answers given there to my situation and location of libraries. Therefore I am asking for help here.
More information:
I'm running Linux Ubuntu 18.04, MySQL version 8.0.19 and have the following files in /usr/lib/x86_64-linux-gnu/
libmysqlcppconn.so
libmysqlcppconn.so.7.8.0.19
libmysqlcppconn.so.7
but I do not know how to refer to them.
In /usr/include/mysql-cppconn-8/ I have the directories jdbc/, mysql/ and mysqlx/.
I installed the following binary packages using the apt package manager: libmysqlcppconn-dev, libmysqlcppconn7, libmysqlcppconn8-1 and libmysqlcppconn8-2 (which is probably overkill but according to the installation guide one has to install quite a few of these libraries).
which mysql returns /usr/bin/mysql
When you compile source files and link binaries with object files and libraries, the order does matter. Shared libraries providing exported symbols must follow object files and other shared libraries importing these symbols. In your case, the shared library must be placed in the end of the c++ command invitation:
c++ -o test1 -std=c++11 -I /usr/include/mysql-cppconn-8/ testfile.cpp -lmysqlcppconn8
The undefined symbols discovered after compiling testfile.cpp will be imported from the following libmysqlcppconn8.so. Linkers doesn't remember exported symbols from prior libraries. For more information read this nice article: Why does the order in which libraries are linked sometimes cause errors in GCC.

Compiling using gcc of a Cpp code which is calling a TCL script

I have a cpp code in which I have included tcl.h library. I am trying to compile it using the gcc compiler. but I'm getting the following error :
gcc -o top.o -std=c99 top.c
top.c:12: warning: return type defaults to 'int'
/tmp/ccDOTTZQ.o: In function `main':
top.c:(.text+0xa): undefined reference to `Tcl_CreateInterp'
top.c:(.text+0x1f): undefined reference to `Tcl_EvalFile'
top.c:(.text+0x3d): undefined reference to `Tcl_GetVar2Ex'
top.c:(.text+0x75): undefined reference to `Tcl_ListObjGetElements'
top.c:(.text+0xb1): undefined reference to `Tcl_GetString'
top.c:(.text+0xcc): undefined reference to `Tcl_GetInt'
collect2: ld returned 1 exit status
Its not able to find the Cpp-tcl APIs. Kindly help me with this.
Your code is not linking to the Tcl library, so obviously it can't find the implementations of those functions. (In C and C++, the linking to the implementations of functions is a separate stage from the use of the declarations of those functions, which is what the header files provide.)
Except that you're actually calling gcc wrong. You need to use two steps, first with -c to compile the source code to an object file:
gcc -c -o top.o -std=c99 top.c
Then like this to link the result and make an executable:
gcc -o top.exe -std=c99 top.o -ltcl
With the first, you might need to additionally specify an appropriate -I option to locate the include files (if they're not in the standard locations). With the second, you might need to specify an appropriate -L option to locate the library files (libtcl.so). Depending on the system, you might also need to specify some version numbers (e.g., -ltcl86 or -ltcl8.6 instead of -ltcl). These are all options that depend on your build system configuration, so they're hard to predict exactly here.

TCL - undefined reference to `_imp__Tcl_ResetResult' for g++

I am relatively new to TCL and I am trying to execute a C++ program using SWIG on Windows 10. Using command prompt. I am not using Visual Studio
I am basically trying to run r_cpp using C++ MinGW from TCL
C:\swigwin-3.0.12\Examples\r\class>swig -c++ -tcl example.i`
C:\swigwin-3.0.12\Examples\r\class>g++ -c example.cxx
C:\swigwin-3.0.12\Examples\r\class>g++ -c example_wrap.cxx -I/Tcl/include/tcl8.6
C:\swigwin-3.0.12\Examples\r\class>g++ -shared example.o example_wrap.o -o example.dll
example_wrap.o:example_wrap.cxx:(.text+0x981): undefined reference to `_imp__Tcl_ResetResult'`example_wrap.o:example_wrap.cxx:(.text+0x995): undefined reference to `_imp__Tcl_SetObjResult'`example_wrap.o:example_wrap.cxx:(.text+0x9b9): undefined reference to `_imp__Tcl_SetErrorCode'
example_wrap.o:example_wrap.cxx:(.text+0x9cf): undefined reference to `_imp__Tcl_ResetResult'
example_wrap.o:example_wrap.cxx:(.text+0x9f3): undefined reference to `_imp__Tcl_SetErrorCode
example_wrap.o:example_wrap.cxx:(.text+0xa1e): undefined reference to `_imp__Tcl_AppendResult'
example_wrap.o:example_wrap.cxx:(.text+0xa3c): undefined reference to `_imp__Tcl_NewStringObj'
collect2.exe: error: ld returned 1 exit status
Can someone please help me on this??
Should I make changes to my Makefile.in in the folder?????
Its been a while since I've done C but I would think that you are not linking in the static/shared library that has the functions that g++ is complaining about. In this case the tcl library something like libTclXX.dll. I'm not too familiar with command lines on windows but something like -llibtclXX.dll -L path_to_tcllib could be added. If I recall correctly tcl does provide a stub library for you to link staticially your extension then at runtime the shared library can be use to resolve the functions... so something like -llibtclstubs.dll . look in your installed lib directory for actual names of these libraries.

Compiling Fortran netCDF programs on Ubuntu

Ok, newb question here.
I'm trying to compile simple_xy_wr.f90 -- a netCDF example program -- using gfortran on Ubuntu, and I must be doing something pretty silly; I don't have much experince compiling Fortran.
First, I've got the libnetcdf-dev package installed, which includes files like
/usr/lib/libnetcdf.a
/usr/lib/libnetcdff.a
/usr/include/netcdf.mod
So, I've tried to compile the code with (various command like)
f95 -o xy -I/usr/include/ -L/usr/lib/ -lnetcdff -lnetcdf simple_xy_wr.f90
and I get the following output
/tmp/ccE6g7sr.o: In function `check.1847':
simple_xy_wr.f90:(.text+0x72): undefined reference to `__netcdf_MOD_nf90_strerror'
/tmp/ccE6g7sr.o: In function `MAIN__':
simple_xy_wr.f90:(.text+0x284): undefined reference to `__netcdf_MOD_nf90_create'
simple_xy_wr.f90:(.text+0x2b6): undefined reference to `__netcdf_MOD_nf90_def_dim'
simple_xy_wr.f90:(.text+0x2e8): undefined reference to `__netcdf_MOD_nf90_def_dim'
simple_xy_wr.f90:(.text+0x432): undefined reference to `__netcdf_MOD_nf90_def_var_manydims'
simple_xy_wr.f90:(.text+0x468): undefined reference to `__netcdf_MOD_nf90_enddef'
simple_xy_wr.f90:(.text+0x4aa): undefined reference to `__netcdf_MOD_nf90_put_var_2d_fourbyteint'
simple_xy_wr.f90:(.text+0x4cb): undefined reference to `__netcdf_MOD_nf90_close'
collect2: error: ld returned 1 exit status
I think that I'm including the right libraries. E.g. it seems that __netcdf_MOD_nf90_strerror should be there:
$ nm /usr/lib/libnetcdff.a | grep __netcdf_MOD_nf90_strerror
000000000004a100 T __netcdf_MOD_nf90_strerror
What am I doing wrong?
(FWIW, a few relevant references I've looked at are below.
undefined reference using netcdf library
Compiling problems with gfortran and NETCDF
Compiling and Running Fortran Programs - a basic guide
)
Ordering of object files and archives on the linker command line is very important on Unix systems since the default linker behaviour is to search for symbol definitions only in archives that follow the object file or archive, where an unresolved reference was found, referred to single pass linking.
This means that if your code references __netcdf_MOD_nf90_strerror, then the archive that contains the definition of this symbol (libnetcdff.a) must appear after the list of object files from your program. libnetcdff.a itself references symbols from the C library libnetcdf.a, hence it must be linked after libnetcdff.a. So the correct link order is:
/tmp/ccE6g7sr.o libnetcdff.a libnetcdf.a
where /tmp/ccE6g7sr.o is the temporary object file that the assembler produces from the compiled source file. The correct command line to compile your code is then:
f95 -o xy -I/usr/include/ simple_xy_wr.f90 -lnetcdff -lnetcdf
In this case the linker is not called directly, rather the compiler does it. GCC compilers pass all link-related things in the same order to an intermediate utility called collect2 which then calls the actual linker ld.
Note that if shared object versions of the netCDF library archives are also present (i.e. there are libnetcdff.so and libnetcdf.so), then the linker would prefer them to the static archives (unless static linking is enabled with the -static option) and the final link phase would be handled to the run-time link editor (RTLD) (/lib64/ld-linux-x86-64.so.2 on Ubuntu). In this case the same command line as in your question would actually succeed without link errors, despite the fact that both libraries are positioned before the code that references them, as the missing symbol references would be resolved by the RTLD while it is loading the executable file.
In Ubuntu 12.10, the order of the libraries is the trick (as Hristo suggested):
angelv#palas:~$ gfortran -o xy -I/usr/include/ -L/usr/lib/ -lnetcdf -lnetcdff simple_xy_wr.f90
/tmp/ccj95anF.o: In function `check.1847':
simple_xy_wr.f90:(.text+0x72): undefined reference to `__netcdf_MOD_nf90_strerror'
/tmp/ccj95anF.o: In function `MAIN__':
simple_xy_wr.f90:(.text+0x284): undefined reference to `__netcdf_MOD_nf90_create'
simple_xy_wr.f90:(.text+0x2b6): undefined reference to `__netcdf_MOD_nf90_def_dim'
simple_xy_wr.f90:(.text+0x2e8): undefined reference to `__netcdf_MOD_nf90_def_dim'
simple_xy_wr.f90:(.text+0x432): undefined reference to `__netcdf_MOD_nf90_def_var_manydims'
simple_xy_wr.f90:(.text+0x468): undefined reference to `__netcdf_MOD_nf90_enddef'
simple_xy_wr.f90:(.text+0x4aa): undefined reference to `__netcdf_MOD_nf90_put_var_2d_fourbyteint'
simple_xy_wr.f90:(.text+0x4cb): undefined reference to `__netcdf_MOD_nf90_close'
collect2: error: ld returned 1 exit status
angelv#palas:~$ gfortran -o xy -I/usr/include/ simple_xy_wr.f90 -L/usr/lib/ -lnetcdf -lnetcdff
angelv#palas:~$ ./xy
0 12 24 36
*** SUCCESS writing example file simple_xy.nc!