使用xlC 13.1.2在AIX 7.1上编译boost C ++库

时间:2015-09-30 09:20:56

标签: c++ boost shared-libraries aix xlc

我正在尝试使用xlC编译器在AIX上编译boost C ++库的正则表达式部分并将其用作64位动态库,因为我需要比较几个C ++正则表达式库和内置解决方案的性能并且提升似乎是一个可行的候选人。

以下是我的确切操作系统和编译器版本:

$ uname -a
AIX host_name 1 7 00F9A2144C00
$ xlC -qversion
IBM XL C/C++ for AIX, V13.1.2 (5725-C72, 5765-J07)
Version: 13.01.0002.0000

由于我没有root权限,我实际上无法安装boost库,我只是尝试将regex部分编译成共享对象文件并获取我的测试应用程序所需的所有头文件。我已经尝试编译最新的可用版本(1.59.0)以及版本1.55.0,因为我发现IBM已经发布了一个用于boost的源代码补丁:

http://www-01.ibm.com/support/docview.wss?uid=swg27042921

我使用以下命令编译boost并将标头和共享对象文件复制到我的开发文件夹:

bootstrap.sh --with-toolset=vacpp --prefix=/my/user/directory --exec-prefix=/my/user/directory
./b2 address-model=64 cxxflags=-q64 cflags=-q64
b2 tools/bcp
./dist/bin/bcp boost/regex.hpp /my/include/directory
cp stage/lib/libboost_regex.so /my/library/directory

我知道我可以添加--with-libraries=regex标志来仅编译正则表达式部分,但它与我的问题无关。

对于这两个版本,无论是否修补了增强源代码,我都会遇到同样的问题。

首先:我已经编译了一些库,并链接到我的简单测试应用程序,例如PCRE C ++正则表达式库。当我还尝试将boost正则表达式库与-lboost_regex编译标志链接时,我收到以下错误:

ld: 0706-006 Cannot find or open library file: -l boost_regex
ld:open(): No such file or directory
make: The error code from the last command is 255.

这是通过添加-brtl编译标志来解决的,据我所知,只有当我尝试链接一个静态库时才需要它,所以它看起来像我实际上libboost_regex.so是libboost_regex.a

第二次:当我在代码中添加行#include "boost/regex.hpp"时,出现编译错误:

"/opt/IBM/xlC/13.1.2/include/xtr1common", line 217.19: 1540-0130 (S) "false_type" is not declared.
"/opt/IBM/xlC/13.1.2/include/xtr1common", line 223.19: 1540-0130 (S) "true_type" is not declared.
"/opt/IBM/xlC/13.1.2/include/xtr1common", line 229.19: 1540-0130 (S) "true_type" is not declared.
"/opt/IBM/xlC/13.1.2/include/xtr1common", line 235.19: 1540-0130 (S) "true_type" is not declared.
"/opt/IBM/xlC/13.1.2/include/xtr1common", line 244.11: 1540-0130 (S) "false_type" is not declared.
"/opt/IBM/xlC/13.1.2/include/xtr1common", line 250.11: 1540-0130 (S) "true_type" is not declared.
make: The error code from the last command is 1.

我的测试应用程序非常简单。这些是我的Makefile的内容:

all:
    /opt/IBM/xlC/13.1.2/bin/xlC -q64 -Iinclude -Llibs -lpcrecpp main.cpp -o regexp_test

clean:
    rm regexp_test

以下是我的基本测试应用程序的源代码:

#include <iostream>
#include <string.h>

#ifndef __IBMCPP_TR1__
#define __IBMCPP_TR1__ 1
#include <regex>
#undef __IBMCPP_TR1__
#endif

#define __IBMCPP_TR1__ 1

/* Regular expression libraries to be included */
#include <sys/types.h>
#include <regex.h>
#include "pcrecpp.h"
// #include "boost/regex.hpp"
#include "deelx.h"

