【问题分析】Tensorflow build过程发生 ‘undefined reference to‘ Error

问题描述

在定制tensorflow的过程中,进行bazel build的过程中莫名提示如下的undefined reference to `tensorflow::DataTypeToEnum<float>::value' 的错误,由于并没有修改过tensorflow的相关source code,所以感觉很困惑

 

问题分析

  • 报错的DataTypeToEnum是一个template struct,它的定义在tensorflow/core/framework/types.h 中,并且紧跟着定义之后通过宏MATCH_TYPE_AND_ENUM(xxx, DT_xxx) 实例化了不同的DataTypeToEnum<xxx>类型,

 

  • 照理在tensorflow/core/kernels/conv_ops_benchmark_test.cc的开头就include了头文件tensorflow/core/framework/types.h,那么根据上面对types.h的分析,MATCH_TYPE_AND_ENUM(float, DT_FLOAT);宏已经实例化了struct tensorflow::DataTypeToEnum<float> 类型,并且定义了tensorflow::DataTypeToEnum<float>::value 成员,不应该会发生build过程中undefined reference

  • 仔细分析DataTypeToEnum中 static constexpr DataType value 这个成员的声明,怀疑蹊跷处在static constexpr 的修饰符上,百度static constexpr后发现很多说明该修饰符的用法和特性,其中特别强调了它会在编译阶段被编译器直接优化成一个常量,提示了自己在定制tensorflow的过程中为了debug tensorflow的运行过程,将gcc的编译开关做过调整:改为了-O0 -g,即不做任何优化编译带debug symbol的binary;通过将编译开关改为-O2 后即可以正常编译通过,问题得到解决
  • 为了进一步求证编译开关对static constexpr的影响,可以使用下面的问题重现示意代码
//base.h

class base {
public:
    static constexpr unsigned int A_VAL{0x69U};
};
//derived.h

#include "base.h"
#include <iostream>

using namespace std;

class derived : public base
{
public:
    int some_func(void) {
        cout << "Some func" << endl;
        return 0;
    }
};
//concrete.h

#include "derived.h"

#include <utility>

class concrete : public derived
{
public:
    concrete(int a, std::pair<unsigned int, unsigned int> data = {A_VAL, A_VAL}) {
        some_func();
        std::cout << "First: " << data.first << " Second: " << data.second << endl;
    }
};
//main.cpp

#include "concrete.h"

int main (int argc, char *argv[])
{
    concrete c{1};
    c.some_func();
}
  • 使用-O2优化编译成功,程序运行成功
# g++ -O2 -std=c++11 main.cpp -o main
# ./main

Some func
First: 105 Second: 105
Some func
  • 使用-O0不带优化编译,发生找不到static constexpr修饰符的成员变量A_VAL  
# g++ -O0 -std=c++11 main.cpp -o main
/tmp/ccBUwOEa.o: In function `main':
main.cpp:(.text+0x25): undefined reference to `base::A_VAL'
main.cpp:(.text+0x2c): undefined reference to `base::A_VAL'
collect2: error: ld returned 1 exit status

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值