0

首先是一些背景知识 - 我有三个 VS2010 C++/OpenCL 项目,它们在 Windows 7 64 位上编译和运行良好。我一直在尝试在 Linux 64 位(Ubuntu/Debian)上编译和运行它们。前两个是在 linux 上编译和运行,并没有真正使用任何外部库。第三个仅使用 Boost 1.50.0,并且没有使用与前两个相同的方法进行编译。因此,首先让我回顾一下我为使前两个工作正常所做的工作。

  1. 我只从无数文件夹中提取了源代码。
  2. 我将 windows 特定代码移植到 linux 特定代码。
  3. 我编写了一个 bash 脚本来生成带有所有源的 g++ 命令来编译它们。
  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++ 工具链的新手,这是我能想到的最快和最简单的方法来完成工作,它确实让前两个项目启动并运行。但是,第三个使用 boost 并且这种方法不起作用,我需要您的帮助来弄清楚所有这些奇怪的错误是什么。

我得到的错误实际上不是来自项目代码,而是来自 Boost 和 AMD 的 opencl 库代码,这很奇怪,因为其他项目也在使用 opencl 并且工作正常。

下面是一些 boost 错误的示例。

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)根据我正在使用的构建方法,这些错误的根本原因是什么?我该如何解决这个问题?文件或库包含的顺序是否重要?我使用 boost 的本地源下载作为我的 g++ 命令的一部分,按照 boost 文档的指示,而不是预构建的二进制文件,因为我没有使用任何需要预构建二进制文件的东西。

2)我意识到我的构建方式非常原始。我正在学习 make 并且我已经看到了一些使用 cmake 和 kdevelop 的建议,我需要研究这些建议。使用 make 的主要问题是这些项目在编写时没有考虑到 make 所以我不知道源文件之间的依赖关系图来创建 makefile (如果我的想法正确的话;我对它)。如果您对如何做得更好有任何建议,请赐教。

谢谢。

4

2 回答 2

1

我终于设法克服了这个问题,在这里我简要介绍一下。需要明确的是,我不知道原始问题的根本原因是什么。换句话说 - 我不知道为什么会出现问题。我要说的是,我的解决方法使我能够解决问题并解决其他问题(编译时错误)。

本质上,重申一下,问题在于无论出于何种原因,使用 boost 的项目都没有在 Linux 上编译,因为所有使用 BOOST_PP_CAT() 函数的实例都产生了以下错误。

error: unterminated argument list invoking macro "BOOST_PP_CAT_I"

无论出于何种原因,编译器都无法正确处理此函数的使用,但能够处理其他 boost 函数的使用,例如 BOOST_PP_LPAREN()、BOOST_PP_RPAREN() 和 BOOST_PP_COMMA。这个问题看起来几乎肯定与预处理阶段有关,在该阶段结合使用上述提升函数会导致未终止的参数列表。

为了详细说明相关代码的性质(幸好不是我写的),之前的开发人员基本上使用了 boost 预处理器函数来创建一个 DSL,然后他们可以多次重复使用以生成函数列表。对我来说,简单地直接编写函数似乎要容易得多,但无论如何这是另一个问题。

我的解决方法是更改​​代码的相关部分,使其不使用任何 BOOST_PP_CAT() 函数,但最终定义了与以前完全相同的函数。我通过将 BOOST_PP_CAT() 的使用替换为它生成的代码来做到这一点。这克服了上面引用的所有错误实例,但在我将这个项目从 windows 迁移到 linux 的过程中,还留下了数百个其他编译时错误。

Although this was a very specific and unusual question with an equally specific and unusual answer I wanted to feed this back to dispel the mystery behind this problem. As to why this particular function was failing to preprocess/compile on linux but passing on Windows I don't know but would very much like to know. I can only assume it is a fundamental difference in the way VC++ performs preprocessing as opposed to g++ and clang or more specifically perhaps a difference in the order of resolution of nested functions in preprocessor directives. Who knows. Anyway, thanks for your help guys.

于 2012-11-20T10:46:52.960 回答
0

unterminated argument list invoking macro错误表明缺少右括号。使用编辑器的括号匹配器来检查它。确保您的源文件是 Unix 格式,而不是 DOS 格式(例如,在每个行尾使用\nà la Unix,而不是\r\nà la MSDOS)。dos2unix需要时使用。

否则,不要忘记您可以运行g++ -Wall -C -E -H -I/home/junkie/downloads/boost_1_51_0 yoursourcecode.cc以获取 的预处理形式yoursourcecode.cc,并且通过重定向该命令,您可以使用您选择的编辑器(如emacs)检查该预处理形式。

正如我所评论的,学习使用 Gnu make(如果在调试你的 . 时遇到问题Makefile,你应该用一个好的编辑器编辑它emacs,使用remake -x来调试它)。

而且-I/home/junkie/downloads/boost_1_51_0看起来非常可疑:即使 Boost 通常是一个仅包含头文件的库,据我所知,它在 Unix 上具有安装过程(而 Linux 发行版通常会打包 Boost 库)。您应该按照文档说明安装您的 Boost 库(并在配置它们之后),对于 OpenCL 也是如此。

于 2012-11-12T19:11:22.150 回答