44

cppソースファイルで使用したいcoolStuff.h関数を含むと呼ばれるヘッダーファイルがあります。awesomeSauce(arg1)

ディレクトリ構造:

  • RworkingDirectory
    • sourceCpp
      • theCppFile.cpp
    • cppHeaders
      • coolStuff.h

コード:

#include <Rcpp.h>
#include <cppHeaders/coolStuff.h>
using namespace Rcpp;

// [[Rcpp::export]]
double someFunctionCpp(double someInput){

 double someOutput = awesomeSauce(someInput);

return someOutput;
}

エラーが発生します:

 theCppFile.cpp:2:31: error: cppHeaders/coolStuff.h: No such file or directory

ファイルとディレクトリをあちこちに移動しましたが、これを機能させることができないようです。サードパーティのヘッダーを使用する場所のいたるところに、これを実行するという例があります。

#include <boost/array.hpp>

(Hadley / devtoolsからのもの)

https://github.com/hadley/devtools/wiki/Rcpp

では、何が得られるのでしょうか?私は午前中ずっと探していましたが、単純なことのように思えるものに対する答えを見つけることができません。

更新01.11.12

さて、RstudioでRcppを使用するパッケージを構築する方法を理解したので、質問を言い換えさせてください。cppコードで使用したい関数を含むスタンドアロンのヘッダーファイルcoolStuff.hがあります。

1)CoppFile.cppで使用できるように、パッケージディレクトリ構造のどこにcoolStuff.hを配置する必要がありますか?

2)cppファイルでcoolStuff.hを呼び出すにはどうすればよいですか?よろしくお願いします。前回の会話から多くのことを学びました。

注:「Rcppを使用するパッケージの作成」というビネットを読みましたが、その方法は説明されていません。

答え:

このページに散らばっているので、私の質問に対する答えを要約しましょう。詳細が間違っている場合は、これを編集するか、お知らせください。編集します。

そのため、で使用するために作成しているファイルで使用する関数またはその他のコードを含む.hまたはファイルが見つかりました。.cpp.cppRcpp

この見つかったコードcoolStuff.hを呼び出し続け、使用する関数を呼び出しましょうawesomeSauce()。あなたが書いているファイルを呼び出しましょうtheCppFile.cpp

(ここで、.hファイルと.cppファイルのコードはすべてC ++コードであり、それらの違いは、C++プログラマーが適切な方法で整理されていることです。違いについてはここで説明します。 、ただし、ここでSOを検索するだけで、違いについて説明できます。Rプログラマーが見つけたコードを少し使用する必要がある場合は、実際の違いはありません。)

短期間で:他のライブラリを呼び出さない場合と同様coolStuff.hに、にカットアンドペーストするtheCppFile.cppか、パッケージを作成する場合は、ファイルを\src含むディレクトリにファイルを配置して、ファイルの先頭でtheCppFile.cpp使用することができます。#include "coolStuff.h"あなたは書いている。後者はより柔軟性がありcoolStuff.h、他の.cppファイルの関数を使用できます。

詳細:

1)coolStuff.h他のライブラリを呼び出さないでください。つまり、上部にincludeステートメントを含めることはできません。もしそうなら、私が以下に詳述することはおそらく機能しないでしょう、そして他のライブラリを呼び出す見つかったコードの使用はこの答えの範囲を超えています。

2)ファイルをコンパイルする場合は、にカットアンドペーストするsourceCpp()必要があります。例外があると言われていますが、 1つのファイルをコンパイルするように設計されているため、これが最善の方法です。coolStuff.htheCppFile.cppsourceCpp().cpp

(注:単純なカットアンドペーストがすぐに機能することを保証するものではありません。変数の名前を変更するか、使用しているデータ型を切り替えて、使用しているデータ型と一致させる必要がありますtheCppFile.cpp。しかし、これまでのところ、カットアンドペーストは、6つの異なる単純な.hファイルで私にとって最小限の手間で機能しました)

