OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Mar 28, 2024 5:11 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 2 posts ] 
Author Message
 Post subject: Splitting libc and libk, linker error
PostPosted: Wed Apr 14, 2021 8:54 pm 
Offline
Member
Member

Joined: Wed Feb 24, 2021 8:52 pm
Posts: 25
So, I've decided that I want to split libc and libk. I went ahead and created a new branch in my Github repo, and then began altering the makefiles, in the hopes of coming up with something that successfully distinguishes between libc and libk. Overall, I have libc's stuff in the following location:
/usr/include
/usr/lib

I wasn't sure where to put libk relative to libc, and so I decided that I would put it in these locations:
/usr/src/include
/usr/src/lib

Both libc and libk compile correctly. libc.a is put in /usr/lib, and libk.a is put in /usr/src/lib. The kernel's stuff seems to be accessing the right headers, and the functions compile correctly. The issue seems to be a linking error. Basically, even when I use -L in order to specify the path to the library used in order to access libk functions (/usr/src/lib), the linker says the following:
Code:
/usr/libexec/gcc/i686-elf/ld: cannot find -lk
collect2: error: ld returned 1 exit status


This happens even if I do -l:libk.a

The -lk option works in the non split version in the master branch. In the course of making the changes to the makefile, now it can't find the library, even after the path has been specified with -L.

I'll link the Github, and I'll also post as attachment several files that I specifically changed from the Meaty Skeleton template.
If there's any information (code, makefile portions) that I can specifically post in the comments in order to make things easier, let me know.

Github: https://github.com/dengeltheyounger/BlueOS
master contains the code before I tried to separate libc and libk.
separate_libc_libk is the code that results from me trying to separate the two.

UPDATE: The problems still hasn't been solved. However, I've tried one thing:
I added an echo statement to echo LIBDIR, which is included here:
Code:
LIBS:=$(LIBS) -nostdlib -L$(LIBDIR) -l:libk.a -lgcc


LIBS is added to the final formula here:
Code:
LINK_LIST=\
$(LDFLAGS) \
$(ARCHDIR)/crti.o \
$(ARCHDIR)/crtbegin.o \
$(KERNEL_OBJS) \
$(LIBS) \
$(ARCHDIR)/crtend.o \
$(ARCHDIR)/crtn.o \


Code:
blueos.kernel: $(OBJS) $(ARCHDIR)/linker.ld
        $(CC) -T $(ARCHDIR)/linker.ld -o $@ $(CFLAGS) $(LINK_LIST)
        grub-file --is-x86-multiboot blueos.kernel


I did an @echo in order to confirm that LIBDIR points to where it needs to. LIBDIR points to /usr/src/lib, just like it's supposed to. /usr/src/lib is actually in the sysroot path, just like it should be. libk.a is in /usr/src/lib. The -L option is part of the linker option just like it should. It's just not recognizing libk.a for some reason.

UPDATE2:
I've figured out that it is a linker issue. I don't really know why, and I don't know what's going on, but for whatever reason, the linker is not accepting the new library path. Basically, it starts out thinking that the library path is /usr/lib, and for whatever reason it looks like it's still looking in /usr/lib, even with the -L option. I don't really know why.

This is the result of verbose:

