Changing the path to a dynamic library in an executable - dynamic-linking

I'm building my program with clang and its using an external library. I've been developing for a while with the binaries they provided (/usr/lib/libary.so), but I now want to move over to a more current version.
I downloaded the source code and built it, resulting in an include file and a new library (in my ~/library/build directory).
When compiling my code, I use
clang++ main.cpp -I ~/library/include -L ~/library/build/lib -llibrary
This includes the up to date header, and finds the correct library (I know it finds the correct library, because without the -L flag, I get an error saying 'undefined reference to NewlyIntroducedFunction').
However, when I try to run a.out, I get the error:
./a.out: symbol lookup error: ./a.out: undefined symbol: NewlyIntroducedFunction
Running ldd on ./a.out shows me the line:
library.so => /usr/lib/library.so
So I assume that, although at compile time the correct library is being used, at runtime it isn't. I added ~/library/build to the start of PATH and that didn't work.
What do I do to get the correct version of library.so found?

Your LD_LIBRARY_PATH variable (library search path) is probably not correct

Related

Compiling SQLite RTREE in MSVC?

I need to compile the rtree extension for SQLite from source code. The readme includes these instructions:
The easiest way to compile and use the RTREE extension is to build
and use it as a dynamically loadable SQLite extension. To do this
using gcc on *nix:
gcc -shared rtree.c -o libSqliteRtree.so
You may need to add "-I" flags so that gcc can find sqlite3ext.h
and sqlite3.h. The resulting shared lib, libSqliteRtree.so, may be
loaded into sqlite in the same way as any other dynamicly loadable
extension.
Problem I'm having is that I'm on Windows, not Linux, and so need to use MSVC. I tried:
cl rtree.c -link -out:libSqliteRtree.so
This gave cannot open include file errors until I found the various .h files it was complaining about and moved them into the same directory. Now, however, it's gotten to:
/out:rtree.exe
-out:libSqliteRtree.so
rtree.obj
Creating library libSqliteRtree.lib and object libSqliteRtree.exp
LINK : fatal error LNK1561: entry point must be defined
I admit I have pretty much zero clue what I'm doing in a compiler, and I'm not sure where to go from here to resolve its problem. Am I "translating" the compiler flags correctly from GCC to MSVC? What else can I tweak to try to get the SQLite extension out of the source code? Should I beg a favor from a developer on ateam with a Linux server and ask them to do it for me?
Thanks to Shawn for commenting to look at the SQLite Run-Time Loadable Extensions documentation, which had more information in it:
To compile on Windows using MSVC, a command similar to the following will usually work:
cl YourCode.c -link -dll -out:YourCode.dll
So for my situation: cl rtree.c -link -dll -out:libSqliteRtree.dll worked.

Build a QT program from command line

I know this question has already been asked, but I encounter an issue that I haven't seen elsewhere.
I am trying to build automatically a QT program on Jenkins through a JenkinsFile.
So I want to build this program in command line.
On Qt Creator, everything works fine, my makefile is generated and the program compiles.
But when I manually type the exact commands that are executed in Qt on a terminal (cmd and cygwin), the compilation fails.
The errors are usually ld: cannot find -lXXXXXX
My guess is that it is an environment problem so I tried to add some lib paths in the $PATH, $LIBRARY_PATH, and $LD_LIBRARY_PATH variables but it doesn't resolve the problem. The error just becomes Undefined reference to ___XXXXXX
I would appreciate some help on this issue !
Thanks.
EDIT
The building (slave) machine is a windows 7. Here is a screenshot of the compilation stage in Qt (which works fine). The commands I try to type in a terminal are exactly the same as the blue lines on the screenshot. (sorry some lines are written in French)
From the error message ld: cannot find -lXXXXXX and the environment variables, I would suppose that you are compiling in Linux/Unix. Now, if you are compiling with g++, the environment variables $PATH, $LIBRARY_PATH, and $LD_LIBRARY_PATH won't have any effect on finding libraries. What you may try is an -L argument to the compiler telling it where the library is located, I mean:
g++ -L /path/to/libXXXXX.so -l XXXXX -o result source.cpp

Sqlite 3.7.15 Crosss compilation for ARM

