How do I link a C++ library with CGO and Swig? - c++

I want to use the C++ program xmr-stak in my Go program. After some research, I settled on SWIG to generate the bindings. The issue is that ld cannot find the library file. I'll just write down step by step what I did.
I created this file at src/miner/xmrstak/xmrstak.swigcxx along with the source code of xmr-stak:
%module xmrstak
%{
#include "xmrstak/net/jpsock.hpp"
#include "xmrstak/jconf.hpp"
#include "xmrstak/misc/executor.hpp"
%}
%include "xmrstak/misc/executor.hpp"
Since Swig is supported by Go, it will automatically generate the bindings at build time. But Go still requires a package name, so I've just created package.go:
package xmrstak
Now, I can build this project, which results in lots of errors like:
/tmp/go-build176223381/gitlab.com/jgillich/autominer/miner/xmrstak/_obj/xmrstak_wrap.cxx.o: In function `executor::inst()':
./xmrstak/misc/executor.hpp:35: undefined reference to `executor::executor()'
To fix this, it appears I need to tell ld to link the library. I've added the following to my package.go:
// #cgo LDFLAGS: -L${SRCDIR}/xmrstak/ -l${SRCDIR}/libxmr-stak-backend.a
import "C"
And copied the libxmr-stak-backend.a in the same folder. This file is obtained by building xmr-stak using cmake . && make and should include everything I need (for now).
My issue is that this doesn't actually work. I get the following output:
$ go install
# gitlab.com/jgillich/autominer/miner/xmrstak
xmrstak/misc/executor.hpp:43: Warning 507: No Go typemap defined for ex_event &&
[further warnings ommitted]
# gitlab.com/jgillich/autominer/miner/xmrstak
/usr/bin/ld: cannot find -l/home/jgillich/go/src/gitlab.com/jgillich/autominer/miner/xmrstak/libxmr-stak-backend.a
collect2: error: ld returned 1 exit status
The file however definitely exists:
$ ls
libxmr-stak-backend.a package.go xmrstak xmrstak.swigcxx
$ file /home/jgillich/go/src/gitlab.com/jgillich/autominer/miner/xmrstak/libxmr-stak-backend.a
/home/jgillich/go/src/gitlab.com/jgillich/autominer/miner/xmrstak/libxmr-stak-backend.a: current ar archive
Did I do anything wrong here?

This fixed it for me:
// #cgo LDFLAGS: -L${SRCDIR} -lxmr-stak-backend
import "C"
Seems like I was just using ld wrong.

Related

libstdc++.so.6: error adding symbols: DSO missing from command line

I have started learning C++ on Ubuntu. I am only a few months into using Linux as well.
I am attempting to port over a 2D Ball Collision Script from Javascript to C++ for learning purposes.
I am using simple2D for the drawing in C++: https://github.com/simple2d/simple2d
I go to run this command:
simple2d build c-code-test.cpp
I receive this response:
cc1plus: warning: command line option ‘-std=c11’ is valid for C/ObjC but not for C++
/usr/bin/ld: /tmp/ccl07DBG.o: undefined reference to symbol '_ZNSt8ios_base4InitD1Ev##GLIBCXX_3.4'
//usr/lib/x86_64-linux-gnu/libstdc++.so.6: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
Due to how fresh I am with Linux and C++ I am unable to make the correct inferences to solve this based on previous questions on stack overflow. I have installed libstdc++6 so I would have though it would be linked correctly.
Can someone walk me through in steps 1, 2, 3 ... Please? Thank you kindly!
The errors you see look to be from trying to compile C++ as C. The command line option is selecting the C11 standard, which is for C, not C++. The missing symbol is because the C++ library isn't being linked in, which also happens when linking a program as C.
I haven't used simple2d, but my guess here is that the compile script they wrote does not support C++ or there is some option you need to use C++. If we look at docs:
The simple2d build command is a helpful shortcut for compiling a
single source file. Of course, you can also use a compiler directly,
for example on Unix-like systems:
cc triangle.c `simple2d --libs` -o triangle
Why don't you try something like their example that invokes the compiler directly. But you would need to use g++ instead of cc. Something like: g++ c-code-test.cpp `simple2d --libs` -o c-code-test
This is a bug with the simple2d script.
They're basically using the wrong build command for C++.
You could work around it by patching in the fix I've linked to, or using the manual build step shown by TrentP.
Or wait for the next version after v1.1.0.

