0

I'm trying to create simple lib for the R with statically linked boost.

CMakeLists.txt

cmake_minimum_required(VERSION 3.3)
project(TheRPath)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Werror")

set(Boost_USE_STATIC_LIBS ON)

find_package(Boost 1.50.0 REQUIRED COMPONENTS filesystem)

include_directories(${Boost_INCLUDE_DIRS})
include_directories("/usr/share/R/include")

set(SOURCE_FILES Path.cpp Path.h)

add_library(therpath SHARED ${SOURCE_FILES})

target_link_libraries(therpath ${Boost_LIBRARIES})

Interpreter gives me an error when I'm trying to load shared object.

> dyn.load("libtherpath.so")
Error in dyn.load("libtherpath.so") : 
  unable to load shared object 'libtherpath.so':
  libtherpath.so: undefined symbol: _ZN5boost6system15system_categoryEv

I have the following code:

Path.h

#ifndef PATH_H
#define PATH_H

#include <Rinternals.h>

extern "C" SEXP foo(SEXP snapshotPath);

#endif // PATH_H

Path.cpp

#include <string>
#include <boost/filesystem.hpp>
#include "Path.h"

extern "C" SEXP foo(SEXP snapshotPath) {
  std::string path(R_CHAR(STRING_ELT(snapshotPath, 0)));

  std::cerr << path << boost::filesystem::path::preferred_separator << "file.txt" << std::endl;

  return R_NilValue;
}

Could you tell me what I'm doing wrong?

UPD 1

Output of make VERBOSE=1:

/home/user/Soft/clion-latest/bin/cmake/bin/cmake -H/home/user/Workspace/TheRPath -B/home/user/.CLion12/system/cmake/generated/a69e8583/a69e8583/Debug --check-build-system CMakeFiles/Makefile.cmake 0
/home/user/Soft/clion-latest/bin/cmake/bin/cmake -E cmake_progress_start /home/user/.CLion12/system/cmake/generated/a69e8583/a69e8583/Debug/CMakeFiles /home/user/.CLion12/system/cmake/generated/a69e8583/a69e8583/Debug/CMakeFiles/progress.marks
make -f CMakeFiles/Makefile2 all
make[1]: Entering directory `/home/user/.CLion12/system/cmake/generated/a69e8583/a69e8583/Debug'
make -f CMakeFiles/therpath.dir/build.make CMakeFiles/therpath.dir/depend
make[2]: Entering directory `/home/user/.CLion12/system/cmake/generated/a69e8583/a69e8583/Debug'
cd /home/user/.CLion12/system/cmake/generated/a69e8583/a69e8583/Debug && /home/user/Soft/clion-latest/bin/cmake/bin/cmake -E cmake_depends "Unix Makefiles" /home/user/Workspace/TheRPath /home/user/Workspace/TheRPath /home/user/.CLion12/system/cmake/generated/a69e8583/a69e8583/Debug /home/user/.CLion12/system/cmake/generated/a69e8583/a69e8583/Debug /home/user/.CLion12/system/cmake/generated/a69e8583/a69e8583/Debug/CMakeFiles/therpath.dir/DependInfo.cmake --color=
make[2]: Leaving directory `/home/user/.CLion12/system/cmake/generated/a69e8583/a69e8583/Debug'
make -f CMakeFiles/therpath.dir/build.make CMakeFiles/therpath.dir/build
make[2]: Entering directory `/home/user/.CLion12/system/cmake/generated/a69e8583/a69e8583/Debug'
[ 50%] Building CXX object CMakeFiles/therpath.dir/Path.cpp.o
/usr/bin/c++   -Dtherpath_EXPORTS -std=c++11 -Wall -Werror -g -fPIC -I/usr/share/R/include    -o CMakeFiles/therpath.dir/Path.cpp.o -c /home/user/Workspace/TheRPath/Path.cpp
[100%] Linking CXX shared library libtherpath.so
/home/user/Soft/clion-latest/bin/cmake/bin/cmake -E cmake_link_script CMakeFiles/therpath.dir/link.txt --verbose=1
/usr/bin/c++  -fPIC  -std=c++11 -Wall -Werror -g  -shared -Wl,-soname,libtherpath.so -o libtherpath.so CMakeFiles/therpath.dir/Path.cpp.o /usr/lib/x86_64-linux-gnu/libboost_filesystem.a 
make[2]: Leaving directory `/home/user/.CLion12/system/cmake/generated/a69e8583/a69e8583/Debug'
[100%] Built target therpath
make[1]: Leaving directory `/home/user/.CLion12/system/cmake/generated/a69e8583/a69e8583/Debug'
/home/user/Soft/clion-latest/bin/cmake/bin/cmake -E cmake_progress_start /home/user/.CLion12/system/cmake/generated/a69e8583/a69e8583/Debug/CMakeFiles 0

UPD 2

