Le 08/10/13 17:12, Dominick Samperi a écrit :
That is interesting Romain, but the linking complexity remains
for derived packages like RcppOctave, and especially for derived
packages that export their C/C++ functions to clients (unless
these derived packages can also place all C++ code in header files).

Sure. There is always the issue of linking against R, etc ... but this would eliminate the need for linking against Rcpp.

As for placing the client package in headers, not everything has to go there, I have e.g. some functions in Rcpp11 that are only defined in Rcpp11's .cpp file.

For example:

const char * type2name__impl(int sexp_type);

What I've done is making it so that Rcpp11's headers calls this one instead:

inline const char* type2name(int sexp_type){
        GET_CALLABLE(type2name__impl, sexp_type)
}

and all the magic is in the GET_CALLABLE macro:

#if defined(COMPILING_RCPP11)
#define GET_CALLABLE(__FUN__, ...) return __FUN__( __VA_ARGS__ ) ;
#else
#define GET_CALLABLE(__FUN__, ...)                          \
typedef decltype(__FUN__)* Fun ;                            \
static Fun fun = (Fun)R_GetCCallable( "Rcpp11", #__FUN__) ; \
return fun(__VA_ARGS__) ;
#endif

So if we are compiling Rcpp11 (which is true only for .cpp files in Rcpp11), then type2name would directly call type2name__impl, otherwise we first get the function pointer with :

static Fun fun = (Fun)R_GetCCallable( "Rcpp11", "type2name__impl" ) ;

and then call fun.

Writing this, I do realize that this in fact uses some C++11 features: variadic macros and decltype. It does not mean we could not do it in Rcpp, but it would be harder and would involve macro bloat (we would need something like GET_CALLABLE_0, GET_CALLABLE_1, GET_CALLABLE_2, ...

Then, when Rcpp11 dynamic library is loaded by R, the __impl function is registered:

#define REGISTER(__FUN__) R_RegisterCCallable( "Rcpp11", #__FUN__ "__impl", (DL_FUNC)__FUN__ ## __impl );

    REGISTER(type2name)

This allows me to have all in headers and use R's mechanism for "linking". Not really linking as it just involves resolving the function pointer.

I find this more maintainable than depending on each platform's linker.

Anyway, just saying a client package could use something similar so that it does not have to actually link.

Romain

On Tue, Oct 8, 2013 at 9:58 AM, Romain Francois
<rom...@r-enthusiasts.com <mailto:rom...@r-enthusiasts.com>> wrote:

    Hello,

    I've only been following that thread from a distance. There is
    always so much I can do when it comes to windows.

    Anyway, in Rcpp11 I'm experimenting with completely letting go of
    the whole linking against the Rcpp library and all the issues it has
    brought to the table over the years (should it be static linking,
    how to call Rcpp:::LdFlags, need for a Makevars and a Makevars.win,
    ...).

    With Rcpp11, the only thing you'll ever need will be: LinkingTo: Rcpp11

    This was made possible by moving quite a big chunk of code into
    headers, and for the rest using the R mechanism (R_GetCCallable,
    R_RegisterCCallable) as described in WRE.

    Now, I have no idea yet if Rcpp11 works on windows. Right now I'm
    fearcely developping it, so I don't have time for playing games with
    windows. But that time will come.

    None of the techniques I'm using for that are depending on C++11,
    which would make it possible to use the same strategy for Rcpp too.
    But I fear that because too many depend on the current setting
    (Makevars, Makevars.win, making a library and non portably link
    against it) it is not likely to happen.

    Romain

    Le 08/10/13 15:47, Dominick Samperi a écrit :

        I just installed the binary with Rtools not on my path (but with
        R in PATH)
        and the first time I tried to load/unload RcppOctave I got the
        obscure
        Windows load error (app terminated "in an unusual way"), but now I
        cannot reproduce it! If you are linking to the static Rcpp lib there
        should be no problems.

        I guess the source distribution is not in sync with the binary?


        On Tue, Oct 8, 2013 at 2:11 AM, Renaud <geto...@gmail.com
        <mailto:geto...@gmail.com>
        <mailto:geto...@gmail.com <mailto:geto...@gmail.com>>> wrote:

             Good. Still wondering why path to Rcpp.dll is needed when
        installing
             the binary package since RcppOctave.dll is linked static to
        Rcpp.a
             with full path specified. Most users will use the binary
        and not
             build it from source (which requires Rtools and possibly
        more config.

             Did you try installing the binary directly from the repo
        (with only
             octave bin/ in the path, not Rtools nor R)?

             Renaud


             On Monday, October 7, 2013, Dominick Samperi wrote:

                 I don't think you need to worry about linking against
        the .dll
                 files, as the
                 import libraries (.dll.a files) contain all of the
        information
                 that the linker needs,
                 and you PATH will tell Windows where to find the
        corresponding
                 dll's.
                 It is possible to link against the dll's without using
        import libs,
                 but then various tricks have to be used to specify what is
                 exported from each dll.

                 I downloaded the source for 0.10.1 and it seems to
        build and install
                 ok provided I place Rcpp.dll on PATH. It would save the
        user some
                 trouble if PATH could be updated automatically, but it is
                 probably not
                 a good idea to have R package installation or startup
        update the
                 users
                 environment...



                 On Mon, Oct 7, 2013 at 10:52 AM, Renaud Gaujoux
                 <ren...@mancala.cbio.uct.ac.za
        <mailto:ren...@mancala.cbio.uct.ac.za>__> wrote:

                     Thanks for the details Dominick.
                     I think I got it working now, by ad Octave bin
        directory to
                     the path prior loading RcppOctave library.
                     I tested it by renaming the Octave root directory into
                     something different than at building time.

                     I added the option to specify Octave path via option
                     octave.path (e.g., see ?OctaveInit), so that the
        package
                     loads fine even if Octave is not installed/found.
        The user
                     can also define this option in the .Rprofile if
        Octave is
                     not installed in the path by default.

                     Please let me know if it works for you:

                     install.packages('RcppOctave', repos =
        c(getOption('repos'),
                     'http://web.cbio.uct.ac.za/~__renaud/CRAN'
        <http://web.cbio.uct.ac.za/~renaud/CRAN'>))
                     library(RcppOctave)
                     .O$rand()

                     Note that this version (0.10.1) was linked against the
                     .dll.a files, but will load the .dll files... I
        will try
                     later to link against the .dll files as you suggested.

                     Bests,
                     Renaud



                     On 7 October 2013 16:24, Dominick Samperi
                     <djsamp...@gmail.com <mailto:djsamp...@gmail.com>>
        wrote:

                         Yes, I placed Octave bin on my path. This is
        required to
                         find its dll's for the same reason
                         that Rcpp libs (directory containing Rcpp.dll)
        needs to
                         be on PATH. If you enable clients
                         of RcppOctave.dll to link against functions
        provided by
                         RcppOctave, then these clients
                         will have to add the RcppOctave libs directory
        to their
                         PATH.

                         The Octave dll's must be in its bin directory
        due to
                         another Windows dll search rule:
                         when you run an executable (like octave.exe) that
                         depends on dll's, Windows will
                         resolve the dependencies when the dll's are in
        the same
                         directory as the executable.

                         You should be able to link to liboctave-1.dll using
                         '-loctave-1', provided the bin
                         directory is on your PATH. The gcc '.dll.a'
        suffix means
                         the file is an import library,
                         not a static lib or a shared lib. Import libs tell
                         Windows how to resolve references
                         in the corresponding dll. Windows uses the
        '.lib' suffix
                         for import libs. For your
                         purposes you should link against the dll's, not
        the dll.a's.



                         On Mon, Oct 7, 2013 at 4:59 AM, Renaud Gaujoux
                         <ren...@mancala.cbio.uct.ac.za
        <mailto:ren...@mancala.cbio.uct.ac.za>__> wrote:

                             Dominick, just to be sure: did you have
        Octave bin
                             directory in your PATH when you tested the
        package?
                             Because Octave dlls are also in that directory.

                             I am getting confused on which path/dll is
        to be
                             used where. Currently I build
        RcppOctave.dll linking
                             against the dll.a files found in

        "C:\Octave\Octave3.6.4_gcc4.6.__2\lib\octave\3.6.4".
                             But there are .dll files (although named
                             liboctave-1.dll and not liboctave.dll as I
        would
                             expect) in
        ""C:\Octave\Octave3.6.4_gcc4.__6.2\bin"
                             where octave.exe. and octave-config.exe
        also live.
                             I had tried loading the .dll.a files with
        dyn.load
                             in R but got errors. The -1.dll files load
        fine, and
                             might be the ones I could load manually in
        .onLoad.

                             Now, should I also link using the bin/ path
        and the
                             -1.dll files?

                             Renaud


--
Romain Francois
Professional R Enthusiast
+33(0) 6 28 91 30 30

_______________________________________________
Rcpp-devel mailing list
Rcpp-devel@lists.r-forge.r-project.org
https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel

Reply via email to