C++ linker has problems finding openssl MD4 function - c++

I have a program that I am writing and that needs to calculate some hashes. I need SHA, MD, HMAC algorithms. That is why I chose openssl as solution.
My code is the following:
#include <openssl/md4.h>
void calc();
void calc(unsigned char* data, unsigned long len) {
unsigned char* h = new unsigned char[128];
MD4(data, len, h);
}
Compiler returns me the following:
myfile.cpp:(.text+0x3e): undefined reference to `MD4' collect2: ld
returned 1 exit status
I compile simply using:
g++ myfile.cpp -o myapp.o
under Linux Fedora.
I downloaded openssl libraries from here and compiled them cby using ./configure and then make install in the downloaded untarpalled directory. I also copied in /usr/local/include directory the include directory in the one I downloaded so that headers can be found by compiler because /usr/local/include is in my $PATH env var.
However the problem is that the linker cannot find the function. I understand that the reason might be two:
The compiler can find headers but cannot find implementations.
There are problems because openssl is written in C not in C++.
How should I proceeed? Thankyou
Edit1
I actually changed something in my openssl installation.
I installed openssl again and I could see that it places everything under /usr/local/ssl where I can find /usr/local/ssl/include and /usr/local/ssl/lib directories. I change my compilation string in:
g++ -I/usr/local/ssl/include -L/usr/local/ssl/lib -lssl -lcrypto
In the directories that I mentioned before I can find, respectively, /usr/local/ssl/include/openssl directory with all headers there and /usr/local/ssl/lib/libssl.a and /usr/local/ssl/lib/libcrypto.a libraries.
Before I did this change when I used the old compilation command, the compiler was telling me: Cannot find -lssl. With these changes, now it can find libs and headers, but ld always fails in the same way:
myfile.cpp:(.text+0x3e): undefined reference to `MD4' collect2: ld
returned 1 exit status
A little disappointed.
What do you think?

Linking against openssl usually requires -lssl.
g++ -o myapp myfile.cpp -lssl
By the way, it sounds like you may have done the installation a little incorrectly.
You shouldn't have to copy header files anywhere. And you may not have copied the shared libraries anyway.
The compilation should go something like this:
./configure --prefix=/usr/local/openssl
make
make install
And then you compile your program like:
g++ -c -o myapp1.o myfile1.cpp -I/usr/local/openssl/include
g++ -c -o myapp2.o myfile2.cpp -I/usr/local/openssl/include
g++ -o myapp myapp1.o myapp2.o -I/usr/local/openssl/include -L/usr/local/openssl/lib -lssl -lcrypto

The error is caused because you do not link the program to the openssl library during compilation.
Fix it with
g++ myfile.cpp -o myapp.o -lssl
See OpenSSL link options -lssl and -lcrypto in GCC
for how to link a program to openssl.

Related

Botan AutoSeeded_RNG can not be initialized, unknown reference, although libs are correctly linked

