Unable to link find libraries when linking - gcc

When I link the .ld file using gcc I got the following error
/usr/bin/ld: cannot find -lreadline
collect2: error: ld returned 1 exit status
my run.sh scripts contains the following command
rm *.o *.bin *.iso
rm -rf isodir
assemble boot.s file
as --32 boot.s -o boot.o
linking the kernel with kernel.o and boot.o files
gcc -m32 -lunistd -Wno-unused-result -c kernelCheck.c -o kernel.o -std=gnu99 -ffreestanding -flto -O2 -Wall -Wextra -L/usr/lib -fno-exceptions
gcc -m32 -T linker.ld -o MoraWing.bin -ffreestanding -Wl,--build-id=none -O2 -nostdlib boot.o kernel.o -lgcc
grub-file --is-x86-multiboot MoraWing.bin
building the iso file
mkdir -p isodir/boot/grub
cp MoraWing.bin isodir/boot/MoraWing.bin
cp grub.cfg isodir/boot/grub/grub.cfg
grub-mkrescue -o MoraWing.iso ./isodir
run it in qemu
qemu-system-x86_64 -cdrom MoraWing.iso

You need to install libreadline-dev, or a similar package suitable for your system (you should also specify what your system is).

Related

How do I link a archive file with C code?

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.

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.

Compiling asm with gcc - ubuntu

I've been trying to compile some language (CISC) that my professor created which is pseudo assembly. He wanted us to make a makefile and compile the file with .asm extension using gcc.
This is the makefile:
.SUFFIXES: .asm
all:schemeCompiler
schemeCompiler:target.o
gcc -g -m32 -Wall -o schemeCompiler target.o
target.o: target.asm
gcc -m32 -g -Wall -ansi -c -o target.o target.asm
.PHONY: clean
clean:
rm -f *.o schemeCompiler
And this is the error I get:
gcc -m32 -g -Wall -ansi -c -o target.o target.asm
gcc: warning: target.asm: linker input file unused because linking not done
gcc -g -m32 -Wall -o schemeCompiler target.o
gcc: error: target.o: No such file or directory
gcc: fatal error: no input files
compilation terminated.
I've put the makefile with the asm file in the same directory
Thanks !
***We've figured out the problem , we weren't running the make command right. Also the makefile wasn't right:
.SUFFIXES: .asm
all:schemeCompiler
schemeCompiler:$#
gcc -g -m32 -Wall -o schemeCompiler $#
%: %.asm
gcc -x c -o $# $<
.PHONY: clean
clean:
rm -f *.o schemeCompiler

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

Ubuntu LDFLAGS --as-needed

I have a C project that won't link correctly, and I suspect it's because of the --as-needed flag passed to the ld program by gcc. Because of that flag, gcc sees any linked library listed as an option before the *.c files as unnecessary, and won't link them.
PREFIX?=/usr/local
CFLAGS=-D_LARGEFILE64_SOURCE=1 -g -Wall -I${PREFIX}/apr/include/apr-1 -I${PREFIX}/apr/include/apr-util-1
LDFLAGS=-lapr-1 -pthread -laprutil-1
all: devpkg
devpkg: bstrlib.o db.o shell.o commands.o
install: all
install -d $(DESTDIR)/$(PREFIX)/bin/
install devpkg $(DESTDIR)/$(PREFIX)/bin/
clean:
rm -f *.o
rm -f devpkg
rm -rf *.dSYM
When I run this makefile I get the following.
cc -D_LARGEFILE64_SOURCE=1 -g -Wall -I/usr/local/apr/include/apr-1 -I/usr/local/apr/include/apr-util-1 -c -o bstrlib.o bstrlib.c
cc -D_LARGEFILE64_SOURCE=1 -g -Wall -I/usr/local/apr/include/apr-1 -I/usr/local/apr/include/apr-util-1 -c -o db.o db.c
cc -D_LARGEFILE64_SOURCE=1 -g -Wall -I/usr/local/apr/include/apr-1 -I/usr/local/apr/include/apr-util-1 -c -o shell.o shell.c
cc -D_LARGEFILE64_SOURCE=1 -g -Wall -I/usr/local/apr/include/apr-1 -I/usr/local/apr/include/apr-util-1 -c -o commands.o commands.c
cc -D_LARGEFILE64_SOURCE=1 -g -Wall -I/usr/local/apr/include/apr-1 -I/usr/local/apr/include/apr-util-1 -lapr-1 -pthread -laprutil-1 devpkg.c bstrlib.o db.o shell.o commands.o -o devpkg
/tmp/ccZcAm9b.o: In function `main':
/home/zach/Desktop/devpkgzed/devpkg.c:14: undefined reference to `apr_pool_initialize'
/home/zach/Desktop/devpkgzed/devpkg.c:15: undefined reference to `apr_pool_create_ex'
/home/zach/Desktop/devpkgzed/devpkg.c:29: undefined reference to `apr_getopt_init'
/home/zach/Desktop/devpkgzed/devpkg.c:31: undefined reference to `apr_getopt'
My issue is that I don't really understand how make is coming up with these commands via the CFLAGS that are set. How can I get the linker options to follow the compilation part instead of the other way around, which is triggering this issue?
Make has built-in rules to compile source files and link executables and libraries. The commands you list are produced by these rules.
The reason this fails for you is that, when linking, libraries should be listed after object files, because the linker does a single pass through its arguments and will discard any symbols that are not unresolved at the time they are seen. To correct it, put your libraries in the LDLIBS variable, not the LDFLAGS variable (i.e. just replace LDFLAGS by LDLIBS). The LDFLAGS variable is meant for non-library options for the linker, such as -L or -shared etc

Resources