tensorflow2.0出來了,在python環境很容易構建,在linux環境也很好構建,不過在windows環境就有點麻煩了,要做的事比較多,經驗多次失敗,最終成功構建。


一、保證安裝了python,編譯tensorflow2.0建議用3.6.8
    使用pip list查看需要的python工具包,保證有以下版本的工具包
    Keras-Applications     1.0.8
    Keras-Preprocessing 1.1.0
    numpy                        1.16.2
    six                              1.13.0
    wheel                         0.33.6
二、安裝msys64,並把安裝路徑加入到環境變量的path中,包括msys64安裝目錄及msys64/usr/bin目錄
三、下載bazel-0.26.1並拷貝到msys64的/usr/bin目錄,編譯tensorflow2需要這個版本
    設置bazel及visual c++的相關係統環境變量(如果還沒有的就添加,已經存在的檢查一下是不是正確)

    (本人開發開發環境全部放在D盤)
    BAZEL_SH=D:\msys64\usr\bin\bash.exe
    BAZEL_VC=D:\Program Files (x86)\Microsoft Visual Studio 14.0\VC
    BAZEL_VS=D:\Program Files (x86)\Microsoft Visual Studio 14.0
    
    運行以下命令更新msys及bazel,通常你肯定會遇到超時的麻煩,加上這個參數吧:--disable-download-timeout
    pacman -Syu
    pacman -S git
    pacman -S patch unzip grep
    pacman -S git patch unzip

四、以管理員身份運行Power shell
五、下載tensorflow
    git clone https://github.com/tensorflow/tensorflow.git
    cd tensorflow
    提取指定的版本,這裏説的是r2.0
    git checkout r2.0

六、配置編譯環境
    python ./configure.py

    這裏主要是配置問題,如果使用CUDA需要先行配置CUDA SDK。
七、按需求執行以下命令編譯出相關的內容

查看\tensorflow\tensorflow\BUILD的創建規則,分別多次調用以下命令來生成DLL和LIB還有相關頭文件

-- 生成C庫

bazel build --config=opt --config=cuda --copt=-nvcc_options=disable-warnings //tensorflow/tools/lib_package:libtensorflow

-- 生成C庫

bazel build --config=opt --copt=-nvcc_options=disable-warnings //tensorflow/tools/lib_package:libtensorflow

-- 生成C++庫

bazel build --config=opt --config=cuda --copt=-nvcc_options=disable-warnings --define=no_tensorflow_py_deps=true //tensorflow:tensorflow_cc.dll

-- 生成C++ import lib (也可以不使用此方法生成輸入庫,而是把生成的.ifso文件改名為.lib)

bazel build --config=opt --config=cuda --copt=-nvcc_options=disable-warnings //tensorflow:tensorflow_cc_dll_import_lib 

-- 生成相關頭文件

bazel build --config=opt --config=cuda --copt=-nvcc_options=disable-warnings //tensorflow:install_headers

七、低版本Visual Studio可能會出現的錯誤(2017以下)

Execution platform: @bazel_tools//platforms:host_platform
tensorflow/core/grappler/optimizers/data/rebatch.cc(66): fatal error C1001: An internal error has occurred in the compiler.
(compiler file 'msc1.cpp', line 1468)
 To work around this problem, try simplifying or changing the program near the locations listed above.
Please choose the Technical Support command on the Visual C++
 Help menu, or open the Technical Support help file for more information

主要是由於編譯器無法解釋constexpr char這種寫法。編輯tensorflow\tensorflow\core\grappler\optimizers\data\rebatch.cc文件,把kBatchDatasetOps註釋掉,改成以下樣子。

//constexpr std::array<const char*, 6> kBatchDatasetOps = {
//    kBatchOp,       kBatchV2Op,      kMapAndBatchOp, kExperimentalMapAndBatchOp,
//    kPaddedBatchOp, kPaddedBatchV2Op};
constexpr std::array<const char*, 6> kBatchDatasetOps = {
    "BatchDataset", "BatchDatasetV2", "MapAndBatchDataset", "ExperimentalMapAndBatchDataset",
    "PaddedBatchDataset", "PaddedBatchDatasetV2"
};

