Error of linking a static lib embedded with Lua on Linux - c++

Update
after using -ldl and link liblua.a in Project 2(console) the compile is okay, but when it runs it crashed with error Segment fault (core dumped) as soon as it runs a Lua function.
Problem Background:
OS: Linux Ubuntu
IDE: CodeBlock
Launguage: C++
2 project:
Project 1: static lib using Lua;
Project 2: console application, using the lib generated by Project 1
Problem description
Project 1 (static lib) is built successfully.
The problem is that when building project 2, it says that those Lua functions in the lib from project 1 are undefined, here is part of the error messages:
g++ -o bin/Release/BattleConsoleCB obj/Release/main.o -s
../BattleConsole/libBattleCore.a
../BattleConsole/libBattleCore.a(DataLoader.o):
In function `boolDataLoader::GetNumber<double>(char const*, double&) [clone .isra.5]':
DataLoader.cpp:(.text+0x13): undefined reference to `lua_settop'
DataLoader.cpp:(.text+0x1e): undefined reference to `lua_getglobal'
DataLoader.cpp:(.text+0x2b): undefined reference to `lua_isnumber'
DataLoader.cpp:(.text+0x3e): undefined reference to `lua_tonumberx'
DataLoader.cpp:(.text+0x51): undefined reference to `lua_settop'
Note that "DataLoader.cpp" is from project 1, which should have been built in the static lib "libBattleCore.a" which should have been embedded with Lua.
How to solve the problem? Thanks for your help.
Additional information:
Project 2 should include: "libBattleCore.h", "main.cpp", libBattleCore.a
Project 1 : CodeBlockbuilding options have included "Lua/install/include" in Compile search directory and "Lua/install/lib" in Link search directory
The same code is successfully built and run on Win with VS2012
If anything else is needed, please inform, I will add it.
I am a green hand on linux and g++. :-(
Thank you

I can't comment without 50 rep. There is no support for anonymous replies. So posting here is all I can do.
It's been a few years, but with g++, I thought it was .o files that you listed on the command line and with libraries you used -L to specify the directory to search and then -lname to include the library. (Where name lacked the leading lib and trailing .a.) E.g. -L../BattleConsole -lBattleCore
Oh, and the ordering of -lfoo -lbar vs -lbar -lfoo is critical, determining which library can use code from the other.
It's not clear that a static library will necessary include code from other libraries. You may need to link (in the right order) against the libraries from project1.
Try "nm". As in nm --demangle libBattleCore.a | grep ... This will let you see what precisely is included in each library. man nm or http://linux.die.net/man/1/nm can help you figure out what the letters stand for. For example, U is Undefined (used by not provided). T is defined in the text (code) segment. W and V are weakly-defined. Etc.

Related

Unable to link CCfits example program

This is probably related to
c++ reading fits file using ccfits
which was never answered.
Anyway, I hope my question is easier to reproduce. There is an example program for CCfits at:
http://heasarc.gsfc.nasa.gov/fitsio/CCfits/html/cookbook.html
I am attempting to compile this using:
g++ cookbook.cpp -o cookbook -lCCfits -lcfitsio
The link fails for every CCfits function in the file:
/tmp/cc7hVaju.o: In function main':
cookbook.cpp:(.text+0x14): undefined reference towriteImage()'
cookbook.cpp:(.text+0x31): undefined reference to writeAscii()'
cookbook.cpp:(.text+0x4e): undefined reference towriteBinary()'
cookbook.cpp:(.text+0x6b): undefined reference to copyHDU()'
cookbook.cpp:(.text+0x88): undefined reference toreadHeader()'
cookbook.cpp:(.text+0xa5): undefined reference to readImage()'
cookbook.cpp:(.text+0xc2): undefined reference toreadTable()'
cookbook.cpp:(.text+0xdf): undefined reference to readExtendedSyntax()'
cookbook.cpp:(.text+0xfc): undefined reference toselectRows()'
collect2: error: ld returned 1 exit status
I have tried this with the CCfits package that comes with Ubuntu. I have also tried installing the package myself. Same error.
Strangely, I get similar messages if I do not include the libraries on the command line (i.e., "g++ cookbook.cpp -o cookbook"). The one difference is that I also get this error:
/tmp/ccMVMkSB.o: In function CCfits::FITS::setVerboseMode(bool)':
cookbook.cpp:(.text._ZN6CCfits4FITS14setVerboseModeEb[_ZN6CCfits4FITS14setVerboseModeEb]+0xf): undefined reference toCCfits::FITS::s_verboseMode'
This must be a clue, right? Seems to say that the libraries I have named, although they exist, do not contain all the functions I need.
Thanks for any help,
Charles
Not sure if you got a suitable answer to this question but as far as I can tell the main issue is that you are not including the definitions to the function signatures. These are usually defined in the header files of c++ libraries.
For example, if your library is installed in "/usr/local" on a UNIX system then the header files will be installed in the location "/usr/local/include/CCfits". The corresponding lib files will be installed at "/usr/local/lib". The important thing is that the compiler does not know this and you need to inform it of these locations.
g++ cookbook.cpp -o cookbook -I /usr/local/include/CCfits -L /usr/local/lib -lCCfits -lcfitsio
The "-I /usr/local/include/CCfits" flag and the given parameter inform g++ of the location of the header files that it is looking for. The "-L /usr/local/lib" flag and the given parameter inform g++ of the location of the library files. It is important to note that g++ will search in the standard location for libraries on in your environment as well this is just giving it more locations to search. There are in fact rules for what it should do if it finds multiple libraries which are the same in different locations but I don't explicitly remember those.
Also to be safe, ensure that the libraries are loaded into memory by the OS. These are shared libraries not static so they are not stored into the executable file. This won't make a difference when compiling the source but will prevent the successful execution of the executable. To ensure that the OS has loaded the library into memory run the following command:
sudo ldconfig
Yours Aye,
Omar EQ

compiling against libstdc++.so.5 is not finding symbols #GLIBCPP_3.2

I am building an application which makes use of a third party library which requires libstdc++.so.5. Until recently I was compiling my application with libstdc++.so.6 which worked fine, however it had some portability issues.
Therefore I decided installing g++ version 3.3.4 in order to be capable of compiling my application with libstdc++.so.5. However now I cannot compile my application at all. Neither with my old g++ nor with the 3.3.4 Version of it... Building the application reports the following error message:
/opt/ExPansion/lib/libexpansion.so: undefined reference to `std::basic_istream<char, std::char_traits<char> >::basic_istream(std::basic_streambuf<char, std::char_traits<char> >*)#GLIBCPP_3.2'
EDIT:
Interesting might also be the output of the following commands:
$ strings /usr/lib/libstdc++.so.5 | grep 'LIB'
GLIBCPP_3.2
GLIBCPP_3.2.1
GLIBCPP_3.2.2
GLIBCPP_3.2.3
GLIBCPP_3.2.4
GLIBC_2.0
GLIBC_2.3
GLIBC_2.1.3
GLIBC_2.1
GLIBC_2.2
GLIBCPP_FORCE_NEW
The only thing that makes me wonder is the following:
$ nm /usr/lib/libstdc++.so.5
nm: /usr/lib/libstdc++.so.5: no symbols
Is that "normal"? Is it possible that my lib is not containing the needed symbols? I downloaded this lib through:
yum install compat-libstdc++-33
..so it shouldn't be causing any problems..
From my understanding #GLIBCPP_3.2 is provided by my libstdc++.so.5. So what could be going wrong here?
I have no idea what causes my linker not finding the lib on its own...
The following question helped me however find a "workaround" to my problem: how to force linker to use shared library instead of static library?
Simply forcing my linker to link against the library helped..
gcc -o app app.o {other libs} /usr/lib/libstdc++.so.5

GMP Library, compile error in C++, MinGW, Code::Blocks

I have built GMP for MinGW. The IDE I'm using is Code::Blocks. I don't have any problems with C functions of GMP. But I'm having problem with C++. The program I tried to run is as simple as this,
#include<iostream>
#include<gmpxx.h>
using namespace std;
main()
{
mpz_class a;
a=12345;
cout<<"value"<<a<<"\n";
return 0;
}
And the Errors I get are
F:\Compilers\C_Libraries\GMP\lib\libgmpxx.a(osmpz.o):osmpz.cc|| undefined reference to `__gmpz_get_str'|
F:\Compilers\C_Libraries\GMP\lib\libgmpxx.a(osfuns.o):osfuns.cc:(.rdata+0x1c)||undefined reference to `__gmp_asprintf_memory'|
F:\Compilers\C_Libraries\GMP\lib\libgmpxx.a(osfuns.o):osfuns.cc:(.rdata+0x20)||undefined reference to `__gmp_asprintf_reps'|
F:\Compilers\C_Libraries\GMP\lib\libgmpxx.a(osdoprnti.o):osdoprnti.cc|| undefined reference to `__gmp_doprnt_integer'|
F:\Compilers\C_Libraries\GMP\lib\libgmpxx.a(osdoprnti.o):osdoprnti.cc|| undefined reference to `__gmp_asprintf_final'|
||=== Build finished: 5 errors, 0 warnings ===|
Now, some additional data:
I don't have any problem with C functions. And also, if I remove cout<< statement the file compiles and runs fine. The problem is probably with overloaded operators.
libgmpxx.a and libgmp.a are linked with compiler. It can be seen in the error messages too...
The problem is probably with the libgmpxx.a alone. So, I built the Library again, but the files are same.
I used this tutorial build GMP with MSYS for MinGW. http://www.cs.nyu.edu/exact/core/gmp/ and http://suchideas.com/journal/2007/07/installing-gmp-on-windows/
The version of GMP I'm using is 5.0.4.
So, what I want to know is, what could be the problem? And how could it be solved?
And, if unsolvable and if you have the working files for 5.0.4 version, please share it. :(
I suspect the command to build your program specifies the libgmp* libraries in the wrong order. Make sure the libgmp.a library is specified after the libgmpxx.a library:
-lgmpxx -lgmp
If they are specified in the other order, then when pulling in dependencies from libgmpxx.a library, the libgmp.a library won't be searched.
From the ld linker's docs on the -l option:
The linker will search an archive only once, at the location where it
is specified on the command line. If the archive defines a symbol
which was undefined in some object which appeared before the archive
on the command line, the linker will include the appropriate file(s)
from the archive. However, an undefined symbol in an object appearing
later on the command line will not cause the linker to search the
archive again.
See the -( option for a way to force the linker to search archives
multiple times.
You may list the same archive multiple times on the command line.

Undefined reference to MySQL libraries using g++

I am getting undefined reference to 'mysql_suchandsuch##' messages when trying to link my program with the MySQL libraries supplied with the 5.5 server. When MySQL was installed, I used the default path, which for me on Windows is C:\Program Files\MySQL\MySQL Server 5.5\. Originally, I had thought that the spaces are causing my grief, but I think I've correctly worked out how to point to the library path without spaces (still with no luck). If there's another probable cause, please let me know.
I have reviewed a series of questions on this site trying to resolve my issue...
Question 1
Question 2
Question 3
Question 4
Question 5
Question 6
Question 7
Using mingw/g++, I have tried to link using the following options, based on my own research as well as suggestions here:
-L"C:\Program Files\MySQL\MySQL Server 5.5\lib\" -llibmysql.lib
-L"C:\Program Files\MySQL\MySQL Server 5.5\lib\" -lmysqlclient.lib
-L"C:\Progra~1\MySQL\MySQLS~1.5\lib\" -llibmysql.lib
-LC:\Progra~1\MySQL\MySQLS~1.5\lib\ -lmysqlclient.lib
-L"C:\Progra~1\MySQL\MySQLS~1.5\lib\" -lmysql
In all cases, I have put the -L/-l options at the right-most part of the statement, as I understand this can matter.
I have confirmed the libraries do exist. In the /lib dir, I have libmysql.lib, mysqlclient.lib, and libmysql.dll. I have not tried to link with the .dll, as no tutorial/forum I've reviewed suggested that.
I am not using MAKEFILES.
Does anyone have specific experience with g++/MySQL?
The following commands work fine for me using a GCC 4.6.1 from November 2011:
g++ my.cpp -I D:\Opt\MySQL5.5\include ^
D:\Opt\MySQL5.5\lib\libmysql.dll -o myWithDll.exe
g++ my.cpp -I D:\Opt\MySQL5.5\include ^
-L D:\Opt\MySQL5.5\lib -lmysql -o myWithLib.exe
So both linking against the LIB and the DLL do work.
You may get a warning (see Gaffi's comment). This is because the linker does fuzzy linking for you without you having it specified; normally, it would have failed to link. It is being nice, though, and making it work for you, at the same time warning you about things happening without your having requested them. The way to suppress the warning is to make fuzzy linking explicit:
g++ -Wl,--enable-stdcall-fixup my.cpp -I D:\Opt\MySQL5.5\include ^
D:\Opt\MySQL5.5\lib\libmysql.dll -o myWithDll.exe
g++ -Wl,--enable-stdcall-fixup my.cpp -I D:\Opt\MySQL5.5\include ^
-L D:\Opt\MySQL5.5\lib -lmysql -o myWithLib.exe
This is a Cygwin/RedHat/MinGW extension to the linker; the docs are here:
--enable-stdcall-fixup
--disable-stdcall-fixup
If the link[er] finds a symbol that it cannot resolve, it will attempt to
do “fuzzy linking” by looking for another defined symbol that differs
only in the format of the symbol name (cdecl vs stdcall) and will
resolve that symbol by linking to the match. For example, the
undefined symbol _foo might be linked to the function _foo#12, or the
undefined symbol _bar#16 might be linked to the function _bar. When
the linker does this, it prints a warning, since it normally should
have failed to link, but sometimes import libraries generated from
third-party dlls may need this feature to be usable. If you specify
--enable-stdcall-fixup, this feature is fully enabled and warnings
are not printed. If you specify --disable-stdcall-fixup, this feature is
disabled and such mismatches are considered to be errors. [This option
is specific to the i386 PE targeted port of the linker]
did you try -lmysql as the linker automatically prepends lib and appends .lib

Linking with .so files (webkit)

I'm trying to create a program that uses some of the code from WebKit/GTK+. Specifically, I want to load a string, use WebKit's parser to construct a DOM tree and then iterate over that tree.
I'm trying to use a class called HTMLDocument. WebKit/GTK+ doesn't expose this as part of its API and I'm running into some trouble linking against it.
I'm able to build WebKit/GTK+ normally, which gives me a file called: libwebkit-1.0.so. My program is:
#include <iostream>
#include <WebCore/config.h>
#include <WebCore/html/HTMLDocument.h>
using namespace WebCore;
int main() {
String title = "test";
RefPtr<HTMLDocument> d = HTMLDocument::create(0);
d->open();
d->write("<!doctype html><html><head><title>" + title + "</title></head><body></body></html>");
}
This compiles fine (I'm using the same include directives used by webkit to build), but results in linking errors.
...test_doc.cpp:18: undefined reference to `WebCore::String::String(char const*)'
...test_doc.cpp:21: undefined reference to WebCore::Document::open(WebCore::Document*)'
...(similar for every function I use)
If I run:
nm -C .libs/libwebkit-1.0.so | grep 'WebCore::Document::open'
I see:
003b1830 T WebCore::Document::open(WebCore::Document*)
which seems to indicate that the function is available. I have a reasonable amount of C++ experience, but not much experience with linking files under Linux.
I'm not expecting this exact problem to be solved, but I'm hoping someone can correct me if I have conceptual problems. My main question is why I see "undefined reference" errors when I'm linking with an .so file that lists that function as being defined. Is another file or build step needed?
Thank you very much.
Using:
Ubuntu 9.10
g++ 4.4.1
g++ is invoked with:
g++ --debug -DHAVE_CONFIG_H -I. `pkg-config --cflags libsoup-2.4` \
-DBUILDING_CAIRO__=1 -DBUILDING_GTK__=1 -DWTF_CHANGES -DWTF_USE_ICU_UNICODE=1 \
-DNDEBUG -I./WebCore -I./WebCore/accessibility -I./WebCore/bindings/js \
-I./WebCore/bridge -I./WebCore/bridge/c -I./WebCore/css -I./WebCore/dom \
...many more webkit include directories...
-DDATA_DIR=\"/usr/local/share\" \
test_doc.cpp -o test_doc.out \
./webkit-1.1.15.3/.libs/libwebkit-1.0.so
(I get the same result with -L/path/to/lib -lwebkit-1.0)
I think you might be running into an ordering problem: man g++ specifies that the order of the -l option is significant, and from memory the linker will only look for symbols in objects which have preceeded the current file on the command line.
I suspect what is happening is that the linker is trying to link test_doc before it's seen libwebkit-1.0.so, so it hasn't seen any of those symbols yet and bails.
You should use the -L/path/to/web and -lwebkit-1.0.
Also, I would compile your .cpp file in to a .o and then build your executable separately to make sure things are isolated.
Anyway, you may need to set your $LD_LIBRARY_PATH environment variable to include the path where that .so is stored. If you link to a shared library, you will need that library at run-time. Therefore, you do not want to have your webkit SO stored in its build directory (build/.libs). You want to install it. If you are not root, then you should ./configure with a --prefix=/some/path to install it to some local directory. Alternatively, you can link against the static library. One way to do this is to use the -bstatic (or similar) flag before your -lwebkit-1.0.
This is a good resource for Linux library creation and use.
I think you're issue is that the symbols you need are not exported. You can do objdump --dynamic-syms libwebkit-1.0.so to see which symbols are available. In the WebKit GTK build files there is use of the -fvisibility=hidden flag to restrict the symbols. Check your generated GNUMakefile and you'll see SYMBOL_VISIBILITY = -fvisibility=hidden. You should be able to modify the build files to get what you need.