I've got an alpha cross compiler on an x86_64 host, that seems to build everything, but I can't get it to compile this simple test program:
#include <stdio.h> /* puts */
#include <stdlib.h> /* atexit */
void fnExit1 (void)
{
puts ("Exit function 1.");
}
void fnExit2 (void)
{
puts ("Exit function 2.");
}
int main ()
{
atexit (fnExit1);
atexit (fnExit2);
puts ("Main function.");
return 0;
}
>alpha-linux-gnu-gcc 1.cpp --sysroot=/opt
cc1plus: warning: '-fstack-protector' not supported for this target
/opt/tools/bin/../lib/gcc/alpha-linux-gnu/14.2.0/../../../../alpha-linux-gnu/bin/ld: /tmp/ccCNt1S8.o: in function `main':
(.text+0xb0): undefined reference to `atexit'
/opt/tools/bin/../lib/gcc/alpha-linux-gnu/14.2.0/../../../../alpha-linux-gnu/bin/ld: (.text+0xc8): undefined reference to `atexit'
collect2: error: ld returned 1 exit status
>alpha-linux-gnu-gcc 1.cpp --sysroot=/opt -lc -L/lib
cc1plus: warning: '-fstack-protector' not supported for this target
/opt/tools/bin/../lib/gcc/alpha-linux-gnu/14.2.0/../../../../alpha-linux-gnu/bin/ld: /tmp/ccAF0OeC.o: in function `main':
(.text+0xb0): undefined reference to `atexit'
/opt/tools/bin/../lib/gcc/alpha-linux-gnu/14.2.0/../../../../alpha-linux-gnu/bin/ld: (.text+0xc8): undefined reference to `atexit'
collect2: error: ld returned 1 exit status
>grep atexit /opt/lib/*so
grep: /opt/lib/libc-2.41.so: binary file matches
grep: /opt/lib/libc.so: binary file matches
nm info against glibc in sysroot:
>alpha-linux-gnu-nm /opt/lib/libc-2.41.so |grep atexit
000000000005ac80 t __GI___cxa_atexit
000000000005ac80 T __cxa_atexit
000000000005b240 T __cxa_thread_atexit_impl
00000000001d5d10 t __dyn_atexit
000000000005ab00 t __internal_atexit
00000000001d5d10 T atexit@GLIBC_2.0
Cross compiler info from build
>alpha-linux-gnu-gcc -v
Using built-in specs.
COLLECT_GCC=alpha-linux-gnu-gcc
COLLECT_LTO_WRAPPER=/opt/tools/bin/../libexec/gcc/alpha-linux-gnu/14.2.0/lto-wrapper
Target: alpha-linux-gnu
Configured with: ../gcc-14.2.0/configure --target=alpha-linux-gnu --prefix=/opt//tools --with-glibc-version=2.41 --with-sysroot=/opt/ --with-newlib --without-headers --enable-default-pie --enable-default-ssp --disable-nls --disable-shared --disable-multilib --disable-threads --disable-libatomic --disable-libgomp --disable-libquadmath --disable-libssp --disable-libvtv --disable-libstdcxx --enable-languages=c,c++
Thread model: single
Supported LTO compression algorithms: zlib zstd
gcc version 14.2.0 (GCC)
Verbose compile with the cross-compiler, as requested:
# alpha-linux-gnu-gcc -v 1.cpp --sysroot=/opt
Using built-in specs.
COLLECT_GCC=alpha-linux-gnu-gcc
COLLECT_LTO_WRAPPER=/opt/tools/bin/../libexec/gcc/alpha-linux-gnu/14.2.0/lto-wrapper
Target: alpha-linux-gnu
Configured with: ../gcc-14.2.0/configure --target=alpha-linux-gnu --prefix=/opt//tools --with-glibc-version=2.41 --with-sysroot=/opt/ --with-newlib --without-headers --enable-default-pie --enable-default-ssp --disable-nls --disable-shared --disable-multilib --disable-threads --disable-libatomic --disable-libgomp --disable-libquadmath --disable-libssp --disable-libvtv --disable-libstdcxx --enable-languages=c,c++
Thread model: single
Supported LTO compression algorithms: zlib zstd
gcc version 14.2.0 (GCC)
COLLECT_GCC_OPTIONS='-v' '--sysroot=/opt' '-dumpdir' 'a-'
/opt/tools/bin/../libexec/gcc/alpha-linux-gnu/14.2.0/cc1plus -quiet -v -iprefix /opt/tools/bin/../lib/gcc/alpha-linux-gnu/14.2.0/ -isysroot /opt 1.cpp -quiet -dumpdir a- -dumpbase 1.cpp -dumpbase-ext .cpp -version -o /tmp/ccLFcKBK.s
GNU C++17 (GCC) version 14.2.0 (alpha-linux-gnu)
compiled by GNU C version 14.2.0, GMP version 6.3.0, MPFR version 4.2.2, MPC version 1.3.1, isl version isl-0.27-GMP
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
ignoring duplicate directory "/opt/tools/bin/../lib/gcc/../../lib/gcc/alpha-linux-gnu/14.2.0/../../../../alpha-linux-gnu/include/c++/14.2.0"
ignoring duplicate directory "/opt/tools/bin/../lib/gcc/../../lib/gcc/alpha-linux-gnu/14.2.0/../../../../alpha-linux-gnu/include/c++/14.2.0/alpha-linux-gnu"
ignoring duplicate directory "/opt/tools/bin/../lib/gcc/../../lib/gcc/alpha-linux-gnu/14.2.0/../../../../alpha-linux-gnu/include/c++/14.2.0/backward"
ignoring duplicate directory "/opt/tools/bin/../lib/gcc/../../lib/gcc/alpha-linux-gnu/14.2.0/include"
ignoring duplicate directory "/opt/tools/bin/../lib/gcc/../../lib/gcc/alpha-linux-gnu/14.2.0/include-fixed"
ignoring duplicate directory "/opt/tools/bin/../lib/gcc/../../lib/gcc/alpha-linux-gnu/14.2.0/../../../../alpha-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
/opt/tools/bin/../lib/gcc/alpha-linux-gnu/14.2.0/../../../../alpha-linux-gnu/include/c++/14.2.0
/opt/tools/bin/../lib/gcc/alpha-linux-gnu/14.2.0/../../../../alpha-linux-gnu/include/c++/14.2.0/alpha-linux-gnu
/opt/tools/bin/../lib/gcc/alpha-linux-gnu/14.2.0/../../../../alpha-linux-gnu/include/c++/14.2.0/backward
/opt/tools/bin/../lib/gcc/alpha-linux-gnu/14.2.0/include
/opt/tools/bin/../lib/gcc/alpha-linux-gnu/14.2.0/include-fixed
/opt/tools/bin/../lib/gcc/alpha-linux-gnu/14.2.0/../../../../alpha-linux-gnu/include
/opt/usr/local/include
/opt/usr/include
End of search list.
cc1plus: warning: '-fstack-protector' not supported for this target
Compiler executable checksum: 1f850107005d162dc105cc0cda692399
COLLECT_GCC_OPTIONS='-v' '--sysroot=/opt' '-dumpdir' 'a-'
/opt/tools/bin/../lib/gcc/alpha-linux-gnu/14.2.0/../../../../alpha-linux-gnu/bin/as -v -o /tmp/ccrw7cHl.o /tmp/ccLFcKBK.s
GNU assembler version 2.44 (alpha-linux-gnu) using BFD version (GNU Binutils) 2.44
COMPILER_PATH=/opt/tools/bin/../libexec/gcc/alpha-linux-gnu/14.2.0/:/opt/tools/bin/../libexec/gcc/:/opt/tools/bin/../lib/gcc/alpha-linux-gnu/14.2.0/../../../../alpha-linux-gnu/bin/
LIBRARY_PATH=/opt/tools/bin/../lib/gcc/alpha-linux-gnu/14.2.0/:/opt/tools/bin/../lib/gcc/:/opt/tools/bin/../lib/gcc/alpha-linux-gnu/14.2.0/../../../../alpha-linux-gnu/lib/:/opt/lib/:/opt/usr/lib/
COLLECT_GCC_OPTIONS='-v' '--sysroot=/opt' '-dumpdir' 'a.'
/opt/tools/bin/../libexec/gcc/alpha-linux-gnu/14.2.0/collect2 -plugin /opt/tools/bin/../libexec/gcc/alpha-linux-gnu/14.2.0/liblto_plugin.so -plugin-opt=/opt/tools/bin/../libexec/gcc/alpha-linux-gnu/14.2.0/lto-wrapper -plugin-opt=-fresolution=/tmp/cc3JrLwT.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc --sysroot=/opt --eh-frame-hdr -m elf64alpha -O1 -dynamic-linker /lib/ld-linux.so.2 -pie /opt/usr/lib/crt1.o /opt/usr/lib/crti.o /opt/tools/bin/../lib/gcc/alpha-linux-gnu/14.2.0/crtbegin.o -L/opt/tools/bin/../lib/gcc/alpha-linux-gnu/14.2.0 -L/opt/tools/bin/../lib/gcc -L/opt/tools/bin/../lib/gcc/alpha-linux-gnu/14.2.0/../../../../alpha-linux-gnu/lib -L/opt/lib -L/opt/usr/lib /tmp/ccrw7cHl.o -lgcc -lc -lgcc /opt/tools/bin/../lib/gcc/alpha-linux-gnu/14.2.0/crtend.o /opt/usr/lib/crtn.o
/opt/tools/bin/../lib/gcc/alpha-linux-gnu/14.2.0/../../../../alpha-linux-gnu/bin/ld: /tmp/ccrw7cHl.o: in function `main':
(.text+0xb0): undefined reference to `atexit'
/opt/tools/bin/../lib/gcc/alpha-linux-gnu/14.2.0/../../../../alpha-linux-gnu/bin/ld: (.text+0xc8): undefined reference to `atexit'
collect2: error: ld returned 1 exit status
################################################################################################################################################
I took the LD_LIBRARY list and took a look, and no, all I have are the cross compiled root (/opt):
# for x in `echo "/opt/tools/bin/../lib/gcc/alpha-linux-gnu/14.2.0/:/opt/tools/bin/../lib/gcc/:/opt/tools/bin/../lib/gcc/alpha-linux-gnu/14.2.0/../../../../alpha-linux-gnu/lib/:/opt/lib/:/opt/usr/lib/" |tr ":" "\n"` ; do ls -al $x/libc* 2>/dev/null; done
-rwxr-xr-x 1 root root 12206288 May 20 13:42 /opt/lib//libc-2.41.so*
lrwxrwxrwx 1 root root 12 May 20 14:06 /opt/lib//libc.so -> libc-2.41.so*
lrwxrwxrwx 1 root root 12 May 20 13:16 /opt/lib//libc.so.6 -> libc-2.41.so*
lrwxrwxrwx 1 root root 12 May 20 14:06 /opt/lib//libc.so.6.1 -> libc-2.41.so*
lrwxrwxrwx 1 root root 17 May 20 13:16 /opt/lib//libcrypt.so.1 -> libcrypt1-2.41.so*
lrwxrwxrwx 1 root root 17 May 20 13:16 /opt/lib//libcrypt.so.2 -> libcrypt2-2.41.so*
-rwxr-xr-x 1 root root 410744 May 20 13:44 /opt/lib//libcrypt1-2.41.so*
-rwxr-xr-x 1 root root 409464 May 20 13:44 /opt/lib//libcrypt2-2.41.so*
-rw-r--r-- 1 root root 30198284 May 20 12:53 /opt/usr/lib//libc.a
lrwxrwxrwx 1 root root 11 May 20 16:18 /opt/usr/lib//libc.so -> libc.so.6.1*
-rwxr-xr-x 1 root root 12206288 May 20 12:53 /opt/usr/lib//libc.so.6.1*
-rw-r--r-- 1 root root 249 May 20 12:53 /opt/usr/lib//libc.so.hold
lrwxrwxrwx 1 root root 22 May 20 13:16 /opt/usr/lib//libc_malloc_debug.so -> libc_malloc_debug.so.0*
-rwxr-xr-x 1 root root 251808 May 20 12:53 /opt/usr/lib//libc_malloc_debug.so.0*
-rw-r--r-- 1 root root 18962 May 20 12:53 /opt/usr/lib//libc_nonshared.a
-rw-r--r-- 1 root root 30477670 May 20 12:53 /opt/usr/lib//libc_p.a
-rw-r--r-- 1 root root 362888 May 20 12:57 /opt/usr/lib//libcrypt.a
lrwxrwxrwx 1 root root 23 May 20 13:16 /opt/usr/lib//libcrypt.so -> ../../lib/libcrypt.so.2*
lrwxrwxrwx 1 root root 21 May 19 16:39 /opt/usr/lib//libctf-nobfd.so -> libctf-nobfd.so.0.0.0*
lrwxrwxrwx 1 root root 21 May 19 16:39 /opt/usr/lib//libctf-nobfd.so.0 -> libctf-nobfd.so.0.0.0*
-rwxr-xr-x 1 root root 1616752 May 19 16:39 /opt/usr/lib//libctf-nobfd.so.0.0.0*
lrwxrwxrwx 1 root root 15 May 19 16:39 /opt/usr/lib//libctf.so -> libctf.so.0.0.0*
lrwxrwxrwx 1 root root 15 May 19 16:39 /opt/usr/lib//libctf.so.0 -> libctf.so.0.0.0*
-rwxr-xr-x 1 root root 1465552 May 19 16:39 /opt/usr/lib//libctf.so.0.0.0*
Your program:
$ cat 1.cpp
#include <stdio.h> /* puts */
#include <stdlib.h> /* atexit */
void fnExit1 (void)
{
puts ("Exit function 1.");
}
void fnExit2 (void)
{
puts ("Exit function 2.");
}
int main ()
{
atexit (fnExit1);
atexit (fnExit2);
puts ("Main function.");
return 0;
}
links successfully for me on:
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 24.04.2 LTS
Release: 24.04
Codename: noble
if I do:
$ sudo apt install gcc-alpha-linux-gnu g++-alpha-linux-gnu
...[cut]...
$ alpha-linux-gnu-gcc 1.cpp
$ file a.out
a.out: ELF 64-bit LSB executable, Alpha (unofficial), version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, BuildID[sha1]=685ad826db93d1c5393d323e944517eb433b566b, for GNU/Linux 3.2.0, not stripped
I installed g++-alpha-linux-gnu
even though I'm just running alpha-linux-gnu-gcc
because
for your example you compile C source in a file 1.cpp
that the frontend will identify as C++ source and
for which it will invoke the C++ compiler, cc1plus
, as your verbose build log shows. Happily the
GNU Standard C header files that you #include
are equipped with conditional extern C
declarations,
so this does not cause me any undefined reference linkage failure, and isn't the cause of yours.
We can see where atexit
is successfully resolved by repeating the linkage to request that information:
$ alpha-linux-gnu-gcc 1.cpp -Wl,-trace-symbol=atexit
/usr/lib/gcc-cross/alpha-linux-gnu/13/../../../../alpha-linux-gnu/bin/ld: /tmp/ccaDrpG3.o: reference to atexit
/usr/lib/gcc-cross/alpha-linux-gnu/13/../../../../alpha-linux-gnu/bin/ld: /usr/alpha-linux-gnu/lib/libc_nonshared.a(atexit.oS): definition of atexit
The definition comes from archive member /usr/alpha-linux-gnu/lib/libc_nonshared.a(atexit.oS)
. Modulo the <prefix>/<target>
= /usr/alpha-linux-gnu
, this is normal.
This will lead us to see how your cross installation is broken
We can see from your verbose build log that -lc_nonshared
is not present. Take my word
that it isn't in mine either. So how does my linkage succeed?
It succeeds because -lc
is present, and -lc
is resolved to my:
/usr/alpha-linux-gnu/lib/libc.so
which is not actually a shared library but is:
$ file /usr/alpha-linux-gnu/lib/libc.so
/usr/alpha-linux-gnu/lib/libc.so: ASCII text
$ cat /usr/alpha-linux-gnu/lib/libc.so
/* GNU ld script
Use the shared library, but some functions are only in
the static library, so try that secondarily. */
OUTPUT_FORMAT(elf64-alpha)
GROUP ( /usr/alpha-linux-gnu/lib/libc.so.6.1 /usr/alpha-linux-gnu/lib/libc_nonshared.a AS_NEEDED ( /usr/alpha-linux-gnu/lib/ld-linux.so.2 ) )
an incremental linker script, which pulls in both the real GLIBC shared library:
/usr/alpha-linux-gnu/lib/libc.so.6.1
plus:
/usr/alpha-linux-gnu/lib/libc_nonshared.a
in which atexit
is defined.
Again, this is normal. If you want to understand the motivation of these shenanigans, see What is the purpose of libc_nonshared.a?
But it is not so in your case. We can see from the listing of your /opt/usr/lib
that:
lrwxrwxrwx 1 root root 11 May 20 16:18 /opt/usr/lib//libc.so -> libc.so.6.1*
libc.so
is simply a symlink to libc.so.6.1
.
And libc.so.6.1
does not resolve your reference to atexit
.
Why not?
That reference:
$ alpha-linux-gnu-gcc -c 1.cpp
$ readelf -sW 1.o | grep atexit
12: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND atexit
is an unversioned external reference. Your libc.so.6.1
defines:
$ readelf -sW /usr/alpha-linux-gnu/lib/libc.so.6.1 | grep atexit
466: 00000000001924d0 56 FUNC GLOBAL DEFAULT [STD GPLOAD] 12 atexit@GLIBC_2.0
1114: 000000000004a960 344 FUNC GLOBAL DEFAULT [STD GPLOAD] 12 __cxa_thread_atexit_impl@@GLIBC_2.18
1823: 000000000004a680 28 FUNC GLOBAL DEFAULT [STD GPLOAD] 12 __cxa_atexit@@GLIBC_2.1.3
only the versioned atexit@GLIBC_2.0
. And this is not a default version - which would be
atexit@@GLIBC_2.0
, with double @
- so it will only, by intent, resolve references to atexit@GLIBC_2.0
,
not references to unversioned atexit
. To resolve unversioned atexit
, trusting the linker to find the right definition, you are supposed to link libc_unshared.a
, which you don't, because your libc.so
is not the band-aid linker script that it ought to be.
Fixes?
If you can, get rid of your existing alpha-linux-gnu-(gcc|g++)
cross installation
and replace it with your package-manager's, which should work.
If you can't get rid of it then as root replace your libc.so
symlink with
an incremental linker script as per my /usr/alpha-linux-gnu/lib/libc.so
above,
with the paths corrected for your installation. But in that case I wouldn't be suprised if other problems surface.