/home/user/Soft/clion-latest/bin/cmake/bin/cmake -H/home/user/Workspace/TheRPath -B/home/user/.CLion12/system/cmake/generated/a69e8583/a69e8583/Debug --check-build-system CMakeFiles/Makefile.cmake 0
/home/user/Soft/clion-latest/bin/cmake/bin/cmake -E cmake_progress_start /home/user/.CLion12/system/cmake/generated/a69e8583/a69e8583/Debug/CMakeFiles /home/user/.CLion12/system/cmake/generated/a69e8583/a69e8583/Debug/CMakeFiles/progress.marks
make -f CMakeFiles/Makefile2 all
make[1]: Entering directory `/home/user/.CLion12/system/cmake/generated/a69e8583/a69e8583/Debug'
make -f CMakeFiles/therpath.dir/build.make CMakeFiles/therpath.dir/depend
make[2]: Entering directory `/home/user/.CLion12/system/cmake/generated/a69e8583/a69e8583/Debug'
cd /home/user/.CLion12/system/cmake/generated/a69e8583/a69e8583/Debug && /home/user/Soft/clion-latest/bin/cmake/bin/cmake -E cmake_depends "Unix Makefiles" /home/user/Workspace/TheRPath /home/user/Workspace/TheRPath /home/user/.CLion12/system/cmake/generated/a69e8583/a69e8583/Debug /home/user/.CLion12/system/cmake/generated/a69e8583/a69e8583/Debug /home/user/.CLion12/system/cmake/generated/a69e8583/a69e8583/Debug/CMakeFiles/therpath.dir/DependInfo.cmake --color=
make[2]: Leaving directory `/home/user/.CLion12/system/cmake/generated/a69e8583/a69e8583/Debug'
make -f CMakeFiles/therpath.dir/build.make CMakeFiles/therpath.dir/build
make[2]: Entering directory `/home/user/.CLion12/system/cmake/generated/a69e8583/a69e8583/Debug'
[ 50%] Building CXX object CMakeFiles/therpath.dir/Path.cpp.o
/usr/bin/c++   -Dtherpath_EXPORTS -std=c++11 -Wall -Werror -g -fPIC -I/usr/share/R/include    -o CMakeFiles/therpath.dir/Path.cpp.o -c /home/user/Workspace/TheRPath/Path.cpp
[100%] Linking CXX shared library libtherpath.so
/home/user/Soft/clion-latest/bin/cmake/bin/cmake -E cmake_link_script CMakeFiles/therpath.dir/link.txt --verbose=1
/usr/bin/c++  -fPIC  -std=c++11 -Wall -Werror -g  -shared -Wl,-soname,libtherpath.so -o libtherpath.so CMakeFiles/therpath.dir/Path.cpp.o /usr/lib/x86_64-linux-gnu/libboost_system.a /usr/lib/x86_64-linux-gnu/libboost_filesystem.a 
/usr/bin/ld: /usr/lib/x86_64-linux-gnu/libboost_system.a(error_code.o): relocation R_X86_64_32 against `.rodata.str1.1' can not be used when making a shared object; recompile with -fPIC
/usr/lib/x86_64-linux-gnu/libboost_system.a: error adding symbols: Bad value
collect2: error: ld returned 1 exit status
make[2]: *** [libtherpath.so] Error 1
make[2]: Leaving directory `/home/user/.CLion12/system/cmake/generated/a69e8583/a69e8583/Debug'
make[1]: *** [CMakeFiles/therpath.dir/all] Error 2
make[1]: Leaving directory `/home/user/.CLion12/system/cmake/generated/a69e8583/a69e8583/Debug'
make: *** [all] Error 2
user2235698
  • 7,053
  • 1
  • 19
  • 27
  • `Path.h` should not be in your "source files." Only .cpp files belong there. Anyway that won't fix your problem, so can you post the full linker command that runs when you do `make VERBOSE=1`? – John Zwinck Dec 18 '15 at 15:06
  • To catch this problem sooner (during build time) you may try adding `-Wl,--no-undefined` to your linker options. See here: http://stackoverflow.com/questions/2356168/force-gcc-to-notify-about-undefined-references-in-shared-libraries – John Zwinck Dec 18 '15 at 15:37
  • Generally you want either all static libraries or all dynamic libraries. Mixing them together can be a source of strange errors at runtime unless you know what you are doing. (Multiple copies of shared global state.) Is there some reason you don't just use boost shared libraries as well? – legalize Dec 23 '15 at 17:46

1 Answers1

1

libboost_filesystem depends on libboost_system. You need to add it to your CMakeLists.txt:

find_package(Boost REQUIRED COMPONENTS filesystem system)

Note I omitted the optional Boost version number, because you probably don't really need or want to specify it. But you can if you feel compelled.

John Zwinck
  • 239,568
  • 38
  • 324
  • 436
  • Fixes the problem when Boost_USE_STATIC_LIBS is OFF, but cause linking error when it's ON. – user2235698 Dec 18 '15 at 15:30
  • @user2235698: How about just leaving static off then? If it works that should be the best solution. – John Zwinck Dec 18 '15 at 15:32
  • Correct me if I'm wrong, but in that case my lib won't work if boost is not installed. That's why I'd like to statically link with boost. – user2235698 Dec 18 '15 at 15:34
  • Would you please update your question with the linker command line that is now generated when you use static and add `system` to the `find_package` list? – John Zwinck Dec 18 '15 at 15:35
  • OK, so you see the `/usr/bin/ld: /usr/lib/x86_64-linux-gnu/libboost_system.a(error_code.o): relocation R_X86_64_32 against `.rodata.str1.1' can not be used when making a shared object; recompile with -fPIC` there now? This means your build of Boost is not capable of statically linking into your shared library (that's pretty par for the course, most people would just use dynamic linking which is the default). If you want to fix this with static linking, you must rebuild Boost yourself--see: http://stackoverflow.com/questions/12418838/how-to-compile-static-library-with-fpic-from-boost-python – John Zwinck Dec 18 '15 at 15:40