How to use CityHash128 in c++ code? - c++

I am trying to use google's cityhash hashing function. I am unable to link it to my c++ code. I have installed cityHash and it has generated libcityhash.la, etc files in my /usr/local/lib.
I am setting LD_LIB_LIBRARY=/usr/local/lib, but it doesn't seem to link to these files.
CODE:
#include <iostream>
#include <fstream>
#include <cstdlib>
int main()
{
std::ifstream file("dev/urandom");
char buff[4096];
file.read(buff, 4096);
const uint128 hashed = CityHash128(buff,4096);
file.close();
}
Compiling:
g++ -o city cityHash.cpp
Error:
/tmp/cctSoHTX.o: In function main:
cityHash.cpp:(.text+0x73): undefined reference to `CityHash128(char const*, unsigned long)'
collect2: error: ld returned 1 exit status
I include "city.h" and trying to compile it as follows:
g++ -I /usr/local/include/ -L/usr/local/lib -llibcityhash.a cityHash.cpp -o city
But i m still getting :undefined reference to `CityHash128(char const*, unsigned long)' –

Ok, it's the good old "order makes a difference". Instead of:
g++ -I /usr/local/include/ -L/usr/local/lib /usr/local/lib/libcityhash.a cityHash.cpp -o city
you should do:
g++ -I /usr/local/include/ -L/usr/local/lib cityHash.cpp -o city -lcityhash
(libraries and object files are processed in the order of appearance in the command line, and since none of the code so far has used anything from the library when you list it, nothing gets include from that library - then when you get to the actual code that does use it, you don't give the linker the library after it, so it can't find the symbol - note that this is dependant on the behaviour of the linker, so the same rules may not apply in for example a MS Visual Studio compiler/linker setup)

Related

why I use the static library to compile and link is corrent while the dynamic library is wrong for am ace demo?