!!!注意!!!

按照上面的操作你肯定可以得到相應的so或者dll,但是當你以為得米的時候馬上寫一個hello world來驗證時會發現
VS的輸出界面遍佈“無法解析的符號”。(你肯定會遇到的)

例如以下的代碼

#include <iostream>

#include <vector>

#include "tensorflow/core/public/session.h"
//tensorflow-master為tensorflow源碼根目錄,不喜歡include這麼長的路徑可以把這個路徑加到cmakelist,再直接包含session.h

#include <iostream>using namespace std;

using namespace tensorflow;

int main()

{

    Session* session;

    Status status = NewSession(SessionOptions(), &session);

    if (!status.ok()) {

        std::cout << status.ToString() << std::endl;

    }

    else {

        std::cout << "Session created successfully" << std::endl;

    }

    cout << "Session successfully created.\n";

}

 ??0SessionOptions@tensorflow@@QEAA@XZ
?NewSession@tensorflow@@YA?AVStatus@1@AEBUSessionOptions@1@PEAPEAVSession@1@@Z

編輯 tensorflow/tools/def_file_filter/def_file_filter.py.tpl文件,

# Header for the def file.

    if args.target:

      def_fp.write("LIBRARY " + args.target + "\n")

    def_fp.write("EXPORTS\n")

    def_fp.write("\t ??1OpDef@tensorflow@@UEAA@XZ\n")

    def_fp.write("\t ??0SessionOptions@tensorflow@@QEAA@XZ\n")

    def_fp.write("\t ?NewSession@tensorflow@@YA?AVStatus@1@AEBUSessionOptions@1@PEAPEAVSession@1@@Z\n")


把缺少的符號按上面的形式加入到新的行,保存後再bazel build編譯出新的庫。

務必注意,執行腳本的是PYTHON,代碼的縮進非常重要,請必須保證前面有四個空格。筆者實際加了以下條目:

def_fp.write("\t ??1OpDef@tensorflow@@UEAA@XZ\n")
    def_fp.write("\t ??0SessionOptions@tensorflow@@QEAA@XZ\n")
    def_fp.write("\t ?NewSession@tensorflow@@YA?AVStatus@1@AEBUSessionOptions@1@PEAPEAVSession@1@@Z\n")
    def_fp.write("\t ??0Operation@tensorflow@@QEAA@PEAVNode@1@@Z\n")
    def_fp.write("\t ??1Scope@tensorflow@@QEAA@XZ\n")
    def_fp.write("\t ?NewRootScope@Scope@tensorflow@@SA?AV12@XZ\n")
    def_fp.write("\t ?ToGraphDef@Scope@tensorflow@@QEBA?AVStatus@2@PEAVGraphDef@2@@Z\n")
    def_fp.write("\t ?WithOpNameImpl@Scope@tensorflow@@AEBA?AV12@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z\n")
    def_fp.write("\t ??0ExpandDims@ops@tensorflow@@QEAA@AEBVScope@2@VInput@2@1@Z\n")
    def_fp.write("\t ??0Placeholder@ops@tensorflow@@QEAA@AEBVScope@2@W4DataType@2@@Z\n")
    def_fp.write("\t ??0Cast@ops@tensorflow@@QEAA@AEBVScope@2@VInput@2@W4DataType@2@@Z\n")
    def_fp.write("\t ??0Div@ops@tensorflow@@QEAA@AEBVScope@2@VInput@2@1@Z\n")
    def_fp.write("\t ?NewSession@tensorflow@@YAPEAVSession@1@AEBUSessionOptions@1@@Z\n")

其它編譯器相關的麻煩不一一列出,通常改加一下相關宏定義就可以了。