How to create a library (Ansi C) with private functions in linux? - linux

I am trying to create a library (static or shared) that has only a specified functionality accessible for those who use that library.
If I generate the library as follows, all functions implemented in the library are usable from an external application. Can I hide some functions?
gcc -fPIC -g -c -Wall -I/usr/include/extrernalLibDIR modulo1.c
gcc -fPIC -g -c -Wall modulo2.c
gcc -fPIC -g -c -Wall modulo3.c
gcc -shared -Wl,-soname,libMyLib.so.1 -o libMyLib.so.1.0.1 modulo1.o modulo2.o modulo3.o -lc
gcc -g -Wall main.c -o app -I/usr/include/PCSC/ -lMyLib -lpcsclite
And another question: what should I do to avoid having to include a third party library (libpcsclite) that uses my library just created? I wonder if I generate in my library including libpcsclite library.
Pretty grateful!!

Related

why is cythonization not working for me when I have a simple file that takes in arguments?

I followed this procedure, which I integrated from several webpages:
import distutils.core
import Cython.Build
distutils.core.setup( ext_modules = Cython.Build.cythonize("main_file_that_accepts_sysv_args.py"))
distutils.core.setup( ext_modules = Cython.Build.cythonize("helper_file.py"))
I ran this code, and it went without errors, creating c files with extensions .c.
I then ran
gcc -shared -pthread -fPIC -fwrapv -O2 -Wall -fno-strict-aliasing -Ipython/anaconda3/include/python3.9 -o main main_file_that_accepts_sysv_args.c
however, when trying to run main, I get segfault, even when giving the proper arguments.
There are several things to note: the real file to optimize is actually helper_file.py (which I do have .c file for), but I am not sure if I should just add it to the list of files in the above gcc command.
I am also not sure why I am getting segfault to begin with, and if I should further modify the C code in any way.
I am using python 3.9.
What steps am I missing?
EDIT
Following the comments below I tried instead:
gcc -shared -pthread -fPIC -fwrapv -O2 -Wall -fno-strict-aliasing -Ipython/anaconda3/include/python3.9 -o main.so main_file_that_accepts_sysv_args.c
gcc -shared -pthread -fPIC -fwrapv -O2 -Wall -fno-strict-aliasing -Ipython/anaconda3/include/python3.9 -o helper.so helper_file.c
gcc -o main main.so helper.so
but I get a lot of undefined reference errors by the linker.
So I suppose I need to link the cythonize main library (??) but I am not sure where it is.
I am a bit fuzzy here on the details...

Compiling a shared object folder without libc

Is it possible to build a shared object file on Linux without using libc? I tried building the shared object using -nostdlib, and it complains that there is a conflicting type for built-in function 'memset'(I have my own version of the function defined within the shared object I am trying to build).
I am not using any libc functions from within the shared object file. I am building the shared object as follows :-
CC = gcc
CFLAGS = -Wall -Wextra -Werror -nostdlib
OUTPUTDIR = ./build
test: outputdir
$(CC) $(CFLAGS) -c -fPIC test.c -o ${OUTPUTDIR}/test.o
$(CC) $(CFLAGS) ${OUTPUTDIR}/test.o -shared -o ${OUTPUTDIR}/libtest.so
outputdir:
mkdir -p ${OUTPUTDIR}
clean:
rm -rf ${OUTPUTDIR}
If you link with -nostdlib, you should also compile with -ffreestanding and/or -fno-builtin as well.
You also have to be careful that you do not reference a libc.so.6 symbol without linking against glibc. Things may appear to work superficially, but it tends to introduce breakage in certain environments, especially once additional IFUNCs are added to glibc. (Intel did that with the ICC 16 compiler library.)

Cross Compile ncurses application for ARM linux

I want to cross compile an application from my workstation (x86, linux) for an ARM application processor. First I build for my system:
gcc -static -g -Wall -c main.c -o main.o
gcc -g -Wall main.o -o myApplication -lncurses
this build like I want and also work. If I want to build this for arm
arm-linux-gnueabi-gcc -static -g -Wall -c main.c -o main.o
arm-linux-gnueabi-gcc -g -Wall main.o -o myApplication -lncurses
But this will not compile.
/usr/lib/gcc-cross/arm-linux-gnueabi/4.7/../../../../arm-linux-gnueabi/bin/ld: cannot find -lncurses
collect2: Error
So: how to cross-compile a ncurses Application in this way?
One easy way to do it would be to download a binary release of ELLCC. It comes with a pre-built libraries, including ncurses. The download page is here. If you grab e.g. http://ellcc.org/releases/ellcc-x86_64-linux-eng-0.1.27.tgz (The version number will change over time), you can untar it. For the ARM, your build lines would look like:
~/ellcc/bin/ecc -target arm-linux-engeabihf -g -Wall -c main.c -o main.o
~/ellcc/bin/ecc -target arm-linux-engeabihf -g -Wall main.o -o myApplication -lncurses
It creates a static binary, so you don't have to worry about shared library versions.