3)どこからcoolStuff.hでもコードを使用する必要がある場合は、それを切り取ってに貼り付ける必要があります。theCppFile.cpptheCppFile.cpp

(繰り返しますが、カットアンドペーストに関する上記の注を参照してください)

4) ANDの他のファイルcoolStuff.hに含まれているコードを使用する場合は、パッケージの作成を検討する必要があります。これは難しいことではありませんが、Rcppを使用したパッケージの構築に関する情報は、Rパッケージで必要な徹底的なドキュメント(ただし、初心者としては頭上にあります)から、初心者に敏感なものまでさまざまであるため、少し注意が必要です。イントロダクション(必要な詳細省略される場合があります)。theCppFile.cpp.cpp

これが私が提案するものです:

A)最初に、カットアンドペーストから、期待どおりにコンパイルおよび動作theCppFile.cppするコードを含むバージョンを取得します。これは必須ではありませんが、Rcpp ORパッケージを初めて使用する場合は、以下のより複雑なケースに進む前に、コードがこの単純な状況で機能することを確認しておくと便利です。coolStuff.htheCppFile.cppsourceCpp()

B)Rcpp.package.skeleton()RStudioのビルド機能を使用または使用してパッケージをビルドします(強くお勧めします)。hadley/devtoolsまたはRcppAttributesVignetteRcpp.package.skeleton()での使用に関する詳細を見つけることができます。Rcppを使用してパッケージを作成するための完全なドキュメントは、Rcppを使用するパッケージの作成にありますが、これは、C ++の使い方をかなりよく知っていることを前提としており、Rcppを実行する新しい「属性」の方法を使用していません。

RStudioを使用している場合、またはRStudioを使用していない場合は、「ビルドとリロード」を忘れないでくださいcompileAttributes()

C)これで、\Rディレクトリに。というファイルが表示されますRcppExports.R。それを開いてチェックしてください。ディレクトリにRcppExports.Rあるすべての.cppファイルのRラッパー関数が表示されます\src。かなり甘い。

D)で書いた関数に対応するR関数を試してみてくださいtheCppFile.cpp。それは機能しますか?もしそうなら、次に進みます。

coolStuff.hE)パッケージを作成したら、。を使用してsrcフォルダーに移動できますtheCppFile.cpp

F)これで、の直後に配置された(およびcoolStuff.hのコードを使用するその他の.cppファイル)theCppFile.cppの先頭にあるカットアンドペーストコードを削除できます。ranker.hの前後には角かっこはなく、「」があることに注意してください。これは、RcppやSTLなどのライブラリファイルではなく、ユーザーが提供するローカルファイルを含める場合のC++規則です。theCppFile.cpp#include "coolStuff.h"#include <Rcpp.h>

G)パッケージを再構築する必要があります。RStudioでは、これは[ビルド]メニューの[ビルドとリロード]です。RStudioを使用していない場合は、実行する必要がありますcompileAttributes()

H)ステップD)で行ったのと同じように、R関数を再試行します。うまくいけばうまくいきます。

4

7 に答える 7

22

問題はsourceCpp、単一のスタンドアロンソースファイルのみをビルドするように明示的に設計されていることです。sourceCpp依存関係が必要な場合は、次のいずれかである必要があります。

  1. システムにディレクトリ(すなわち/usr/local/libまたは/usr/lib)を含めます。また

  2. Rcpp::depends属性にリストするRパッケージ内

Dirkが言ったように、複数のソースファイルをビルドしたい場合は、ではなくRパッケージの使用を検討する必要がありますsourceCpp

パッケージで作業していて、パッケージのsrcディレクトリ内のファイルに対してsourceCppを実行すると、パッケージ内にあるのようにビルドされることに注意してください(つまり、srcディレクトリまたはinst / includeディレクトリのファイルを含めることができます)。

于 2012-12-21T19:34:05.393 に答える
7

sourceCppを呼び出す前に、2つの環境変数を設定することで、任意のライブラリ(この場合はMPFR)をリンクできました。

