How to update shared library file - clang

I'm trying to add a .lo object file compiled through libtool with clang into a shared library file.
$ libtool --tag=CC --mode=compile clang -c newobject.c -shared
Is there an equivalent command to
$ ar r libmylib.a newobject.o
for shared libraries?
Alternatively, is there a way to dump all the .lo files that are already contained in a .so file so I can re-create tne shared library, say, using this command?
$ libtool --mode=link ld -soname libmylib.so -o libmylib.so.1 libmylib.so.0 newobject.o

There is no way to incrementally alter a shared library. You need all the component object files and rebuild the shared library from those each time.
I don't know of a way to extract object files from a shared library.

Related

what are the rules zig build-lib uses for shared objects filenames?

I have a sqlite extension file. The source is sqliteext/csv.c. When I build the lib with clang the output file is created at lib/csv.so.
cc -g -fPIC -I /usr/local/include -shared sqliteext/csv.c -o lib/csv.so
When I compile the lib using zig...
zig build-lib -I /usr/local/include -I /usr/include -I /usr/include/x86_64-linux-gnu --c-source sqliteext/csv.c -dynamic --output-dir lib
There are two problems.
zig prefixes the filename with a lib
zig add a version number thing in the suffix
so the output file is lib/libcsv.so.0.0.0
And what's interesting about this is that I need to change the filename in my extension loader (that's ok) but that I also need a symlink to handle the 0.0.0.
I'm still looking at the CLI help but I'm still not seeing the thing I need.
See https://github.com/ziglang/zig/issues/2230 and https://github.com/ziglang/zig/issues/2231
The former was fixed the same day as your post via https://github.com/ziglang/zig/pull/6315

Linking Boost static libraries

