Linking guile to Rcpp - scheme

I am trying to link guile to an Rcpp file. It seems like things compile but there is an error when loading:
sourceCpp("test_2.cpp", rebuild = TRUE, showOutput = TRUE)
/usr/lib/R/bin/R CMD SHLIB --preclean -o 'sourceCpp_2.so' 'test_2.cpp'
g++-10 -I"/usr/share/R/include" -DNDEBUG -I"/home/matias/R/x86_64-pc-linux-gnu-library/4.0/Rcpp/include" -I"/home/matias/Documentos/Program/R/guile" -fpic -O3 -march=native -mtune=native -fPIC -pthread -I"/usr/include/guile/3.0" -c test_2.cpp -o test_2.o
g++-10 -shared -L/usr/lib/R/lib -lm -ldl -lgmpxx -lgmp -lmpfr -lmpc -lguile-3.0 -lgc -o sourceCpp_2.so test_2.o -L/usr/lib/R/lib -lR
Error in dyn.load("/tmp/Rtmpm2flY8/sourceCpp-x86_64-pc-linux-gnu-1.0.5/sourcecpp_29e2d33505085/sourceCpp_2.so") :
unable to load shared object '/tmp/Rtmpm2flY8/sourceCpp-x86_64-pc-linux-gnu-1.0.5/sourcecpp_29e2d33505085/sourceCpp_2.so':
/tmp/Rtmpm2flY8/sourceCpp-x86_64-pc-linux-gnu-1.0.5/sourcecpp_29e2d33505085/sourceCpp_2.so: undefined symbol: scm_init_guile
The linking works fine if I remove the Rcpp header and build directly with g++ instead.
My Makevars look like this:
CXX = g++-10
CXXFLAGS = -O3 -march=native -mtune=native -fPIC -pthread -I"/usr/include/guile/3.0"
CXXSTD = -std=c++11
LDFLAGS = -lm -ldl -lgmpxx -lgmp -lmpfr -lmpc -lguile-3.0 -lgc
The .cpp file:
#include <Rcpp.h>
#include <stdio.h>
#include <libguile.h>
using namespace Rcpp;
// [[Rcpp::export]]
int test_guile() {
SCM func, func2;
scm_init_guile();
scm_c_primitive_load("script.scm");
func = scm_variable_ref(scm_c_lookup("simple-func"));
func2 = scm_variable_ref(scm_c_lookup("quick-test"));
scm_call_0(func);
scm_call_0(func2);
return 0;
}