Sys.setenv("PKG_CXXFLAGS"="-I/usr/include")
Sys.setenv("PKG_LIBS"="-L/usr/lib/x86_64-linux-gnu/ -lm -lmpc -lgmp -lmpfr")

最初の変数には、ライブラリヘッダーのパスが含まれています。2つ目は、ライブラリバイナリのパスとそのファイル名を含みます。この場合、他の依存ライブラリも必要です。詳細については、g++コンパイルとリンクフラグを確認してください。この情報は通常、pkg-configを使用して取得できます。

pkg-config --cflags --libs mylib

理解を深めるために、g ++コンパイルおよびリンクコマンドを出力するために、詳細な出力でsourceCppを使用することをお勧めします。

sourceCpp("mysource.cpp", verbose=TRUE, rebuild=TRUE)
于 2016-04-01T11:15:51.607 に答える
4

sourceCppを呼び出す前に、Rで次のグローバルコマンドを使用してBoostライブラリをリンクすることができました。

Sys.setenv("PKG_CXXFLAGS"="-I \path-to-boost\")

基本的にこの投稿をミラーリングしますが、コンパイラオプションが異なります:http://gallery.rcpp.org/articles/first-steps-with-C++11/

于 2013-08-15T20:25:56.020 に答える
2

いくつかのこと:

  1. あなたの主題のような「サードパーティのヘッダーライブラリ」は意味がありません。

  2. サードパーティのヘッダーは、ヘッダーが必要なすべてのテンプレートコードを介して機能します。つまり、インクルードステップのみがあり、コンパイラーが問題を解決します。

  3. sourceCppライブラリとオブジェクトコードの実際のリンクが必要になると、プラグイン(またはenv。vars)を介してメタ情報を提供しない限り、強力で便利なものが得られない可能性があります。

  4. その場合は、パッケージを作成してください。

簡単でシンプルなのは、Rcppと新しい属性、または古いインラインとcxxfunction。複雑な使用の場合はさらに---外部ライブラリより複雑で、ドキュメントを参照する必要があります。そのために、Rcppにいくつかのビネットを追加しました。

于 2012-12-21T19:29:22.653 に答える
1

山かっこ<>は、標準ライブラリなどのシステムインクルード用です。

独自のプロジェクトにローカルなファイルの場合は、引用符「」を使用します。

また、ヘッダーを別のディレクトリに配置する場合は、ヘッダーパスをそれを含むソースファイルに対してローカルに指定する必要があります。

したがって、あなたの例では、これは機能するはずです:

#include "../cppHeaders/coolStuff.h"

それを行わなくてもファイルが見つかるように検索パスを構成できますが、通常は、複数のプロジェクトに含めたいもの、または誰かが「インストール」することを期待するものに対してのみ行う価値があります。

于 2012-12-21T18:36:44.627 に答える
1

以下に示すようPKG_CXXFLAGSに、ファイルの変数のヘッダーへのパスを書き込むことで追加できます。以下は、 macOSにAnacondaとともにインストールされた.R/Makevarsのヘッダーファイルを追加する例です。xtensor

⋊&gt; ~ cat ~/.R/Makevars                                                                                                                              
CC=/usr/local/bin/gcc-7
CXX=/usr/local/bin/g++-7
CPLUS_INCLUDE_PATH=/opt/local/include:$CPLUS_INCLUDE_PATH
PKG_CXXFLAGS=-I/Users/kuroyanagi/.pyenv/versions/miniconda3-4.3.30/include
LD_LIBRARY_PATH=/opt/local/lib:$LD_LIBRARY_PATH
CXXFLAGS= -g0 -O3 -Wall
MAKE=make -j4
于 2018-02-01T04:17:58.000 に答える
0

これはWindowsで私のために働いた:

Sys.setenv("PKG_CXXFLAGS"='-I"C:/boost/boost_1_66_0"')

編集:ブーストヘッダーを使用する場合、実際にはこれは必要ありません(Ralf Stubnerのおかげで):

// [[Rcpp::depends(BH)]]

于 2018-09-14T00:47:24.720 に答える