I am using SQLite 3 for Database management in my ARM9 based microprocessor.
I want to cross compile the latest version of the SQLite 3 for my project in Linux (Ubuntu 10.04). I am using the arm-none-linux-gnueabi-gcc compiler for development.
I tried to cross compile using following commands,
Downloaded the sqlite-amalgamation-3.7.0.tar
I extract it and then write the following command on Terminal,
sudo ./configure --exec-prefix=/media/8CCC8E9BCC8E7F68/SQLIte3/sqliteinstall/ --host=arm --target=arm CC=/opt/arm-2011.03/bin/arm-none-linux-gnueabi-gcc AR=/opt/arm-2011.03/bin/arm-none-linux-gnueabi-ar STRIP=/opt/arm-2011.03/bin/arm-none-linux-gnueabi-strip RANLIB=/opt/arm-2011.03/bin/arm-none-linux-gnueabi-ranlib CFLAGS="-Os"
It successfully cross compiled the SQLite.
Then,
sudo make command.
It successfully run.
Now "make install " command.
It did not give me an error but when i went to the config.log file i found there is some sentences as following,
1.conftest.c:17:7: error: size of array 'off_t_is_large' is negative
2.conftest.c:12:28: fatal error: ac_nonexistent.h: No such file or directory
compilation terminated.
3.conftest.cpp:23:28: error: ac_nonexistent.h: No such file or directory
4.conftest.c:67:13: error: invalid type argument of unary '*' (have 'int')
I doubt that weather it has been cross compiled properly or not.
I can not understand.
I inserted the library on my board it works fine but the problem is that the speed got very slow. I think there is some problem that i have not set any flags for the GCC compiler.
I could not find any options.How I can set the particular flags for the GCC compiler so that unnecessary features can be omitted.
You probably shouldn't try to do cross-compilation manually. Instead, use an embedded Linux build system that will do that for you, and automate the cross-compilation process entirely. My favourite is of course Buildroot (http://buildroot.org), but there are plenty of others (with varying levels of quality, complexity and features) : OpenEmbedded, Yocto, PTXdist, etc.

mingw ignores '-L' flag

