[Rcpp-commits] r1901 - linkingto

noreply at r-forge.r-project.org noreply at r-forge.r-project.org
Mon Aug 2 16:39:37 CEST 2010


Author: edd
Date: 2010-08-02 16:39:37 +0200 (Mon, 02 Aug 2010)
New Revision: 1901

Modified:
   linkingto/linkingto-proposal.Rnw
Log:
added idea of automagically prefixing 'lib' when ProvidesLibrary


Modified: linkingto/linkingto-proposal.Rnw
===================================================================
--- linkingto/linkingto-proposal.Rnw	2010-08-02 10:46:45 UTC (rev 1900)
+++ linkingto/linkingto-proposal.Rnw	2010-08-02 14:39:37 UTC (rev 1901)
@@ -24,47 +24,47 @@
 \maketitle
 
 \abstract{
-  \noindent This document is a proposal for extending the role of the 
+  \noindent This document is a proposal for extending the role of the
   \texttt{LinkingTo} directive of \proglang{R} package \texttt{DESCRIPTION}
-  files. Currently \texttt{LinkingTo} facilitates access of header files of 
+  files. Currently \texttt{LinkingTo} facilitates access of header files of
   one package from another package, but linking to shared or static libraries
-  provided by other packages does not have dedicated support apart from 
-  documentation notes in section 5.8 of \cite{R:exts}. 
+  provided by other packages does not have dedicated support apart from
+  documentation notes in section 5.8 of \cite{R:exts}.
 }
 
 \section{Motivation}
 
-The ability to include compiled code in R packages is a great way to 
+The ability to include compiled code in R packages is a great way to
 leverage performance of compiled languages such as \proglang{C++}
 while keeping the flexibility of \proglang{R}. Adding compiled code is
-straightforward --- and properly documented in \cite{R:exts} --- when 
-this involves only one package. 
+straightforward --- and properly documented in \cite{R:exts} --- when
+this involves only one package.
 
 The \texttt{R\_RegisterCCallable} / \texttt{R\_GetCCallable} mechanism
-allows compiled code from one package to invoke a compiled function 
-from another package by means of function pointers. The packages 
-\texttt{Matrix}/\texttt{lme4} provide an example of the mechanism. 
-The mechanism does not involve actual linking since essentially it 
+allows compiled code from one package to invoke a compiled function
+from another package by means of function pointers. The packages
+\texttt{Matrix}/\texttt{lme4} provide an example of the mechanism.
+The mechanism does not involve actual linking since essentially it
 is a way to pass function pointers from one package to another. This requires
-a lot of discipline from both packages and lacks of flexibility, one has to 
-expose/retrieve each function. This quickly becomes unusable in C++ where 
-actual linking would be preferable. 
+a lot of discipline from both packages and lacks of flexibility, one has to
+expose/retrieve each function. This quickly becomes unusable in C++ where
+actual linking would be preferable.
 
-\cite{R:exts} also includes material on how to link against a library 
-included in another package, although the document seems to discourage 
-users to do it, because of portability subtleties. 
+\cite{R:exts} also includes material on how to link against a library
+included in another package, although the document seems to discourage
+users to do it, because of portability subtleties.
 
 \section{State of the art}
 
 \subsection{What does the current LinkingTo does}
 
 \texttt{LinkingTo} facilitates retrieving the header files of one package
-(the target package) and sets the appropriate compiler flags so that 
-another package (the client package) can use the declarations therein. 
+(the target package) and sets the appropriate compiler flags so that
+another package (the client package) can use the declarations therein.
 
-Assuming the source package \texttt{packA} distributes its headers 
-in the \texttt{inst/include} directory, then having the following line 
-in the client package \texttt{packB} : 
+Assuming the source package \texttt{packA} distributes its headers
+in the \texttt{inst/include} directory, then having the following line
+in the client package \texttt{packB} :
 
 \begin{verbatim}
 LinkingTo: packA
@@ -75,24 +75,24 @@
 
 \subsection{Compiling against target package library}
 
