How do I link a archive file with C code? - makefile

I'm trying to link a static library archive file (libx/libx.a) with a C code. The library requires 2 flags (-lx -lpthread). After linking the static library my ultimate goal is to create a shared library. I have the following Make file,
rsa-engine: rsa/rsa.c rsa/bignum.c rsa/aes.c rsa/x509parse.c rsa/pem.c
gcc -fPIC -o rsa/rsa.o -c rsa/rsa.c
gcc -fPIC -o rsa/bignum.o -c rsa/bignum.c
gcc -fPIC -o rsa/aes.o -c rsa/aes.c
gcc -fPIC -o rsa/x509parse.o -c rsa/x509parse.c
gcc -fPIC -o rsa/pem.o -c rsa/pem.c
gcc -fPIC rsa-engine.c libx/libx.a -L.libx/ -lx -lpthread -o rsa-engine.o
gcc -shared -o librsa_engine.so -lcrypto rsa-engine.o rsa/rsa.o rsa/bignum.o rsa/aes.o rsa/x509parse.o rsa/pem.o
clean:
rm -f *.o rsa/*.o *.so rsa-engine
After using the make command it produces the following output,
/usr/bin/ld: cannot find -lx
collect2: error: ld returned 1 exit status
Makefile:2: recipe for target 'rsa-engine' failed
make: *** [rsa-engine] Error 1
I found similar questions here. But that did not help. Seems like I can't make the link work. Any help with what I'm doing wrong?
I would like to achieve the same result generated by the following command,
CC := gcc
CFLAGS := -Wall -g -MD -O2 -I ../
LDFLAGS := -lx -lpthread
tests_files := hello
all: $(tests_files)
hello: hello.o ../libx/libx.a
$(CC) $(CFLAGS) -static $(<) -L../libx/ $(LDFLAGS) -o $(#)

It seems that your libx.a is located in libx, yet -L references .libx directory. Anyway, since you reference libx/libx.a directly, you may skip both -L.libx/ -lx and it should link just fine.

Related

script-file Not found by linker

when running a makefile, which includes a usage of
a script-file, I receive an error saying the linker doesn't find the script file.
When running the make file the output is as follows:
arm-none-eabi-gcc -g -Wall -Werror -c -o main.o main.c
arm-none-eabi-gcc -g -Wall -Werror -c -o misc.o misc.c
arm-none-eabi-gcc main.o misc.o misc.h -g -Wall -Werror -Wl,-Map=HOST.map -T=msp432p401r.lds -o HOST
/usr/lib/gcc/arm-none-eabi/9.2.1/../../../arm-none-eabi/bin/ld: cannot open linker script file =msp432p401r.lds: No such file or directory
collect2: error: ld returned 1 exit status
make: *** [Makefile:11: HOST] Error 1
The makefile content is:
#---- Variables (machine depending) --------
TARGET = HOST
CC = arm-none-eabi-gcc #gcc
CFLAGS = -g -Wall -Werror # compiler flags
LDFLAGS = -Wl,-Map=$(TARGET).map -T=msp432p401r.lds # linker flag
SOURCE = main.c misc.c misc.h
OBJS = $(SOURCE:.c=.o) # replace all c with o
#---- Targets -----------
$(TARGET): $(OBJS)
$(CC) $(OBJS) $(CFLAGS) $(LDFLAGS) -o $#
I have searched a lot for a solution for this issue, and tried various fixes, with no success.
The script file is located at the same location as the source files.
What can be the reason for not finding the file?
Thanks

Same Makefile executing different commands in different computers

During installation of pintos, I had to run make.
Following is the Makefile.
all: setitimer-helper squish-pty squish-unix
CC = gcc
CFLAGS = -Wall -W
LDFLAGS = -lm
setitimer-helper: setitimer-helper.o
squish-pty: squish-pty.o
squish-unix: squish-unix.o
clean:
rm -f *.o setitimer-helper squish-pty squish-unix
In one computer it executed correctly. (output for the command is given below)
gcc -Wall -W -c -o setitimer-helper.o setitimer-helper.c
gcc -lm setitimer-helper.o -o setitimer-helper
gcc -Wall -W -c -o squish-pty.o squish-pty.c
gcc -lm squish-pty.o -o squish-pty
gcc -Wall -W -c -o squish-unix.o squish-unix.c
gcc -lm squish-unix.o -o squish-unix
but in other computer I got the following error
gcc -lm setitimer-helper.o -o setitimer-helper
setitimer-helper.o: In function `main':
setitimer-helper.c:(.text+0xc9): undefined reference to `floor'
collect2: error: ld returned 1 exit status
<builtin>: recipe for target 'setitimer-helper' failed
make: *** [setitimer-helper] Error 1
If looked at first line of outputs of both make commands
gcc -Wall -W -c -o setitimer-helper.o setitimer-helper.c
and
gcc -lm setitimer-helper.o -o setitimer-helper
They are different.
Why make is executing different commands for the same Makefile? and What should I do to remove error?
In the first computer, the setitimer-helper.o file either doesn't exist or the setitimer-helper.c file is newer, so make needs to rebuild it. Thus it runs the compiler, then afterwards it performs the link operation:
gcc -Wall -W -c -o setitimer-helper.o setitimer-helper.c
gcc -lm setitimer-helper.o -o setitimer-helper
On the second computer, the setitimer-helper.o file already exists and is newer than the setitimer-helper.c file, so the compile command was not needed and the second computer proceeded directly to the link line:
gcc -lm setitimer-helper.o -o setitimer-helper
The real question is why you got the linker error on the second computer.
The answer to that is that the -lm flag needs to come on the linker line after the object files. This happens because you added -lm to the LDFLAGS variable which is not the right one: that should contain options that tell the linker where to look for files, etc. (for example, the -L option).
Libraries should be added to the LDLIBS variable, not LDFLAGS. Change your makefile to this:
all: setitimer-helper squish-pty squish-unix
CC = gcc
CFLAGS = -Wall -W
LDLIBS = -lm
setitimer-helper: setitimer-helper.o
squish-pty: squish-pty.o
squish-unix: squish-unix.o
clean:
rm -f *.o setitimer-helper squish-pty squish-unix
Your link line will then look like:
gcc setitimer-helper.o -o setitimer-helper -lm
and should work properly.

relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC

So I ve been trying to recompile with -fPIC but it seems I am getting the same error, am I doing it right or am I missing something else?
all: pr1 pr2
pr1:
g++ -std=c++11 -fPIC -c $(wildcard pr1.cpp)
g++ -std=c++11 -o $(PROGRAM) pr1.o $(LIBRARY) $(LINKER_FLAGS)
rm -f pr1.o
pr2:
g++ -std=c++11 -fPIC -c $(wildcard pr2.cpp)
g++ -std=c++11 -o $(PROGRAM1) pr2.o $(LIBRARY) $(LINKER_FLAGS)
rm -f pr2.o
The problem seems to occur at the second program (pr2), possibly when I am trying to reuse LIBRARY(.a file)?
apparently I was not removing the .a library that was produced . make clean first

how to build g++ Makefile

Last time i asked sth about how to use CLAPACK.
Using CLAPACK undefined reference error
After that i tried to separate everything for a larger project.
Now I have "blitzLA.cpp" "InterfaceCLAPACK.cpp" "InterfaceCLAPACK.hpp"
I could successfully make it work just by calling
g++ -Wall -g InterfaceCLAPACK.cpp blitzLA.cpp -llapack -lblas -lf2c -o blitzLA
But if I do the Makefile, it gives me some errors.. My makefile is shown below.
CC = g++
CFLAGS = -Wall -g
linker = -llapack -lblas -lf2c
blitzLA: blitzLA.o InterfaceCLAPACK.o
${CC} ${CFLAGS} InterfaceCLAPACK.o blitzLA.o -o blitzLA
blitzLA.o: blitzLA.cpp InterfaceCLAPACK.hpp
${CC} ${CFLAGS} ${linker} -c blitzLA.cpp
InterfaceCLAPACK.o: InterfaceCLAPACK.cpp InterfaceCLAPACK.hpp
${CC} ${CFLAGS} ${linker} -c InterfaceCLAPACK.cpp
clean:
rm -rf *.o blitzLA
I guess the problem is where do i leave "-llapack -lblas -lf2c"..Now i get the errors shown below.
g++ -Wall -g -llapack -lblas -lf2c -c blitzLA.cpp
g++ -Wall -g -llapack -lblas -lf2c -c InterfaceCLAPACK.cpp
g++ -Wall -g InterfaceCLAPACK.o blitzLA.o -o blitzLA
InterfaceCLAPACK.o: In function `quantfin::interfaceCLAPACK::SolveLinear(blitz::Array<double, 2>
bunch of things here..
/home/baozi/Dropbox/Linux/LinearAlgebra/InterfaceCLAPACK.cpp:64: undefined reference to `dgttrf_'
/home/baozi/Dropbox/Linux/LinearAlgebra/InterfaceCLAPACK.cpp:67: undefined reference to `dgttrs_'
collect2: error: ld returned 1 exit status
make: *** [blitzLA] Error 1
Where do i go wrong.. Help plz

Gcc /usr/bin/ld compiler error

I got this error when I do make
gcc -o tests/simple_test tests/simple_test.o -L. libtraceback.a -Wall -Werror -gdwarf-2 -O0 -m32 -fno-stack-protector -fno-omit-frame-pointer -Itraceback/ -mpreferred-stack-boundary=2 -static
/usr/bin/ld: cannot find crt1.o: No such file or directory
/usr/bin/ld: cannot find crti.o: No such file or directory
/usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-linux-gnu/4.8/libgcc.a when searching for -lgcc
/usr/bin/ld: cannot find -lgcc
/usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-linux-gnu/4.8/libgcc_eh.a when searching for -lgcc_eh
/usr/bin/ld: cannot find -lgcc_eh
/usr/bin/ld: cannot find -lc
collect2: error: ld returned 1 exit status
I read one post and tried
sudo ln -s /usr/lib/x86_64-linux-gnu /usr/lib64
But it doesn't help, is there any reason for this?
Im running on a surface pro 2 using vmware running 64bits ubuntu 13.10.
If you do not have any parcticular reason to build a 32bit application on a 64bit machine just do not use the option -m32.
In case you are following this tutorial then fixed make file code is below working on Ubuntu 20
# $# = target file
# $< = first dependency
# $^ = all dependencies
# First rule is the one executed when no parameters are fed to the Makefile
all: run
kernel.bin: kernel-entry.o kernel.o
ld -m elf_i386 -o $# -Ttext 0x1000 $^ --oformat binary --entry main
kernel-entry.o: kernel-entry.asm
nasm $< -f elf -o $#
kernel.o: kernel.c
gcc -m32 -ffreestanding -c $< -o $# -fno-pie
mbr.bin: mbr.asm
nasm $< -f bin -o $#
os-image.bin: mbr.bin kernel.bin
cat $^ > $#
run: os-image.bin
qemu-system-i386 -fda $<
clean:
$(RM) *.bin *.o *.dis
To run make file
make run
to clean all output files
make clean

Resources