Error compiling against libopcodes - c

I'm following some code from here which is as follows:
The OP says that you can link with -lbfd -lopcodes.
However, for OpenSuSE I've found that for libbfd I need -lbfd -liberty -lz -ldl
When trying to compile, here is my results:
make
gcc ./main.c -lbfd -liberty -lz -ldl -lopcodes -g -o bfd_se
/usr/lib64/gcc/x86_64-suse-linux/4.8/../../../../lib64/libopcodes.a(arm-dis.o): In function `print_insn_neon':
/home/abuild/rpmbuild/BUILD/binutils-2.24/build-dir/opcodes/../../opcodes/arm-dis.c:2927: undefined reference to `floatformat_ieee_single_little'
/home/abuild/rpmbuild/BUILD/binutils-2.24/build-dir/opcodes/../../opcodes/arm-dis.c:2927: undefined reference to `floatformat_to_double'
/usr/lib64/gcc/x86_64-suse-linux/4.8/../../../../lib64/libopcodes.a(m68k-dis.o): In function `print_insn_arg':
/home/abuild/rpmbuild/BUILD/binutils-2.24/build-dir/opcodes/../../opcodes/m68k-dis.c:1103: undefined reference to `floatformat_m68881_ext'
/home/abuild/rpmbuild/BUILD/binutils-2.24/build-dir/opcodes/../../opcodes/m68k-dis.c:1103: undefined reference to `floatformat_to_double'
/home/abuild/rpmbuild/BUILD/binutils-2.24/build-dir/opcodes/../../opcodes/m68k-dis.c:1099: undefined reference to `floatformat_ieee_double_big'
/home/abuild/rpmbuild/BUILD/binutils-2.24/build-dir/opcodes/../../opcodes/m68k-dis.c:1099: undefined reference to `floatformat_to_double'
/home/abuild/rpmbuild/BUILD/binutils-2.24/build-dir/opcodes/../../opcodes/m68k-dis.c:1095: undefined reference to `floatformat_ieee_single_big'
/home/abuild/rpmbuild/BUILD/binutils-2.24/build-dir/opcodes/../../opcodes/m68k-dis.c:1095: undefined reference to `floatformat_to_double'
collect2: error: ld returned 1 exit status
Makefile:4: recipe for target 'bfd_se' failed
make: *** [bfd_se] Error 1
What other flags do I need to add to have this program compile? I see the error is related to different architectures, but I'm not trying to cross compile.
Thanks!
useful information:
uname -a
Linux node 4.0.5-THS_on #1 SMP PREEMPT Thu Jun 18 16:37:06 CDT 2015 x86_64 x86_64 x86_64 GNU/Linux
gcc --version
gcc (SUSE Linux) 4.8.3 20140627 [gcc-4_8-branch revision 212064]
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
objdump --version (it uses libbfd and libopcodes)
GNU objdump (GNU Binutils; openSUSE 13.2) 2.24.0.20140403-6.1
Copyright 2013 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or (at your option) any later version.
This program has absolutely no warranty.

Most of the time libbfd and libopcodes does not come as shared libraries in standard distributions (because they are not meant to be linked to). You must either link to the static libraries (libbfd.a and libopcodes.a) or recompile your distribution package and include the shared libraries in it (.so files).
So, to make it clear, try:
gcc ./main.c -liberty -lz -ldl -g -o bfd_se /usr/lib64/gcc/x86_64-suse-linux/4.8/../../../../lib64/libopcodes.a /usr/lib64/gcc/x86_64-suse-linux/4.8/../../../../lib64/libbfd.a

Related

What is the proper way to build archived intel tbb on Mac m1