G++ can't find references to raw() or cbreak(), even when linking curses [duplicate]

This question already has an answer here:
DSO missing from command line [duplicate]
(1 answer)
Closed 5 years ago.
I'm having trouble getting some absolute basic work with curses.h done, even though I've worked with it before. I'm sure it's a classic case of missing something small, but I'm at my wit's end.
G++ absolutely won't recognize the functions raw() or cbreak(), even though curses.h is included in my .cpp and header file, and linked to when compiling with (minimal version):
g++ debugC.cpp -lcurses
With the relevant code being:
#include <curses.h>
#include "debugC.h"
#include "machine.h"
using namespace std;
debugC::debugC(machine *BFM){
localMachine = BFM;
}
//entry into debugger
void debugC::start(){
void * v = NULL;
initscr();
raw();
noecho();
}
The errors returned by g++:
/usr/bin/ld: /tmp/cci6mA0L.o: undefined reference to symbol 'raw'
/usr/lib/libtinfo.so.6: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
I've stripped this down to minimal functioning code for clarity. It compiles without the call to raw().
curses.h is clearly included, and I've linked against it when compiling. How could it not understand references to some curses functions, and not others?
I've scoured SO and Google for help but I can't seem to find a solution, I'd really appreciate any possible insight. Thanks.
Some systems configure ncurses as two libraries: ncurses (or ncursesw) which is the high-level library, and tinfo (or tinfow) which is the low-level library. raw is a low-level feature.
Most systems provide the package/configuration scripts (e.g., ncursesw6-config or the data files for pkg-config), and the --libs option lists both libraries when it is built in this way:
$ ncursesw6-config --libs
-lncursesw6 -ltinfow6
$ pkg-config --libs ncursesw6
-lncursesw6 -ltinfow6
For example, assuming a correctly installed pkg-config, you could do something like:
g++ debugC.cpp $(pkg-config --libs ncurses)
In some configurations (using the rpath feature for instance), the dependent library names are stored in the shared library, so that all one needs to do is refer to the top-level library to get both. Debian (and derived systems such as Ubuntu) don't use rpath, while also configuring ncurses as two libraries.
Two methods of configuration are provided (but depends on the packager...), by the way:
ncurses*-config script predates pkg-config, and works (though some are confused by the naming convention for cross-compiler tools), while
pkg-config has problems with standardization (not noticed by single-platform developers).

Unable to compile program with twitcurl

