Build 'libconfig' as a 32-bit library - c

I am trying to use the libconfig (http://www.hyperrealm.com/libconfig/ ) for a little utility I am trying to write. I am trying to build libconfig then copy the library file (libconfig.a) to my utility's directory. When I build my utility I get warnings about the architecture being incompatible. Here is one of the specific warning messages I receive.
/usr/bin/ld: warning: i386:x86-64 architecture of input file 'libconfig.a(libconfig_la-libconfig.o)' is incompatible with i386 output
I am building on a Red Hat Enterprise Linux Server release 5.10 machine (uname -m produces 'x86_64'). I tried building libconfig with the following:
configure --disable-cxx CFLAGS='-m32' LDFLAGS='-m32'
But unfortunately, this didn't seem to produce the correct library as I still see the same warnings. There are other utilities that are created during the build process and all utilities share make common make directives which are specifying CFLAGS = -m32 -Wextra -Wall -Werror -Os and LDFLAGS = -m32, so I am unable to change this behavior.
I have also tried configure --disable-cxx CFLAGS='-arch i386' LDFLAGS='-arch i386, but this command line will not build the library.
Does anyone know how to build the libconfig as a 32-bit library to be consumed correctly.
Thanks,
Mark

The configure script will ignore arguments like CFLAGS= when passed on the command line. You need to set them for the invocation of configure, i.e. something like:
env CFLAGS=-m32 LDFLAGS=-m32 ./configure --disable-cxx
When this is done, all the symbols listed in the resulting lib/.libs/libconfig.a are listed with 32-bit addresses when the library is rebuilt.
Note in the configure script help output it does say:
Some influential environment variables:
which means that they need to be environment variables, not passed in as parameters to the command

Related

Cross compile module with arm-eabi-gcc

I have a video module and I am compiling with arm-eabi-gcc cross compiler. I used following command to compile
$ arm-eabi-gcc -O2 -DMODULE -D__KERNEL__ -W -Wall -isystem /lib/modules/uname -r/build/include panel-xxxxxxx.c.
I got the following error
In file included from /lib/modules/3.13.0-32-generic/build/include/linux/types.h:5:0,
from /lib/modules/3.13.0-32-generic/build/include/linux/list.h:4,
from /lib/modules/3.13.0-32-generic/build/include/linux/module.h:9,
from panel-gis317.c:17:
/lib/modules/3.13.0-32-generic/build/include/uapi/linux/types.h:4:23: fatal error: asm/types.h: No such file or directory
compilation terminated.
And after searching on google, I found that I need to specify hardware architecture but I could not find the right usage to use arch with gccon the command line.
Can anyone please suggest me the what flags can I use to cross-compile a give .cfile(module) on the command line without using Makefile
Note: I am doing this to do insmod of .ko module on the hardware for test purpose.
BTW with the help of .o file, can we know which cross-compiler is used to compile the .c file
With the linux kernel architecture specific includes are in arch//include. Though it will probably not ensure correct compilation just setting that...
But try adding /lib/modules/$(uname -r)/build/arch/arm/include to your include path.
Here's a simple guide for building your own kernel and modules for a Pi2 on your PC:
http://lostindetails.com/blog/post/Compiling-a-kernel-module-for-the-raspberry-pi-2
They use the makefile approach.
The following link will help you
Cross-compiling of kernel module for ARM architecture
This has an example of the make file approach also.
As a side note if you want to have an Idea about the importance the "asm/types.h" in Linux you can have a look here to see what all functions use this . http://docs.cs.up.ac.za/programming/asm/derick_tut/syscalls.html
For knowing more about your out (.o) file use the command "file"
"file outputfilename.o" If you are cross compiling the file correctly and you are using a 64 bit system as host and your target is 32 bit you can verify it here. Your compiled output will be 32bit in proper working case .
There are a couple of things to change in how you build an out-of-core kernel module.
First, use the kernel Makefile rather than invoking the compiler directly, in order to get all the necessary CFLAGS.
Second, specify CROSS_COMPILE=arm-eabi- because other binutils are needed in the build.
Run the following command from the directory containing your module source code and Makefile:
$ make CROSS_COMPILE=arm-eabi- -C <path_to_kernel_src> M=$PWD
The Makefile for a module consisting of a single source file would contain the following line:
obj-m := panel-xxxxxxx.o
The kernel kbuild Makefile rules would take care of generating a modinfo source file, and compiling and linking those into a .ko module binary.
See Documentation/kbuild/modules.txt for more details.

How to configure a non-standard linker for an autotooled build?

I wanted to configure an autotooled project to invoke a non-standard
linker (the gold linker),
using the stock autotools of Linux Mint 16/Ubuntu 13.10
I believed I would achieve this by:
libtoolize-ing the project
Running ./configure LD=/path/to/my/linker ... etc.
However this has been ineffective. libtoolize has been successful. After
a standard ./configure; make I now see that libtool is doing the
linking:
/bin/bash ./libtool --tag=CXX --mode=link g++ -g -O2 -o helloworld helloworld.o
But passing LD=/path/to/my/linker to configure makes no difference. Experimentally,
I even ran:
./configure LD=/does/not/exist
expecting to provoke an error, but I didn't. The output contains:
checking if the linker (/does/not/exist -m elf_x86_64) is GNU ld... no
checking whether the g++ linker (/does/not/exist -m elf_x86_64) supports shared libraries... yes
And thereafter a make continues to link, successfully, invoking g++ exactly as before.
What is the right way to configure a non-standard linker?
But passing LD=/path/to/my/linker to configure makes no difference
This is because LD is almost never and should almost never be used to link any user-space program. Correct links are performed by using the appropriate compiler driver (gcc, g++, etc) instead.
What is the right way to configure a non-standard linker?
If you have /some/path/ld and you want gcc to use that ld, pass -B/some/path flag to gcc.
It then follows that you likely want:
./configure CC='gcc -B/some/path' CXX='g++ -B/some/path' ...
I landed on this via a Google search, though my scenario is a bit different from yours; there was no libtool involved. An old open source program's Makefile was hard-coding ld to create an object file with a symbol from binary data.
This is what I ended up doing to work around the lack of $(LD) being recognized when passed to configure:
https://github.com/turboencabulator/tuxnes/commit/bab2747b175ee7f2fc3d9afb28d69d82db054b5e
Basically I added to configure.ac:
AC_CHECK_TOOL([LD], [ld])
Leaving this answer here for if someone else lands via a google search.

Overcome DLL Hell with Code::Blocks

I'm using Code::Blocks for a project. I have not used an IDE on Linux in years, so I'm a bit out of touch with Linux IDEs.
I'm working with an OpenSSL project that uses FIPS validated library. I duplicated the GCC compiler toolchain and modified it to use OpenSSL's fipsld (and set it as default).
When the project's code executes under Code::Blocks via F8, FIPS_mode_set fails with error 252104805 (0xF06D065). 0xF06D065 is:
$ openssl errstr 0xF06D065
error:0F06D065:common libcrypto routines:FIPS_mode_set:fips mode not supported
which tells me Code::Blocks is not using the OpenSSL I specified in /usr/local/ssl/lib. Rather, the program is using the non-FIPS library provided by Debian in /usr/lib/x86_64-linux-gnu/.
An image of the link library settings is below. Note that the libraries are fully specified, and nothing is left to chance.
CodeBlocks is clearly doing things with LD_LIBRARY_PATH (shown below).
I've also verified the project is using the correct search directories - /usr/local/ssl/include for headers and /usr/local/ssl/lib for the linker.
With compiler logging set to "Full Command Line" set, here's what I get from the build log:
-------------- Build: Debug in ac ---------------
Compiling: main.cpp
/home/jwalton/Desktop/ac/main.cpp:8:5: warning: unused parameter ‘argc’ [-Wunused-parameter]
/home/jwalton/Desktop/ac/main.cpp:8:5: warning: unused parameter ‘argv’ [-Wunused-parameter]
Linking console executable: bin/Debug/ac
Output size is 569.67 KB
Process terminated with status 0 (0 minutes, 0 seconds)
0 errors, 2 warnings
I'm aware of Basile Starynkevitch's suggestions on rpath's and LD_PRELOAD tricks, but this seems like one of those things the IDE should be handling for me (Visual Studio will handle it properly, and even gives us an input box to set Working Directories to find additional libraries).
Any ideas how to make Code::Blocks use the shared objects in /usr/local/ssl/lib when executing the program under the debugger?
Your IDE instructs the compiler to link against the specified libraries, but not to load them at run time. For this latter thing to happen, you need to pass another option to the linker, namely
-rpath=/path/to/directory/with/your/libraries
or, if the linker is invoked by the compiler,
-Wl,-rpath=/same/thing
Code::Blocks don't use shared objects (DLL are a Windows thing). Because Code::Blocks is simply an IDE. IDEs are glorified source code editors with the ability to run external software development tools. You could (and sometimes you should, at least to learn how things happen) edit your code with a plain good editor like emacs, and build it with commands. Your IDE is just running commands, notably a compiler and a linker, probably using gcc
So what is using shared objects in /usr/local/ssl/lib/ is the compiler and linker (and the runtime dynamic linker). BTW, /usr/local/ssl/lib/ is a very strange name for a directory containing shared objects; you should have configured OpenSSL to be installed in /usr/local/lib/ !
First, I really believe you should reconfigure and recompile and rebuild and reinstall your SSL to get it installed under /usr/local/ (or perhaps /opt/) prefix (i.e. shared libraries in /usr/local/lib).
Then you could add appropriate options for the ld linker (from binutils). You probably want -L/usr/local/ssl/lib (to the gcc command which is running ld), and you may want to pass -Wl,-rpath (see this).
I would suggest to reinstall your SSL in /usr/local/, add /usr/local/lib/ into /etc/ld.so.conf (or at least into your LD_LIBRARY_PATH...) and run ldconfig
Otherwise, add at least /usr/local/ssl/lib/ in front of your LD_LIBRARY_PATH (and also -L/usr/local/ssl/lib/ to your linking command).
Read Program Library HowTo, the answers to this, and Drepper's How To Write Shared libraries paper.
Just open the terminal and type
export LD_LIBRARY_PATH=/path/to/your/libraries
sudo ldconfig

Compile shared library with link to other .so

I want to link an existing shared library (FlashRuntimeExtensions.so) to my C-code while compiling my own shared library. But whatever I try I always get the same error; that the file is in a wrong format. Does anybody have an idea on how to solve this?
Here is my compile command:
$ g++ -Wall ane.c FlashRuntimeExtensions.so -o aneObject
FlashRuntimeExtensions.so: could not read symbols: File in wrong format
collect2: ld gaf exit-status 1 terug
Your command line tries to generate x86 code and link it to ARM code using the native g++ available in your distribution.
This will not work. Use the Android NDK available here: http://developer.android.com/tools/sdk/ndk/index.html
The NDK includes a set of cross-toolchains (compilers, linkers, etc..) that can generate native ARM binaries on Linux, OS X, and Windows (with Cygwin) platforms.
In general .so will be linked using -l.
for example, pthread -lpthread we use.
gcc sample.c -o myoutput -lpthread
But as per #chill's statement, what you are doing in command is correct only.
I suggest you to refer the following link.
C++ Linker Error SDL Image - could not read symbols
It should be an architecture mismatch. I faced this problem once, I have solved it by building the libs in same target platform and it is obvious. If you are using linux or Unix like OS you can see that by file command and if you are using windows you can see that using Dependency Walker. You need to make sure that all the libs matches architecture.

Why is gcc failing with 'unrecognized command line option "-L/lusr/opt/mpfr-2.4.2/lib"'?

My sysadmin recently installed a new version of GCC, in /lusr/opt/gcc-4.4.3. I tested it as follows:
mike#canon:~$ cat test.c
int main(){
return 0;
}
mike#canon:~$ gcc test.c
/lusr/opt/gcc-4.4.3/libexec/gcc/i686-pc-linux-gnu/4.4.3/cc1: error while loading shared libraries: libmpfr.so.1: cannot open shared object file: No such file or directory
After informing my sysadmin about this, he said to add /lusr/opt/mpfr-2.4.2/lib:/lusr/opt/gmp-4.3.2/lib to my LD_LIBRARY_PATH. After doing this, I get the following error:
mike#canon:~$ gcc test.c
cc1: error: unrecognized command line option "-L/lusr/opt/mpfr-2.4.2/lib"
First, my sysadmin wasn't entirely sure this was the best workaround(though he did say it worked for him...), so is there a better solution?
Second, why am I getting a linker error from cc, and how can I fix it?
Some information which may be helpful:
mike#canon:~$ env | grep mpfr
OLDPWD=/lusr/opt/mpfr-2.4.2/lib
LD_LIBRARY_PATH=/lusr/opt/mpfr-2.4.2/lib:/lusr/opt/gmp-4.3.2/lib:
mike#canon:~$ echo $LDFLAGS
(the above is a blank line)
I would suggest that your sysadmin needs to install the GMP and MPFR libraries from the build machine into the same location on your machine. (There's also the MPC library which you may also need.) Alternatively, your sysadmin needs to install a rebuild of GCC - preferably version 4.5.2 since that is (AFAIK) current - with the correct settings for where the GMP and MPFR libraries will be installed on your machine.
You shouldn't need to set LD_LIBRARY_PATH to use GCC. If you need to do so, it indicates that it was not built for the machine where it is running. Key libraries are missing.
To go further with your debugging, you probably need to use:
gcc -v test.c
This will show you the command lines executed. There is no call for the -L option (which affects the way programs are linked) to be passed to the phase 1 compiler.
This looks like some buggy argument parsing by gcc (it shouldn't complain about -Lfoo).
Can you try setting
LD_LIBRARY_PATH=\ /lusr/opt/mpfr-2.4.2/lib:/lusr/opt/gmp-4.3.2/lib
so that there's a leading space before that mpfr library path?

Resources