Error building Glib due to undefined reference in libffi - c

I am currently working on building Glib version 2.45.8 on CentOS 7 running on x86-64 targeting a custom distro based off Linux from Scratch running on x86-64. There is a problem linking with libffi which is version 3.2.1.
path/to/build/directory/bin/ld: warning: libc.so.6, needed by //lib/../libffi.so, not found (try using -rpath or -rpath-link)
path/to/build/directory/lib64/libffi.so: undefined reference to `free#GLIBC_2.2.5'
path/to/build/directory/lib64/libffi.so: undefined reference to `mkostemp#GLIBC_2.7'
(etc ... there are about 15 undefined references total)
path/to/build/directory/lib64/libffi.so: undefined reference to `__getdelim#GLIBC_2.2.5'
path/to/build/directory/lib64/libffi.so: undefined reference to `getenv#GLIBC_2.2.5'
Using -rpath or -rpath-link will not work because the libc.so.6 file does not exist anywhere in the file system for my build.
However I do have libc.so and libc.so.0 in path/to/build/directory/lib64/ the directory in which libc.so.6 cannot be found.
Here are my ./configure and make commmands.
glib_cv_stack_grows=no \
glib_cv_uscore=no \
ac_cv_func_posix_getpwuid_r=yes \
ac_cv_func_posix_getgrgid_r=yes \
LIBFFI_CFLAGS=-lffi \
LIBFFI_LIBS=-lffi \
ZLIB_CFLAGS=-lz \
ZLIB_LIBS=-lz \
PKG_CONFIG_LIBDIR=$TARG/lib/pkgconfig \
./configure --prefix=/ --host=x86_64-linux --with-libiconv
make -j32 LDFLAGS=-liconv
How do I get the correct libc.so to be built?

There we several things that had to be done to solve this problem.
The first thing I found out was that if software has a dependancy on libc.so.6 it was built against glibc.
However our toolchain for this build is using uClibc instead, which does not produce libc.so.6 when it is built.
The solution was to write the LIBFFI and ZLIB clags and libs to link to the libffi and zlib built with uClibc.
glib_cv_stack_grows=no \
glib_cv_uscore=no \
ac_cv_func_posix_getpwuid_r=yes \
ac_cv_func_posix_getgrgid_r=yes \
ZLIB_CFLAGS=-I$TARG/include \
ZLIB_LIBS="-L$TARG/lib -lz" \
LIBFFI_CFLAGS=-I$TARG/include \
LIBFFI_LIBS="$TARG/lib/libffi.a" \
PKG_CONFIG_LIBDIR=$TARG/lib/pkgconfig \
./configure --prefix=/ --host=x86_64-linux --with-libiconv
make -j32 LDFLAGS=-liconv

Related

Cross-compiling C project to PE32+ executable from within macOS using Clang

