Skip to content

[Rcpp-devel] undefined symbol: clock_gettime in Rcpp 0.10.2

6 messages · Dirk Eddelbuettel, Martin Morgan, Yan Zhou

#
When trying to install Rcpp 0.10.2 with

$ R --version
R Under development (unstable) (2012-12-18 r61372) -- "Unsuffered Consequences"
$ clang++ --version
Ubuntu clang version 3.0-6ubuntu3 (tags/RELEASE_30/final) (based on LLVM 3.0)
Target: x86_64-pc-linux-gnu
Thread model: posix

I get

$ R CMD INSTALL Rcpp_0.10.2.tar.gz
...
clang++ -I/home/mtmorgan/bin/R-devel/include -DNDEBUG -I../inst/include/ 
-I/usr/local/include    -fpic  -g -O2  -c Timer.cpp -o Timer.o
...
** testing if installed package can be loaded
Error in dyn.load(file, DLLpath = DLLpath, ...) :
   unable to load shared object 
'/home/mtmorgan/R/x86_64-unknown-linux-gnu-library/2.16/Rcpp/libs/Rcpp.so':
   /home/mtmorgan/R/x86_64-unknown-linux-gnu-library/2.16/Rcpp/libs/Rcpp.so: 
undefined symbol: clock_gettime
Error: loading failed

 From man clock_gettime I have

...
        Link with -lrt.

and adding PKG_LIBS += -lrt to src/Makevars addresses the problem for me, but 
I'm not sure that is a universal solution? Also, I had an identical problem with 
another package (Matrix, since corrected) so there is perhaps something 
a-typical about my configuration.

Martin
#
-lrt is required on Linux. On other platform it will generate an error instead  since librt is Linux specific.

Yan
On Dec 24, 2012, at 10:31 AM, Martin Morgan <mtmorgan at fhcrc.org> wrote:

            
#
On 23 December 2012 at 18:31, Martin Morgan wrote:
| When trying to install Rcpp 0.10.2 with
| 
| $ R --version
| R Under development (unstable) (2012-12-18 r61372) -- "Unsuffered Consequences"
| $ clang++ --version
| Ubuntu clang version 3.0-6ubuntu3 (tags/RELEASE_30/final) (based on LLVM 3.0)
| Target: x86_64-pc-linux-gnu
| Thread model: posix

I just upgraded my r-devel version today; the one I used to test 0.10.2 was
probably a week or at the most two weeks old. I did quite a few R CMD check
runs; they all passed -- but I only used g++.

Methinks I could have caught that if I had used clang.
 
| I get
| 
| $ R CMD INSTALL Rcpp_0.10.2.tar.gz
| ...
| clang++ -I/home/mtmorgan/bin/R-devel/include -DNDEBUG -I../inst/include/ 
| -I/usr/local/include    -fpic  -g -O2  -c Timer.cpp -o Timer.o
| ...
| ** testing if installed package can be loaded
| Error in dyn.load(file, DLLpath = DLLpath, ...) :
|    unable to load shared object 
| '/home/mtmorgan/R/x86_64-unknown-linux-gnu-library/2.16/Rcpp/libs/Rcpp.so':
|    /home/mtmorgan/R/x86_64-unknown-linux-gnu-library/2.16/Rcpp/libs/Rcpp.so: 
| undefined symbol: clock_gettime
| Error: loading failed
| 
|  From man clock_gettime I have
| 
| ...
|         Link with -lrt.
| 
| and adding PKG_LIBS += -lrt to src/Makevars addresses the problem for me, but 
| I'm not sure that is a universal solution? Also, I had an identical problem with 
| another package (Matrix, since corrected) so there is perhaps something 
| a-typical about my configuration.

I don't think so. The internal-to-Rcpp Timer class is new in 0.10.2.  And Yan
is (as usual) correct, -lrt is AFACR specific to Linux. I needed that in the
past when using the kernel-based high-res timer.

So this is something we need to figure out. So we seem to know that r-devel
and clang need it. Can you check if r-release needs it?  With g++, neither R
versions seems to need it.  

OTOH I don't think adding -lrt does any harm so maybe we'll add "in general".
Might run this by Simon too....  This needs more work.

Thanks so much for the heads-up!

Dirk

| 
| Martin
| -- 
| Computational Biology / Fred Hutchinson Cancer Research Center
| 1100 Fairview Ave. N.
| PO Box 19024 Seattle, WA 98109
| 
| Location: Arnold Building M1 B861
| Phone: (206) 667-2793
| _______________________________________________
| Rcpp-devel mailing list
| Rcpp-devel at lists.r-forge.r-project.org
| https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
#
Just a guess.

