Fabric源碼編譯及示例

源碼的編譯-Why?
Fabric源碼的編譯是建立在已經基本掌握了Fabric的部分模塊或者很多模塊的代碼的基礎上.但是爲什麼要編譯Fabric的源碼呢,大神們不是已經寫好了Fabric這個項目框架並編譯好了嗎,拿來用不就好了嗎?

1.部署Fabric網絡的docker容器是通過編譯Fabric裏的peer/Order/fabric-ca/模塊的代碼形docker鏡像創建的.固有的已編譯好的鏡像讓我們要開發的系統也禁錮住了,每個要開發的應用系統都有自身的特點,我們需要通過編譯Fabric的改寫的模塊代碼生成應用系統所需要的鏡像.比如說,阿里通過基於OpenJDK定製的TaobaoVM,也是自身編譯的軟件開發包.
2.編譯Fabric源碼可以驗證自己的想法,當閱讀Fabric源碼時候,代碼如何的運行只是通過我們理論上的猜想,通過實際的編譯代碼可以驗證我們的猜想.
3.定位錯誤,修改bug.源碼的編譯是建立在Fabric的源碼的閱讀上的,當系統運行的日誌裏出現錯誤時,根據錯誤提示能定位到源碼中的錯誤點,根據源碼能修改bug.

準備工作

1.編譯環境的安裝,go的安裝,Fabric的源碼下載,在Fabric的源碼的閱讀一篇中講述了.
2.安裝其他必要的組件.

假設GOPATH爲/home/gopath該文件夾下有兩個文件夾:src用於存放Fabric源碼.bin用於存放go編譯好的可執行文件.
2.1安裝go的包管理工具gopm.
export GOPATH=/home/gopath
go get -u github.com/gpmgo/gopm

/home/gopath/bin目錄下將有gopm,go get是下載和編譯的意思
2.2通過 gopm安裝 goimports.(go代碼格式化工具,自動修正import的package)
export GOPATH=/home/gopath
gopm get -g -d golang.org/x/tools/cmd/goimports
再使用 go install 安裝 goimports
go install golang.org/x/tools/cmd/goimports
/home/gopath/bin目錄下將有goimports

2.3安裝 gocov(go的單元測試覆蓋率檢查工具)
GOPATH=/home/gopath
gopm get -g -d golang.org/x/tools/cover
gopm get -g -d github.com/axw/gocov/gocov
go install github.com/axw/gocov/gocov
/home/gopath/bin目錄下將有gocov

2.4安裝 gocov-xml
GOPATH=/home/gopath
gopm get -g -d github.com/AlekSi/gocov-xml
go install github.com/AlekSi/gocov-xml
/home/gopath/bin目錄下將有 gocov-xml

2.5安裝其他組件
yum install -y gcc libtool libltdl-dev libtool-ltdl-devel openssl

3.Makefile文件的語法理解.
Fabric的源碼鏡像是通過make按照Makefile中文件的編譯規則來編譯鏡像的.

簡要介紹Makefile的語法規則.
3.1 Makefile文件的一般形式.
target ... : prerequisites ...
command
...
...

其中表示多個.
target是一個目標文件,可以是Object File,也可以是執行文件。也可以是一個標籤(Label),make就不會自動去找lable後的文件的依賴性,也就不會自動執行其後所定義的命令。 需要明確使用make Label。纔會執行命令。
prerequisites是要生成target所需要的文件或是目標。
command也就是make需要執行的命令。(任意的Shell命令)
說明,上面的一般形式是一個文件的依賴關係.target這一個或多個的目標文件依賴於prerequisites中的文件,其生成規則定義在command中。特別的,prerequisites中如果有一個以上的文件比target文件要新的話,command所定義的命令就會被執行。這就是Makefile的規則。
3.2依賴關係的實質上就是說明了目標文件是由哪些文件生成的,換言之,目標文件是哪些文件更新的。
3.3僞目標使用方法的終端編譯命令是make lable,避免當前文件夾下也有文件叫lable。
僞目標eg:
.PHONY lable.PHONY避免同名
lable:
rm *.o