I am currently attempting to cross-compile my C source code into a PE32+ executable, which hasn't yielded the greatest results.
I'm running macOS Ventura Beta 8 (macOS 13), using Clang which is bundled with LLVM (which was installed via the Homebrew tap).
Here is the command for compiling the source files:
/usr/local/opt/llvm/bin/clang \
--target=x86_64-unknown-windows-gnu \
-Wl,-e,_KernMain \
-o kernel.o \
src/Kernel/Kernel.c \
src/Kernel/Memory/KernMem.c \
src/Kernel/Graphics/KernGraphics.c \
-I/Users/kernel/Documents/edk2-master/edk2/MdePkg/Include/ \
-I/Users/kernel/Documents/edk2-master/edk2/MdePkg/Include/X64 \
-I/Users/kernel/Documents/edk2-master/edk2/KernelOSPkg/src/Common \
-I/Users/kernel/Downloads/mingw64/x86_64-w64-mingw32/include \
-L/Users/kernel/Documents/edk2-master/edk2/MdePkg/Library/ \
-L/Users/kernel/Downloads/mingw64/x86_64-w64-mingw32/lib \
-L/Users/kernel/Downloads/mingw64/x86_64-w64-mingw32/lib/ldscripts \
-L/usr/local/lib \
-fuse-ld="/usr/local/opt/llvm/bin/ld.lld"
It throws the following error:
lld: error: unable to find library -lgcc
lld: error: unable to find library -lgcc_eh
lld: error: unable to find library -lgcc
lld: error: unable to find library -lgcc_eh
clang-15: error: linker command failed with exit code 1 (use -v to see invocation)
CLANG info:
/usr/local/opt/llvm/bin/clang --version
Homebrew clang version 15.0.2
Target: x86_64-apple-darwin22.1.0
Thread model: posix
InstalledDir: /usr/local/opt/llvm/bin
ld.lld info:
/usr/local/opt/llvm/bin/ld.lld --version
Homebrew LLD 15.0.2 (compatible with GNU linkers)
The issue was that I didn't include the /path/to/mingw64/lib/gcc/x86_64-w64-mingw32/<version> directory, which included the libgcc.a and libgcc_eh.a files.
Though, I still do not know how to resolve the issue with an undefined symbol: WinMain. I will update this answer if I find a solution.
Error in question:
ld.lld: error: undefined symbol: WinMain
>>> referenced by libmingw32.a(lib64_libmingw32_a-crt0_c.o):(.text.startup)
clang-15: error: linker command failed with exit code 1 (use -v to see invocation)
Compilation command (does not compile successfully due to undefined symbol):
/usr/local/opt/llvm/bin/clang \
-target x86_64-unknown-windows-gnu \
-Wl,-e,KernMain \
-fuse-ld=lld \
-ffreestanding \
-o kernel.o \
src/Kernel/Kernel.c \
src/Kernel/Memory/KernMem.c \
src/Kernel/Graphics/KernGraphics.c \
-I/Users/kernel/Documents/edk2-master/edk2/MdePkg/Include/ \
-I/Users/kernel/Documents/edk2-master/edk2/MdePkg/Include/X64 \
-I/Users/kernel/Documents/edk2-master/edk2/KernelOSPkg/src/Common \
-I/Users/kernel/Downloads/mingw64/x86_64-w64-mingw32/include \
-L/Users/kernel/Downloads/mingw64/lib/gcc/x86_64-w64-mingw32/12.2.0 \
-L/Users/kernel/Documents/edk2-master/edk2/MdePkg/Library/ \
-L/Users/kernel/Downloads/mingw64/x86_64-w64-mingw32/lib \
-fshort-wchar
EDIT: To fix the aforementioned error with the undefined symbol, simply supply -nostdlib to the compiler.

How to create alias for particular (new/existing) function in glibc

For some reasons I wish to create alias to function
pthread_mutex_trylock(pthread_mutex_t *mutex);
from the glibc to alias named
lab_pthread_mutex_trylock(pthread_mutex_t *mutex);
I try add
weak_alias (__pthread_mutex_trylock, lab_pthread_mutex_trylock)
in the file pthread_mutex_trylock.c (editing source code of the library) and then
./configure --prefix=/home/user/glibc
make
make install
After that I compile my program like
gcc \
-L "/home/user/glibc/lib" \
-I "/home/user/glibc/include" \
-Wl,--rpath="/home/user/glibc/lib" \
-Wl,--dynamic-linker="/home/user/glibc/lib/ld-linux-x86-64.so.2" \
-std=c11 \
-o main.out \
-v \
main.c \
-pthread \
;
ldd ./main.out
./main.out
The ldd script show me that some functions (from default libc) are really from my build of glibc, but use lab_pthread_mutex_trylock(pthread_mutex_t *mutex) causes error.
glibc has very complicated structure and I have quite weak knowledge about build management so I feel that lot of things I should to do was missed by me. Please, help me, it's very important for me...
Error by gcc:
gcc -L "/ home / anahel / glibc-test / lib" -I "/ home / anahel / glibc-test / include" -Wl, - rpath = "/ home / anahel / glibc-test / lib" -Wl , - dynamic-linker = "/ home / anahel / glibc-test / lib / ld-linux-x86-64.so.2" -std = c11 -o main.out main.c -pthread
/ usr / bin / ld: /tmp/ccivqLEz.o: in the "main" function:
main.c :(. text + 0x1b): undefined reference to "lab_pthread_mutex_trylock"
collect2: error: ld returned 1 exit status
The steps I did in glibc sources:
1) If file glibc-2.31/nptl/pthread_mutex_trylock.c I added
weak_alias (__pthread_mutex_trylock, lab_pthread_mutex_trylock)
2) In file glibc-2.31/sysdeps/nptl/pthread.h I added
extern int lab_pthread_mutex_trylock (pthread_mutex_t *__mutex)
__THROWNL __nonnull ((1));
right after
/* Try locking a mutex. */
extern int pthread_mutex_trylock (pthread_mutex_t *__mutex)
__THROWNL __nonnull ((1));
This error:
undefined reference to "lab_pthread_mutex_trylock"
means that the lab_pthread_mutex_trylock is not exported from /home/user/glibc/lib/libpthread.so.0. You can confirm this with:
nm -D /home/user/glibc/lib/libpthread.so.0 | grep lab_pthread_mutex_trylock
(expect no output if my guess is correct).
The likely reason it's not exported: GLIBC build process tightly controls which functions are exported, and what version they have, via a linker script (which is generated by combining several Version files).
In particular, you very likely need to add lab_pthread_mutex_trylock to the glibc-2.31/nptl/Versions file.

