01
目的
本文档介绍了工程化开发智能合约项目的工程树目录,介绍了各个文件夹及文件的含义和用途。本文档将沿用之前文章中实现的地址簿合约内容,以初始化项目为例展开介绍,适合刚接触合约开发的开发人员用来了解智能合约项目,帮助其快速了解以及上手智能合约。
02
智能合约介绍
区块链作为一种分布式可信计算平台,去中心化是其最本质的特征。每笔交易的记录不可篡改地存储在区块链上。智能合约中定义可以在区块链上执行的动作 action 和交易 transaction 的代码。可以在区块链上执行,并将合约执行状态作为该区块链实例不可变历史的一部分。
因此,开发人员可以依赖该区块链作为可信计算环境,其中智能合约的输入、执行和结果都是独立的,不受外部影响。
03
术语解释
WebAssembly(WASM)
用于执行可移植二进制代码格式的虚拟机,托管在 nodeos 中。
应用程序二进制接口(ABI)
定义如何将数据编组进出 WebAssembly 虚拟机的接口。
04
Make 介绍
make 工具可以看成是一个智能的批处理工具,它本身并没有编译和链接的功能,而是通过调用 Makefile 文件中用户指定的命令来进行编译和链接的。
它使得用户可以在不知道构建细节的情况下构建和安装,因为细节都记录在 Makefile。
05
CMake 介绍
CMake 是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的安装(编译过程)。组态档取名为 CMakeLists.txt,它能够通过识别 CMakeLists.txt 输出 Makefile 文件,能测试编译器所支持的 C++特性。熟悉某个集成开发环境(IDE)的开发者可以通过 CMake 用标准的方式建构软件。
EOS 中通过命令行生成的初始化项目中就自带一个 CMakeLists.txt 文件。如果不需要做个性化改动,用户只需要使用 cmake 指令构建项目即可,不需要其余的修改。
语法介绍:
PROJECT 关键字可以用来指定工程的名字和支持的语言,默认支持所有语言
PROJECT(HELLO)指定工程名字,支持所有语言
PROJECT(HELLO CXX)指定工程名字,支持 C++
PROJECT(HELLO C CXX)指定工程名字,支持 C 和 C++
SET 关键字用来显示指定变量
SET(SRC_LIST main.cpp)SRC_LIST 变量就包含了 main.cpp
SET(SRC_LIST main.cpp t1.cpp t2.cpp)SRC_LIST 变量包含多个 cpp
MESSAGE 关键字向终端输出用户自定义的信息
SEND_ERROR 产生错误、生成过程被跳过
STATUS 输出前缀为--的信息
FATAL_ERROR 立即终止所有 cmake 过程
ADD_EXECUTABLE 关键字生成可执行文件
ADD_EXECUTABLE(hello ${SRC_LIST})生成可执行文件名为 hello,源文件读取变量为 SRC_LIST
06
编译后目录树介绍
(一)综述
本文依旧以 addressbook 项目为例。
使用初始化 eosio-init 工具可以创建一个自定义项目名称的智能合约项目。在--path=后添加创建项目的路径,--project=后添加创建项目的名称。执行以下命令得到一个智能合约空项目 addressbook:
eosio-init --path=. --project=addressbook
复制代码
项目中存在一个空的 build 文件夹,进入 build 目录下运行指令:
指令将根据根目录和 src 文件夹中的 CMakeLists.txt 文件生成构造。将会在 build 目录下生成所有的临时文件,不会对源文件有任何影响,也称为外部构建。
根目录下 CMakeLists.txt 文件内容如下:
include(ExternalProject)
# if no cdt root is given use default path
if(EOSIO_CDT_ROOT STREQUAL "" OR NOT EOSIO_CDT_ROOT)
find_package(eosio.cdt)
endif()
ExternalProject_Add(
addressbook_project
SOURCE_DIR ${CMAKE_SOURCE_DIR}/src
BINARY_DIR ${CMAKE_BINARY_DIR}/addressbook
CMAKE_ARGS -DCMAKE_TOOLCHAIN_FILE=${EOSIO_CDT_ROOT}/lib/cmake/eosio.cdt/EosioWasmToolchain.cmake
UPDATE_COMMAND ""
PATCH_COMMAND ""
TEST_COMMAND ""
INSTALL_COMMAND ""
BUILD_ALWAYS 1
)
复制代码
文件中规定了外部构造的形式,构造后源文件夹位置,以及与 eosio 有关的配置。
src 中的 CMakeLists.txt 文件如下:
project(addressbook)
set(EOSIO_WASM_OLD_BEHAVIOR "Off")
find_package(eosio.cdt)
add_contract( addressbook addressbook addressbook.cpp )
target_include_directories( addressbook PUBLIC ${CMAKE_SOURCE_DIR}/../include )
target_ricardian_directory( addressbook ${CMAKE_SOURCE_DIR}/../ricardian )
复制代码
文件中规定了:
project 项目名称
add_contract 合约涉及的所有 cpp 文件
target_include_directories 合约的头文件存放位置
target_ricardian_directory 合约的李嘉图合约存放位置
运行 cmake 后,将在 build 文件夹中创建如下文件:
├── addressbook 空文件夹
├── addressbook_project-prefix 项目前缀文件夹
├── CMakeFiles CMake版本文件夹
├── cmake_install.cmake 安装文件
├── CMakeCache.txt Cache文件
└── Makefile CMake初始化文件
复制代码
运行以下指令完成构建:
运行成功后,addressbook 文件夹中会生成如下内容:
├── CMakeFiles CMake版本文件夹
├── addressbook.abi 应用程序二进制接口文件
├── addressbook.wasm WebAssembly文件
├── cmake_install.cmake 安装文件
├── CMakeCache.txt Cache文件
└── Makefile CMake初始化文件
复制代码
(二)CMake 文件集
CMakeFiles 文件夹、cmake_install.cmake 文件、 CMakeCache.txt 文件、 Makefile 文件都是由 cmake 指令产生的与 CMake 有关的文件。该文件集会重复的出现在自动构建的文件夹目录中,一般情况下不需要改动。
1、CMakeFiles 文件夹
CMakeFiles 文件夹中存放了与 CMake 版本和项目启动有关的各种文件。
2、cmake_install.cmake 文件
cmake_install.cmake 为项目目录安装脚本,安装配置名称和组件。
# Install script for directory: /home/xxx/biosboot/genesis/addressbook
# Set the install prefix
if(NOT DEFINED CMAKE_INSTALL_PREFIX)
set(CMAKE_INSTALL_PREFIX "/usr/local")
endif()
string(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}")
# Set the install configuration name.
if(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME)
if(BUILD_TYPE)
string(REGEX REPLACE "^[^A-Za-z0-9_]+" ""
CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}")
else()
set(CMAKE_INSTALL_CONFIG_NAME "")
endif()
message(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"")
endif()
# Set the component getting installed.
if(NOT CMAKE_INSTALL_COMPONENT)
if(COMPONENT)
message(STATUS "Install component: \"${COMPONENT}\"")
set(CMAKE_INSTALL_COMPONENT "${COMPONENT}")
else()
set(CMAKE_INSTALL_COMPONENT)
endif()
endif()
# Install shared libraries without execute permission?
if(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE)
set(CMAKE_INSTALL_SO_NO_EXE "1")
endif()
# Is this installation the result of a crosscompile?
if(NOT DEFINED CMAKE_CROSSCOMPILING)
set(CMAKE_CROSSCOMPILING "FALSE")
endif()
if(CMAKE_INSTALL_COMPONENT)
set(CMAKE_INSTALL_MANIFEST "install_manifest_${CMAKE_INSTALL_COMPONENT}.txt")
else()
set(CMAKE_INSTALL_MANIFEST "install_manifest.txt")
endif()
string(REPLACE ";" "\n" CMAKE_INSTALL_MANIFEST_CONTENT
"${CMAKE_INSTALL_MANIFEST_FILES}")
file(WRITE "/home/ljy/biosboot/genesis/addressbook/addressbook/build/${CMAKE_INSTALL_MANIFEST}"
"${CMAKE_INSTALL_MANIFEST_CONTENT}")
复制代码
3、CMakeCache.txt 文件
CMakeCache.txt 文件中描述了 CMake 建立和使用的一些初始化数值,如果需要更改,可以编辑该文件并保存退出。
# This is the CMakeCache file.
# For build in directory: /home/xxx/biosboot/genesis/addressbook/build
# It was generated by CMake: /usr/bin/cmake
# You can edit this file to change values found and used by cmake.
# If you do not want to change any of the values, simply exit the editor.
# If you do want to change a value, simply edit, save, and exit the editor.
# The syntax for the file is as follows:
(文件的语法如下:)
# KEY:TYPE=VALUE
(键:类型=值)
# KEY is the name of a variable in the cache.
(KEY是缓存中变量的名称。)
# TYPE is a hint to GUIs for the type of VALUE, DO NOT EDIT TYPE!.
(TYPE是对GUI的VALUE类型的提示,请勿编辑TYPE!。)
# VALUE is the current value for the KEY.
(VALUE是KEY的当前值。)
复制代码
4、Makefile 文件
Makefile 文件由 Unix Makefiles 生成器根据版本自动生成,请勿编辑。当没有要生成的参数时执行默认目标。
# CMAKE generated file: DO NOT EDIT!
# Generated by "Unix Makefiles" Generator, CMake Version 3.16
# Default target executed when no arguments are given to make.
default_target: all
.PHONY : default_target
# Allow only one "make -f Makefile2" at a time, but pass parallelism.
.NOTPARALLEL:
复制代码
(三)项目文件夹 addressbook
完成构建后项目文件夹内除了 CMake 文件集以外,还有 addressbook.abi 和 addressbook.wasm 两个文件。
addressbook.abi 是应用程序二进制接口文件 ABI(Application Binary Interface)。描述了应用程序和操作系统之间,一个应用和它的库之间,或者应用的组成部分之间的低接口。
ABI 涵盖了各种细节,如:
数据类型的大小、布局和对齐;
调用约定(控制着函数的参数如何传送以及如何接受返回值);
哪个寄存器用于哪个函数参数;通过栈传递的第一个函数参数是最先 push 到栈上还是最后;
系统调用的编码和一个应用如何向操作系统进行系统调用;
在一个完整的操作系统 ABI 中,目标文件的二进制格式、程序库等。
.abi 文件定义了数据如何编组进出 WASM 引擎。
addressbook.wasm 是 WebAssembly 文件,是一个可移植、体积小、加载快并且兼容 Web 的全新格式。WebAssenbly 并不是一种编程语言,而是一种编译器的编译目标,可以把.wasm 文件当成是.cpp 文件通过编译以后生成的文件。.wasm 文件是区块链中的 WebAssembly 引擎执行的二进制代码。WebAssembly 引擎托管在 nodeos 守护进程中并执行智能合约代码。
(四)项目前缀文件夹 addressbook_project-prefix
cmake 生成的临时文件夹,内部有 src 和 tmp 两个文件夹。存放的大多是空文件,或者与 cmake 有关的 cmd 指令。
电脑访问 DDC 网络门户
ddc.bsnbase.com
-END-
评论