-Because \pkg{Rcpp} essentially consists of a \proglang{C++} library and R does not 
-offer explicit support for cross package linking, \pkg{Rcpp} package has been 
+Because \pkg{Rcpp} essentially consists of a \proglang{C++} library and R does not
+offer explicit support for cross package linking, \pkg{Rcpp} package has been
 using its own mechanism for client packages to link against its library.
 
-The mechanism used by \pkg{Rcpp} consists of : 
+The mechanism used by \pkg{Rcpp} consists of :
 \begin{itemize}
-\item create a dynamic library \texttt{lib[/arch]/libRcpp.dylib} in addition 
-to the shared object \texttt{libs[/arch]/Rcpp.so} that \proglang{R} 
+\item create a dynamic library \texttt{lib[/arch]/libRcpp.dylib} in addition
+to the shared object \texttt{libs[/arch]/Rcpp.so} that \proglang{R}
 automatically makes
 \item create a static library \texttt{lib[/arch]/libRcpp.a}
 \item provide the \proglang{R} function \texttt{Rcpp:::LdFlags} to generate the suitable
-flags for linking against the dynamic or static library. 
+flags for linking against the dynamic or static library.
 \end{itemize}
 
-A package that wishes to use the classes of \pkg{Rcpp} then has to : 
+A package that wishes to use the classes of \pkg{Rcpp} then has to :
 
 \begin{itemize}
-\item locate the headers of \pkg{Rcpp}, which is straightforward thanks to 
+\item locate the headers of \pkg{Rcpp}, which is straightforward thanks to
 the use of \texttt{LinkingTo: Rcpp}
 \item link against the library by adding this line in the \texttt{Makevars}
 file
@@ -102,7 +102,7 @@
 PKG_LIBS = $(shell $(R_HOME)/bin/Rscript -e "Rcpp:::LdFlags()" )
 \end{verbatim}
 
-and this line in the \texttt{Makevars.win} file for Windows: 
+and this line in the \texttt{Makevars.win} file for Windows:
 
 \begin{verbatim}
 PKG_LIBS = $(shell "${R_HOME}/bin${R_ARCH_BIN}/Rscript.exe" -e "Rcpp:::LdFlags()")
@@ -110,47 +110,68 @@
 
 This works, and is tested as part of \pkg{Rcpp} unit tests, but we believe
 that it could be made easier by extending the role played by the \texttt{LinkingTo}
-directive. We believe client package should only have to use \texttt{LinkingTo} 
-to both find the headers and link against the library. The rest of this document 
-discusses the proposed extension for \texttt{LinkingTo}. 
+directive. We believe client package should only have to use \texttt{LinkingTo}
+to both find the headers and link against the library. The rest of this document
+discusses the proposed extension for \texttt{LinkingTo}.
 
 
 
 \section{Compiled library}
 
-By the current implementation, compiled code from the target package may only 
+By the current implementation, compiled code from the target package may only
 be realistically used from itself. This isolates compiled code and delegates
-abstraction to the R level. This is not sufficient for packages such as 
-\pkg{Rcpp} which aim to provide \proglang{C++}-level abstractions. 
+abstraction to the R level. This is not sufficient for packages such as
+\pkg{Rcpp} which aim to provide \proglang{C++}-level abstractions.
 
 \subsection{ProvidesLibrary}
 
-The shared object that is made as part of the compilation of the 
-\texttt{src} directory of an \pkg{R} package is not necessarilly 
-a dynamic library on all platforms, and is not named appropriately 
-for being useful to the linker. 
+The shared object that is made as part of the compilation of the
+\texttt{src} directory of an \pkg{R} package is not necessarilly
+a dynamic library on all platforms, and is not named appropriately
+for being useful to the linker.
 
-We propose a new \texttt{DESCRIPTION} directive that specifies if a 
+We propose a new \texttt{DESCRIPTION} directive that specifies if a
 dynamic library, suitably named, should also be created in the \texttt{libs}
-directory. 
+directory.
 
 \begin{verbatim}
 ProvidesLibrary: yes
 \end{verbatim}
 