Recently I have been trying to compile an older application for Mac M1, I have so far been successful in compiling and linking all requirements except for the last, TBB.
The application uses an older version of TBB, 2019_U9 11009.
Here is my attempt to make it using gmake on Mac M1:
oneTBB-2019_U9 ❯ gmake --debug=v
GNU Make 4.3
Built for arm-apple-darwin20.2.0
Copyright (C) 1988-2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Reading makefiles...
Reading makefile 'Makefile'...
Reading makefile 'build/common.inc' (search path) (no ~ expansion)...
Reading makefile 'build/macos.inc' (search path) (no ~ expansion)...
Updating makefiles....
Updating goal targets....
Considering target file 'default'.
File 'default' does not exist.
Considering target file 'tbb'.
File 'tbb' does not exist.
Considering target file 'mkdir'.
File 'mkdir' does not exist.
Finished prerequisites of target file 'mkdir'.
Must remake target 'mkdir'.
Created ./build/macos_ia32_clang_cc_os11.3.1_release and ..._debug directories
Successfully remade target file 'mkdir'.
Finished prerequisites of target file 'tbb'.
Must remake target 'tbb'.
gmake -C "./build/macos_ia32_clang_cc_os11.3.1_debug" -r -f ../../build/Makefile.tbb cfg=debug
GNU Make 4.3
Built for arm-apple-darwin20.2.0
Copyright (C) 1988-2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Reading makefiles...
Reading makefile '../../build/Makefile.tbb'...
Reading makefile '../../build/common.inc' (search path) (no ~ expansion)...
Reading makefile '../../build/macos.inc' (search path) (no ~ expansion)...
Reading makefile '../../build/macos.clang.inc' (search path) (no ~ expansion)...
gmake[1]: Entering directory '/Users/trisimix/Hacking/ikos/tbb/oneTBB-2019_U9/build/macos_ia32_clang_cc_os11.3.1_debug'
At this point it will hang for hours.
Here is what happens with I use make:
oneTBB-2019_U9 ❯ make
Created ./build/macos_ia32_clang_cc_os11.3.1_release and ..._debug directories
/Applications/Xcode.app/Contents/Developer/usr/bin/make -C "./build/macos_ia32_clang_cc_os11.3.1_debug" -r -f ../../build/Makefile.tbb cfg=debug
../../build/Makefile.tbb:28: CONFIG: cfg=debug arch=ia32 compiler=clang target=macos runtime=cc_os11.3.1
clang++ -fPIC -o libtbb_debug.dylib concurrent_hash_map.o concurrent_queue.o concurrent_vector.o dynamic_link.o itt_notify.o cache_aligned_allocator.o pipeline.o queuing_mutex.o queuing_rw_mutex.o reader_writer_lock.o spin_rw_mutex.o x86_rtm_rw_mutex.o spin_mutex.o critical_section.o mutex.o recursive_mutex.o condition_variable.o tbb_thread.o concurrent_monitor.o semaphore.o private_server.o rml_tbb.o tbb_misc.o tbb_misc_ex.o task.o task_group_context.o governor.o market.o arena.o scheduler.o observer_proxy.o tbb_statistics.o tbb_main.o concurrent_vector_v2.o concurrent_queue_v2.o spin_rw_mutex_v2.o task_v2.o -ldl -lpthread -dynamiclib -install_name #rpath/libtbb_debug.dylib -stdlib=libc++ -m32 -mmacosx-version-min=10.11 -Wl,-exported_symbols_list,tbb.def
ld: unknown/unsupported architecture name for: -arch armv4t
clang-13: error: linker command failed with exit code 1 (use -v to see invocation)
make[1]: *** [libtbb_debug.dylib] Error 1
make: *** [tbb] Error 2
You can give it a try with the below command:
make arch=arm64 compiler=clang -j 16
-->You can get the "arch" value from the command :
/usr/bin/arch
Also please note that you need to meet the system requirements as mentioned below:
Systems with OS X* or macOS* operating systems
OS X* 10.11
macOS* 10.12, 10.13 are only supported for using oneTBB2019u9.

Linking error: selective static linking of libm.a in GCC

