0

最初の背景 - Windows 7 64 ビットで正常にコンパイルおよび実行される 3 つの VS2010 C++/OpenCL プロジェクトがあります。Linux 64 ビット (Ubuntu/Debian) でそれぞれをコンパイルして実行しようとしています。最初の 2 つは Linux 上でコンパイルおよび実行されており、実際には外部ライブラリを使用していません。3 つ目は Boost 1.50.0 のみを使用し、最初の 2 つと同じ方法でコンパイルしていません。最初に、最初の 2 つを機能させるために何をしたかを見てみましょう。

  1. 無数のフォルダからソースだけを抽出しました。
  2. Windows 固有のコードを Linux 固有のコードに移植しました。
  3. すべてのソースをコンパイルして g++ コマンドを生成する bash スクリプトを作成しました。
  4. コンパイル スクリプトを実行して、出力ターゲット ファイルを生成しました。

bash スクリプトは次のとおりです。

#!/bin/bash          

SOURCE=""

for i in `ls *.h *.cpp *.hpp`; do
   SOURCE+="${i} "
done

COMMAND="g++ -I/home/junkie/downloads/boost_1_51_0 -o out ${SOURCE} -L/opt/AMDAPP/lib/x86_64/ -I/opt/AMDAPP/include -lOpenCL -fpermissive"

echo -e "\n"
echo -e "${COMMAND}"
echo -e "\n"

$COMMAND
exit $?

そして、次のようなコマンドを生成して実行します。

g++ -I/home/junkie/downloads/boost_1_51_0 -o out blah.cpp blah.h foo.hpp baz.cpp etc.cpp  -L/opt/AMDAPP/lib/x86_64/ -I/opt/AMDAPP/include -lOpenCL -fpermissive

次のコマンドを使用してコンパイルします。

./compile.sh &> log; echo $?; grep -ci error log; wc -l log

ここで、C++ プロジェクトをコンパイルして Linux で実行するために、なぜこのような型破りで冗長な手段を採用したのか疑問に思われるかもしれません。私は Linux の C および C++ ツールチェーンに慣れていないため、これが仕事を成し遂げるために理解できる最も迅速で簡単なルートであり、最初の 2 つのプロジェクトを立ち上げて実行することができました。しかし、3 つ目はブーストを使用しており、この方法は機能していません。これらすべての奇妙なエラーの原因を突き止めるために、あなたの助けが必要です。

私が得ているエラーは、実際にはプロジェクト コードからではなく、Boost および AMD の opencl ライブラリ コードからのものです。これは、他のプロジェクトも opencl を使用しており、それらが正常に機能していたためです。

ブースト エラーの例を以下に示します。

foo.hpp:2331:1: error: unterminated argument list invoking macro "BOOST_PP_CAT_I"
In file included from main.cpp:4:                                   
foo2.hpp:1610:1: error: unterminated argument list invoking macro "BOOST_PP_CAT_I"
/home/junkie/downloads/boost_1_51_0/boost/preprocessor/cat.hpp:22: error: variable or field ‘BOOST_PP_CAT_I’ declared void                                  /home/junkie/downloads/boost_1_51_0/boost/preprocessor/cat.hpp: At global scope:
/home/junkie/downloads/boost_1_51_0/boost/preprocessor/cat.hpp:22: error: variable or field ‘BOOST_PP_CAT_I’ declared void
/home/junkie/downloads/boost_1_51_0/boost/preprocessor/cat.hpp:22: error: expected ‘;’ at end of input
/home/junkie/downloads/boost_1_51_0/boost/preprocessor/cat.hpp:22: error: expected ‘;’ at end of input
/home/junkie/downloads/boost_1_51_0/boost/preprocessor/cat.hpp:22: error: expected ‘}’ at end of input
/home/junkie/downloads/boost_1_51_0/boost/preprocessor/cat.hpp:22: error: expected unqualified-id at end of input
/home/junkie/downloads/boost_1_51_0/boost/preprocessor/cat.hpp:22: error: expected ‘}’ at end of input
/home/junkie/downloads/boost_1_51_0/boost/preprocessor/cat.hpp:22: error: expected ‘}’ at end of input
foo.hpp:2331:1: error: unterminated argument list invoking macro "BOOST_PP_CAT_I"

opencl エラーの例を以下に示します。

In file included from /opt/AMDAPP/include/CL/cl_platform.h:35,      
                 from /opt/AMDAPP/include/CL/cl.h:30,               
                 from bar.h:7,                                      
                 from fooGPU.hpp:6,                                 
                 from main.cpp:4:                                   
/usr/include/stdint.h:49: error: expected ‘;’ before ‘typedef’      
In file included from /opt/AMDAPP/include/CL/cl.h:30,               
                 from bar.h:7,                                      
                 from fooGPU.hpp:6,                                 
                 from main.cpp:4:                                   
/opt/AMDAPP/include/CL/cl_platform.h:41: error: expected unqualified-id before string constant
main.cpp:136: error: expected ‘}’ at end of input                   
main.cpp:136: error: expected unqualified-id at end of input        
main.cpp:136: error: expected ‘}’ at end of input                   
main.cpp:136: error: expected ‘}’ at end of input                   