Is it possible that this is caused by the way how R was built? Since you are using clang and R unstable, it is clear that you build R yourself.
ldd libR.so
shows among other things librt. In other words, librt was loaded when R was started. However building Rcpp only builds libraries rather than executables, and thus there shouldn't be errors when building Rcpp while loading Rcpp may cause errors unless librt was already loaded or linked to libRcpp.so

Another reason that I suspect that this is not a problem with compiler but how R is built is that, try the following program,

#include <time.h>

int main ()
{
    clock_gettime(0,0);
}

with either g++ or clang++, without explicit linking to -lrt, the same undefined symbol error occurs. For instance, on my RHEL, with g++ 4.4,
$ g++ -o foo foo.cpp 
/tmp/ccKB2Ftv.o: In function `main':
foo.cpp:(.text+0xf): undefined reference to `clock_gettime'
collect2: ld returned 1 exit status

Change main to say, foo, and build a shared or static library without linking to librt causes no problems at all (though loading that library will cause problems as usual).

If so far what I am talking is not non-sense, then I suggest you find your libR.so library, and check if it indeed does not link to librt. If that is the case, we need to find out how to build R to trigger the linking to librt (build R with profiling, which is the default?)

Anyway, as Dirk said, linking to librt is harmless on Linux nonetheless, so that is perhaps the easiest 'fix'.

Best,

Yan Zhou
On Dec 24, 2012, at 1:11 PM, Dirk Eddelbuettel <edd at debian.org> wrote:

            
#
On 12/23/2012 10:08 PM, Yan Zhou wrote:
I usually build with

~/bin$ CC=clang CFLAGS=-g -O0 CXX=clang++ ~/src/R-devel/configure 
--enable-memory-profiling --enable-R-shlib --disable-byte-compiled-packages

Looking at R's config.log carefully, I eventually spotted a difference depending 
on compilation with -O0 (when the symbol is not found) and -O2 (when everything 
is fine). The essence of the test is

~/tmp$ clang -O0 conftest.c
/tmp/conftest-hn9uU6.o: In function `main':
conftest.c:(.text+0x9): undefined reference to `clock_gettime'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
~/tmp$ clang -O2 conftest.c

for either gcc or clang, in R-2-15 or R-devel. conftest.c is, at the end of the day

#include <time.h>

int
main ()
{
#ifndef clock_gettime
   char *p = (char *) clock_gettime;
#endif

   ;
   return 0;
}

with -O2 succeeding because, well, the 'check' is optimized out (right?). This 
is from R-devel/configure.ac:1835

R_CHECK_FUNCS([clock_gettime timespec_get], [#include <time.h>])
if test "${ac_cv_have_decl_clock_gettime}" = "yes"; then
AC_CHECK_LIB(rt, clock_gettime)
fi

I'm not completely sure of this...

Martin
|    /home/mtmorgan/R/x86_64-unknown-linux-gnu-library/2.16/Rcpp/libs/Rcpp.so:

  
    
#
I think it at least confirms that this was indeed a problem related to building R.

I tried gcc -O0, same error happens, including the error when installing Rcpp.

Also I think you are right about the optimization thing. With -O2, the compiler see that p was never used and thus optimized the whole statement. Therefore when linking, there is no error at all (because clock_gettime was not referenced at all) and R happily conclude that clock_gettime was there with or without librt. To confirm this, try the following two program,

#include <time.h>
#include <stdio.h>

int main ()
{
    char *p = (char *) clock_gettime;
    printf("%c", *p);
}

Without the printf (just like conftest.c), then either gcc or clang complains undefined symbol with -O0 and silent when -O2. With the printf, which make the pointer actually used, with either gcc or clang, and whatever optimization level, the program won't compile unless -lrt.

I think the whole test of clock_gettime in R's configure.ac is flawed. It test first if clock_gettime exists by compiling an executable, which won't success unless -lrt or -O2. And only when it succeeded, it checks if clock_gettime is in librt. If -O0, then it will always fail because no -lrt was used in the first test and the test in librt was not performed at all. I guess the second line was meant to b
if test "${ac_cv_have_decl_clock_gettime}" = "no"; then
However I am not familiar with autotools, again.
With -O2, then the test succeed as long as clock_gettime was declared in the header.

 I think you shall report a bug to relevant R list.

Whether it is wise to having Rcpp link explicitly to librt is for Dirk and others to decide, considering this should be linked by R if it exists (I guess it is used for system.time etc)

Best,

Yan Zhou