Linking Rcpp to interp2d (GSL-type library)

I need some help with a linker error I get during installation of an Rcpp package on a linux system where I don't have admin rights. In a nutshell, I get this error:
relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC
I have a file solve.cpp that uses external library interp2d, which in turn has a GSL dependency. I specify my dependencies via [[Rcpp::depends(RcppArmadillo,RcppGSL)]] and in the DESCRIPTION. My Makevars is like the one from the RcppGSL package, with the addition of the linterp2d flag:
PKG_CPPFLAGS = -W $(GSL_CFLAGS) $(LOCAL_INCLUDE)
PKG_LIBS += $(GSL_LIBS) $(LOCAL_LIBS) -linterp2d $(RCPP_LDFLAGS)
where I define the environement variables
export LOCAL_INCLUDE="-I/data/uctpfos/local/include/"
export LOCAL_LIBS="-L/data/uctpfos/local/lib/"
on the system.
I do R CMD INSTALL bkPackage and see:
g++ -I/cm/shared/apps/R/3.0.1/lib64/R/include -DNDEBUG -W -I/cm/shared/apps/gsl/1.15/include -I/data/uctpfos/local/include -fPIC -I/usr/local/include -I"/data/uctpfos/R/x86_64-unknown-linux-gnu-library/3.0/Rcpp/include" -I"/data/uctpfos/R/x86_64-unknown-linux-gnu-library/3.0/RcppArmadillo/include" -I"/data/uctpfos/R/x86_64-unknown-linux-gnu-library/3.0/RcppGSL/include" -fpic -O3 -fPIC -c RcppExports.cpp -o RcppExports.o
g++ -I/cm/shared/apps/R/3.0.1/lib64/R/include -DNDEBUG -W -I/cm/shared/apps/gsl/1.15/include -I/data/uctpfos/local/include -fPIC -I/usr/local/include -I"/data/uctpfos/R/x86_64-unknown-linux-gnu-library/3.0/Rcpp/include" -I"/data/uctpfos/R/x86_64-unknown-linux-gnu-library/3.0/RcppArmadillo/include" -I"/data/uctpfos/R/x86_64-unknown-linux-gnu-library/3.0/RcppGSL/include" -fpic -O3 -fPIC -c solve.cpp -o solve.o
The problems appears after that in the linking step:
g++ -shared -L/usr/local/lib64 -o bkPackage.so RcppExports.o solve.o -L/cm/shared/apps/gsl/1.15/lib -lgsl -lgslcblas -lm -L/data/uctpfos/local/lib -linterp2d -L/data/uctpfos/R/x86_64-unknown-linux-gnu-library/3.0/Rcpp/lib -lRcpp -Wl,-rpath,/data/uctpfos/R/x86_64-unknown-linux-gnu-library/3.0/Rcpp/lib
The error follows as:
/usr/bin/ld: /data/uctpfos/local/lib/libinterp2d.a(interp2d_spline.c.o): relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC
/data/uctpfos/local/lib/libinterp2d.a: could not read symbols: Bad value
As you can see I compiled this with -fPIC, so that can't be it.
It's complaining that libinterp2d.a was not compiled with -fPIC; are you sure that was also compiled with -fPIC on?
Also, it seems you both have -fpic and -fPIC in your flags; you probably just want -fPIC. I think R actually ensures that's on by default.

undefined reference while using shared library

I want to use one program as a shared library for an other program.
I started as follows:
I have a application which I have compiled using:
/usr/bin/g++ -I/usr/include/libxml2 -Xlinker -zmuldefs -fPIC -c a.cpp
/usr/bin/g++ -I/usr/include/libxml2 -Xlinker -zmuldefs -fPIC -c b.cpp
/usr/bin/g++ -I/usr/include/libxml2 -Xlinker -zmuldefs -fPIC -c c.cpp
Then I have created a shared object library from the objects I get from this file using this command:
g++ -fPIC -Xlinker -zmuldefs -shared -o libabc.so a.o b.o c.o
After this I get the libabc.so file which I copy to the
sudo cp libabc.so /usr/local/lib/libabc.so
Now when I compile my orignal application which will use this newly created library libabc.so using this command:
/usr/local/lib/libabd.so: undefined reference to `xmlXPathNewContext'
I get errors for all the functions I used from the included library libxml2 in the first application and the function which has this undefined reference is actually the library I include in the first program I mean I have tested it.
So kindly anyone guide me where I need corrections.
You may have to pass the path also using -I/path/to/library, or alternatively export it to LD_LIBRARY_PATH.
I don't see the command line that you used to link your application against your library, but I suppose that adding -lxml2 to the flags passed to the linker should solve the problem.

Resources