I must do a shared object that it will be used with "Import Shared Object" of LabView.
The initial file .cpp include other .cpp for use function.
How can I include other .o?
I must use, for example:
g++ name.o -shared -o libname.so
with the "-L" option?
g++ name.o -shared -o libname.so -L /usr/lib/name2.so
Is it right?
Thanks.
Related
I have a problem trying to create a Makefile that compile multiple sorces, generate only a shared library and make an exe with another file wiht the main function.
The sorces also have dependencies.
My Makefile is
CC=gcc
CFLAGS=-Wall -g
BINS=libsensorMotor.so maintarget
all: $(BINS)
libsensorMotor.o: libsensorMotor.cpp sensorMotor.h Adafruit_ADS1015.cpp Adafruit_ADS1015.h wiringPiI2C.c wiringPiI2C.h enumADCGain.h
$(CC) $(CFLAGS) -c libsensorMotor.cpp Adafruit_ADS1015.cpp wiringPiI2C.c
libsensorMotor.so: libsensorMotor.cpp sensorMotor.h
$(CC) $(CFLAGS) -fPIC -shared -o $# libsensorMotor.cpp -lc
maintarget: maintarget.c
$(CC) $(CFLAGS) -o $# $^ -L. -lsensorMotor -pthread
clean:
rm *.o $(BINS)
The script show the errors:
libsensorMotor.so Undefined reference to 'functionXXXX'
maintarget contains the main and use libsensorMotor as a shared library. libsensorMotor depends and include all the rest of the files
The error mention all the functions that libsensorMotor uses from the include sources.
I only need to generate a correct libsensorMotor.so that can use as shared library from any other main file. Internet has many tutorials but are unclear, weird and complicated, and not show how do this simple.
Is not Makefile problem, simply the line
gcc -pthread -lm -o maintarget maintarget.c libsensorMotor.cpp Adafruit_ADS1015.cpp wiringPiI2C.c
sends same error, the compiler not recongnice the function inside the pthread_create while compile C and C++ with gcc
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.
Seems archive file can be generated from object file:
ar rvs libprofile.a profile.o
What's the difference between object file and archive file?
It seems to me that both can be used with gcc directly,e.g.:
gcc *.c profile.o or gcc *.c libprofile.a
What's the difference?
The static library is a collection of one or more object files, with an index to allow rapid searching. There are some minor differences in how the compiler deals with them. With an object file you link like this:
gcc f1.o f2.o -o myexe
with libraries you can also do that:
gcc f1.o libf2.a -o myexe
or you can use shorthand:
gcc d1.o -lf2 -L. -o myexe
Also, gcc will ALWAYS link .o files, but it will only search libraries and link from them if there are undefined names still to resolve.
I know -Wl,-shared is a option of ld. I've seen some person compile like this,
$ gcc -shared -Wl,-soname,libtest.so -o libtest.so *.o
And some person like this
$ gcc -Wl,-shared -Wl,-soname,libtest.so -o libtest.so *.o
So, I want to know if there is some difference between -shared and -Wl,-shared.
Thanks.
There is a difference between passing -shared to gcc or -shared to ld (via -Wl). Passing -shared to GCC may enable or disable other flags at link time. In particular, different crt* files might be involved.
To get more information, grep for -shared in GCC's gcc/config/ directory and subdirectories.
Edit: To give a specific example: on i386 FreeBSD, gcc -shared will link in object file crtendS.o, while without -shared, it will link in crtend.o instead. Thus, -shared and -Wl,-shared are not equivalent.
I don't think there is any difference. -shared is not a supported option of gcc and it is passed to linker whether you specify it with -Wl or not. -Wl option of gcc is used to specify that a comma separated list of options is to be passed to linker for further processing.
When compiling our project, we create several archives (static libraries), say liby.a and libz.a that each contains an object file defining a function y_function() and z_function(). Then, these archives are joined in a shared object, say libyz.so, that is one of our main distributable target.
g++ -fPIC -c -o y.o y.cpp
ar cr liby.a y.o
g++ -fPIC -c -o z.o z.cpp
ar cr libz.a z.o
g++ -shared -L. -ly -lz -o libyz.so
When using this shared object into the example program, say x.c, the link fails because of an undefined references to functions y_function() and z_function().
g++ x.o -L. -lyz -o xyz
It works however when I link the final executable directly with the archives (static libraries).
g++ x.o -L. -ly -lz -o xyz
My guess is that the object files contained in the archives are not linked into the shared library because they are not used in it. How to force inclusion?
Edit:
Inclusion can be forced using --whole-archive ld option. But if results in compilation errors:
g++ -shared '-Wl,--whole-archive' -L. -ly -lz -o libyz.so
/usr/lib/libc_nonshared.a(elf-init.oS): In function `__libc_csu_init':
(.text+0x1d): undefined reference to `__init_array_end'
/usr/bin/ld: /usr/lib/libc_nonshared.a(elf-init.oS): relocation R_X86_64_PC32 against undefined hidden symbol `__init_array_end' can not be used when making a shared object
/usr/bin/ld: final link failed: Bad value
Any idea where this comes from?
You could try (ld(2)):
--whole-archive
For each archive mentioned on the command line after the --whole-archive option, include every object file in the
archive in the link, rather than searching the archive for the required object files. This is normally used to turn
an archive file into a shared library, forcing every object to be included in the resulting shared library. This
option may be used more than once.
(gcc -Wl,--whole-archive)
Plus, you should put -Wl,--no-whole-archive at the end of the library list. (as said by Dmitry Yudakov in the comment below)