Unable to make shared library while embedding Python to C - c

I am trying to make a shared library which consists of one C header file and two C source files, one of which calls a Python file for implementation.
The compilation comand used is
gcc -fPIC -c -I-I/usr/local/include -I/usr/local/include -I/usr/local/include/python3.4m -I/usr/local/include/python3.4m -DNDEBUG -g -fwrapv -O0 -Wall -Wstrict-prototypes -DDOUBLE_PRECISION *.c
I am able to compile all these without any error, but when I try to make a shared object file using the following command
gcc *.o -L/usr/local/lib -lpthread -ldl -lutil -lm -Xlinker -export-dynamic /usr/local/lib/python3.4/config-3.4m/libpython3.4m.a -shared -o libroughness.so
I get the following error which I am unable to resolve
/usr/bin/ld: /usr/local/lib/python3.4/config-3.4m/libpython3.4m.a(abstract.o): relocation R_X86_64_32S against `_PyObject_NextNotImplemented' can not be used when making a shared object; recompile with -fPIC
/usr/local/lib/python3.4/config-3.4m/libpython3.4m.a: could not read symbols: Bad value
collect2: ld returned 1 exit status
I am using -fPIC tag while compilation, however it still asks me to recompile with fPIC. Any help on how to resolve this case would be appreciated.

Related

Building a C application against an external library on linux

I'm working on a Linux project in C consisting of two different open source applications. "Project A" (libduo) creates an archive used for linking a couple test programs and creates the library like this:
/usr/bin/ar rv libduo.a duo.o http_parser.o https.o match.o parson.o urlenc.o
/usr/bin/ar: creating libduo.a
a - duo.o
a - http_parser.o
a - https.o
a - match.o
a - parson.o
a - urlenc.o
ranlib libduo.a
One of the libduo test programs is built like this:
gcc -g -O2 -Wall -D_FORTIFY_SOURCE=2 -fstack-protector -I. -I. -DDUODIR=\"/usr/local/duo/libduo/etc\" -DHAVE_CONFIG_H -c test-duologin.c
gcc -o test-duologin test-duologin.o -L. -lduo -lssl -lcrypto
"Project B" is an OpenLDAP module which I've built with -lduo and a few options to tell it where to find things:
(cd .libs && rm -f pw-apr1.la && ln -s ../pw-apr1.la pw-apr1.la)
../../../libtool --mode=compile gcc -g -O2 -Wall -I../../../include -I../../../include -I../../../servers/slapd -I../../../contrib/slapd-modules/passwd/libduo -c pw-duo.c
gcc -g -O2 -Wall -I../../../include -I../../../include -I../../../servers/slapd -I../../../contrib/slapd-modules/passwd/libduo -c pw-duo.c -fPIC -DPIC -o .libs/pw-duo.o
gcc -g -O2 -Wall -I../../../include -I../../../include -I../../../servers/slapd -I../../../contrib/slapd-modules/passwd/libduo -c pw-duo.c -o pw-duo.o >/dev/null 2>&1
../../../libtool --mode=link gcc -g -O2 -Wall -version-info 0:0:0 \
-rpath /usr/local/libexec/openldap -module -o pw-duo.la pw-duo.lo libduo.a -lduo
*** Warning: Linking the shared library pw-duo.la against the
*** static library libduo.a is not portable!
cc -shared .libs/pw-duo.o libduo.a -lduo -Wl,-soname -Wl,pw-duo.so.0 -o .libs/pw-duo.so.0.0.0
/usr/bin/ld: libduo.a(duo.o): relocation R_X86_64_32 against `.rodata.str1.1' can not be used when making a shared object; recompile with -fPIC
libduo.a: error adding symbols: Bad value
collect2: error: ld returned 1 exit status
Makefile:51: recipe for target 'pw-duo.la' failed
make: *** [pw-duo.la] Error 1
The Makefile I'm using is the same one distributed with the OpenLDAP project. I've just added a section in the Makefile to build my module, using the same options for the other modules already there but adding -lduo to my section along with the paths to the libduo includes and libduo.a.
As make suggests above, I've recompiled by adding -fPIC after the -Wall option but it the same error was repeated. As a last resort, I tried adding -static to the module build but make was having none of that either:
*** Warning: Linking the shared library pw-duo.la against the
*** static library libduo.a is not portable!
This is the first time I've tried to build a C application against a lib not in the standard Linux locations so not exactly sure what's going on. I suspect libduo is built intended to be statically linked into everything, but the OpenLDAP modules are designed to use shared libraries. Can anyone elucidate?
Update: with help of comments below and this link I created a shared library from the .o files and distributed/built against that.