Problem to compile ed25519-donna in MacOs

I'm using QT and the ed25519-donna lib to validate my signature.
Linux I'm using this lib => libssl-dev
MacOs I'm using this lib => openssl
So when I try to compile by Linux its work but when I try in MacOs the donna libs give a error:
openssl/rand.h is not found
I've this line in my Makefile:
LIBS = $(SUBLIBS) -L/home/laion/Desktop/lethean-gui/lethean/lib -lwallet_merged -lepee -lunbound -leasylogging -lboost_serialization -lboost_thread -lboost_system -lboost_date_time -lboost_filesystem -lboost_regex -lboost_chrono -lboost_program_options -lssl -lcrypto -Wl,-Bdynamic -Wl,-Bdynamic -lunwind -ldl -lQt5Quick -lQt5Widgets -lQt5Gui -lQt5Qml -lQt5Network -lQt5Core -lGL -lpthread
When you look to donna libs you can see a ed25519.c file and inside of that call the ed25519-randombytes.h, inside of this file has the openssl/rand.h include.
Inside of my .pro file I use this:
macx {
# mixing static and shared libs are not supported on mac
# CONFIG(static) {
# message("using static libraries")
# LIBS+= -Wl,-Bstatic
# }
LIBS+= \
-L/usr/local/lib \
-L/usr/local/opt/openssl/lib \
-L/usr/local/opt/boost/lib \
-lboost_serialization \
-lboost_thread-mt \
-lboost_system \
-lboost_system-mt \
-lboost_date_time \
-lboost_filesystem \
-lboost_regex \
-lboost_chrono \
-lboost_chrono-mt \
-lboost_program_options \
-lssl \
-lcrypto \
-ldl
INCLUDEPATH += /usr/local/opt/boost/include/
}
So, if I add this path in INCLUDEPATH:
/usr/local/opt/openssl/include \
/usr/local/opt/openssl/lib
I get a different error:
The program has unexpectedly finished.
// every donna file get this message
was built for newer osx version (10.13) than being linked (10.12)
For now I get this reference C++, Mac OS X, Xcode 8 : Compile Boost : Set deployment target to OS X 10.11 and I come back to let you know if works
FIXED << The problem was the version of Mac. To work with donna and openssl is necessary 10.12+ to compile

Matlab mex without xcode, but with standalone command line tools

