I'm doing a R package which is linked to the RcppCGAL package, which contains the C++ library CGAL, which depends on the C++ library Boost. If I link my package to the BH package (in order to include Boost), then R CMD CHECK throws a warning on Windows ("found significant warnings...") and then my package is not acceptable to CRAN. But with R-4.2.0, I don't need to link to BH, because Rtools42 contains the Boost library. Then I have my solution for Windows (I will just be obliged to force the R >= 4.2.0 dependency). But if I don't link to BH, the compilation fails on Linux (I tested on Linux with the help of a Github action).
So, is there a way to link or not to BH according to the OS? Or another solution?
Also, if there is such a conditional solution, it would be necessary in addition to include or not // [[Rcpp::depends(BH)]] in the C++ code according to the OS.
EDIT
I found a possible way: I put BH in the Suggests field of the DESCRIPTION file, not in the LinkingTo field, and I use the following Makevars file (BH_PATH is the relevant variable, the rest was already there):
CXX_STD = CXX14
PKG_LIBS = -lmpfr -lgmp -lgmpxx
BH_PATH=`echo 'cat(system.file("include", package="BH", mustWork=TRUE))' | "${R_HOME}/bin/R" --vanilla --no-echo`
PKG_CXXFLAGS = -DCGAL_HEADER_ONLY=1 -I$(BH_PATH)
This has worked on Ubuntu (tested via Github action). Now it remains to check whether this is portable. I gonna check on Rhub and ask to CRAN.
Related
I am trying to use libclang for some source parsing on linux. I have libclang-dev installed and it appears under the list of packages for apt on my system.
However when i try to add it as a dependency through any of:
dependency('clang')
dependency('libclang')
dependency('libclang-dev')
dependency('libclang-cpp-dev')
In all cases I get
Run-time dependency clang found: NO (tried pkgconfig and cmake)
Despite it no being able to find it in my system I thought I could just compile it from source. To that effect I tried this:
opt_var = cmake.subproject_options()
opt_var.append_link_args('-fPIC')
sub_proj = cmake.subproject('clang', options : opt_var)
clang = sub_proj.dependency('clang')
Which gives :
../subprojects/clang/meson.build:0:0: ERROR: Can't link non-PIC static library 'clangBasic' into shared library 'clang_cpp'. Use the 'pic' option to static_library to build with PIC.
I tested compilation of clang outside of meson (i.e. i made a build directory and did cmake .. && make) and it works so this is a problem with how meson is calling cmake, not with the library.
Any ideas?
I found a temporary solution but I hate it because it's too system specific, you can add the following:
cpp = meson.get_compiler('cpp')
includes = include_directories(['/usr/lib/llvm-13/include/'])
libclang_lib = cpp.find_library('clang', dirs:'/usr/lib/llvm-13/lib', header_include_directories: includes)
libclang = declare_dependency(dependencies:libclang_lib, include_directories:includes)
To your meson script. Then use libclang as a dependency.
I am still interested in an answer that is more general/less OS specific.
I wrote a C++ package "P". It has an R interface package "RP", built using Rcpp. P used Make directly for compilation, but was switched to CMake for portability. CMake is used to find headers (let's call their collection HF) and static libraries (SL in the rest of the present post) for system wide libraries.
I want to update RP to be able to depend on the CMake evolution of P. In the C++ sources RP/src/*.cpp, HF elements are included, and of course SL are statically linked.
What is the best way to call CMake in RP/src/Makevars to retrieve the locations of HF and SL ? The point here is not to replace the build system of Rcpp, but to leverage the search capabilities of CMake.
At the moment, P (CMake version) and RP build on my machine, using absolute path references in RP/src/Makevars such as:
INC_NLOPT = /usr/local/Cellar/nlopt/2.4.2_2/include
LIB_NLOPT = /usr/local/Cellar/nlopt/2.4.2_2/lib/libnlopt.a
Since we use RP internaly at the moment, we can expect CMake, HF and SL to be installed on every machine we will deploy to.
The solution was to create a CMakeFileLists.txt file in RP/src. In this file, a Libvar file containing the required library paths is written using CMake file command. Libvar is then included in Makevars using include.
A configure file at the root of the package is executed to ensure that Libvar is generated before every call to make by R.
Question
I'm trying to tell my package to use gcc to compile the C++ code in stead of clang. Why aren't my CXX flags in my Makevars file being used?
(I am expecting/hoping the solution to be something really simple that I've overlooked.)
It's my understanding (see references) that I can specify CXX* flags in either
src/Makevars in the package, or
~/.R/Makevars
However, I can't get option 1 to work, only option 2.
Example Builds
Here are screenshots showing the build options I'm using. In each case I'm showing both the Makevars and the /.R/Makevars files to show which one I'm using in each case.
Option 1: src/Makevars
Here I specify CXX11 = /usr/local/bin/g++-7 inside src/Makevars. The build messages say it's building with clang
Option 2: ~/.R/Makevars
Here I specify CXX11 = /usr/local/bin/g++-7 inside ~/.R/Makevars. The build message shows it builds with g++
Example package
I've noticed this on a few packages I've built recently using Rcpp, but if you want an example to test my googlePolylines package is here on github.
References
Building R packages using Alternate GCC
Understanding the contents of Makevars
Session Info
devtools::session_info()
Session info ----------------------------------------------------------------------------------------------
setting value
version R version 3.4.3 (2017-11-30)
system x86_64, darwin15.6.0 ## Mac OS
ui RStudio (1.1.414)
language (EN)
collate en_AU.UTF-8
tz Australia/Melbourne
date 2018-03-11
Quoting Duncan Murdoch in https://stat.ethz.ch/pipermail/r-package-devel/2017q4/002087.html:
According to section 1.2.1 "Using Makevars" in Writing R Extensions,
R_HOME/etcR_ARCH/Makeconf is included after Makevars, so what you're
seeing is by design. I believe this is so that packages are built with
tools compatible with those that built R. (Remember, packages are
designed for distribution to diverse systems.)
So you might change various flags within src/Makevars via for example PKG_CXXFLAGS, but you cannot overwrite CXXFLAGS or CXX itself. And there is no PKG_CXX.
I do already ask a quiet similar question but in fact I now change my mind.
Id like like to compile proftpd and add a copy of the library it uses to the choosen installation directory.
Let's say I define a prefix in my compilation like:
/usr/local/proftpd
Under this directory I would like to find and use those directories only :
./lib
./usr/lib
./usr/bin
./usr/.....
./etc
./var/log/proftpd
./bin
./sbin
./and others I will not put the whole list
So the idea is after I have all libraries and config file in my main directory I could tar it and send it on another server with the same OS and without installing all the dependencies of protfpd I could use it.
I know it does sound like a windows installer not using shared library but that's in fact exactly what I'm trying to accomplish.
So far I have manage to compile it on AIX using this command line:
./configure --with-modules=mod_tls:mod_sql:mod_sql_mysql:mod_sql_passwd:mod_sftp:mod_sftp_sql --without-getopt --enable-openssl --with-includes=/opt/freeware/include:/opt/freeware/include/mysql/mysql/:/home/poney2/src_proftpd/libmath_header/ --with-libraries=/opt/freeware/lib:/opt/freeware/lib/mysql/mysql/:/home/poney2/src_proftpd/libmath_lib --prefix=/home/poney/proftpd_bin --exec-prefix=/home/poney/proftpd_bin/proftpd
Before trying to ask me why I'm doing so, it's because I have to compile proftpd on IBM AIX with almost all modules and this is not available on the IBM rpm binary repositories.
The use of this LDFLAG
LDFLAGS="-Wl,-blibpath:/a/new/lib/path"
where /a/new/lib/path contains all your library does work with Xlc and Gcc compiler.
How to build Boost.Regex with icu/ unicode support? My compiler is GCC, and IDE is Eclipse C++. How to configure binary files with Eclipse?
I tried to do this "bjam --sHAVE_ICU=1 toolset=gcc". But it did not work.
When i check if icu support is enable with "bjam -has_icu", i still get "has icu builds : no".
I build Boost against ICU using -sICU_PATH=<icuRoot> and -sICU_LINK="-L<icuLibDir>".
I've seen Boost fail to properly detect ICU as well, and have needed to patch the file has_icu_test.cpp (simply return 0 from it's main() function). This will work if you know everything else is set up properly.
Solved the problem by adding directly include path of include ICU directory to cflags when executing b2. For instance:
./b2 --with-regex
cflags="-O0 -I\"$ICU_PATH/include\"
You also may need to add path of ICU lib and moreover full paths to libs to linker. Something like this:
export ICU_LINK="-L\"$ICU_PATH/lib\" -l\"$ICU_PATH/lib/libicudata.a\" -l\"$ICU_PATH/lib/libicui18n.a\" -l\"$ICU_PATH/lib/libicuuc.a\""
./b2 --with-regex
cflags="-O0 -I\"$ICU_PATH/include\"
-sICU_LINK=$ICU_LINK \
Behemoths and Juggernauts
On some unix, this worked for me:
./b2 link=static,shared -sICU_PATH=/usr/local install
In said system, ICU headers are installed in /usr/local/include and ICU libraries in /usr/local/lib
In order to test if you have ICU headers installed (say in /usr/local/include) see if the dir /usr/local/include/unicode/ exists and has lots of header files in it (e.g. symtable.h)
Note that when I followed general advice from then net and passed -sICU_LINK='-L/usr/local/lib' to boost's b2, ICU detection (version 1.62 and 1.63) failed.
In the previous answer, user "NuSkooler" mentions that patching boost file has_icu_test.cpp to simply return 0; short-circuits the test and boost believes all is genkhi with ICU and goes ahead with it.
However make sure you also delete all ICU-related function calls and header files from that file because it is usually the case that has_icu_test.cpp first fails to compile or link because ICU libraries or header files can not be found by boost internals.
With all these, I can confirm that Aegisub's configure now passes the ICU test for me.
(and all these because John Hurt sadly died and I tried to put subtitles in a clip of Heaven's Gate to give to a friend)
b.