You are so, so close. You essentially solved this. I just took your file, made a small modification of making the script an argument and (as you didn't post script.scm) commented out the content-specific stuff. We still load it though:
#include <Rcpp.h>
#include <stdio.h>
#include <libguile.h>
using namespace Rcpp;
// [[Rcpp::export]]
int test_guile(std::string file) {
SCM func, func2;
scm_init_guile();
scm_c_primitive_load(file.c_str());
//func = scm_variable_ref(scm_c_lookup("simple-func"));
//func2 = scm_variable_ref(scm_c_lookup("quick-test"));
//scm_call_0(func);
//scm_call_0(func2);
return 0;
}
Similarly I just added a src/Makevars to the Rcpp.package.skeleton() created file. This is not good enough to ship as you need some minimal configure or alike logic to get these values from guile-config-3.0 or alike. But it passes the litmus test. C++11 is the default already under R 4.0.*, and the compiler is recent on my box anyway so we just have this (after removing a few GNU GMP and related parts we do not need):
PKG_CXXFLAGS = -I"/usr/include/guile/3.0"
PKG_LIBS = -lguile-3.0 -lgc
This now builds, installs, and runs just fine:
> file <- system.file("guile", "script.scm", package="RcppGuile")
> RcppGuile::test_guile(file)
[1] 0
>
For reference, I committed and pushed the entire example package here. If you provide a pointer to script.scm we can add that too.
Edit: A few seconds of googling leads to the script.scm you may have used so now we have a fully working example with a working embedded Guile interpreter:
> library(RcppGuile)
> test_guile(system.file("guile", "script.scm", package="RcppGuile"))
Script called, now I can change this
Adding another function, can modify without recompilation
Called this, without recompiling the C code
[1] 0
>

Related

Undefined reference to sequence when trying to input a vector

This seems a simple but somehow the compile sends this error message which I'm not able understand thus correct my code.
This is a simplified version of what I did, just so it can appear the error for you:
Main.cpp
include "myfunction.h"
int main(){
std::vector<int> myVet = {1,4,3};
sequence(1,2,1,myVet);
}
myfunction.h
#include <vector>
/*funtion creates a sequence*/
void sequence(int start, int end,
int step, std::vector<int> skip);
myfunction.cpp
#include "myfunction.h"
void sequence(int start, int end,
int step, std::vector<int> skip){
auto x = 0;
};
This gives me an error message which says
In function 'main':
/home/machina/Documents/Grafos&Redes/Implementação/main.cpp:18: undefined reference to 'sequence(int, int, int, std::vector <int, std::allocator<int> >)'
collect2: error: ld returned 1 exit status
Could you please explain me why it appears?
This is the following command which I've been using for compiling
g++ -std=c++11 -g -Wall -Wextra -Werror main.cpp -o main.out
You are only passing main.cpp to g++.
g++ needs to know about myfunction.cpp where your function is defined so as to compile and link it to your program.
The command to use should be:
g++ -std=c++11 -g -Wall -Wextra -Werror main.cpp myfunction.cpp -o main.out

error: ‘defaultfloat’ is not a member of ‘std’

std::defaultfloat doesn't seem to be defined in GCC, despite being in the standard (I think it's §27.5.6.4). I've isolated it to this simple program:
// test.cpp
#include <iostream>
int main()
{
std::cout << std::defaultfloat << 1.3;
return 0;
}
This compiles in VC++11. I tried compiling this with g++ 4.7.2 and g++ 4.9.0 using both of these commands:
g++ test.cpp
g++ test.cpp -std=c++11
I also tried an online compile on GCC 4.8.1 here, always with the same result:
user#office-debian:~/Documents/test$ g++ test.cpp -std=c++11
test.cpp: In function ‘int main()’:
test.cpp:5:15: error: ‘defaultfloat’ is not a member of ‘std’
std::cout << std::defaultfloat << 1.3;
Why am I getting this error?
GCC libstdc++ just doesn't support these C++11 manipulators in any of
the versions you've compiled against. A patch was submitted exactly one month ago

How to use shared library

These are my C codes simply print “Hello" Message. And I want to make mylib.c as shared library.
[mylib.c]
#include <stdio.h>
int mylib();
int main(){
mylib();
return 0;
}
int mylib(){
printf("### Hello I am mylib #####\n");
return 0;
}
[drive.c]
#include <stdio.h>
int mylib();
int main(){
mylib();
return 0;
}
At the firest I compiled mylib.c with folowing command line to make mylib.o
gcc –fPIC –g –c –Wall mylib.c
Then tried to make it shared librarly like this
gcc -shared -Wl,-soname,libmylib.so.1 -o /opt/lib/libmylib.so.1.0.1 mylib.o -lc
And I did ldconfig to update /etc/ld.so.cache
Finaly I compiled drive.c link with mylib but linker showed error
gcc -g -Wall -Wextra -pedantic -I./ -L./ -o drive drive.c –lmylib
/usr/bin/ld: cannot find –lmylib
Dose someone tell me how can I compile it?
In my way, you have to follow some ways to use shared library in C.
At first I have created a header file named "shared_library.h", in this file I have introduced a function named "method" as a function of this library.
The code is following:
/*-------This is starting of shared_library.h file-----------*/
void method();
/*-------------This is ending of shared_library.h file--------*/
Then I have defined the method in another file named "shared_library.c". The definition as in code is:
/*-------------This is starting of shared_library.c file---------*/
#include "shared_library.h"
void method()
{
printf("Method is called");
}
/*-------------This is ending of shared_library.c file---------*/
And finally, the header "shared_library.h" is ready to use. I use the library in my main C file named "main.c". The contents of "main.c" are as follows:
/*-------------This is starting of main.c file----------------*/
#include <stdio.h>
#include "shared_library.h"
int main()
{
method();
return 0;
}
/*-------------This is ending of main.c file----------------\*/
I found this article ld cannot find an existing library.
It works if I change to gcc -g -Wall -Wextra -pedantic -I./ -L/opt/lib -o drive drive.c –l:libmylib.so.1

Not able to use srand48() after changing to c++ 11