I am getting linker failures under MinGW, however I cannot see why. This is the link command:
g++ -shared -mthreads
-Wl,--out-implib,C:\Users\camm\Syren\libs\libSy_polyMesh.a -o C:\Users\camm\Syren\libs\Sy_polyMesh.dll debug/Sy_polyMesh.o
debug/moc_Sy_polyMesh.o debug/qrc_Sy_polyMesh.o -L"c:\Qt\4.8.4\lib"
-lglu32 -lopengl32 -lgdi32 -luser32 -LC:\Users\camm\Syren/libs -lSyren -lglew32 -lboost_system -lQtSvgd4 -lQtSqld4 -lQtOpenGLd4 -lQtGuid4 -lQtCored4
The undefined reference errors come from the Syren dll (I should state the command was automatically generated by qmake). The -LC:\Users\camm\Syren/libs looks malformed to me because of the mix of forward and backslashes, but if I manually set them to all one way or the other - it does not change the compiler output.
I had earlier problems with 3rd party libraries I needed (GLEW and Boost specifically), but because they were relatively 'constant' I didn't have a problem putting them in my C:\MinGW\lib directory. But that is really not an option for my plugins.
What I find is that the MinGW docs state in a few locations:
...since suitable search paths may always be specified using -L
options.
...but that GCC itself furnishes the effective defaults, by supplying
appropriate -L options.
However, C:\Users\camm\Syren\libs is where Syren.dll resides!
Edit: Here are the LIBS declarations in my .pro file:
LIBS += -L$(SYREN_PATH)/libs \
-lSyren
win32 {
LIBS += -lglew32 \
-lboost_system
}
And $(SYREN_PATH) expands to C:\Users\camm\Syren. Also I can see to the 'missing' symbols in Syren.dll, for example:
C:\Users\camm\Documents\Syren\Sy_polyMesh_debug/../Sy_polyMesh/src/Sy_polyMesh.cpp:341:
undefined reference to `Sy_GLBuffer::unbind()'
Can be seen listed as:
6c500bd6 T _ZN11Sy_GLBuffer6unbindEv
Edit2
After adding a verbose flag to the linker stage I noticed that the linker was iterating through each search path and then through each library naming convention, and using the first one it could open.
attempt to open C:\Users\camm\Syren/libs/libSyren.dll.a failed
attempt to open C:\Users\camm\Syren/libs/Syren.dll.a failed
attempt to open C:\Users\camm\Syren/libs/libSyren.a succeeded
Hypothesizing that the libSyren.a may be broken, I renamed it to force the linker to use the .dll:
attempt to open C:\Users\camm\Syren/libs/libSyren.dll.a failed
attempt to open C:\Users\camm\Syren/libs/Syren.dll.a failed
attempt to open C:\Users\camm\Syren/libs/libSyren.a failed
attempt to open C:\Users\camm\Syren/libs/Syren.lib failed
attempt to open C:\Users\camm\Syren/libs/libSyren.dll failed
attempt to open C:\Users\camm\Syren/libs/Syren.dll succeeded
But I still get exactly the same error messages!
If you are linking the right DLL and the linker isn't complaining about a missing file, the dll might be missing exports to allow linking.
The MinGW linker can link directly to a DLL if it properly exports the symbols, although it is still recommended to link to the import library (which should be created in a qmake build) which is named lib*.a or lib*.dll.a. I believe the linker looks for variants with and without the libprefix, but I am unsure and should test this myself.
You can check what symbols a DLL exports by using objdump and/or nm.
If the linker doesn't complain about not being able to load Syren dll, it means that the file is correctly loaded... The symbols are just missing into the Syren dll (not exported ?)... Why it's hard to tell without more information
When you built the Syren lib, did you have any warning about missing prototypes ?
What is used by Syren lib, nothing not portable or requiring a Windows dll ?
Could you give the list of missing symbols ?
Edit : How do you compile the Syren.dll ? Did you use Mingw ? What option did you pass to the compiler / linker ?
I suggest to read these 2 links :
http://www.mingw.org/wiki/sampleDLL
http://www.mingw.org/wiki/CreateImportLibraries
If you are exporting C++ function you must use the same compiler between the program and the DLL. Or you could use a C-style wrapper functions to encapsulate the C++ ABI.
A very good article about this subject : http://www.codeproject.com/Articles/28969/HowTo-Export-C-classes-from-a-DLL
What happens when you replace $(SYREN_PATH) with $${SYREN_PATH}?
Because the former notation $() means the contents of an environment variable at the time Makefile is executed.
See the qmake variable reference.

compiling qt 4.7.3 on mingw32 with gcc 4.6.0

I am trying to compile Qt 4.7.3 on mignw32 using gcc 4.6.0.
I get the following error when running ./configure:
In file included from C:/work/qt-gcc-4.6.0/include/QtCore/private/qcore_unix_p.h:1:0,
from C:/work/qt-gcc-4.6.0/src/corelib/io/qfsfileengine_unix.cpp:45:
C:/work/qt-gcc-4.6.0/include/QtCore/private/../../../src/corelib/kernel/qcore_unix_p.h:59:3: error: #error "qcore_unix_p.h included on a non-Unix system"
The weird thing is that I am running Windows 7, and it is trying to include that.
Also in the Makefile it is using qfsfileengine_unix and qfsfileengine_iterator_unix instead of qfsfileengine_win and qfsfileengine_iterator_win.
If I change the Makefile to use the Windows' ones, I get the following error (the file does not exist):
In file included from C:/work/qt-gcc-4.6.0/include/QtCore/../../src/corelib/global/qglobal.h:62:0,
from C:/work/qt-gcc-4.6.0/include/QtCore/qglobal.h:1,
from C:/work/qt-gcc-4.6.0/mkspecs/win32-g++/qplatformdefs.h:53,
from C:/work/qt-gcc-4.6.0/src/corelib/io/qfsfileengine_win.cpp:43:
C:/work/qt-gcc-4.6.0/include/QtCore/qconfig.h:1:46: fatal error: ../../src/corelib/global/qconfig.h: No such file or directory
compilation terminated.
When compiling /qt/src/corelib/io/qfsfileengine_win.cpp
Suggestions?
Try ./configure --help
There is probably a flag for a ms-windows, x86 compilation.
It might be something like:
./configure --target-os=mingw32
Keep in mind -- the os parameter name might be different, and the selectable target values *might be different* -- with scripts from different authors -- some values you might encounter might be 'win32', 'win32-386', 'x86-windows32', etc.
See if
./configure --help
Won't give you a list...
You can also redirect its output to a file for easy reading in your favorite editor,
./configure --help > myconfighelp.txt
Good luck!

Resources