-When set to \texttt{yes} (the default being \texttt{f	alse}), the directive
+When set to \texttt{yes} (the default being \texttt{false}), the directive
 \texttt{ProvidesDynamicLibrary} would take appropriate actions to create a
-dynamic library in the \texttt{libs} directory. On platforms where it makes 
-sense, this might only create a symbolic link between the usual shared object 
-and the dynamic library. 
+dynamic library in the \texttt{libs} directory. On platforms where it makes
+sense, this might only create a symbolic link between the usual shared object
+and the dynamic library.
 
-For platforms where static linking is preferrable, the directive will trigger 
+For platforms where static linking is preferrable, the directive will trigger
 generation of a static library from all the compiled objects.
 
+Alternatively, a more appropriate if somewhat more disruptive change in
+behaviour could also be contemplated. The issue is that the linker generally
+wants a library from a package \texttt{foo} to be named \texttt{libfoo.dll}
+whereas R currently uses \texttt{foo.dll} (on Windows). So when a package has the
+\texttt{ProvidesLibrary: yes}  field set, the following changes could be made:
+\begin{enumerate}
+\item The resulting library will be prefixed with string \texttt{lib},
+  e.g.~the Rcpp package would create \texttt{libRcpp.so} (on Linux).
+\item The code in R that loads a package will check for
+  \texttt{ProvidesLibrary: yes} and prefix the library name before dynamic
+  loading.
+\item The code in other package that is generated by LinkingTo: will
+  similarly be prefixed by \texttt{lib} for the actualy linking statement.
+\item Other parts of R that would need updating would also be updates.
+\end{enumerate}
+The principal benefit of this approach is that the dual copies (which are even
+identical) of a given library (one for R itself, one for the system linker)
+would be avoided.
+
+\end{enumerate}
+
 \subsection{LinkingTo}
 
-The \texttt{LinkingTo} flag should be extended to honour the 
-\texttt{ProvidesLibrary} directives of the target package. 
+The \texttt{LinkingTo} flag should be extended to honour the
+\texttt{ProvidesLibrary} directives of the target package.
 
 More precisely, if package \texttt{packB} has this line in its \texttt{DESCRIPTION}
 file :
@@ -159,17 +180,17 @@
 LinkingTo: packA
 \end{verbatim}
 
-Then the DESCRIPTION directives of \pkg{packA} should be checked, and if 
-\pkg{packA} declares that it provides a library, the corresponding platform 
-specific flags should be generated so that the shared object of the 
+Then the DESCRIPTION directives of \pkg{packA} should be checked, and if
+\pkg{packA} declares that it provides a library, the corresponding platform
+specific flags should be generated so that the shared object of the
 \pkg{packB} package links against the appropriate library.
 
 
 \section{Implementation}
 
 To compile the content of the \texttt{src} directory, R invokes \texttt{make}
-with several source files as seen on this extract from the 
-\texttt{.shlib\_internal} function in \texttt{install.R} (in package \texttt{tools}). 
+with several source files as seen on this extract from the
+\texttt{.shlib\_internal} function in \texttt{install.R} (in package \texttt{tools}).
 
 <<eval=FALSE>>=
 site <- file.path(p0(R.home("etc"), rarch), "Makevars.site")
@@ -179,11 +200,11 @@
       file.path(R.home("share"), "make",
                 if (WINDOWS) "winshlib.mk" else "shlib.mk"))
 @
-               
+
 The \texttt{Makeconf} sets all the flags relevant for the current platform and
-sub architecture. 
+sub architecture.
 
-The \texttt{shlib.mk} file defines the target for the shared library of the package: 
+The \texttt{shlib.mk} file defines the target for the shared library of the package:
 
 <<lang=make>>=
 ## ${R_HOME}/share/make/shlib.mk
@@ -202,9 +223,9 @@
 	@rm -rf .libs _libs
 	@rm -f $(OBJECTS)
 @
-                        
-Similarly on windows, the \texttt{winshlib.mk} file : 
 
+Similarly on windows, the \texttt{winshlib.mk} file :
+
 <<lang=make>>=
 ## ${R_HOME}/share/make/winshlib.mk
 



More information about the Rcpp-commits mailing list