私が使用しているブーストインクルードは次のとおりです。

#include <boost/preprocessor/punctuation/paren.hpp>
#include <boost/preprocessor/punctuation/comma.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/is_base_of.hpp>
#include <boost/mpl/not.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/logical.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/array.hpp>

最後に、私の質問は次のとおりです。

1) 私が使用している構築方法に照らして、これらのエラーの根本的な原因は何ですか?また、この問題を解決するにはどうすればよいですか? ファイルまたはライブラリのインクルードの順序は重要ですか? ビルド済みのバイナリを必要とするものは何も使用していないため、ビルド済みのバイナリではなく、ブーストのドキュメントで指示されているように、g++ コマンドの一部としてブーストのローカル ソース ダウンロードを使用しています。

2) 私は物事を構築する私の方法がかなり原始的であることを理解しています. 私はmakeを学んでおり、調査する必要があるcmakeとkdevelopを使用するためのいくつかの推奨事項を見てきました。make を使用する際の主な問題は、これらのプロジェクトが make を念頭に置いて作成されていないため、makefile を作成するためのソース ファイル間の依存関係グラフを認識していないことです (私の考えが正しければ、私はまだ make についてかなり初心者です)。それ)。物事をより良く行うための推奨事項があれば、教えてください。

ありがとう。

4

2 に答える 2

1

私は最終的にこの問題を克服することができました。ここでは、その方法について簡単に説明します。明確にするために、元の問題の根本原因が何であるかはわかりません。つまり、なぜ問題が発生したのかわかりません。私が言っているのは、回避策によって問題を解決し、他の問題 (コンパイル時エラー) に進むことができたということだけです。

繰り返しになりますが、問題は、BOOST_PP_CAT() 関数を使用するすべてのインスタンスで次のエラーが発生したため、何らかの理由でブーストを使用するプロジェクトが Linux でコンパイルされなかったことです。

error: unterminated argument list invoking macro "BOOST_PP_CAT_I"

何らかの理由で、コンパイラはこの関数の使用を正しく処理できませんでしたが、BOOST_PP_LPAREN()、BOOST_PP_RPAREN()、BOOST_PP_COMMA などの他のブースト関数の使用は処理できました。この問題は、前述のブースト関数を組み合わせて使用​​した結果、引数リストが終了していない前処理段階にほぼ確実に関連しているように見えました。

関連するコード (ありがたいことに私が書いたものではありません) の性質を詳しく説明するために、以前の開発者は基本的にブースト プリプロセッサ関数を使用して DSL を作成し、それを何度も再利用して関数のリストを生成していました。単純に関数を直接記述する方がはるかに簡単に思えましたが、とにかくそれは別の問題です。

私の回避策は、BOOST_PP_CAT() 関数を使用せず、最終的には以前とまったく同じ関数を定義するように、コードの関連セクションを変更することでした。BOOST_PP_CAT() の使用を、BOOST_PP_CAT() によって生成されたコードに置き換えることでこれを行いました。これにより、上記のエラーのすべてのインスタンスが克服されましたが、このプロジェクトを Windows から Linux に移行する際に、他の何百ものコンパイル時エラーが発生しました。

これは非常に具体的で珍しい質問であり、同様に具体的で珍しい答えがありましたが、この問題の背後にある謎を払拭するためにこれをフィードバックしたいと思いました. この特定の関数が Linux ではプリプロセス/コンパイルに失敗し、Windows ではパスした理由については、私にはわかりませんが、非常に知りたいと思っています。g++ や clang とは対照的に、VC++ が前処理を実行する方法の根本的な違い、またはより具体的には、プリプロセッサ ディレクティブでネストされた関数の解決順序の違いであるとしか思えません。知るか。とにかく、助けてくれてありがとう。

于 2012-11-20T10:46:52.960 に答える
0

エラーは、unterminated argument list invoking macro閉じ括弧がないことを示しています。編集者の括弧マッチャーを使用して確認してください。ソースファイルがDOS形式ではなくUnix形式であることを確認してください(たとえば、各行末で、 \nUnixを使用し、\r\nMSDOSを使用しないでください)。dos2unix必要に応じて使用してください。

g++ -Wall -C -E -H -I/home/junkie/downloads/boost_1_51_0 yoursourcecode.ccそれ以外の場合は、の前処理済みフォームを取得するために実行できることを忘れないでください。yoursourcecode.ccそのコマンドをリダイレクトすることで、選択したエディター(などemacs)を使用して前処理済みフォームを検査できます。

私がコメントしたように、Gnu makeMakefileの使用方法を学びます(そして、のような優れたエディターで編集する必要がある、のデバッグで問題が発生した場合は、 remakeemacsを使用してデバッグします)。 -x

そして、-I/home/junkie/downloads/boost_1_51_0見た目は非常に疑わしいようです。Boostがヘッダーのみのライブラリであることが多い場合でも、私が覚えている限り、Unixでのインストール手順があります(LinuxディストリビューションではBoostライブラリがパッケージ化されていることがよくあります)。文書化されているように(そしてそれらを構成した後に)、OpenCLの場合も同様に、Boostライブラリをインストールする必要があります。

于 2012-11-12T19:11:22.150 に答える