新手教程 智能合约编译合约出错 fatal error: 'eosiolib/eosio.hpp' file not found 。的暴力处理方式。改写 eosiocpp

yaoyh · 2018年08月10日 · 最后由 yaoyh 回复于 2018年08月29日 · 13146 次阅读
本帖已被设为精华帖!

新版的EOS,安装后,合约编译出现找不到h文件的错误。网上很多人问,但好像没有解决的方法。我用EOS根目录下面的sh批处理,重新安装EOS,也没有解决。最后,用暴力的方式解决的。就是改写,eosiocpp

eosiocpp存在与两个地方。

1, 下载到本地的EOS 目录下。 XXXXX/eos/build/tools/
2, 安装目录下。 /usr/local/eosio/bin

2个文件都是bash的脚本,一样的。我改写的是第一个,当然改写第二个也行,执行的时候别忘了执行那个就好。

下面,简单分析一下,这个脚本。

EOSIO_BIN_INSTALL_DIR=`dirname $0`

看到以第一句,我就倒了。EOS的安装路径的获得,居然根据执行时的路径来判断。

临时工写的shell。😝

后面使用的头文件。Lib库的路径,都是在此基础上得来的。

EOSIO_INSTALL_DIR=`dirname ${EOSIO_BIN_INSTALL_DIR}`

既然都暴力修改了,我就直接把我的下载路径写死在里面了。

EOSIO_BIN_INSTALL_DIR不要了,直接定义EOSIO_INSTALL_DIR

/home/yaoyh/app/eos是我的下载路径,换成各位的,基本就能用了。

#EOSIO_BIN_INSTALL_DIR=`dirname $0`
#if [ "${EOSIO_BIN_INSTALL_DIR}" == "." ]; then
#  EOSIO_BIN_INSTALL_DIR=`pwd`
#fi
#EOSIO_INSTALL_DIR=`dirname ${EOSIO_BIN_INSTALL_DIR}`
EOSIO_INSTALL_DIR="/home/yaoyh/app/eos"

决定了修改方针,就一点点编译尝试了,缺什么,直接在下面的 include中追加就OK了。
每个人缺少的可能不同,根据path的相对位置追加就好了。

($PRINT_CMDS; /home/yaoyh/opt/wasm/bin/clang -emit-llvm -O3 --std=c++14 --target=wasm32 -nostdinc \
                           -DBOOST_DISABLE_ASSERTS -DBOOST_EXCEPTION_DISABLE \
                           -nostdlib -nostdlibinc -ffreestanding -nostdlib -fno-threadsafe-statics -fno-rtti \
                           -fno-exceptions -I ${EOSIO_INSTALL_DIR}/include \
                           -I${EOSIO_INSTALL_DIR}/contracts/libc++/upstream/include \
                           -I${EOSIO_INSTALL_DIR}/contracts/musl/upstream/include \
                           -I${BOOST_INCLUDE_DIR} \
                           -I $filePath \
                           -I${EOSIO_INSTALL_DIR}/contracts \
                           -I${EOSIO_INSTALL_DIR}/externals/magic_get/include \
                           ${EOSIOCPP_CFLAGS} \
                           -c $file -o $workdir/built/$name
)

原来的lib库的位置也不对,直接修改。

${EOSIO_INSTALL_DIR}/build/contracts/eosiolib/eosiolib.bc \
${EOSIO_INSTALL_DIR}/build/contracts/libc++/libc++.bc \
${EOSIO_INSTALL_DIR}/build/contracts/musl/libc.bc

改到这里,问题就彻底解决了。
最后,我把完整文件,贴到下面。这个不能直接替换使用,用差分工具和自己本地边比较边修改比较好。

#!/bin/bash

#EOSIO_BIN_INSTALL_DIR=`dirname $0`
#if [ "${EOSIO_BIN_INSTALL_DIR}" == "." ]; then
#  EOSIO_BIN_INSTALL_DIR=`pwd`
#fi
#EOSIO_INSTALL_DIR=`dirname ${EOSIO_BIN_INSTALL_DIR}`
EOSIO_INSTALL_DIR="/home/yaoyh/app/eos"

echo $EOSIO_INSTALL_DIR

ABIGEN=${EOSIO_INSTALL_DIR}/build/programs/eosio-abigen/eosio-abigen
BOOST_INCLUDE_DIR=/home/yaoyh/opt/boost/include
function copy_skeleton {
    set -e
#    cp -r "${EOSIO_INSTALL_DIR}/share/eosio/skeleton/." $newname
    cp -r "${EOSIO_INSTALL_DIR}/contracts/skeleton/." $newname

    for file in $(find ./$newname -name 'skeleton.*')
    do
        newfile=`echo $file | sed 's/skeleton\./'"$newname"'./'`
#        echo mv "${file}" "${newfile}"
        mv "${file}" "${newfile}"
        exp=s/skeleton/${newname}/g
#        echo sed -i ${exp}  ${newfile}
        sed ${exp}  ${newfile} > ${newfile}1
        mv ${newfile}1 ${newfile}
    done
    echo "created $newname from skeleton"
    set +e
}