Why am I not able to compile my code to c++ 11 and use the srand48 function?
I have a program where I play around with some matrices.
The problem is that when I compile the code with the -std=c++0x flag.
I want to use some c++11 only functions and this is my approach to do so.
It compiles without any problems if I do not specify the c++ version. Like this:
g++ -O2 -Wall test.cpp -o test -g
Please correct me if I have misunderstood what the mentioned flag does.
I run my code on a Windows 7 64-bit machine and compile through cygwin. I use g++ version 4.5.3 (GCC). Please comment if more information is required.
For some unknown reason (even to myself) then all my code is written in one compilation unit.
If the error is caused by a structural error then you should also feel free to point it out. :)
I receive the following errors:
g++ -std=c++0x -O2 -Wall test.cpp -o test -g
test.cpp: In function ‘void gen_mat(T*, size_t)’:
test.cpp:28:16: error: there are no arguments to ‘srand48’ that depend on a template parameter, so a declaration of ‘srand48’ must be available
test.cpp:28:16: note: (if you use ‘-fpermissive’, G++ will accept your code, but allowing the use of an undeclared name is deprecated)
test.cpp:33:28: error: there are no arguments to ‘drand48’ that depend on a template parameter, so a declaration of ‘drand48’ must be available
Here is a sub of my code, it generates the errors shown above.
#include <iostream>
#include <cstdlib>
#include <cassert>
#include <cstring>
#include <limits.h>
#include <math.h>
#define RANGE(S) (S)
// Precision for checking identity.
#define PRECISION 1e-10
using namespace std;
template <typename T>
void gen_mat(T *a, size_t dim)
{
srand48(dim);
for(size_t i = 0; i < dim; ++i)
{
for(size_t j = 0; j < dim; ++j)
{
T z = (drand48() - 0.5)*RANGE(dim);
a[i*dim+j] = (z < 10*PRECISION && z > -10*PRECISION) ? 0.0 : z;
}
}
}
int main(int argc, char *argv[])
{
}
Regards Kim.
This is the solution that solved the problem for me:
First n.m. explained that srand() can not be used when compiling with -std=c++0x.
The correct flag to use is -std=gnu++11 however it require g++ version 4.7+
Therefore, the solution for me was to compile my code with -std=gnu++0x
The compile command = g++ -O2 -Wall test.cpp -o test -g -std=gnu++0x
If you explicitly set -stc=c++03 you will get the same error. This is because drand48 and friends are not actually a part of any C++ standard. gcc includes these functions as an extension, and disables them if standard behaviour is requested.
The default standard mode of g++ is actually -std=gnu++03. You may want to use -std=gnu++11 instead of -std=c++0x, or pass -U__STRICT_ANSI__ to the compiler.

libtool doesn't provide library dependencies to link