my gcc/g++ version is 4.1.2 , ACE-6.10 in CentOS 5.10 and I make the ACE Library with static_libs=1 option to get the static library, after make and make install ,I get such libraries such as libACE.so , libACE.a and so on, and then I write following code to test, The codes shows as follow:
#include <ace/Log_Msg.h>
#include <ace/OS_main.h>
using namespace std;
int ACE_TMAIN(int argc, ACE_TCHAR *argv[])
{
ACE_DEBUG( (LM_DEBUG, ACE_TEXT("Hello World!\n") ) );
return 0;
}
then I use the following two method to compile and link :
method 1:
g++ -p -o acetest acetest.cpp /usr/local/src/ACE_wrappers/lib/libACE.a -I$ACE_ROOT -I$ACE_ROOT/ace -pthread -ldl -lrt
method 2:
[root#localhost testCode]# g++ -p -o acetest acetest.cpp -L/usr/local/src/ACE_wrappers/lib -lACE -I$ACE_ROOT -I$ACE_ROOT/ace -pthread -ldl -lrt
/tmp/cc0eKwlC.o: In function `main':
acetest.cpp:(.text+0x15): undefined reference to `ACE_Log_Msg::last_error_adapter()'
acetest.cpp:(.text+0x1d): undefined reference to `ACE_Log_Msg::instance()'
acetest.cpp:(.text+0x3f): undefined reference to `ACE_Log_Msg::conditional_set(char const*, int, int, int)'
acetest.cpp:(.text+0x57): undefined reference to `ACE_Log_Msg::log(ACE_Log_Priority, char const*, ...)'
collect2: ld θΏ”ε›ž 1
And it comes to the question, the method 1 to use static library is corrent, why method 2,which uses the dynamic library, is wrong?
hunger for the answer, thanks all;
When you compile your application you should add the -DACE_AS_STATIC_LIBS flag to the compiler to indicate that you want to link statically with ACE
Try adding no_hidden_visibility=1 to your platform_macros.GNU file. I believe ACE builds its shared libraries with symbols hidden by default.
See here for the benefits this can provide. However, it doesn't seem to work well when mixing static and dynamic libraries. If anyone has more info on why that is, feel free to chime in.

g++ can't find headers but I did include them

I am starting on c++ and already going wrong ...
I am trying to compile a small test of levelDB :
#include <assert.h>
#include "leveldb/db.h"
using namespace std;
int main() {
leveldb::DB* db;
leveldb::Options options;
options.create_if_missing = true;
leveldb::Status status = leveldb::DB::Open(options, "/tmp/testdb", &db);
assert(status.ok());
return 1;
}
Here is the g++ command :
g++ -I include/ testLevelDB.cpp
Output:
/tmp/ccuBnfE7.o: In function `main':
testLevelDB.cpp:(.text+0x14): undefined reference to `leveldb::Options::Options()'
testLevelDB.cpp:(.text+0x57): undefined reference to `leveldb::DB::Open(leveldb::Options const&, std::string const&, leveldb::DB**)'
The include folder is the one with the levelDB headers.
You need to tell the linker to link to the leveldb library such as
g++ -I include/ testLevelDB.cpp -lleveldb
But this won't work if the library is not in /usr/lib or /usr/local/lib for that case assuming the libleveldb.so exists in some path called $LEVELDB_PATH you need to do
g++ -I include -L $LEVELDB_PATH testLevelDB.cpp -lleveldb
-L is much like -I but it tells the linker where to looks for libraries.
Also since you seem to be new to gcc world, please have a look at this gcc intro document.
It is a linkage error. Not related to the headers. Did you link with this lib (-l..) ?

Compiling parts of Festival code written in C++ in a stand-alone C++ program

I am trying to use selective parts of the Festival code (written in C++) and trying to use them in my own C++ programs. Note that this question is not about using the Festival API but about functions within Festival that can be used directly.
The program I wrote takes in a C++ style string and tries to initialize an object of type EST_String (an internal implementation of the String class in Festival). I then try to print the object.
The code I have:
/*EST_String is a string implementation for the festival project.
* This program simply takes in a C++-style string and returns an EST_String.
* This program is being used to test for makefiles etc.
*/
#include <iostream>
#include <EST_String.h>
#include <string>
#include <cstdlib>
using namespace std;
int main(int argc, char *argv[]) {
if(argc != 2) {
cout << "Correct usage: <binary> <string>" << endl;
exit(5);
}
string word(argv[1]);
EST_String e(word.c_str()); //init EST_String.
cout << "C++ String = " << word << endl;
cout << "EST_String = ";
cout << e;
return 0;
}
I am trying to compile it (from the command line directly (no makefile at present)) like so:
g++ -I../../speech_tools/include -I../../speech_tools/base_class/string -L../../speech_tools/lib/ -lestbase -lncurses -lasound -leststring -lestools usingESTString.C -o usingESTString
The error I get is:
/tmp/cczyGTfm.o: In function `main':
usingESTString.C:(.text+0x91): undefined reference to `EST_String::EST_String(char const*)'
/tmp/cczyGTfm.o: In function `EST_Chunk::operator--()':
usingESTString.C:(.text._ZN9EST_ChunkmmEv[EST_Chunk::operator--()]+0x3e): undefined reference to `EST_Chunk::~EST_Chunk()'
usingESTString.C:(.text._ZN9EST_ChunkmmEv[EST_Chunk::operator--()]+0x49): undefined reference to `EST_Chunk::operator delete(void*)'
collect2: ld returned 1 exit status
How can I get the code to compile properly? Where am I going wrong?
Try putting the libraries you link with last on the line.
The linker often resolves references kind of "backwards", meaning that the order of files presented on the command line is important: It wants files containing references first, then the libraries containing those references.
Try adding this to end of your g++ link command: -I/usr/include/festival
-I/usr/include/speech_tools -I/usr/include/boost -lFestival -lestools
-lestbase -leststring
Making sure that the festival and speech_tools headers directory lives at: /usr/include
cd /usr/include
ls festival
ls speech_tools
I am trying to rebuild cogita with festival support, and my program linked successfully after compiling the object files using this line
g++ -Wall -fPIC -Wno-variadic-macros -fopenmp -std=gnu++0x -O2 -g -fstack-protector cogitaconfig.o go-irc.o irc.o whirr-sockets.o -o cogIRCProgram
-rdynamic /usr/local/lib/libcogutil.so -Wl,-rpath,/usr/local/lib
-I/usr/include/festival -I/usr/include/speech_tools -I/usr/include/boost
-lFestival -lestools -lestbase -leststring
I've been trying to link to festival's API too, and the Makefile I wrote executes the following link command
g++ -lpthread build/fetch/festival/src/lib/libFestival.a build/fetch/speech_tools/lib/libestools.a build/fetch/speech_tools/lib/libestbase.a build/fetch/speech_tools/lib/libeststring.a -lcurses -ldl -lm -lstdc++ build/test/speaker.o build/common/message-queue.o build/speaker/speaker-public.o build/fetch/festival/src/lib/libFestival.a -o build/bin/speaker-test
and I get a huge (25k lines) linker error full of undefined references (a part of which is here: http://pastebin.com/PCyV8xAH). I can assert that the *.a files exist (though I'm not sure if they've been built correctly or not). I compile speech_tools with make -j7 and festival with make.
Any suggestions?
I'm running Debian wheezy.

Headers not being recognised

The Background
I have the following source code
#include <libubuntuone-1.0/u1-music-store.h>
#include <libsyncdaemon-1.0/libsyncdaemon/libsyncdaemon.h>
static void
get_credentials (U1MusicStore *music_store,
gchar **oauth_consumer_token,
gchar **oauth_consumer_secret,
gchar **oauth_token,
gchar **oauth_token_secret)
{
SyncdaemonCredentials *credentials;
*oauth_consumer_token = *oauth_consumer_secret = *oauth_token = *oauth_token_secret = NULL;
*oauth_consumer_token = g_strdup (syncdaemon_credentials_get_consumer_key (credentials));
*oauth_consumer_secret = g_strdup (syncdaemon_credentials_get_consumer_secret (credentials));
*oauth_token = g_strdup (syncdaemon_credentials_get_token (credentials));
*oauth_consumer_secret = g_strdup (syncdaemon_credentials_get_token_secret (credentials));
}
int main()
{
return 0;
}
and I am compiling it with the following makefile
main: main.o
g++ main.o -o main
main.o: main.cpp
g++ -c main.cpp `pkg-config --cflags --libs gtk+-2.0`
I need to include the pkg-config option since the u1-music-store.h header tried to included gtk/gtk.h, but the compiler isn't able to find it on it's own.
libsyncdaemon.h is a meta-header whose only purpose is to include a larger list of headers, which can be seen below
#include <libsyncdaemon-1.0/libsyncdaemon/syncdaemon-authentication.h>
#include <libsyncdaemon-1.0/libsyncdaemon/syncdaemon-config-interface.h>
#include <libsyncdaemon-1.0/libsyncdaemon/syncdaemon-credentials.h>
#include <libsyncdaemon-1.0/libsyncdaemon/syncdaemon-daemon.h>
#include <libsyncdaemon-1.0/libsyncdaemon/syncdaemon-events-interface.h>
#include <libsyncdaemon-1.0/libsyncdaemon/syncdaemon-file-info.h>
#include <libsyncdaemon-1.0/libsyncdaemon/syncdaemon-filesystem-interface.h>
#include <libsyncdaemon-1.0/libsyncdaemon/syncdaemon-folder-info.h>
#include <libsyncdaemon-1.0/libsyncdaemon/syncdaemon-folders-interface.h>
#include <libsyncdaemon-1.0/libsyncdaemon/syncdaemon-interface.h>
#include <libsyncdaemon-1.0/libsyncdaemon/syncdaemon-publicfiles-interface.h>
#include <libsyncdaemon-1.0/libsyncdaemon/syncdaemon-share-info.h>
#include <libsyncdaemon-1.0/libsyncdaemon/syncdaemon-status-info.h>
#include <libsyncdaemon-1.0/libsyncdaemon/syncdaemon-status-interface.h>
#include <libsyncdaemon-1.0/libsyncdaemon/syncdaemon-transfer-info.h>
My problem
Whenever I try to compile my code, I get the following error:
main.o: In function `get_credentials(_U1MusicStore*, char**, char**, char**, char**)':
main.cpp:(.text+0x34): undefined reference to `syncdaemon_credentials_get_consumer_key'
main.cpp:(.text+0x3c): undefined reference to `g_strdup'
main.cpp:(.text+0x4e): undefined reference to `syncdaemon_credentials_get_consumer_secret'
main.cpp:(.text+0x56): undefined reference to `g_strdup'
main.cpp:(.text+0x68): undefined reference to `syncdaemon_credentials_get_token'
main.cpp:(.text+0x70): undefined reference to `g_strdup'
main.cpp:(.text+0x82): undefined reference to `syncdaemon_credentials_get_token_secret'
main.cpp:(.text+0x8a): undefined reference to `g_strdup'
collect2: ld returned 1 exit status
make: *** [main] Error
Using grep, I've tracked down the four syncdaemon_credentials_get_* functions to syncdaemon-credentials.h, which I would expect the compiler to be able to find since it's listed in libsyncdaemon.h, but for some reason that's not happening. I'm assuming it's for the reason that u1-music-store.h was unable to find gtk/gtk.h that compelled me to use the pkg-config option in my makefile, but I'm having trouble understanding why this is even the case to begin with. If the file's #included, I would expect it to be included by the compiler.
Using grep again I was able to track down g_strdup to a number of headers, but I also discovered that when I replaced by makefile with the single command
g++ main.cpp -o main `pkg-config --cflags --libs gtk+-2.0`
I can eliminate the g_strdup warning, and I'm just left with the function errors.
My question
There are two things I'm looking to know here:
What should my makefile look like in order to solve my specific problem
What is the general solution to my problem? I'm guessing it's something to do with daisy-chaining #include directives together, and having to use pkg-config to fix that, but I'm not sure.
You need to link against libsyncdaemon.so. Get the appropriate arguments from pkg-config ... libsyncdaemon-1.0.
You need to link against libraries that export the required symbols. If there is a .pc file then you can use it to get the appropriate arguments.
"Unresolved external symbol" (MSVC) and "undefined reference to" (GCC) mean that the compiler found the declarations but the linker couldn't find the definitions.
This either means that you forgot to compile and/or link against a .cpp or that you forgot to link against an external library (.lib (Windows) / .a (Unix/Linux)) or object file (.o) which contains said definitions.

undefined referance to LibSerial

So i'm writing a serial transmision program, and have just changed over to using C++, it been a while since I used C++
(I've been working with C recently, and before that java)
Now I need to use LibSerial,
(it seems much simpler to use than C's termios)
my code is:
//gen1.cpp
#include "string2num.h" // a custom header
#include <iostream>
#include <SerialStream.h>
using namespace LibSerial;
//using namespace std;
int main(int argc, char*argv[])
{
if (argc<2)
{
std::cout<<argv[0]<<"requires the device name eg \"dev/tty0\" as a parameter\nterminating.\n";
return 1;
}
SerialStream theSerialStream(argv[1]); //open the device
return 0;
}
When I compile the output:
g++ -Wall -o gen1 gen1.cpp string2num.o
/tmp/cchPBWgx.o: In function `main':
gen1.cpp:(.text+0x121): undefined reference to `LibSerial::SerialStream::SerialStream(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::_Ios_Openmode)'
/tmp/cchPBWgx.o:(.rodata._ZTVN9LibSerial15SerialStreamBufE[vtable for LibSerial::SerialStreamBuf]+0x24): undefined reference to `LibSerial::SerialStreamBuf::showmanyc()'
/tmp/cchPBWgx.o:(.rodata._ZTVN9LibSerial15SerialStreamBufE[vtable for LibSerial::SerialStreamBuf]+0x28): undefined reference to `LibSerial::SerialStreamBuf::xsgetn(char*, int)'
/tmp/cchPBWgx.o:(.rodata._ZTVN9LibSerial15SerialStreamBufE[vtable for LibSerial::SerialStreamBuf]+0x2c): undefined reference to `LibSerial::SerialStreamBuf::underflow()'
/tmp/cchPBWgx.o:(.rodata._ZTVN9LibSerial15SerialStreamBufE[vtable for LibSerial::SerialStreamBuf]+0x34): undefined reference to `LibSerial::SerialStreamBuf::pbackfail(int)'
/tmp/cchPBWgx.o:(.rodata._ZTVN9LibSerial15SerialStreamBufE[vtable for LibSerial::SerialStreamBuf]+0x38): undefined reference to `LibSerial::SerialStreamBuf::xsputn(char const*, int)'
/tmp/cchPBWgx.o:(.rodata._ZTVN9LibSerial15SerialStreamBufE[vtable for LibSerial::SerialStreamBuf]+0x3c): undefined reference to `LibSerial::SerialStreamBuf::overflow(int)'
collect2: ld returned 1 exit status
make: *** [gen1] Error 1
This is the linker complaining that it cannot find the functions referenced by the libserial header file.
If I look on my Linux system to see how the shared library is called:
$ dpkg -L libserial0
...
/usr/lib/libserial.so.0.0.0
/usr/lib/libserial.so.0
On my system this implies I would add -lserial as a g++ option (aka link with libserial.so) this would turn your compilation command into
g++ -Wall -lserial -o gen1 gen1.cpp string2num.o
Including the header file is not enough - you also need to link with the library that implements SerialStream. Assuming it is a static library called serstream.a (it is almost certainly actually called something else):
g++ -Wall -o gen1 gen1.cpp string2num.o serstream.a
old thread, but i still use Libserial. here the completed answer
My working setup.
Ubuntu 18.04
g++ 7.3.0
1) Install package for libserial
apt install libserial-dev
2) check for your headers(.h) and .so files
dpkg -l libserial0
dpkg -l libserial-dev
the first command give you the directory of shared library and the second gives you the headers location.
3) Your code.
I have to change a little your code, first i delete the custom header and modifing the constuctor call to this.
SerialStream theSerialStream;
4) compile with g++
Here my compiling command
g++ -o test -I/usr/include test.cpp -L/usr/lib/x86_64-linux-gnu -lserial -lpthread
check for the -lpthread linking option, beacuse Libserial uses mutex.
In Ubuntu/Debian make sure you have to libserial-dev package installed and use the '-lserial' flag for gcc.