I simply try to initialize the Botan AutoSeeded_RNG but it fails because of a bad reference. I just wanted to test if i can initialize any kind of botan RNG, corse i have trouble with it in another project.
I have the correct header included and am linking to the lib of Botan, therefore i don't know, why it can not find the referende.
Here is my code:
1 #include <botan/auto_rng.h>
2 #include <botan/ecdh.h>
3 #include <botan/ec_group.h>
4 #include <botan/pubkey.h>
5 #include <botan/hex.h>
6 #include <iostream>
7
8 int main() {
9
10 Botan::AutoSeeded_RNG rng;
11
12 return 0;
13 }
14
And here is my output:
~/projects $ g++ ecdh.cpp -o ecdh -I/usr/local/include/botan-2/ -L/usr/local/lib/
/usr/bin/ld: /tmp/cccPpNuZ.o: in function `main':
ecdh.cpp:(.text+0x18): undefined reference to `Botan::AutoSeeded_RNG::AutoSeeded_RNG(unsigned int)'
/usr/bin/ld: ecdh.cpp:(.text+0x28): undefined reference to `Botan::AutoSeeded_RNG::~AutoSeeded_RNG()'
collect2: error: ld returned 1 exit status
What am i doing wrong?
Thx for your advice in advance.
You are not linking against the botan library. The -L <dir> flag only adds the directory to the library search paths, it does not tell g++ to link against any specific library. To link against a library, you have to use the -l <lib> parameter. The linker will then search for this library in its library search paths, including the directories passed with -L <dir>.
To link against the botan library, you have to find the directory containing the botan library. I understand in your case this is /usr/local/lib/libbotan-2.so. You would then add the -lbotan-2 parameter to the g++ parameter list. This will make g++ look for libraries called libbotan-2.so in its library search paths. Since you added /usr/local/lib to the library search paths with the -L /usr/local/lib parameter, g++ should then be able to locate the library in this folder.
Note that additional parameters may be required or are recommended by the botan library for an optimal experience. You can find these parameters in a file called botan-2.pc, which should be contained somewhere in your custom installation. On my system, it contains the following information:
$ cat /usr/lib/pkgconfig/botan-2.pc
prefix=/usr
exec_prefix=${prefix}
libdir=/usr/lib
includedir=${prefix}/include/botan-2
Name: Botan
Description: Crypto and TLS for C++11
Version: 2.15.0
Libs: -L${libdir} -lbotan-2 -fstack-protector -m64 -pthread
Libs.private: -lbz2 -ldl -llzma -lrt -lz
Cflags: -I${includedir}
This information can also be queried directly using the pkg-config command:
$ PKG_CONFIG_PATH=/some/path:$PKG_CONFIG_PATH pkg-config --libs --cflags botan-2
-I/usr/include/botan-2 -lbotan-2 -fstack-protector -m64 -pthread
Where /some/path is the directory containing the botan-2.pc. This gives us the recommended compiler and linker flags for the botan library. We could either copy them to the g++ parameter list manually, or pass them automatically using:
g++ $(PKG_CONFIG_PATH=/some/path:$PKG_CONFIG_PATH pkg-config --libs --cflags botan-2) my_program.cpp

mingw g++ is unable to link with libraries

I'm trying to use X86_64-w64-mingw32-g++ (packaged in Archlinux's MingW package) to cross compile some C++ code into an Windows executable, however I'm having trouble getting past some issues.
I'm calling
x86_64-w64-mingw32-g++ -o build_win/asm build_win/asm.o build_win/asm_lib.o build_win/socket_boost.o -I../extra/etc -fopenmp -lrt -std=c++11 -g -lboost_system -lboost_serialization
from a makefile, but I get thrown the errors:
/usr/lib/gcc/x86_64-w64-mingw32/5.1.0/../../../../x86_64-w64-mingw32/bin/ld: cannot find -lrt
/usr/lib/gcc/x86_64-w64-mingw32/5.1.0/../../../../x86_64-w64-mingw32/bin/ld: cannot find -lboost_system
/usr/lib/gcc/x86_64-w64-mingw32/5.1.0/../../../../x86_64-w64-mingw32/bin/ld: cannot find -lboost_serialization
This works fine with native g++, so exactly do I have to change for mingw to compile?
EDIT: I have mingw-w64-boost package installed, which includes boost libraries pre-compiled and ready to be linked. However, it seems the naming convention is a bit different, and -lboost_system for example becomes -llibboost_system-mt (not exactly sure what the -mt suffix entails).
Problem is I can't find the mingw counterpart for -lrt. I've tried with both -lrtm and -lrtutils but in both cases I get:
[...]
undefined reference to `__imp_getsockopt'
Are you sure that -lboost_system and other libraries are present in the same directory as makefile ?
If not then please include -L flag which indicates the location of your library.
For example:
-L /path_openmp -fopenmp -L /path_boost_system/ -lboost_system -L /path_serialization -lboost_serialization
Moreover, you need not include -I and -g flag when creating an executable from .o files. These are needed when you create .o from .cpp files.
There is no rt library on Windows.
You are missing -lws2_32.
$ x86_64-w64-mingw32-nm -A /usr/x86_64-w64-mingw32/lib/*.a 2>/dev/null | grep getsockopt | grep " T "

C++: linker cannot find -lcrypto, but the library is in the path

I am compiling a C++ application using GNU g++. The project takes advantage of OpenSSL libraries.
Background
On my machine (a 64 bit CentOS quad core) I compile and link my files.
g++ -g -c -L/usr/local/lib/ -L/usr/lib64/
-I/usr/local/include/ -I/usr/local/ssl/include/
-lcrypto mysrc1.cpp mysrc2.cpp mysrc3.cpp
g++ -L/usr/local/lib/ -L/usr/lib64/ -lcrypto
*.o -o ./myapp.out
My application uses function MD5 which is contained in libcrypto.so. As you can see I specify to g++ the dirs where to search using the -L, -I options and which libraries to look for with the -l<lib-name> option. There are some trivial paths like /usr/local/lib which can be omitted of course, but I specified them because the makefile is parametric.
The problem
My problem is that I can successfully compile my stuff (first command), but linking fails (second command):
/usr/bin/ld: cannot find -lcrypto
collect2: ld returned 1 exit status
make: * [cppsims_par] Error 1
But I did check folders and everything... libcrypto.so is inside /usr/lib64/. What is going on?
It may help if you try strace to find why it failed the file lookup
strace -f -e trace=file g++ -L/usr/local/lib/ -L/usr/lib64/ -lcrypto
*.o -o ./myapp.out
I did find the problem and it is related to this question: ld cannot find an existing library
Actually I had no symlink libcrypto.so and the compiler was not able to find the library...
I had related issue, and resolved it after inspecting the trace.
I had
-L<my/path/to/lib> -llib_some_library
when it should have been
-L<my/path/to/lib> -lsome_library

/usr/bin/ld: cannot find

I created a .so file and put it in the location /opt/lib and added this path to LD_LIBRARY_PATH now after this when I try to compile my main program with the following command:
g++ -Wall -I/home/alwin/Development/Calculator/ main.cpp -lcalc -o calculator
I get the following error:
/usr/bin/ld: cannot find -lcalc
collect2: ld returned 1 exit status
Can someone help me with this.
I created the shared library using the code blocks IDE
Add -L/opt/lib to your compiler parameters, this makes the compiler and linker search that path for libcalc.so in that folder.
When you make the call to gcc it should say
g++ -Wall -I/home/alwin/Development/Calculator/ -L/opt/lib main.cpp -lcalc -o calculator
not -libcalc.so
I have a similar problem with auto-generated makes.
You can create a soft link from your compile directory to the library directory.
Then the library becomes "local".
cd /compile/directory
ln -s /path/to/libcalc.so libcalc.so
You need to add -L/opt/lib to tell ld to look there for shared objects.
#Alwin Doss
You should provide the -L option before -l. You would have done the other way round probably. Try this :)
export LDFLAGS=-L/path to lib/ this will solve the error

CUDA: Creating object with G++ linker and cuda object files

I compiled my normal cpp files to .o, and my cuda .cu files to .co
I want to link these so I can call the cuda stuff from my normal C++ file
Here is my linker command that Make is running:
g++ -I ../readers/ -I../writers -I../common/ -I /home/dcole/software/xerces-c-3.1.1/src -I /home/dcole/NVIDIA_GPU_Computing_SDK/C/common/inc/ -I /usr/local/cuda/include -O3 -fPIC -fopenmp -DFIX_PAULI -DFIX_YAMA -DUSING_CUDA -o YamaguchiGPU YamaguchiMain.o YamaguchiDecomp.o cuYamaguchi.co -L/usr/lib64/ ../../lib/IDT.a ../../lib/Linux/libxerces-c.a ../../lib/Linux/libfftw3f.a -lcurl -lidn -ldl -lssl -lm -lpthread -lcuda -L/usr/local/cuda/lib64/libcudart.so
So I am definitly linking cuda, and cudart, but yet I get this:
cuYamaguchi.co: In function `__sti____cudaRegisterAll_46_tmpxft_00003190_00000000_4_cuYamaguchi_cpp1_ii_init_gpu()':
tmpxft_00003190_00000000-1_cuYamaguchi.cudafe1.cpp:(.text+0x1b4): undefined reference to `__cudaRegisterFatBinary'
tmpxft_00003190_00000000-1_cuYamaguchi.cudafe1.cpp:(.text+0x20f): undefined reference to `__cudaRegisterFunction'
The Cuda file is being linked without problems but it looks like you might have forgotten to define some necessary function (like cudaRegisterFatBinary).
Upgrading to gcc 4.7.0 or higher should fix this horrid linker issue.
I was using an absolute search path in the linker to _libcudart.so_. I changed the -L to point to just the folder, then added -libcudart so it would search the folder for that lib.