function build_contract {
    set -e
    workdir=`mktemp -d`

    if [[ ${VERBOSE} == "1" ]]; then
       PRINT_CMDS="set -x"
    fi

    ($PRINT_CMDS; mkdir $workdir/built)

    for file in $@; do
        name=`basename $file`
        filePath=`dirname $file`

        ($PRINT_CMDS; /home/yaoyh/opt/wasm/bin/clang -emit-llvm -O3 --std=c++14 --target=wasm32 -nostdinc \
                                   -DBOOST_DISABLE_ASSERTS -DBOOST_EXCEPTION_DISABLE \
                                   -nostdlib -nostdlibinc -ffreestanding -nostdlib -fno-threadsafe-statics -fno-rtti \
                                   -fno-exceptions -I ${EOSIO_INSTALL_DIR}/include \
                                   -I${EOSIO_INSTALL_DIR}/contracts/libc++/upstream/include \
                                   -I${EOSIO_INSTALL_DIR}/contracts/musl/upstream/include \
                                   -I${BOOST_INCLUDE_DIR} \
                                   -I $filePath \
                                   -I${EOSIO_INSTALL_DIR}/contracts \
                                   -I${EOSIO_INSTALL_DIR}/externals/magic_get/include \
                                   ${EOSIOCPP_CFLAGS} \
                                   -c $file -o $workdir/built/$name
        )

    done

    ($PRINT_CMDS; /home/yaoyh/opt/wasm/bin/llvm-link -only-needed -o $workdir/linked.bc $workdir/built/* \
                                   ${EOSIO_INSTALL_DIR}/build/contracts/eosiolib/eosiolib.bc \
                                   ${EOSIO_INSTALL_DIR}/build/contracts/libc++/libc++.bc \
                                   ${EOSIO_INSTALL_DIR}/build/contracts/musl/libc.bc


    )
    ($PRINT_CMDS; /home/yaoyh/opt/wasm/bin/llc -thread-model=single --asm-verbose=false -o $workdir/assembly.s $workdir/linked.bc)
    ($PRINT_CMDS; ${EOSIO_INSTALL_DIR}/build/externals/binaryen/bin/eosio-s2wasm -o $outname -s 16384 $workdir/assembly.s)
    ($PRINT_CMDS; ${EOSIO_INSTALL_DIR}/build/libraries/wasm-jit/Source/Programs/eosio-wast2wasm $outname ${outname%.*}.wasm -n)

    ($PRINT_CMDS; rm -rf $workdir)
    set +e
}

function generate_abi {

    if [[ ! -e "$1" ]]; then
        echo "You must specify a file"
        exit 1
    fi

    context_folder=$(cd "$(dirname "$1")" ; pwd -P)

    ${ABIGEN} -extra-arg=-c -extra-arg=--std=c++14 -extra-arg=--target=wasm32 \
        -extra-arg=-nostdinc -extra-arg=-nostdinc++ -extra-arg=-DABIGEN \
        -extra-arg=-I${EOSIO_INSTALL_DIR}/contracts/libc++/upstream/include \
        -extra-arg=-I${EOSIO_INSTALL_DIR}/contracts/musl/upstream/include \
        -extra-arg=-I${BOOST_INCLUDE_DIR} \
        -extra-arg=-I${EOSIO_INSTALL_DIR}/contracts \
        -extra-arg=-I${EOSIO_INSTALL_DIR}/externals/magic_get/include \
        -extra-arg=${EOSIOCPP_CFLAGS}  \
        -extra-arg=-I${EOSIO_INSTALL_DIR}/include -extra-arg=-I$context_folder \
        -extra-arg=-fparse-all-comments -destination-file=${outname} -verbose=0 \
        -context=$context_folder $1




    if [ "$?" -ne 0 ]; then
        exit 1
    fi    

    echo "Generated ${outname} ..."
}

function print_help {
    echo "Usage: $0 -o output.wast contract.cpp [other.cpp ...]"
    echo "       OR"
    echo "       $0 -n mycontract"
    echo "       OR"
    echo "       $0 -g contract.abi types.hpp"
    echo
    echo "Options:"
    echo "   -n | --newcontract [name]"
    echo "      Create a new contract in the [name] folder, based on the example contract"
    echo "   OR"
    echo "   -o | --outname [output.wast] [input.cpp ...]"
    echo "      Generate the wast output file based on input cpp files"
    echo "      The wasm output will also be created as output.wasm"
    echo "   OR"
    echo "   -g | --genabi contract.abi types.hpp"
    echo "      Generate the ABI specification file [EXPERIMENTAL]"
}

command=""

while [[ $# -gt 1 ]]
do
key="$1"

case $key in
    -h|--help)
        print_help
        break;
        ;;
    -n|--newcontract)
        newname="$2"
        command="newcontract"
        shift 2
        break
        ;;
    -o|--outname)
        outname="$2"
        command="outname"
        shift 2
        break
        ;;
    -g|--genabi)
        outname="$2"
        command="genabi"
        shift 2
        ;;
    *)
        echo "Unrecognized option: $1"
        exit 1
        ;;
esac
done

if [[ "outname" == "$command" ]]; then
    build_contract $@
elif [[ "newcontract" == "$command" ]]; then
    copy_skeleton
elif [[ "genabi" == "$command" ]]; then
    generate_abi $@
else
    print_help
    exit 1
fi

共收到 4 条回复
strahe 将本帖设为了精华贴 08月10日 11:14

无法生成ADI的问题,也做了修改。

修正了一个不能生成abi文件的笔误。

我服了这最新版本的eosiocpp,写完之后自己都没测试过就放出来

vergil 回复

没有测试就发布出来的可能性不大。

我仍然怀疑是那个安装步骤或前提条件没有设置好。
上述暴力的方法,虽然解决了问题,但不完美。

可惜没有时间和精力浪费在上面了,妥协了。

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册