I am using libtool 2.2.6b on ubuntu lucid, and libtool 2.4.2 on ubuntu precise. On lucid my project will link properly. On precise it fails to link. Here's example code that demonstrates my problem;
configure.ac
AC_INIT([ltp], [0.0.1], [someone])
AM_INIT_AUTOMAKE
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_MACRO_DIR([.m4])
AC_CONFIG_FILES([Makefile foo/Makefile bar/Makefile wah/Makefile])
AC_PROG_CXX
AC_PROG_LIBTOOL
AM_SANITY_CHECK
AC_LANG_CPLUSPLUS
AC_OUTPUT
Makefile.am
SUBDIRS = foo bar wah
ACLOCAL_AMFLAGS = -I .m4
foo/Foo.h
#ifndef FOO_FOO_H_
#define FOO_FOO_H_
namespace Foo
{
class Foo
{
public:
Foo(long l);
private:
long l;
};
}
#endif
foo/Foo.cpp
#include "foo/Foo.h"
namespace Foo
{
Foo::Foo(long l) : l(l) {}
}
foo/Makefile.am
lib_LTLIBRARIES = libfoo.la
libfoo_la_SOURCES = Foo.cpp
libfoo_la_CPPFLAGS =
libfoo_la_LDFLAGS = -release 0.0.1
libfoo_la_LIBADD =
bar/Bar.h
#ifndef BAR_BAR_H_
#define BAR_BAR_H_
#include "foo/Foo.h"
namespace Bar
{
class Bar
{
public:
Bar(const Foo::Foo & f);
private:
Foo::Foo f;
};
}
#endif
bar/Bar.cpp
#include "bar/Bar.h"
namespace Bar
{
Bar::Bar(const Foo::Foo & f) : f(f) { }
}
bar/Makefile.am
lib_LTLIBRARIES = libbar.la
libbar_la_SOURCES = Bar.cpp
libbar_la_CPPFLAGS =
libbar_la_LDFLAGS = -release 0.0.1
libbar_la_LIBADD = -L../foo -lfoo
wah/main.cpp
#include "bar/Bar.h"
int main(int argc, char * argv[])
{
Bar::Bar( 5 );
return 0;
}
wah/Makefile.am
bin_PROGRAMS = wah
wah_SOURCES = main.cpp
wah_CPPFLAGS =
wah_LDADD = -L../bar -lbar
On Lucid, wah links, on Precise, it fails with:
wah/main.cpp:5 undefined reference to `Foo::Foo::Foo(long)'
I can fix this by adding -L../foo -lfoo to wah_LDADD, but really, isn't libtool supposed to do that for me automagically? The libtool manual section on `Linking executables' seems to indicate that is exactly what it should do.
On any Debian machine I use for development, I have to compile and install Libtool by hand, because the Debian-supplied version is patched and ignores dependencies in a way that break my builds.
If Ubuntu's version is similar, you might want to install Libtool from source too.
I suppose you could say it's more of a difference in philosophy. The point of Debian's change is to encourage users to be explicit about what they depend on, which reduces the amount of unnecessary churn when dependencies deep down the tree get upgraded.
When link_all_deplibs=yes (unmodified libtool), if your program wah depends on bar and bar depends on foo, then it is implied that wah depends foo as well.
When link_all_deplibs=no (Debian's modified libtool), if your program wah depends on bar and bar depends on foo, then it is not implied that wah depends foo as well.
So, taking Debian's perspective, this is false in your program: wah does depend on foo by virtue of this line:
Bar::Bar( 5 );
Here, you are calling the constructor of Foo::Foo implicitly. As far as the C++ compiler is concerned, your program is really more like:
Bar::Bar( Foo::Foo( 5 ) );
Therefore, wah depends on foo not just indirectly, but directly. Hence, from Debian's perspective, you are should explicitly link to foo via -lfoo.
In particular, this is not the same situation as libtool's example for Linking Executables. In that example, main.o does not explicitly depend on libm, thus -lm should, in principle, be unnecessary when linking the main.o (main.c does not call cos directly). Perhaps the reason why libtool links recursively is as a work around for older systems where linkers are unable to handle indirect dependencies?
Works for me on Ubuntu 12.04 (Precise Pangolin) 32-bit, libtool 2.4.2.
I did have to change your Makefiles a bit to make dist (more) correctly:
foo/Makefile.am:
lib_LTLIBRARIES = libfoo.la
libfoo_la_SOURCES = Foo.cpp Foo.h
libfoo_la_CPPFLAGS =
libfoo_la_LDFLAGS = -release 0.0.1
libfoo_la_LIBADD =
bar/Makefile.am:
lib_LTLIBRARIES = libbar.la
libbar_la_SOURCES = Bar.cpp Bar.h
libbar_la_CPPFLAGS =
libbar_la_LDFLAGS = -release 0.0.1
libbar_la_LIBADD = -L../foo -lfoo
wah/Makefile.am
bin_PROGRAMS = wah
wah_SOURCES = main.cpp ../bar/Bar.h
wah_CPPFLAGS =
wah_LDADD = -L../bar -lbar
Here's how it links main.cpp:
make[2]: Entering directory `/xxx/ltp-0.0.1/wah'
g++ -DHAVE_CONFIG_H -I. -I.. -g -O2 -MT wah-main.o -MD -MP -MF .deps/wah-main.Tpo -c -o wah-main.o `test -f 'main.cpp' || echo './'`main.cpp
mv -f .deps/wah-main.Tpo .deps/wah-main.Po
/bin/bash ../libtool --tag=CXX --mode=link g++ -g -O2 -o wah wah-main.o -L../bar -lbar
libtool: link: g++ -g -O2 -o .libs/wah wah-main.o -L../bar /xxx/ltp-0.0.1/bar/.libs/libbar.so -L../foo /xxx/ltp-0.0.1/foo/.libs/libfoo.so
isn't libtool supposed to do that for me automagically?
Yes, it does, at least when the distribution tarball is created on a non-Ubuntu distribution. After I autoreconf on an Ubuntu box, I get the same error you do.
Apparently (according to adl) the Ubuntu distro has a patched version of libtool which sets the libtool script variable:
link_all_deplibs=no
I patched the configure generated libtool script to replace all these instances with:
link_all_deplibs=unknown
and everything linked as expected. I suppose you could do the same in a script that invokes autoreconf. Or install a non-patched version of libtool on the Ubuntu host. Or patch the patched libtool on the Ubuntu host. So there's a few options on how to fix it.

Resources