int main(int argc, char **argv)
{
    if(argc != 4){
        std::cerr << "Use: ./regexp_test <posix|tr1|pcre|deelx> value regexp" << std::endl;
        return 1;
    }

    int status;
    char buffer[256], regexp[256];
    snprintf(buffer,sizeof(buffer),argv[2]);
    snprintf(regexp,sizeof(regexp),argv[3]);
    std::string buffer_string = buffer;
    bool match = false;

    if(strcmp(argv[1],"posix")==0){

        regex_t comp;
        if (regcomp(&comp, regexp, REG_EXTENDED) != 0) {
            std::cerr << "The regular expression '" << regexp << "' could not be compiled!" << std::endl;
            return 1;
        } else {
            status = regexec(&comp, buffer, (size_t) 0, NULL, 0);
            regfree(&comp);
            if (status == 0) {
                match = true;
            }
        }

    } else if(strcmp(argv[1],"tr1")==0){

        try {
            std::tr1::smatch matches;
            std::tr1::regex rgx(regexp);
            status = std::tr1::regex_search(buffer_string, matches, rgx);
            if(status){
                match = true;
            }
        }
        catch(std::tr1::regex_error& re)
        {
            std::cerr << "TR1 exception caught!" << std::endl;
        }

    } else if(strcmp(argv[1],"pcre")==0){

        pcrecpp::RE re(regexp);
        if(re.PartialMatch(buffer)){
            match = true;
        }

    } else if(strcmp(argv[1],"deelx")==0){

        static CRegexpT <char> deelx_regexp(regexp, IGNORECASE | MULTILINE);
        MatchResult result = deelx_regexp.Match(buffer);
        if(result.IsMatched()){
            match = true;
        }

    } else {
        std::cerr << "Use: ./regexp_test <posix|tr1|pcre|deelx> value regexp" << std::endl;
        return 1;
    }

    if (!match) {
        std::cout << "The regular expression '" << regexp << "' does NOT match the value '" << buffer << "'." << std::endl;
    } else {
        std::cout << "The regular expression '" << regexp << "' matches the value '" << buffer << "'." << std::endl;
    }

    return 0;
}

如何解决这些问题?任何提示或建议将不胜感激。

1 个答案:

答案 0 :(得分:2)

我找到了解决我的两个问题的方法。

链接问题:

我发现这篇文章: https://web.archive.org/web/20100514132209/http://durgaprasad.wordpress.com/2006/09/28/problems-with-linking-of-shared-libraries-in-aix/

  

AIX中链接共享库的问题2006年9月28日   上午8:13(AIX,C / C ++)       通常,在Solaris,Linux和其他常见平台中,共享库用.so / .sl后缀表示。静态库是   用文件名中的.a后缀表示。但在AIX中,静态库   有.a后缀和共享库可以有.so或.a后缀。

     

当我们尝试编译一个使用.so的共享库的c文件时   后缀,默认情况下不会成功。它给出了编译错误。   另外,我们必须将“-Wl,-brtl”标志传递给编译器。 “-Wl”   是说它是链接器的标志,所以“-brtl”在内部   传递给链接器[ld]。 “-brtl”说它应该考虑文件   .so后缀也作为共享库。没有必要通过   共享库包含.a后缀时,此标志。这类   链接是加载时间链接。

     

当我们想要在运行时使用dlopen&amp; amp;来访问共享库时   dlsym调用,它被称为运行时链接。在这种情况下,我们不会得到   任何编译错误。如果共享库包含.a后缀,我们   在运行时也不会得到任何错误。但是如果共享库   包含.so后缀,我们在运行时得到分段错误。扑朔迷离   事情是,它成功执行dlopen调用,但在时间   dlsym,它以分段错误退出。如果我们给“-Wl-brtl”标志   在编译时编译器,运行时链接没问题。

详细说明在AIX上,共享库可以同时具有.so和.a后缀,并指示编译器搜索.so文件,您需要包含-brtl标志。它还指示包含-Wl标志,以便将链接标志直接传递给链接器(ld),但我发现使用此版本的xlC时,不推荐使用此功能。

代码问题:

预处理程序指令#define __IBMCPP_TR1__ 1导致boost regex库因编译错误而失败。这个定义仅用于我正在使用的AIX的内置tr1正则表达式,但事实证明它只需要#include <regex>部分,我可以省略第二个定义。