I want to selectively link libm.a statically, all the other libraries (libc.so included) dinamically. But if I use the math functions from math.h, it almost always fails to link correctly. Why?
And why does it work sometimes? (For example if I only use sqrt, fabs or, strangely, tanh, it seems to link correctly)
myscript.sh:
#!/bin/bash
for i in sqrt tanh sin tan
do
echo "-----$i----------"
sed "s/ciao/$i/" prova.c >provat.c
gcc provat.c -fno-builtin -l:libm.a
[[ $? -eq 0 ]] && { echo -n "$i(2.0)="; ./a.out; echo " OK!"; }
echo
done
prova.c:
#include <stdio.h>
#include <math.h>
int main()
{
printf("%f", ciao(2.0));
return 0;
}
If I run myscript.sh, I can see that sqrt and tanh give no problems. sin and tan, instead, fail to link:
$./myscript.sh
-----sqrt----------
sqrt(2.0)=1.414214 OK!
-----tanh----------
tanh(2.0)=0.964028 OK!
-----sin----------
/usr/lib/x86_64-linux-gnu/libm-2.27.a(s_sin.o): In function `__sin_ifunc':
(.text+0x4d42): undefined reference to `_dl_x86_cpu_features'
/usr/lib/x86_64-linux-gnu/libm-2.27.a(s_sin.o): In function `__cos_ifunc':
(.text+0x4da2): undefined reference to `_dl_x86_cpu_features'
collect2: error: ld returned 1 exit status
-----tan----------
/usr/lib/x86_64-linux-gnu/libm-2.27.a(s_tan.o): In function `__tan_ifunc':
(.text+0x5782): undefined reference to `_dl_x86_cpu_features'
collect2: error: ld returned 1 exit status
I don't understand these error messages. Can somebody explain what happens?
Why can't I link libm.a statically (and the rest dinamically)? And why does it work sometimes?
Note: I use the -fno-builtin flag to GCC, so that GCC doesn't use any of its builtin functions. So the problem is not there.
It's not very clear (to me) why the restriction (libm.a + libc.so) is necessary, so it smells like an XY Problem.
According to [RedHat.Bugzilla]: Bug 1433347 - glibc: Selective static linking of libm.a fails due to unresolved _dl_x86_cpu_features symbol (pointed out by #KamilCuk):
This is not supported.
You would be mixing a static libm.a with future libc.so.6 and ld.so and that breaks the interdependencies between the core libraries which form "the implemetnation of the C runtime."
Either the entire implementation of the runtime is statically linked or none of it is statically linked. You can't choose to link parts of it statically and not others because each part depends on the other to form a complete implementation. The math library is not a thin you can link against statically, it happens we have a libm.a, but that's an implementation detail.
Please use '-static' for the entire application.
it seems like it's an unsupported configuration. That makes sense, but it's also a little bit confusing: even if libc and libm are 2 separate files on disk (for each configuration: static, shared), they are part of the same library (glibc), so:
It's not OK to use half of a library statically built, and the other half as a shared object (some things that come into my mind are: gcc's -fPIC flag, and also library's initialization)
Of course, most of the times, a library consists of a single file, so the above bullet wouldn't apply (there's where the confusion comes from)
From the beginning, I suspected that it's some code that (detects and) uses (if present) some CPU capabilities (most likely to improve speed or accuracy), that:
Is only used by some of the (trigonometric) functions (like sin, cos, but not tanh) - I'm just guessing here: based on how the function values are computed (e.g. Taylor series)
It only happens when libc (libm) are in sync
I used this simple program.
main.c:
#include <stdio.h>
#include <math.h>
#if !defined(FUNC)
# define FUNC sqrt
#endif
int main() {
double val = 3.141592;
printf("func(%.06lf): %.06lf\n", val, FUNC(val));
return 0;
}
Below it's a series of steps that I followed when looking into the problem:
Environment:
[cfati#cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q056415996]> ~/sopr.sh
*** Set shorter prompt to better fit when pasted in StackOverflow (or other) pages ***
[prompt]> uname -a
Linux cfati-ubtu16x64-0 4.15.0-51-generic #55~16.04.1-Ubuntu SMP Thu May 16 09:24:37 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
[prompt]> gcc --version
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.11) 5.4.0 20160609
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
[prompt]> ldd --version
ldd (Ubuntu GLIBC 2.23-0ubuntu11) 2.23
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Written by Roland McGrath and Ulrich Drepper.
[prompt]> ls
main.c
The case when the 2 library parts (libc and libm) are in sync:
[prompt]> gcc -fPIC main.c -DFUNC=sin -o sin_static.out -static -lm
[prompt]> ll sin_static.out
-rwxrwxr-x 1 cfati cfati 1007744 Jun 13 20:08 sin_static.out
[prompt]> ldd sin_static.out
not a dynamic executable
[prompt]> ./sin_static.out
func(3.141592): 0.000001
[prompt]>
[prompt]> gcc -fPIC main.c -DFUNC=sin -o sin_mso.out -l:libm.so
[prompt]> ll sin_mso.out
-rwxrwxr-x 1 cfati cfati 8656 Jun 13 20:09 sin_mso.out
[prompt]> ldd sin_mso.out
linux-vdso.so.1 => (0x00007ffc80ddd000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f999636b000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f9995fa1000)
/lib64/ld-linux-x86-64.so.2 (0x00007f9996674000)
[prompt]> ./sin_mso.out
func(3.141592): 0.000001
Everything works fine in both cases.
Switch to libm.a (for sin and tanh):
[prompt]> gcc -fPIC main.c -DFUNC=sin -o sin_ma.out -l:libm.a
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libm.a(s_sin.o): In function `__cos':
(.text+0x3542): undefined reference to `_dl_x86_cpu_features'
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libm.a(s_sin.o): In function `__sin':
(.text+0x3572): undefined reference to `_dl_x86_cpu_features'
collect2: error: ld returned 1 exit status
[prompt]> ll sin_ma.out
ls: cannot access 'sin_ma.out': No such file or directory
[prompt]>
[prompt]> gcc -fPIC main.c -DFUNC=tanh -o tanh_ma.out -l:libm.a
[prompt]> ll tanh_ma.out
-rwxrwxr-x 1 cfati cfati 12856 Jun 13 20:10 tanh_ma.out
[prompt]> ldd tanh_ma.out
linux-vdso.so.1 => (0x00007ffcfa531000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f124625c000)
/lib64/ld-linux-x86-64.so.2 (0x00007f1246626000)
[prompt]> ./tanh_ma.out
func(3.141592): 0.996272
As seen:
For sin, the linker complained (even without -fno-builtin)
For tanh, things went fine
From now on, I'm going to focus on the case that doesn't work.
Play a bit with the linker flags (man ld ([die.linux]: ld(1) - Linux man page)):
[prompt]> gcc -fPIC main.c -DFUNC=sin -o sin_ma_undefined.out -l:libm.a -Wl,--warn-unresolved-symbols
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libm.a(s_sin.o): In function `__cos':
(.text+0x3542): warning: undefined reference to `_dl_x86_cpu_features'
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libm.a(s_sin.o): In function `__sin':
(.text+0x3572): warning: undefined reference to `_dl_x86_cpu_features'
[prompt]> ll sin_ma_undefined.out
-rwxrwxr-x 1 cfati cfati 104088 Jun 13 20:10 sin_ma_undefined.out
[prompt]> ldd sin_ma_undefined.out
linux-vdso.so.1 => (0x00007fff984b0000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f274ad00000)
/lib64/ld-linux-x86-64.so.2 (0x00007f274b0ca000)
[prompt]> ./sin_ma_undefined.out
Segmentation fault (core dumped)
It passed the link phase, but segfaulted at runtime (which was kind of expected).
Came across [Amper.Git]: open-source/glibc - Add _dl_x86_cpu_features to rtld_global (note that none of that is in the official glibc: [GNU]: Index of /gnu/libc). It's some pretty heavy stuff there. I "borrowed" some and saved it.
_dl_x86_cpu_features.c:
#if defined(_DL_X86_CPU_FEATURES__WORKAROUND)
# define FEATURE_INDEX_MAX 1
enum {
COMMON_CPUID_INDEX_1 = 0,
COMMON_CPUID_INDEX_7,
COMMON_CPUID_INDEX_80000001, // for AMD
// Keep the following line at the end.
COMMON_CPUID_INDEX_MAX
};
struct cpu_features {
enum cpu_features_kind {
arch_kind_unknown = 0,
arch_kind_intel,
arch_kind_amd,
arch_kind_other
} kind;
int max_cpuid;
struct cpuid_registers {
unsigned int eax;
unsigned int ebx;
unsigned int ecx;
unsigned int edx;
} cpuid[COMMON_CPUID_INDEX_MAX];
unsigned int family;
unsigned int model;
unsigned int feature[FEATURE_INDEX_MAX];
};
struct cpu_features _dl_x86_cpu_features;
#endif
#include "_dl_x86_cpu_features.c" also needs to be added in main.c:
[prompt]> gcc -fPIC main.c -DFUNC=sin -D_DL_X86_CPU_FEATURES__WORKAROUND -o sin_ma_workaround.out -l:libm.a
[prompt]> ll sin_ma_workaround.out
-rwxrwxr-x 1 cfati cfati 104088 Jun 13 20:13 sin_ma_workaround.out
[prompt]> ldd sin_ma_workaround.out
linux-vdso.so.1 => (0x00007fff17b6c000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f5a992e5000)
/lib64/ld-linux-x86-64.so.2 (0x00007f5a996af000)
[prompt]> ./sin_ma_workaround.out
func(3.141592): 0.000001
Apparently, it works (at least in my environment)!!!
Although it did the trick for me (and probably it will be the same in your case), I still consider it a workaround (gainarie), and I'm not aware of the full implications. So, my advice is to go with (either one of) the recommended options (from step #2.). But, it would be interesting to see how other compilers behave.