I want to compile a C++ program with a twitter library, on Linux.
I'm current using twitcurl as the twitter API library and installed g++ and all the necessary files and packages that are listed on the official website: http://code.google.com/p/twitcurl/wiki/WikiHowToUseTwitcurlLibrary
However, when I compile my program using this command g++ twitterClient.cpp -ltwitcurl, I get this error: cannot find -ltwitcurl
I also used CodeBlocks IDE to compile it but got this error: undefined reference to twitCurl::~twitCurl()
`
My code only contains a few lines:
#include <iostream>
#include "Twitter/Twitter.hpp"
using namespace std ;
int main ()
{
Twitter t ;
return 0 ;
}
I've already spent a lot of time on this but am unable to solve the problem. What should I do in order to compile the program on the command-line and CodeBlocks?
$ g++ twitterClient.cpp -ltwitcurl
cannot find -ltwitcurl
This means your compiler doesn't find the libtwitcurl.so.1. in its library directories.
First, make sure you correctly build the twitcurl library and obtained the libtwitcurl.so.1. file with something like this :
svn co http://twitcurl.googlecode.com/svn/trunk/libtwitcurl
cd libtwitcurl/
make
Secondly, make sure you put the file (or a symlink) in one of your compiler's library path :
cp libtwitcurl.so.1.0 /usr/lib/
You can check g++ library paths using the following command :
g++ --print-search-dirs | grep libraries
(/usr/lib/ is usually at the end.)
If you don't want/can't put the file in your compiler's library path, you can also tell it where to find libtwitcurl.so.1. by adding -L/path/to/twitcurl/ in the g++ options, but it is not needed if the file is already in one of the compiler's library path.
You need to specify path to twitter lib:
g++ twitterClient.cpp -L/path/to/lib/dir -ltwitcurl

Errors while trying to compile with external libraries

I have downloaded the mimetic library installation files,
and followed the INSTALL instructions.
./configure
a script that creates the make file after checking a series of things.
make
compiles the cpp files, after this different .o and .lo files appear in the original folder.
make install
seems to do a lot but the only thing that I seem to notice is that a mimetic directory
appears under /usr/local/include with all the header files.
than I try to compile the most simple main file possible:
(as offered in the library site : original example )
#include <mimetic/mimetic.h>
using namespace mimetic;
int main()
{
MimeEntity me;
return 0;
}
I am compiling with following command ( on CentOS 5.7, gcc version : 4.1.2 ):
g++ mimetic.cpp
The error I get:
/tmp/ccWnsteO.o: In function `main':
mimetic.cpp:(.text+0x80): undefined reference to `mimetic::MimeEntity::MimeEntity()'
mimetic.cpp:(.text+0x91): undefined reference to `mimetic::MimeEntity::~MimeEntity()'
collect2: ld returned 1 exit status
From this I understand that the header files are found but the source/library itself
is missing.
the MimeEntity constructor declaration appears in : /usr/local/include/mimetic/mimeentity.h
when I do a search for mimeentity I get the following :
/home/mimetic-0.9.7/mimetic/mimeentity.o
/home/mimetic-0.9.7/mimetic/mimeentity.h
/home/mimetic-0.9.7/mimetic/mimeentitylist.h
/home/mimetic-0.9.7/mimetic/mimeentity.cxx
/home/mimetic-0.9.7/mimetic/.libs/mimeentity.o
/home/mimetic-0.9.7/mimetic/mimeentity.lo
/home/mimetic-0.9.7/mimetic/.deps/mimeentity.Plo
/usr/local/include/mimetic/mimeentity.h
/usr/local/include/mimetic/mimeentitylist.h
I've tried with a search path to the libraries but the same error appears
g++ mimetic.cpp -L/home/mimetic-0.9.7/mimetic/
Something else strange is happening, when I try to compile the main mimetic.cpp file
with the line
MimeEntity me;
changed to
MimeEntity me();
it compiles.
You are getting a linker error simply because you are not referencing the library when compiling the test source file. It needs to be something like:
g++ mimetic.cpp -l<libraryname>
The reason it compiles when you add the braces is that you are really declaring a function called 'me' that returns a MimeEntry. While it compiles, it does not do what you want.
The command you are using to build your mimetic example seems incomplete. You are specifying library search patch (-L) but not the library itself.
Make sure that -L option specified the location of the mimetic library
Add -l'the-name-of-the-mimetic-library'. My guess would be -lmimetic
Add -I (that is capital i) option for the location of the headers.

/usr/bin/ld: cannot find -lCImg

I am newbie in C++ and Eclipse simultaneously...
I want to use CImg library but when I just used a line for it I have the problem that it is described below :
My code is:
#include "CImg.h"
using namespace cimg_library;
int main() {
CImg <unsigned char> img(640,400,1,3);
return 0;}
and the error that I get is :
/usr/bin/ld: cannot find -lCImg
collect2: ld returned 1 exit status
I have searched a lot yesterday and I have tried many things that I found.
I tried almost everything for X11 library and pathread.
I changed many times the flags in the settings of the project...
Thank you in advance.
PS: I know that there is a similar(almost the same question) here g++: No such file or directory? but in my case I can not change the makefile.
CImg is a template-based library that is compiled 'on the fly' with your program, so it is not pre-compiled and thus doesn't have a libCImg.so or libCImg.a files associated to it.
You just don't need an option '-lCImg' when you call g++. Eventually, if you are using the display capabilities of CImg (which is the default behavior), you need to add
-lX11 -lpthread
on your compilation line, but that is all (and if you don't use CImgDisplay at all, those dependencies can be even removed by putting
-Dcimg_display=0
when compiling with g++).