終端使用make labe,執行的操作是刪除所有的.o文件.
一般形式的eg :
main.o : main.c defs.h
cc -c main.c
#make最後生成 main.o文件依賴於main.c defs.h兩個文件,cc -c main.c執行可執行文件main.c進行編譯.

3.4 Makefile中的第一個目標會被作爲其默認目標。

How

1.進入Fabric源碼目錄/home/gopath/src/hyperledger/fabric.並添加gopath的環境變量,一定要加.
export GOPATH= /home/gopath
sudo su

2.編譯生成 protoc-gen-go
cd $GOPATH
gopm get -g -d github.com/golang/protobuf/protoc-gen-go
go install github.com/golang/protobuf/protoc-gen-go
# /home/gopath/bin出現protoc-gen-go執行文件

3.根據Fabric源碼目錄下的Makefile文件中的說明.在源碼目錄下打開終端,根據下圖1中方框的targets僞目標,選擇你要編譯的target,執行命令make peer/all/orderer...
這裏寫圖片描述
執行make命令後會在當前文件夾下生成一個build文件夾.編譯後的鏡像或者可運行工具都是在這個文件夾裏找.

編譯peer模塊的代碼示例

說明:peer網絡節點啓動時運行的命令是peer node start,實際上Fabric網絡節點的peer docker容器中執行的便是通過Fabric源碼編譯的peer可執行文件來操作peer下的命令.本例中在peer節點下通過修改代碼並編譯來添加test命令.
1.在/home/gopath/src/hyperledger/fabric/peer下添加test包.並在test包下創建test.go文件.

package test
import (
    "github.com/hyperledger/fabric/common/flogging"
    "github.com/spf13/cobra"
)
var logger = flogging.MustGetLogger("testCommand")
func Cmd() *cobra.Command {
    return testCommond
}
var testCommond = &cobra.Command{
    Use:   "test",
    Short: "test the node.",
    Long:  `test a node that interacts with the network.`,
    Run: func(cmd *cobra.Command, args []string) {
        logger.Info("Build test by JinaWenJun----------------------")
    },
}

2.在/home/gopath/src/hyperledger/fabric/peer下的main.go文件中添加

    mainCmd.AddCommand(version.Cmd())
    mainCmd.AddCommand(node.Cmd())
    mainCmd.AddCommand(chaincode.Cmd(nil))
    mainCmd.AddCommand(clilogging.Cmd(nil))
    mainCmd.AddCommand(channel.Cmd(nil))
    //添加的另外一個test命令,並在前面導入包"github.com/hyperledger/fabric/peer/test"
    mainCmd.AddCommand(test.Cmd())

3.在源碼目錄下打開終端進行編譯 make peer,在/home/gopath/src/hyperledger/fabric/build/bin下將會生成可執行文件peer.將該文件拷貝到/home/gopath/bin下測試新添加的test 命令.(模擬在peer docker的容器下peer命令的執行).
4.打開終端,執行peer test
這裏寫圖片描述

遇到的問題解決方案

1.終端執行make 命令時,出現沒有那個文件或目錄如圖,
這裏寫圖片描述
方法:需要在終端下添加環境變量,執行export GOPATH= /home/gopath

2.當因爲網速終端卡住時,需要將Makefile文件中的curl部分刪除.手動下載相應的文件chaintool目錄/build/bin下面.
chaintool
3.當出現文件找不到或者命令找不到,如圖
這裏寫圖片描述
方法:終端執行下面兩條命令,將命令複製進去
cp $GOPATH/bin/protoc-gen-go $GOPATH/src/github.com/hyperledger/fabric/build/docker/gotools/bin/

cp $GOPATH/bin/gocov $GOPATH/src/github.com/hyperledger/fabric/build/docker/gotools/bin/

4.當終端make peer出現下圖錯誤時候.
這裏寫圖片描述
方法:根據錯誤提示core/chaincode/ccproviderimpl.go:20:2:不能找到context.進入到相應的文件ccproviderimpl.go修改.
這裏寫圖片描述
如果在出現提示哪裏不能找到”context”到指定的文件下按照上述形式修改即可.
編譯成功:
這裏寫圖片描述相應的 build/bin/文件夾下有peer可執行文件.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章