Compiling for rx600 with gcc

I have a project that compiles for an RX600 with renasas' gcc compiler (from now on rx-elf-gcc). But I was wondering, shouldn't I be able to compile it with standard gcc? And if, how?
I'm making a docker container for the project, and I would prefere if I did not have to install renesas' compiler, installing it and supplying the activation code, etc.
I have found this piece of documentation, that got me started
https://gcc.gnu.org/onlinedocs/gcc-7.3.0/gcc/RX-Options.html
I then expected to be able to do something like:
$ gcc -mcpu=rx600 -mlittle-endian-data dummy.c
But it gives the error:
gcc: warning: ‘-mcpu=’ is deprecated; use ‘-mtune=’ or ‘-march=’ instead
gcc: error: unrecognized command line option ‘-mlittle-endian-data’
I have tried using -mtune instead, but it seems rx is not a valid option
$ gcc -mtune=rx600 dummy.c
cc1: error: bad value (‘rx600’) for ‘-mtune=’ switch
cc1: note: valid arguments to ‘-mtune=’ switch are: nocona core2 nehalem corei7 westmere sandybridge corei7-avx ivybridge core-avx-i haswell core-avx2 broadwell skylake skylake-avx512 bonnell atom silvermont slm knl intel x86-64 eden-x2 nano nano-1000 nano-2000 nano-3000 nano-x2 eden-x4 nano-x4 k8 k8-sse3 opteron opteron-sse3 athlon64 athlon64-sse3 athlon-fx amdfam10 barcelona bdver1 bdver2 bdver3 bdver4 znver1 btver1 btver2 generic
So, can I add a new hardware model to my installation? Or will these models just simply redirect my to rx-elf-gcc?
As a side note:
$ gcc --version
gcc (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ rx-elf-gcc --version
rx-elf-gcc (GCC_Build_20180315) 4.8.4.201801-GNURX
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
And the following works:
$ rx-elf-gcc -mcpu=rx600 -mlittle-endian-data -c dummy.c

Make and apply apue.h

I started to learn APUE* and compile the source code
Download the source code from Source Code
Extract it to
$ pwd
/Users/me/Desktop/PubRepo/C/APUE/apue.3e
Read readme
$ cat readme
Read the file called DISCLAIMER.
On Freebsd, type "gmake".
On other platforms, type "make" (as long as this is gnu make).
For FAQs, updated source code, and the lost chapter, see http://www.apuebook.com.
Please direct questions, suggestions, and bug reports to sar#apuebook.com.
Steve Rago
January 2013
I checked make version
$ make --version
GNU Make 3.81
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
This program built for i386-apple-darwin11.3.0
make but report error:
gcc -ansi -I../include -Wall -DMACOS -D_DARWIN_C_SOURCE -c -o sleep.o sleep.c
making intro
gcc -ansi -I../include -Wall -DMACOS -D_DARWIN_C_SOURCE getcputc.c -o getcputc -L../lib -lapue
ld: archive has no table of contents file '../lib/libapue.a' for architecture x86_64
clang: error: unable to execute command: Segmentation fault: 11
clang: error: linker command failed due to signal (use -v to see invocation)
make[1]: *** [getcputc] Error 254
make: *** [all] Error 1
I searched and found answer to add cp ./lib/error.c /usr/local/include/
$ cp ./lib/error.c /usr/local/include/
make clean and make
making intro
gcc -ansi -I../include -Wall -DMACOS -D_DARWIN_C_SOURCE getcputc.c -o getcputc -L../lib -lapue
ld: archive has no table of contents file '../lib/libapue.a' for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[1]: *** [getcputc] Error 1
make: *** [all] Error 1
The error is still there.
How could I apply apue.h?
* W Richard Stevens, Stephen A Rago
Advanced Programming in the Unix Environment, 3rd Edn, 2013.
I downloaded the APUE source to a Mac running macOS 10.14.1 Mojave with XCode 10.1 installed (see also Can't compile a C program on a Mac after upgrade to Mojave).
I then ran make CC=/usr/bin/clang (using /usr/bin/gcc is also OK) to use that instead of a home-built GCC 8.2.0, which failed in the db subdirectory. If you don't have any non-standard version of GCC installed on your PATH ahead of /usr/bin/gcc or /usr/bin/clang, you shouldn't need the CC=… argument.
This did a lot of building — all of it successfully (once I'd specified the compiler explicitly; I got an error on the -R. argument with the home-built GCC).
Make sure you have XCode properly installed. Worry about the Command Line Tools — see the "Can't compile" question for information on where to get them. You shouldn't need /usr/include for this, but it is likely to make life easier; again, see the "Can't compiler" question for how to install /usr/include.
There is an answer here from #makhlaghi that helped me a long time ago.
https://unix.stackexchange.com/questions/105483/compiling-code-from-apue.
Here is the answer that worked for me:
A short review of how to write and compile the programs in Advanced Programming in the UNIX® Environment, thanks to slm for helping me understand the steps. You can download the source code from here. I wish this information was included as part of appendix b of the book, where the header file is explained.
The uncompressed file contains directories with the names of the chapters and two others named include and lib. The ones with the names of the chapters have all the programs of that chapter in them.
The include directory contains the header file that is used in most of the programs in the book: apue.h. The lib directory has the source code of the implementations for the that header.
Lets assume the uncompressed file is located at: SCADDRESS/, for example it might be: /home/yourid/Downloads/apue.3e/
Once you uncompress the source code, go in the directory and run make:
$ cd SCADDRESS
$ make
make will compile all the programs in all the chapters. But the important thing is that before that, it will make the library that will contain the implementations of the functions in apue.h.
To compile an example program that you write from the book, run this GCC command (assuming your program's name is myls.c which is the first in the book):
gcc -o myls myls.c -I SCADDRESS/include/ -L SCADDRESS/lib/ -lapue
-I tells gcc which directory to look for the include file. -L tells it the location of the library directory, and -lapue, tells the name of the library file to look for in that directory. Such that -LXXX means to look for a file in the library directory with the name: libXXX.a or libXXX.so.

Creating a shared library with main() [duplicate]

This question already has answers here:
How to make a linux shared object (library) runnable on its own?
(2 answers)
Closed 5 years ago.
In glibc (and also EGLIBC I believe), the libc.so library has a main() method:
$ /lib/i386-linux-gnu/libc.so.6
GNU C Library (Debian GLIBC 2.19-18+deb8u1) stable release version 2.19, by Roland McGrath et al.
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by GNU CC version 4.8.4.
Compiled on a Linux 3.16.7 system on 2015-08-30.
Available extensions:
crypt add-on version 2.1 by Michael Glad and others
GNU Libidn by Simon Josefsson
Native POSIX Threads Library by Ulrich Drepper et al
BIND-8.2.3-T5B
libc ABIs: UNIQUE IFUNC
For bug reporting instructions, please see:
<http://www.debian.org/Bugs/>.
Now I want to do the same with the following minimalistic example (i. e. I want my own SO to also have a main()):
#include <stdio.h>
int main(int argc, char *argv[]) {
printf("Hello, World!\n");
return 0;
}
Linking as a regular executable:
$ gcc -g -O0 -Wall -c test.c
$ gcc -o test test.o
$ ./test
Hello, World!
Now linking as a shared object:
$ gcc -g -O0 -Wall -c test.c
$ gcc -shared -o libtest.so test.o
$ ./libtest.so
Segmentation fault
nm shows that main symbol is present (000004f5 T main)
When debugging, gdb doesn't show any meaningful backtrace.
Adding -fpic or -fPIC to the gcc command line doesn't help.
What am I doing wrong?
the libc.so library has a main() method
No, the implementation of C library of gcc has an entry point not a main symbol.
You can find an example of how to do this here.

Resources