I am trying to compile a shared library using static libraries from Boost and OpenCV. Here below the command I am using to compile my library.
g++ -fPIC libsaliency.cpp -shared -o libsaliency.so \
-I/home/poiesi/data/libraries/boost_1_66_0/installed_w_contrib_static/include -I/home/poiesi/data/libraries/opencv-3.4.0/installed_w_contrib_static/include \
-Wl,--whole-archive \
/home/poiesi/data/libraries/boost_1_66_0/installed/lib/libboost_graph.a \
/home/poiesi/data/libraries/boost_1_66_0/installed/lib/libboost_filesystem.a \
/home/poiesi/data/libraries/boost_1_66_0/installed/lib/libboost_system.a \
/home/poiesi/data/libraries/opencv-3.4.0/installed_w_contrib_static/lib/libopencv_core.a \
/home/poiesi/data/libraries/opencv-3.4.0/installed_w_contrib_static/lib/libopencv_highgui.a \
/home/poiesi/data/libraries/opencv-3.4.0/installed_w_contrib_static/lib/libopencv_imgproc.a \
/home/poiesi/data/libraries/opencv-3.4.0/installed_w_contrib_static/lib/libopencv_imgcodecs.a \
/home/poiesi/data/libraries/opencv-3.4.0/installed_w_contrib_static/lib/libopencv_features2d.a \
/home/poiesi/data/libraries/opencv-3.4.0/installed_w_contrib_static/lib/libopencv_video.a \
-Wl,--no-whole-archive
However, I have this error:
usr/bin/ld: /home/poiesi/data/libraries/boost_1_66_0/installed/lib/libboost_graph.a(read_graphviz_new.o): relocation R_X86_64_32 against `.rodata.str1.8' can not be used when making a shared object; recompile with -fPIC
/home/poiesi/data/libraries/boost_1_66_0/installed/lib/libboost_graph.a(read_graphviz_new.o): error adding symbols: Bad value
collect2: error: ld returned 1 exit status
Makefile:7: recipe for target 'saliency' failed
make: *** [saliency] Error 1
Does this mean I have to recompile Boost using -fPIC command? I checked this online but I haven't found much info about it. This makes me wonder if I am searching for the right thing. Do you have any suggestion?
EDIT: As suggested below by Mike, I recompiled Boost like this:
./b2 cxxflags="-fPIC" link=static install
and I can now compile my .so library.
Does this mean I have to recompile Boost using -fPIC command?
Yes. All code that is linked into a shared library must be Position Independent Code. Object
files within static libraries normally are not, as shared libraries normally
link other shared libraries.
But there is nothing in principle to stop you from building boost static libraries
from -fPIC-compiled object files.
It would be simpler, of course, to link the shared versions of the boost libraries.
With boost 1.72.0, fixed this problem by recompile boost static library with -fPIC.
./bootstrap.sh --prefix=/usr/
sudo ./b2 cxxflags=-fPIC cflags=-fPIC link=static -a
sudo ./b2 install

How to build lpeg on windows?

I've downloaded lpeg source code from http://www.inf.puc-rio.br/~roberto/lpeg/lpeg-0.12.tar.gz
How to get the dll? I can't do it with the makefile included. I'm using mingw32.
You can use this simple batch file running from lpeg folder:
set LUA_DIR=D:\lua-5.2
gcc -O2 -shared -s -I %LUA_DIR%\src -L %LUA_DIR%\src -o lpeg.dll lptree.c lpvm.c lpcap.c lpcode.c lpprint.c -llua52
Just set LUA_DIR folder to the folder with your Lua installation; it works with both Lua 5.1 and Lua 5.2.
First change the LUADIR variable to the correct location of your Lua include files. Then add the following make target (using the correct path to your Lua DLL):
mingw: $(FILES)
$(CC) $(CFLAGS) -shared $(FILES) -o lpeg.dll C:\path\to\lua52.dll
I also had to change CC from gcc to mingw32-gcc, but that might just be my broken MinGW installation.
make mingw
should work now.

How to add directories to ld search path for a cross-compilation to ARM?

I am trying to configure util-linux to cross compile using arm-none-linux-gnueabi from CodeSourcery. My only problem so far is that it can't find my ncurses library which I compiled.
How can I add a directory to the ld search path? I've tried adding to my LIBRARY_PATH and LD_LIBRARY_PATH variables, but neither does anything. I know that I can add the -L flag to gcc and it will add to the linker path, but is there any way to do this globally, so that I can do it once, and not have to worry about it again?
Here is the output of arm-none-linux-gnueabi-gcc -print-search-dirs | grep libraries | sed 's/:/\n/g':
libraries
=/tools/bin/../lib/gcc/arm-none-linux-gnueabi/4.6.1/
/tools/bin/../lib/gcc/
/tools/bin/../lib/gcc/arm-none-linux-gnueabi/4.6.1/../../../../arm-none-linux-gnueabi/lib/arm-none-linux-gnueabi/4.6.1/
/tools/bin/../lib/gcc/arm-none-linux-gnueabi/4.6.1/../../../../arm-none-linux-gnueabi/lib/
/tools/bin/../arm-none-linux-gnueabi/libc/lib/arm-none-linux-gnueabi/4.6.1/
/tools/bin/../arm-none-linux-gnueabi/libc/lib/
/tools/bin/../arm-none-linux-gnueabi/libc/usr/lib/arm-none-linux-gnueabi/4.6.1/
/tools/bin/../arm-none-linux-gnueabi/libc/usr/lib/
I would like to add /arm/usr/lib and /arm/usr/local/lib to my ld search path.
If you need output from any other commands, just ask!
EDIT: I just found out about the CFLAGS environment variable--do all configure scripts/makefiles honor it?
Thank you!
If the ncurses library you compiled are going to be linked to the ARM binary you are cross-compiling you can not use LD_LIBRARY_PATH! LD_LIBRARY_PATH is only used by the current run-time and is in no way used by the compiler or linker when building your application.
The use of CFLAGS depends on creator of Makefile. CFLAGS are not automatically used even if they are defined as an environment variable. Only tools like the autoconf tools can pick them up from the environment and use them automagically. In the Makefiles find something like:
$(CC) $(CFLAGS) ....
if this fragment exists then the Makefile uses the CFLAGS variable. LDFLAGS is the more appropriate environment variable to use for link-time options.

How do I include a path to libraries in g++

I am trying to include the path to extra libraries in my makefile, but I can't figure out how to get the compiler to use that path. so far I have:
g++ -g -Wall testing.cpp fileparameters.cpp main.cpp -o test
and I want to include the path to
/data[...]/lib
because testing.cpp includes files from that library. Also, I'm on a linux machine.
EDIT: Not a path to a library. Just to files that were included. My bad.
To specify a directory to search for (binary) libraries, you just use -L:
-L/data[...]/lib
To specify the actual library name, you use -l:
-lfoo # (links libfoo.a or libfoo.so)
To specify a directory to search for include files (different from libraries!) you use -I:
-I/data[...]/lib
So I think what you want is something like
g++ -g -Wall -I/data[...]/lib testing.cpp fileparameters.cpp main.cpp -o test
These compiler flags (amongst others) can also be found at the GNU GCC Command Options manual:
3.16 Options for Directory Search
In your MakeFile or CMakeLists.txt you can set CMAKE_CXX_FLAGS as below:
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I/path/to/your/folder")
Alternatively you could setup environment variables.
Suppose you are using bash, then in ~/.bashrc, write
C_INCLUDE_PATH="/data/.../lib/:$C_INCLUDE_PATH" ## for C compiler
CPLUS_INCLUDE_PATH="/data/.../lib/:$CPLUS_INCLUDE_PATH" ## for Cpp compiler
export C_INCLUDE_PATH
export CPLUS_INCLUDE_PATH
and source it with source ~/.bashrc.
You should be good to go.

Resources