Page 1 of 1

Build shared libstdc++ on cross gcc

Posted: Thu Nov 16, 2017 10:50 am
by marcxDotdev
Hi everyone, I'm new to this forum, but I'm still developing my operating system since 4 years (it's name is MeetiX OS).
I'm adding to my operating system the dynamic linker to support shared libraries but i noticed that the cross building of the GCC (v4.9.1) doesn't creates the libstdc++.so.
On the gcc's configure i added the parameters "--enable-shared" and "--enable-host-shared" and on the config file that patch the gcc i added the support for dynamic executables

Code: Select all

diff -Nur gcc-4.9.1/gcc/config/mx.h gcc-4.9.1-mx/gcc/config/mx.h
--- gcc-4.9.1/gcc/config/mx.h	1970-01-01 01:00:00.000000000 +0100
+++ gcc-4.9.1-mx/gcc/config/mx.h	2017-05-22 21:57:42.000000000 +0200
@@ -0,0 +1,32 @@
+// built-in defines
+#undef TARGET_OS_CPP_BUILTINS
+#define TARGET_OS_CPP_BUILTINS()		\
+do {									\
+	builtin_define_std ("MeetiX");		\
+	builtin_define_std ("unix");		\
+	builtin_assert ("system=mx");	\
+	builtin_assert ("system=unix");		\
+} while(0);
+
+// for MeetiX-specific changes on GCC
+#undef	TARGET_MEETIX
+#define TARGET_MEETIX 1
+
+// don't automatically add extern "C" { } around header files
+#undef	NO_IMPLICIT_EXTERN_C
+#define	NO_IMPLICIT_EXTERN_C 1
+
+// define the default library specifications
+#undef	LIB_SPEC
+#define LIB_SPEC "%{!shared:--start-group -lapi -lc --end-group}"
+
+// start and end files
+#undef STARTFILE_SPEC
+#define STARTFILE_SPEC "%{!shared: %{!pg:crt0.o%s}} crti.o%s %{!shared:crtbegin.o%s}"
+
+#undef ENDFILE_SPEC
+#define ENDFILE_SPEC "%{!shared:crtend.o%s} crtn.o%s"
+
+// specify the links types
+#undef LINK_SPEC
+#define LINK_SPEC "%{shared:-shared} %{static:-static} %{!shared: %{!static: %{rdynamic:-export-dynamic} %{!dynamic-linker:-dynamic-linker /lib/ld.so}}}"
+
+// modify location of the start files
+#undef	STANDARD_STARTFILE_PREFIX
+#define	STANDARD_STARTFILE_PREFIX "/lib/"
but this seems insufficient...
From what I read in another thread the problem is in libtool, that doesn't recognize the cross target, but I didn't find anything that could help me to solve it.

Re: Build shared libstdc++ on cross gcc

Posted: Thu Nov 16, 2017 11:21 am
by Korona
Yes, libtool is the problem.

GCC bundles libtool in ibtool.m4. You need to patch it like this (click me!) or more specifically like this (click again!). Oh god, opening that file reminded me that I called my multilib directories fizz and buzz for debugging purposes and never changed that back to the real names :D.

Building a shared libgcc is a bit different as that requires you to modify the tmake_file variable and add all those t-slibgcc t-slibgcc-gld t-slibgcc-elf-ver t-libgcc-pic options.

By the way, --enable-shared is the default once you configure libtool so that it can build shared libraries (and is overridden if libtool doesn't know how to do it), so you should never need that.

Re: Build shared libstdc++ on cross gcc

Posted: Thu Nov 16, 2017 1:21 pm
by marcxDotdev
Thank you Korona.
Now libtool tries to create .so, but the link process fails with :( :

Code: Select all

MeetiX-OS/toolchain/build/build-gcc/i686-pc-mx/libstdc++-v3/src/c++11/../../../../../gcc-4.9.1/libstdc++-v3/src/c++11/system_error.cc:65: undefined reference to `__dso_handle'
MeetiX-OS/toolchain/MeetiXOSProject/i686-pc-mx/bin/ld: ../src/c++11/.libs/libc++11convenience.a(system_error.o): relocation R_386_GOTOFF against undefined hidden symbol `__dso_handle' can not be used when making a shared object
MeetiX-OS/toolchain/MeetiXOSProject/i686-pc-mx/bin/ld: final link failed: Bad value
From what I have been able to see by analyzing a bit the sources of the library __dso_handle is a symbol that inserts the compiler, but I'm probably missing some configuration parameters, it is not possible that there is such a rough error inside the source :|

Re: Build shared libstdc++ on cross gcc

Posted: Thu Nov 16, 2017 2:22 pm
by Korona
Yes, __dso_handle is a DSO-local variable. Its address is used at some points where a unique per-DSO identifier is required (for example, for __cxa_atexit).

__dso_handle should be defined by libgcc. I think it is in crtbegin.o (crtstuff.c is quite messy). I think you need to link against crtbeginS.o when creating a shared object, just like my GCC patch does (its in the STARTFILE_SPEC/ENDFILE_SPEC).

Re: Build shared libstdc++ on cross gcc

Posted: Thu Nov 16, 2017 3:53 pm
by marcxDotdev
Mmmh, Do I have to compile libgcc as shared too?

Re: Build shared libstdc++ on cross gcc

Posted: Thu Nov 16, 2017 4:12 pm
by Korona
I'm not sure about that but I do think so. GCC internally uses libgcc to perform various operations that it cannot do inline. If libgcc is compiled with -fPIC, it will not correctly link to shared objects.

Re: Build shared libstdc++ on cross gcc

Posted: Fri Nov 17, 2017 9:00 am
by marcxDotdev
I think I should try to create libgcc shared library...
How do I change the libgcc library to create a shared library? You said I should add some variables. Where should I add and what value should they have?

Re: Build shared libstdc++ on cross gcc

Posted: Fri Nov 17, 2017 9:27 am
by Korona
You can just look at my patch to figure that out. The relevant variable is the tmake_file variable which is defined in config.host. The relevant entries are the slibgcc* ones. Appending those entries to the variable tells the build system include makefiles from the libgcc/config directory that in turn build a shared libgcc.

Re: Build shared libstdc++ on cross gcc

Posted: Fri Nov 17, 2017 10:10 am
by marcxDotdev
Ok, now also libgcc creates the shared lib (but only that, I would also need static for my kernel ...), but the undefined reference to '__dso_handle' has remained.
I modified my patch with:

Code: Select all

diff -Nur gcc-4.9.1/libgcc/config.host gcc-4.9.1-mx/libgcc/config.host
--- gcc-4.9.1/libgcc/config.host	2014-03-27 16:40:31.000000000 +0100
+++ gcc-4.9.1-mx/libgcc/config.host	2017-11-17 16:49:50.942408261 +0100
@@ -314,6 +314,16 @@
 esac
 
 case ${host} in
+i[34567]86-*-mx*)
+	extra_parts="$extra_parts crtbegin.o crtend.o"
+	tmake_file="$tmake_file i386/t-crtstuff t-crtstuff-pic t-libgcc-pic"
+    tmake_file="$tmake_file t-slibgcc t-slibgcc-gld t-slibgcc-elf-ver t-libgcc-pic"
+	;;
+x86_64-*-mx*)
+	extra_parts="$extra_parts crtbegin.o crtend.o"
+	tmake_file="$tmake_file i386/t-crtstuff t-crtstuff-pic t-libgcc-pic"
+    tmake_file="$tmake_file t-slibgcc t-slibgcc-gld t-slibgcc-elf-ver t-libgcc-pic"
+	;;
 aarch64*-*-elf)
 	extra_parts="$extra_parts crtbegin.o crtend.o crti.o crtn.o"
 	tmake_file="${tmake_file} ${cpu_type}/t-aarch64"
If is possible i want to build shared and static lib too :oops:

Re: Build shared libstdc++ on cross gcc

Posted: Fri Nov 17, 2017 12:30 pm
by Korona
The issue with __dso_handle should be fixed. Does objdump show whether crtbeginS.o contains __dso_handle? Did you include crtbeginS.o in your specs?

I build a separate compiler for my kernel, so I never bothered with a non-shared libgcc. I don't think using the same libgcc in the kernel and userspace will work in the long term anyway. For example, your kernel won't have pthread functions that libgcc will try to use when they are available. Once you want to build libstdc++ with std::thread support, this will be a problem. I had to do that long ago when I ported Google's protobuf library to my OS (which I now use to compose IPC messages).