using C and cuda create shared library got error at link stage

I was really struggled with this error when I try to build a shared library. My code utilize the Lapacke library and also CUDA. when I compile them, there are no errors(I compile them as)
gcc -m64 -Wall -fPIC -c xxx.c -o xxx.o $(INC)
where INC includes all directories
INC=-I. -I${JAVA_HOME}/include/ -I${JAVA_HOME}/include/linux/ I$/home/sniu/lapack-3.5.0/lapacke/include/ -I${CUDA_INSTALL_PATH}/include/ -I/home/sniu/CBLAS/include/
for cuda part, I wrote it as:
nvcc -m64 -arch=sm_20 -Xcompiler -fPIC $(INC) -c xxx.cu -o xxx.o
but I got the error message at the link stage:
gcc -m64 -D_REENTRANT -Wall -fPIC -g -shared -o libjniWrapper.so jniWrapper.o cholesky_inv.o wls_acc.o utils.o -L/home/sniu/lapack-3.5.0 -L/opt/cuda-toolkit/5.5.22/lib64 -lm -llapacke -llapack -lblas -lgfortran -lrt -lcudart -lcublas -ldl
/usr/bin/ld: /home/sniu/lapack-3.5.0/liblapacke.a(lapacke_dpotrf.o): relocation R_X86_64_32 against `.rodata.str1.1' can not be used when making a shared object; recompile with -fPIC
/home/sniu/lapack-3.5.0/liblapacke.a: could not read symbols: Bad value
collect2: error: ld returned 1 exit status
I am very sure libraries are there, I really confused why I got this error.
Any suggestions are appreciated, Thank you so much!

Undefined reference to `initscr' Ncurses

I'm trying to compile my project and I use the lib ncurse. And I've got some errors when compiler links files.
Here is my flags line in Makefile:
-W -Wall -Werror -Wextra -lncurses
I've included ncurses.h
Some layouts :
prompt$> dpkg -S curses.h
libslang2-dev:amd64: /usr/include/slcurses.h
libncurses5-dev: /usr/include/ncurses.h
libncurses5-dev: /usr/include/curses.h
prompt$> dpkg -L libncurses5-dev | grep .so
/usr/lib/x86_64-linux-gnu/libncurses.so
/usr/lib/x86_64-linux-gnu/libcurses.so
/usr/lib/x86_64-linux-gnu/libmenu.so
/usr/lib/x86_64-linux-gnu/libform.so
/usr/lib/x86_64-linux-gnu/libpanel.s
And here are my erros :
gcc -W -Wall -Werror -Wextra -I./Includes/. -lncurses -o Sources/NCurses/ncurses_init.o -c Sources/NCurses/ncurses_init.c
./Sources/NCurses/ncurses_init.o: In function `ncruses_destroy':
ncurses_init.c:(.text+0x5): undefined reference to `endwin'
./Sources/NCurses/ncurses_init.o: In function `ncurses_write_line':
ncurses_init.c:(.text+0xc5): undefined reference to `mvwprintw'
./Sources/NCurses/ncurses_init.o: In function `ncurses_init':
ncurses_init.c:(.text+0xee): undefined reference to `initscr'
collect2: error: ld returned 1 exit status
Thanks a lot
You need to change your makefile so that the -lncurses directive comes after your object code on the gcc command line, i.e. it needs to generate the command:
gcc -W -Wall -Werror -Wextra -I./Includes/. -o Sources/NCurses/ncurses_init.o -c Sources/NCurses/ncurses_init.c -lncurses
This is because object files and libraries are linked in order in a single pass.
In C++ , I fixed it just by linking the ncurses library .
Here is the command :
g++ main.cpp -lncurses
I got flags to correct order by using LDLIBS variable:
ifndef PKG_CONFIG
PKG_CONFIG=pkg-config
endif
CFLAGS+=-std=c99 -pedantic -Wall
LDLIBS=$(shell $(PKG_CONFIG) --libs ncurses)
man gcc | grep -A10 "\-l library"
-l library
Search the library named library when linking. (The second alternative with the library as a separate argument is only for POSIX
compliance and is not recommended.)
It makes a difference where in the command you write this option; the linker searches and processes libraries and object files
in the order they are specified. Thus, foo.o -lz bar.o searches
library z after file foo.o but
before bar.o. If bar.o refers to functions in z, those functions may not be loaded.

