zoukankan      html  css  js  c++  java
  • 高版本gcc编译代码,链接低版本gcc编译的库

    CFLAG 里面指定  -D_GLIBCXX_USE_CXX11_ABI=0,

    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_GLIBCXX_USE_CXX11_ABI=0")

    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_GLIBCXX_USE_CXX11_ABI=0")

     1、先用旧版本gcc编译整套代码。

    2、然后修改要单独编译的可执行文件的makefile或者CmakeLIST.TXT,增加-D_GLIBCXX_USE_CXX11_ABI=0编译连接选项。

    3、然后删除之前被编译出来的可执行文件。

    4、变更为新版本的gcc(gcc-5.1以上)

    4、重新编译make xxxapp。

    注:   更新gcc编译器,不需要更新stdc++

     

    为什么我们需要-D_GLIBCXX_USE_CXX11_ABI=0

    当您尝试构建 tensorflow 时,会提示您需要添加“-D_GLIBCXX_USE_CXX11_ABI=0”标志,如果您使用的是 GCC 5 或更高版本,以保持您构建的 tensorflow 和官方 tensorflow 构建的兼容性。

    官方 TensorFlow 包是使用 GCC 4 构建的,并使用较旧的 ABI。对于 GCC 5 及更高版本,使用以下命令使您的构建与旧 ABI 兼容:–cxxopt=”-D_GLIBCXX_USE_CXX11_ABI=0”。ABI 兼容性确保针对官方 TensorFlow 包构建的自定义操作继续与 GCC 5 构建包一起使用

    非常详细和正式地解释ABI长话短说,根据我的理解,这是编译器之间的协议/协议,关于如何从另一个编译单元找到路由/符号,以及如何传递参数,获取例程之间的返回值,如何解释函数/符号名称(来源文件和编译器中间二进制文件对于相同的函数/类具有不同的名称)。

    如果您的软件的所有代码/组件都是从您机器上的单个编译器编译的,则 ABI 兼容性根本不是问题,因为编译器将处理所有脏细节。但是,如果您正在编写一个将分发给各种用户的库,将有许多潜在的配置/环境,那么 ABI 绝对是您需要考虑的重要事项之一。

    假设您正在用 C++ 编写一个库,并且您不想分发库的源代码。您可以将其编译为动态库(linux 中的.so 文件),然后将动态库和头文件提供给您的用户。用户然后使用他/她的编译器将他/她的源文件编译为目标文件,然后使用您的动态库将他/她的目标文件再次链接到可执行文件/库。问题来了:

    • 假设您使用的是版本 X 的 GCC 编译器,但用户使用的是另一个版本 Y。在这种情况下,Y 需要知道 X 编译的库的二进制格式。

    关于 C++11_ABI 标志

    这里的文章对此进行了解释。https://developers.redhat.com/blog/2015/02/05/gcc5-and-the-c11-abi/

    基本思想是

    依赖第三方库或仍然使用旧 ABI 的插件接口的用户可以使用 -D_GLIBCXX_USE_CXX11_ABI=0 构建他们的代码,一切都应该正常工作。在大多数情况下,很明显何时需要这个标志是因为链接器的错误抱怨涉及“__cxx11”的未解析符号

    例子

    步骤 1. 编写并编译 lib

    假设您正在编写一个只有一个 cpp 文件的库mylib.cpp,并通过以下方式导出您的 APImylib.h

    //mylib.cpp
    #include <string> #include <iostream> void print_string(const std::string & a)  {
        std::cout <<__FILE__ << __LINE__ << " content of a:"  << a << std::endl;
    }
    
    #ifndef __MYLIB_H #define __MYLIB_H #include <string> void print_string(const std::string & a);
    #endif

    使用以下命令将 cpp 文件编译为动态库。

        g++ -fPIC mylib.cpp -shared -o libmy.so
    

    步骤 2. 编写并编译和应用

    假设您的应用程序的cpp 文件以 命名myapp.cpp,并且它步骤1 中的mylib.cppmylib.hmylib.so同一目录中。具有以下内容。

    #include <string> #include "mylib.h" int main(){
        print_string("FromMyApp");
        return 0;
    }
    

    使用以下命令将cpp文件编译为可执行文件。

    g++ myapp.cpp -o myapp -lmy -L./ -I./
    

    该命令将myapp在当前目录下生成一个exectuble,该 exetuble 运行良好,您只需执行它即可。

    Step 3. 更改库的 ABI 会影响应用程序

    但是如果我将 libary 编译命令更改为以下命令会怎样

    g++ -fPIC mylib.cpp -shared -o libmy.so -D_GLIBCXX_USE_CXX11_ABI=0
    

    在此之后,如果我执行与 step.2 中相同的命令来编译 app g++ myapp.cpp -lmy -L./ -o myapp编译器给出以下错误

    /tmp/ccDPFccW.o: In function `main': myapp.cpp:(.text+0x43): undefined reference to `print_string(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
    collect2: error: ld returned 1 exit status
    

    这明显表明我需要使用与 libary 编译命令相同的编译标志。

    g++ myapp.cpp -lmy -L./ -o myapp -D_GLIBCXX_USE_CXX11_ABI=0 
    

    4. 回到 tensorflow 的例子。

    现在让我们回到 tensorflow 示例,因为官方预构建的 tensorflow 库 (.so) 是由较旧的 GCC 编译的,(这等于较新版本的 GCC wht 标志 -DGLIBCXX_USE_CXX11_ABI=0)。因此,如果使用官方 tensorflow 的现有上级应用程序/库希望由 NO CXX 11 ABI 编译,如果您希望应用程序/库也与您编译的 tensorflow 一起使用,那么您要么需要使用较旧的编译器编译它,要么使用带有标志的新编译器-DGLIBCXX_USE_CXX11_ABI=0

  • 相关阅读:
    综合练习:词频统计
    Dart SDK 2.0安装问题
    The DartEditor executable launcher was unable to locate its companion shared library.
    pycharm中如何正确配置pyqt5
    发现黑苹果带双显示器无法启动的原因
    Pycharm中用鼠标改变字体大小
    失望的visual studio for mac
    laravel 函数测试 --- Route::has()
    laragon 之Nginx
    laragon 之xdebug
  • 原文地址:https://www.cnblogs.com/axjlxy/p/15576044.html
Copyright © 2011-2022 走看看