Code:
COLLECT_GCC=i686-elf-gcc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/i686-elf/10.2.0/lto-wrapper
Target: i686-elf
Configured with: /var/tmp/portage/cross-i686-elf/gcc-10.2.0-r5/work/gcc-10.2.0/configure --host=x86_64-pc-linux-gnu --target=i686-elf --build=x86_64-pc-linux-gnu --prefix=/usr --bindir=/usr/x86_64-pc-linux-gnu/i686-elf/gcc-bin/10.2.0 --includedir=/usr/lib/gcc/i686-elf/10.2.0/include --datadir=/usr/share/gcc-data/i686-elf/10.2.0 --mandir=/usr/share/gcc-data/i686-elf/10.2.0/man --infodir=/usr/share/gcc-data/i686-elf/10.2.0/info --with-gxx-include-dir=/usr/lib/gcc/i686-elf/10.2.0/include/g++-v10 --with-python-dir=/share/gcc-data/i686-elf/10.2.0/python --enable-languages=c --enable-obsolete --enable-secureplt --disable-werror --with-system-zlib --enable-nls --without-included-gettext --enable-checking=release --with-bugurl=https://bugs.gentoo.org/ --with-pkgversion='Gentoo 10.2.0-r5 p6' --disable-esp --disable-libstdcxx-pch --enable-poison-system-directories --disable-libstdcxx-time --disable-shared --disable-libquadmath --disable-libatomic --disable-threads --without-headers --disable-bootstrap --with-newlib --enable-multilib --disable-fixed-point --with-arch=i686 --enable-targets=all --disable-libgomp --disable-libssp --disable-libada --disable-systemtap --disable-vtable-verify --disable-libvtv --without-zstd --enable-lto --without-isl --disable-libsanitizer --enable-default-pie --enable-default-ssp
Thread model: single
Supported LTO compression algorithms: zlib
gcc version 10.2.0 (Gentoo 10.2.0-r5 p6)
COMPILER_PATH=/usr/libexec/gcc/i686-elf/10.2.0/:/usr/libexec/gcc/i686-elf/10.2.0/:/usr/libexec/gcc/i686-elf/:/usr/lib/gcc/i686-elf/10.2.0/:/usr/lib/gcc/i686-elf/
LIBRARY_PATH=/usr/lib/gcc/i686-elf/10.2.0/:/usr/lib/gcc/i686-elf/10.2.0/../../../../i686-elf/lib/:/home/admin/Documents/Programs/osdev/meaty_skeleton/BlueOs/sysroot/usr/lib/
COLLECT_GCC_OPTIONS='-isystem' '=/usr/src/include' '-T' 'arch/i386/linker.ld' '-o' 'blueos.kernel' '-O2' '-g' '-ffreestanding' '-Wall' '-Wextra' '-nostdlib' '-L/usr/src/lib' '-v' '-mtune=generic' '-march=i686'
/usr/libexec/gcc/i686-elf/10.2.0/collect2 -plugin /usr/libexec/gcc/i686-elf/10.2.0/liblto_plugin.so -plugin-opt=/usr/libexec/gcc/i686-elf/10.2.0/lto-wrapper -plugin-opt=-fresolution=/tmp/ccAOwuab.res --sysroot=/home/admin/Documents/Programs/osdev/meaty_skeleton/BlueOs/sysroot -pie -o blueos.kernel -L/usr/src/lib -L/usr/lib/gcc/i686-elf/10.2.0 -L/usr/lib/gcc/i686-elf/10.2.0/../../../../i686-elf/lib -L/home/admin/Documents/Programs/osdev/meaty_skeleton/BlueOs/sysroot/usr/lib -lk -lgcc arch/i386/crti.o arch/i386/crtbegin.o arch/i386/boot.o arch/i386/prep_gdt.o arch/i386/gdt.o arch/i386/tty.o arch/i386/pic.o arch/i386/irq.o arch/i386/isr.o arch/i386/irq_handler.o arch/i386/exception.o arch/i386/exception_handler.o kernel/kernel.o kernel/memory.o arch/i386/crtend.o arch/i386/crtn.o -T arch/i386/linker.ld
/usr/libexec/gcc/i686-elf/ld: cannot find -lk
collect2: error: ld returned 1 exit status


Attachments:
File comment: This is the output that build.sh gave (in the course of running the various makefiles).
output.txt [2.24 KiB]
Downloaded 14 times
Top
 Profile  
 
 Post subject: Re: Splitting libc and libk, linker error
PostPosted: Thu Apr 15, 2021 7:05 pm 
Offline
Member
Member

Joined: Wed Feb 24, 2021 8:52 pm
Posts: 25
So, I managed to get the error fixed. It's really really hacky, but if you're going off of the meaty skeleton and you want to split your libk and libc, you can use this as a starting point (and hopefully improve it).

Basically, instead of having kernel and libc as the only directories, you have kernel, libc, and libk. libc and libk are almost identical at this point.

This is the kernel's makefile
Code:
DEFAULT_HOST!=../default-host.sh
HOST?=DEFAULT_HOST
HOSTARCH!=../target-triplet-to-arch.sh $(HOST)

CFLAGS?=-O2 -ggdb
CPPFLAGS?=
LDFLAGS?=
LIBS?=

DESTDIR?=
PREFIX?=/usr/src
EXEC_PREFIX?=$(PREFIX)
BOOTDIR?=$(EXEC_PREFIX)/boot
KINCLUDEDIR?=$(PREFIX)/include

CFLAGS:=$(CFLAGS) -ffreestanding -Wall -Wextra
CPPFLAGS:=$(CPPFLAGS) -isystem=$(KINCLUDEDIR) -I$(KINCLUDEDIR)
LDFLAGS:=$(LDFLAGS)
# Unfortunately, a linking error results if I don't use -L and $(SYSROOT)
LIBS:=$(LIBS) -nostdlib -L$(SYSROOT)$(KLIBDIR) -lk -lgcc