CS107 Assignment file couldn't compile, missing expat.h and thread_107.h files

I was auditing cs107 at stanford online
The problem I ran into is with assignment 6, when I type "make" in terminal, the error message pops up. Basically, I miss two header files, which I guess can be got from the pre-compiled .lib file. But somehow it just doesn't work.
Here's part of the original make file:
CFLAGS = -D_REENTRANT -g -Wall -D__ostype_is_$(OSTYPE)__ -std=gnu99 -I/usr/class/cs107/include/ -Wno-unused-function $(DFLAG)
LDFLAGS = -L/usr/class/cs107/assignments/assn-6-rss-news-search-lib/$(OSTYPE) -L/usr/class/cs107/lib -lexpat -lrssnews $(PLATFORM_LIBS) $(THREAD_LIBS)
PFLAGS= -linker=/usr/pubsw/bin/ld -best-effort -threads=yes -max-threads=1000
Edit:
When I said "This is supposed to compile even without threading implementation", I meant that it should compile without FURTHER threading implementation by students.
So here's the error message with thread:
gcc -D_REENTRANT -g -Wall -D__ostype_is_linux__ -std=gnu99 -I/usr/class/cs107/include/ -Wno-unused-function -c -o rss-news-search.o rss-news-search.c
rss-news-search.c: In function ‘main’:
rss-news-search.c:109:3: warning: implicit declaration of function ‘InitThreadPackage’ [-Wimplicit-function-declaration]
gcc rss-news-search.o -D_REENTRANT -g -Wall -D__ostype_is_linux__ -std=gnu99 -I/usr/class/cs107/include/ -Wno-unused-function -L/home/h/cs107/assn-6-rss-news-search-lib/linux -L/usr/class/cs107/lib -L. -lexpat -lrssnews -lnsl -lpthread -lthread_107_linux -o rss-news-search
/usr/bin/ld: cannot find -lthread_107_linux
collect2: ld returned 1 exit status
make: *** [rss-news-search] Error 1
here's the error message without $(THREAD_LIBS):
gcc -D_REENTRANT -g -Wall -D__ostype_is_linux__ -std=gnu99 -I/usr/class/cs107/include/ -Wno-unused-function -c -o rss-news-search.o rss-news-search.c
rss-news-search.c: In function ‘main’:
rss-news-search.c:109:3: warning: implicit declaration of function ‘InitThreadPackage’ [-Wimplicit-function-declaration]
gcc rss-news-search.o -D_REENTRANT -g -Wall -D__ostype_is_linux__ -std=gnu99 -I/usr/class/cs107/include/ -Wno-unused-function -L/home/h/cs107/assn-6-rss-news-search-lib/linux -L/usr/class/cs107/lib -L. -lexpat -lrssnews -lnsl -lpthread -o rss-news-search
rss-news-search.o: In function `main':
/home/h/cs107/assn-6-rss-news-search/rss-news-search.c:109: undefined reference to `InitThreadPackage'
collect2: ld returned 1 exit status
make: *** [rss-news-search] Error 1
In the later case, if I comment out "InitThreadPackage", it compiles just fine.
This is the procedure to compile your project:
Create a file assn-6-rss-news-search/thread_107.h, and put this inside:
/* Empty header file */
Copy the library librssnews.a from assn-6-rss-news-search-lib/linux/ to assn-6-rss-news-search/
Modify the file rss-news-search.c by commenting the call to the function : InitThreadPackage on line 109:
//InitThreadPackage(false);
Modify the Makefile to include the path to the current directory (to be able to link to the library you've copied earlier librssnews.a):
The line 27 should look like this:
LDFLAGS = -L/usr/class/cs107/assignments/assn-6-rss-news-search-lib/$(OSTYPE) -L/usr/class/cs107/lib -L. -lexpat -lrssnews $(PLATFORM_LIBS) $(THREAD_LIBS)
Then:
make clean
make
EDIT :
When you got this error cannot find lthread_107_linux, Edit your Makefile to remove this $(THREAD_LIBS) on line 27:
LDFLAGS = -L/usr/class/cs107/assignments/assn-6-rss-news-search-lib/$(OSTYPE) -L/usr/class/cs107/lib -L. -lexpat -lrssnews $(PLATFORM_LIBS)
The class-specific header files, like thread_107.h are found in /usr/class/cs107/include/ on whatever machine the instructor is expecting the students to use. If you're not using that machine, you'll have to copy those include files or make your own.
The expat.h file is from an open source library. You'll need to install the appropriate package on the system you're compiling on. On Ubuntu, that's sudo apt-get install libexpat1-dev, but the package name should be similar on other distributions.

Linker error: undefined reference to shared object

I am trying to use an external library called iniparser in my C program. I'm using gcc 4.4.
I put the iniparser library in a subdirectory called lib/ header files are in lib/iniparser/src and the library is compiled to lib/iniparser/libiniparser.so.0.
I wrote a short Makefile to compile it, here's the output of make:
gcc -Wall -Wextra -Werror -c -I include/ src/smag_main.c -L lib/iniparser -liniparser -I lib/iniparser/src
gcc -Wall -Wextra -Werror -c -I include/ -L lib/iniparser -liniparser -I lib/iniparser/src src/agros.c
gcc -Wall -Wextra -Werror -c -I include/ -L lib/iniparser -liniparser -I lib/iniparser/src src/main.c
gcc -Wall -Wextra -Werror -L lib/iniparser -liniparser -o agros smag_main.o main.o agros.o
smag_main.o: In function `sec_haskey':
smag_main.c:(.text+0xa9): undefined reference to `iniparser_find_entry'
smag_main.o: In function `parse_config':
smag_main.c:(.text+0x153): undefined reference to `iniparser_load'
smag_main.c:(.text+0x18b): undefined reference to `iniparser_getint'
smag_main.c:(.text+0x1c6): undefined reference to `iniparser_getstring'
smag_main.c:(.text+0x202): undefined reference to `iniparser_getstring'
smag_main.c:(.text+0x261): undefined reference to `iniparser_getstring'
smag_main.c:(.text+0x2c2): undefined reference to `iniparser_getint'
smag_main.c:(.text+0x2d5): undefined reference to `iniparser_freedict'
collect2: ld returned 1 exit status
make: *** [agros] Error 1
First call to gcc compiles smag_main.o successfully, the second one compiles agros.o and the third one main.o. The 4th call is the linker, that will link all those objects into an executable agros. It obviously fails.
It looks like it has problems locating iniparser.so at linking time. How's my call wrong?
I am confused.
(Alternate question, if anyone could explain how to the linking by calling ld directly it would be great).
Try putting a symlink from libiniparser.so.0 to libiniparser.so
cd lib/iniparser/
ln -s libiniparser.so.0 libiniparser.so

Resources