-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Re-org file names * Fix package documentation * Update package structure * Switch RStudio project name and update RcppExports * Remove Makevars as that is an artifact of the RcppArmadillo example and fix comment. * Add implementation details * Enable travis
- Loading branch information
Showing
25 changed files
with
362 additions
and
174 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
^.*\.Rproj$ | ||
^\.Rproj\.user$ | ||
^\.travis\.yml$ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# R for travis: see documentation at https://docs.travis-ci.com/user/languages/r | ||
|
||
language: R | ||
sudo: false | ||
cache: packages |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,16 @@ | ||
Package: anRpackage | ||
Package: SrcDir | ||
Type: Package | ||
Title: What the package does (short line) | ||
Version: 1.0 | ||
Date: 2015-03-10 | ||
Author: Who wrote it | ||
Maintainer: Who to complain to <yourfault@somewhere.net> | ||
Description: More about what it does (maybe more than one line) | ||
License: What license is it under? | ||
Title: Embedding Multiple Code Files in Src | ||
Version: 0.0.0.9000 | ||
Authors@R: person("James", "Balamuta", email = "balamut2@illinois.edu", role = c("aut", "cre")) | ||
Description: Provides an implementation showing how multiple compiled code | ||
files in the `src` directory can be used. | ||
BugReports: https://github.com/r-pkg-examples/rcpp-headers-src | ||
Depends: R (>= 3.4.0) | ||
Imports: Rcpp (>= 0.11.5) | ||
LinkingTo: Rcpp, RcppArmadillo | ||
LinkingTo: Rcpp | ||
License: GPL (>= 2) | ||
Encoding: UTF-8 | ||
LazyData: true | ||
RoxygenNote: 6.1.0 | ||
Roxygen: list(markdown = TRUE) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,7 @@ | ||
useDynLib(anRpackage) | ||
importFrom(Rcpp, evalCpp) | ||
exportPattern("^[[:alpha:]]+") | ||
# Generated by roxygen2: do not edit by hand | ||
|
||
export(calc_A_routine) | ||
export(calc_B_routine) | ||
export(calc_modifications) | ||
importFrom(Rcpp,sourceCpp) | ||
useDynLib(SrcDir, .registration = TRUE) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,40 @@ | ||
# This file was generated by Rcpp::compileAttributes | ||
# Generated by using Rcpp::compileAttributes() -> do not edit by hand | ||
# Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393 | ||
|
||
testfunction <- function(x) { | ||
.Call('anRpackage_testfunction', PACKAGE = 'anRpackage', x) | ||
#' Package functions | ||
#' | ||
#' Functions listed here are derived from the exported _C++_ functions. | ||
#' Note that all functions work even after being split into multiple separate | ||
#' files. | ||
#' | ||
#' @param x Vector of Numeric Values with length \eqn{n}. | ||
#' | ||
#' @return A vector of numeric values with length \eqn{n}. | ||
#' | ||
#' @rdname exported_funcs | ||
#' @export | ||
#' @examples | ||
#' my_vec = c(3.5, 8, -1.5, -2, 0, 42) | ||
#' calc_modifications(my_vec) | ||
calc_modifications <- function(x) { | ||
.Call(`_SrcDir_calc_modifications`, x) | ||
} | ||
|
||
testfunctionA <- function(x) { | ||
.Call('anRpackage_testfunctionA', PACKAGE = 'anRpackage', x) | ||
#' @rdname exported_funcs | ||
#' @export | ||
#' @examples | ||
#' my_vecA = c(881, 884, 1,2,-4) | ||
#' calc_A_routine(my_vecA) | ||
calc_A_routine <- function(x) { | ||
.Call(`_SrcDir_calc_A_routine`, x) | ||
} | ||
|
||
testfunctionB <- function(x) { | ||
.Call('anRpackage_testfunctionB', PACKAGE = 'anRpackage', x) | ||
#' @rdname exported_funcs | ||
#' @export | ||
#' @examples | ||
#' my_vecB = c(512,32, -1, 1.3, 5.9) | ||
#' calc_B_routine(my_vecB) | ||
calc_B_routine <- function(x) { | ||
.Call(`_SrcDir_calc_B_routine`, x) | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
#' @useDynLib SrcDir, .registration = TRUE | ||
#' @importFrom Rcpp sourceCpp | ||
"_PACKAGE" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
## Separating Compiled Code into Individual Units with Headers | ||
|
||
[![Travis-CI Build Status](https://travis-ci.org/r-pkg-examples/rcpp-headers-src.svg?branch=master)](https://travis-ci.org/r-pkg-examples/rcpp-headers-src) | ||
|
||
The `SrcDir` R package provides an example of using header files to split | ||
apart functions into separate code files while still being able to use each | ||
function. | ||
|
||
In essence, this project shows how to go from: | ||
|
||
```bash | ||
src/ | ||
|-> large-code-file.cpp | ||
``` | ||
|
||
to: | ||
|
||
```bash | ||
src/ | ||
|-> combined-routines.cpp | ||
|-> routineA.cpp | ||
|-> routineA.h | ||
|-> routineB.cpp | ||
|-> routineB.h | ||
``` | ||
|
||
For further organization, see the [SubdirSrc](https://github.com/r-pkg-examples/rcpp-headers-subdirs) | ||
package for an example of compiling code found in `src/` subdirectories | ||
(e.g. `src/A`, `src/B`). | ||
|
||
### Usage | ||
|
||
To install the package, you must first have a compiler on your system that is | ||
compatible with R. For help on obtaining a compiler consult either | ||
[macOS](http://thecoatlessprofessor.com/programming/r-compiler-tools-for-rcpp-on-os-x/) | ||
or | ||
[Windows](http://thecoatlessprofessor.com/programming/rcpp/install-rtools-for-rcpp/) | ||
guides. | ||
|
||
With a compiler in hand, one can then install the package from GitHub by: | ||
|
||
```r | ||
# install.packages("devtools") | ||
devtools::install_github("r-pkg-examples/rcpp-headers-src") | ||
library("SrcDir") | ||
``` | ||
|
||
### Implementation Details | ||
|
||
Separating out code into different files requires the use of header files (`.h`). | ||
Headers provide a way to share function definitions and preprocessor macros | ||
between two or more _C++_ files (`.cpp`). Using the header inside of another | ||
file requires the use of the `#include` | ||
[preprocessor directive](https://en.wikipedia.org/wiki/Preprocessor), | ||
which effectively "copies" the contents of the header into the other file. | ||
|
||
Take for instance the [`routineA.cpp`](https://github.com/r-pkg-examples/rcpp-headers-src/blob/master/src/routineA.cpp) file. | ||
|
||
```cpp | ||
#include <Rcpp.h> | ||
#include "routineA.h" | ||
|
||
// [[Rcpp::export]] | ||
Rcpp::NumericVector calc_A_routine(Rcpp::NumericVector x) { | ||
Rcpp::NumericVector a = x - 4; | ||
return a; | ||
} | ||
``` | ||
Note, there are two different kinds of `#include` used: | ||
- `#include <header_system.h>` | ||
- `<>` indicate a system header file found in system directories or supplied with `-I`. | ||
- `Rcpp.h` is a system library as it is located outside of the project space. | ||
- `#include "header_local.h"` | ||
- `""` means the file resides in the working directory of the program. | ||
For more details, please see [Section 2.1 Include Syntax](https://gcc.gnu.org/onlinedocs/cpp/Include-Syntax.html#Include-Syntax) | ||
of the [`gcc` documentation](https://gcc.gnu.org/onlinedocs/cpp/index.html#SEC_Contents). | ||
The accompanying header file would be [`routineA.h`](https://github.com/r-pkg-examples/rcpp-headers-src/blob/master/src/routineA.h). The header would | ||
contain the function definition for `calc_A_routine()` as it is the only | ||
function declared within the file. | ||
```cpp | ||
// Defines a header file containing function signatures for functions in src/ | ||
// Protect signatures using an inclusion guard. | ||
#ifndef routineA_H | ||
#define routineA_H | ||
Rcpp::NumericVector calc_A_routine(Rcpp::NumericVector x); | ||
#endif | ||
``` | ||
|
||
As the header contents is "copied", it is important to protect the function | ||
definitions to ensure they are only included once. To prevent this from happening, | ||
an [inclusion guard](https://en.wikipedia.org/wiki/Include_guard) is | ||
used. By checking for whether a variable is defined with `#ifndef`, the header | ||
file can be copied completely or skip the define portion. In short, the | ||
design pattern for this can be succiently stated as: | ||
|
||
```cpp | ||
#ifndef myfilename_H | ||
#define myfilename_H | ||
|
||
// Contents here | ||
|
||
#endif | ||
``` | ||
|
||
From here, both routines A and B can be included inside a third file | ||
such as [`combined-routines.cpp`](https://github.com/r-pkg-examples/rcpp-headers-src/blob/master/src/combined-routines.cpp). The inclusion statements would be: | ||
|
||
```cpp | ||
#include <Rcpp.h> | ||
|
||
// Load directory header files | ||
#include "routineA.h" | ||
#include "routineB.h" | ||
|
||
// additional code | ||
``` | ||
|
||
## License | ||
|
||
GPL (\>= 2) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.