ARCHDIR=arch/$(HOSTARCH)

include $(ARCHDIR)/make.config

CFLAGS:=$(CFLAGS) $(KERNEL_ARCH_CFLAGS)
CPPFLAGS:=$(CPPFLAGS) $(KERNEL_ARCH_CPPFLAGS)
LDFLAGS:=$(LDFLAGS) $(KERNEL_ARCH_LDFLAGS)
LIBS:=$(LIBS) $(KERNEL_ARCH_LIBS)

KERNEL_OBJS=\
$(KERNEL_ARCH_OBJS) \
kernel/kernel.o \
kernel/memory.o \

OBJS=\
$(ARCHDIR)/crti.o \
$(ARCHDIR)/crtbegin.o \
$(KERNEL_OBJS) \
$(ARCHDIR)/crtend.o \
$(ARCHDIR)/crtn.o \

LINK_LIST=\
$(LDFLAGS) \
$(ARCHDIR)/crti.o \
$(ARCHDIR)/crtbegin.o \
$(KERNEL_OBJS) \
$(LIBS) \
$(ARCHDIR)/crtend.o \
$(ARCHDIR)/crtn.o \

.PHONY: all clean install install-headers install-kernel
.SUFFIXES: .o .c .S

all: blueos.kernel

blueos.kernel: $(OBJS) $(ARCHDIR)/linker.ld
   $(CC) -T $(ARCHDIR)/linker.ld -o $@ $(CFLAGS) $(LINK_LIST)
   grub-file --is-x86-multiboot blueos.kernel

$(ARCHDIR)/crtbegin.o $(ARCHDIR)/crtend.o:
   OBJ=`$(CC) $(CFLAGS) $(LDFLAGS) -print-file-name=$(@F)` && cp "$$OBJ" $@

.c.o:
   $(CC) -MD -c $< -o $@ -std=gnu11 $(CFLAGS) $(CPPFLAGS)

.S.o:
   $(CC) -MD -c $< -o $@ $(CFLAGS) $(CPPFLAGS)