I want to compile mex files without installing xcode, using only Command Line Tools (from apple developer center).
Apple Command Line Tools install the compiler and adds standard libraries and headers to the system in a package much smaller than xcode (which is several GBs).
Running mex on linux is possible - I see no reason why matlab mex should require the huge SDKs required for macos. A long evening of trial and error and hacking configuration files hasn't helped. Does anyone have a minimal working example of how to compile a mex file outside matlab, or a simple way to use mex without having xcode installed?
Best Regards, Magnus
Well, I have another option here:
Edit the files under /Applications/MATLAB_R2016b.app/bin/maci64/mexopts (probably there should be 3.xml file, all needs the same modification).
Locate the <XCODE_AGREED_VERSION> portion, comment the whole xml tag, e.g. wrap them with <!-- and --> like this:
<!--XCODE_AGREED_VERSION>
<and diagnostic="Xcode is installed, but its license has not been accepted. Run Xcode and accept its license agreement." >
<or>
<cmdReturns name="defaults read com.apple.dt.Xcode IDEXcodeVersionForAgreedToGMLicense"/>
<cmdReturns name="defaults read /Library/Preferences/com.apple.dt.Xcode IDEXcodeVersionForAgreedToGMLicense"/>
</or>
<cmdReturns name="
agreed=$$
if echo $agreed | grep -E '[\.\"]' >/dev/null; then
lhs=`expr "$agreed" : '\([0-9]*\)[\.].*'`
rhs=`expr "$agreed" : '[0-9]*[\.]\(.*\)$'`
if echo $rhs | grep -E '[\."]' >/dev/null; then
rhs=`expr "$rhs" : '\([0-9]*\)[\.].*'`
fi
if [ $lhs -gt 4 ] || ( [ $lhs -eq 4 ] && [ $rhs -ge 3 ] ); then
echo $agreed
else
exit 1
fi
fi" />
</and>
</XCODE_AGREED_VERSION -->
Some notes:
These files are read only by default, you need to issue sudo chmod
644 * in that directory
after comment out all necessary files, issue this command in matlab:
mex -setup C++
Then you are done
After spending more time, I wound up learning more stuff and answering my own question. I'll post my solution here if anyone else needs it in the future.
Make sure the cord is connected to your computer and that MATLAB is installed, and also install the command line tools from apple. Then call the following makefile to compile arrayProduct.c (comes with matlab) from the terminal as follows:
make mex=arrayProduct
Put this makefile code in the same folder in a file called makefile(edit to your own needs if you have to):
all:
clang -c\
-DMX_COMPAT_32 \
-DMATLAB_MEX_FILE \
-I"/Applications/MATLAB_R2016b.app/extern/include" \
-I"/Applications/MATLAB_R2016b.app/simulink/include" \
-fno-common \
-arch x86_64 \
-fexceptions \
-O2 \
-fwrapv \
-DNDEBUG \
"/Applications/MATLAB_R2016b.app/extern/version/c_mexapi_version.c" \
$(mex).c
clang \
-Wl,-twolevel_namespace \
-undefined error \
-arch x86_64 \
-bundle \
-Wl,-exported_symbols_list,"/Applications/MATLAB_R2016b.app/extern/lib/maci64/mexFunction.map" \
$(mex).o \
c_mexapi_version.o \
-O \
-Wl,-exported_symbols_list,"/Applications/MATLAB_R2016b.app/extern/lib/maci64/c_exportsmexfileversion.map" \
-L"/Applications/MATLAB_R2016b.app/bin/maci64" \
-lmx \
-lmex \
-lmat \
-lc++ \
-o $(mex).mexmaci64
The above makefile is a bare minimum working example, you should edit it to comply with your requirements.
Edit:
Option 2
You can make MATLAB understand how to use the Command Line Tools by editing the xml file containing the compiler options instead. Open the file located at
/User/username/Library/Application Support/MathWorks/MATLAB/R2016b/mex_C_maci64.xml
Remove all compiler and linker options related to ISYSROOT. This will make the compiler search for header files in /usr/include etc instead of in the SDK-folder in XCode.
I fully understand you and I'm a big advocate of non-using the enormous Xcode. From my saver here, run the following to trick mex into seeing an accepted license (no sudo needed).
Here I use the current version 13.0 at the time of writing, to be adapted.
defaults write com.apple.dt.Xcode IDEXcodeVersionForAgreedToGMLicense 13.0

How to get a list of libraries ffmpeg has linked to (static ffmpeg libraries)?

I have compiled Ffmpeg (1.0) with newt configuration:
./configure --disable-doc --disable-ffplay --disable-ffprobe --disable-ffserver --disable-avdevice --disable-avfilter --disable-pthreads --disable-everything --enable-muxer=flv --enable-encoder=flv --enable-encoder=h263 --disable-mmx --disable-shared --prefix=bin/ --disable-protocols --disable-network --disable-debug --disable-asm --disable-stripping
It compiled - no errors - headers and libs (static .a) are in place. (special experimental cigwin, experimental gcc, with no asm options, and no known by ffmpeg platform defines) (yet I have compiled and tested boost on it)
Now I try to compile my app. I get next exceptions:
../ffmpeg-1.0/bin/lib/libavcodec.a: error: undefined reference to 'exp'
../ffmpeg-1.0/bin/lib/libavcodec.a: error: undefined reference to 'log'
My compiler build line looks like this:
g++ -static -emit-swf -o CloudClient.swf -I../boost/boost_libraries/install-dir/include -I../ffmpeg-1.0/bin/include -L../boost/boost_libraries/install-dir/lib -L../ffmpeg-1.0/bin/lib \
timer.o \
audio_encoder.o \
audio_generator.o \
video_encoder.o \
video_generator_rainbow.o \
simple_synchronizer.o \
multiplexer.o \
transmitter.o \
graph_runner.o \
cloud_client.o \
-pthread \
-lswscale \
-lavutil \
-lavformat \
-lavcodec \
-lboost_system \
-lboost_date_time \
-lboost_thread
So as you see quite complex and I already have all object files compiled and ready... Only one thing left - link it all to ffmpeg (striped from ffmpeg version compiled with boost)
Tried adding -lm - no help...
Well here my question is - how to get list of libraries ffmpeg linked to (like -lm etc)?
If in Linux, try
ldd /path/to/ffmpeg-binary
or
ldd `which ffmpeg`

Resources