clean:
   rm -f blueos.kernel
   rm -f $(OBJS) *.o */*.o */*/*.o
   rm -f $(OBJS:.o=.d) *.d */*.d */*/*.d

install: install-headers install-kernel

install-headers:
   mkdir -p $(DESTDIR)$(KINCLUDEDIR)
   cp -R --preserve=timestamps include/. $(DESTDIR)$(KINCLUDEDIR)/.

install-kernel: blueos.kernel
   mkdir -p $(DESTDIR)$(BOOTDIR)
   cp blueos.kernel $(DESTDIR)$(BOOTDIR)

-include $(OBJS:.o=.d)


This is the libc's makefile:

Code:
DEFAULT_HOST!=../default-host.sh
HOST?=DEFAULT_HOST
HOSTARCH!=../target-triplet-to-arch.sh $(HOST)

CFLAGS?=-O2 -g
CPPFLAGS?=
LDFLAGS?=
LIBS?=

DESTDIR?=
PREFIX?=/usr
EXEC_PREFIX?=$(PREFIX)
INCLUDEDIR?=$(PREFIX)/include
LIBDIR?=$(EXEC_PREFIX)/lib

CFLAGS:=$(CFLAGS) -ffreestanding -Wall -Wextra
CPPFLAGS:=$(CPPFLAGS) -Iinclude

ARCHDIR=arch/$(HOSTARCH)

include $(ARCHDIR)/make.config

CFLAGS:=$(CFLAGS) $(ARCH_CFLAGS)
CPPFLAGS:=$(CPPFLAGS) $(ARCH_CPPFLAGS)

FREEOBJS=\
$(ARCH_FREEOBJS) \
stdio/printf.o \
stdio/putchar.o \
stdio/puts.o \
stdlib/abort.o \
stdlib/int_to_ascii.o \
string/memcmp.o \
string/memcpy.o \
string/memmove.o \
string/memset.o \
string/strlen.o \
string/strcmp.o \

HOSTEDOBJS=\
$(ARCH_HOSTEDOBJS) \

OBJS=\
$(FREEOBJS) \
$(HOSTEDOBJS) \

BINARIES=libc.a

.PHONY: all clean install install-headers install-libs
.SUFFIXES: .o .c .S

all: $(BINARIES)

libc.a: $(OBJS)
   $(AR) rcs $@ $(OBJS)

.c.o:
   $(CC) -MD -c $< -o $@ -std=gnu11 $(CFLAGS) $(CPPFLAGS)

.S.o:
   $(CC) -MD -c $< -o $@ $(CFLAGS) $(CPPFLAGS)

clean:
   rm -f $(BINARIES) *.a
   rm -f $(OBJS) *.o */*.o */*/*.o
   rm -f $(OBJS:.o=.d) *.d */*.d */*/*.d

install: install-headers install-libs

install-headers:
   mkdir -p $(DESTDIR)$(INCLUDEDIR)
   cp -R --preserve=timestamps include/. $(DESTDIR)$(INCLUDEDIR)/.

install-libs: $(BINARIES)
   mkdir -p $(DESTDIR)$(LIBDIR)
   cp $(BINARIES) $(DESTDIR)$(LIBDIR)

-include $(OBJS:.o=.d)


This is libk's makefile:
Code:
DEFAULT_HOST!=../default-host.sh
HOST?=DEFAULT_HOST
HOSTARCH!=../target-triplet-to-arch.sh $(HOST)

CFLAGS?=-O2 -g
CPPFLAGS?= -isystem$(KINCLUDEDIR)
LDFLAGS?=
LIBS?=

DESTDIR?=
PREFIX?=/usr/src
EXEC_PREFIX?=$(PREFIX)
KINCLUDEDIR?=$(PREFIX)/include
KLIBDIR?=$(EXEC_PREFIX)/lib

CFLAGS:=$(CFLAGS) -ffreestanding -Wall -Wextra
CPPFLAGS:=$(CPPFLAGS) -Iinclude

ARCHDIR=arch/$(HOSTARCH)

include $(ARCHDIR)/make.config

CFLAGS:=$(CFLAGS) $(ARCH_CFLAGS)
CPPFLAGS:=$(CPPFLAGS) $(ARCH_CPPFLAGS)

FREEOBJS=\
$(ARCH_FREEOBJS) \
stdio/printf.o \
stdio/putchar.o \
stdio/puts.o \
stdlib/abort.o \
stdlib/int_to_ascii.o \
string/memcmp.o \
string/memcpy.o \
string/memmove.o \
string/memset.o \
string/strlen.o \
string/strcmp.o \

HOSTEDOBJS=\
$(ARCH_HOSTEDOBJS) \

OBJS=\
$(FREEOBJS) \
$(HOSTEDOBJS) \

BINARIES=libk.a

.PHONY: all clean install install-headers install-libs
.SUFFIXES: .o .c .S

all: $(BINARIES)

libk.a: $(OBJS)
   $(AR) rcs $@ $(OBJS)

.c.o:
   $(CC) -MD -c $< -o $@ -std=gnu11 $(CFLAGS) $(CPPFLAGS)

.S.o:
   $(CC) -MD -c $< -o $@ $(CFLAGS) $(CPPFLAGS)

clean:
   rm -f $(BINARIES) *.a
   rm -f $(OBJS) *.o */*.o */*/*.o
   rm -f $(OBJS:.o=.d) *.d */*.d */*/*.d

install: install-headers install-libs

install-headers:
   mkdir -p $(DESTDIR)$(KINCLUDEDIR)
   cp -R --preserve=timestamps include/. $(DESTDIR)$(KINCLUDEDIR)/.

install-libs: $(BINARIES)
   mkdir -p $(DESTDIR)$(KLIBDIR)
   cp $(BINARIES) $(DESTDIR)$(KLIBDIR)

-include $(OBJS:.o=.d)


This is config.sh
Code:
SYSTEM_HEADER_PROJECTS="libk libc kernel"
PROJECTS="libk libc kernel"

export MAKE=${MAKE:-make}
export HOST=${HOST:-$(./default-host.sh)}

export AR=${HOST}-ar
export AS=${HOST}-as
export CC=${HOST}-gcc

export PREFIX=/usr
export EXEC_PREFIX=$PREFIX
export BOOTDIR=/boot
export LIBDIR=$EXEC_PREFIX/lib
export KLIBDIR=$EXEC_PREFIX/src/lib
export INCLUDEDIR=$PREFIX/include
export KINCLUDEDIR=$PREFIX/src/include

export CFLAGS='-O2 -g'
export CPPFLAGS=''

# Configure cross-compiler to use desired system root
export SYSROOT="$(pwd)/sysroot"
export CC="$CC --sysroot=$SYSROOT"

# work around that the -elf gcc targets doesn't have a system include dir
# because it was configured with --without-headers rather than --with-sysroot
# if echo "$HOST" | grep -Eq -- '-elf($|-)'; then
#   export CC="$CC -isystem=$INCLUDEDIR"
# fi


I don't think there's anything else that I changed (in build scripts).

I hope this helps someone else!


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 2 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: SemrushBot [Bot] and 68 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group