Skip to content

Commit

Permalink
Merge pull request #140 from ElrondNetwork/contract-build
Browse files Browse the repository at this point in the history
Improve "contract build" for Rust projects
  • Loading branch information
andreibancioiu authored May 18, 2022
2 parents faa629c + 4dcd4d7 commit a39934e
Show file tree
Hide file tree
Showing 11 changed files with 44 additions and 65 deletions.
3 changes: 3 additions & 0 deletions erdpy/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how
## [Unreleased]
- TBD

## [1.5.0]
- [Improve "contract build" for Rust projects](https://github.com/ElrondNetwork/elrond-sdk-erdpy/pull/140)

## [1.4.0]
- [Add `ledgercomm[hid]`](https://github.com/ElrondNetwork/elrond-sdk-erdpy/pull/139)

Expand Down
1 change: 1 addition & 0 deletions erdpy/CLI.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ optional arguments:
analysing the bytecode. Creates larger wasm files. Avoid in production (default:
False)
--wasm-name WASM_NAME for rust projects, optionally specify the name of the wasm bytecode output file
--wasm-suffix WASM_SUFFIX for rust projects, optionally specify the suffix of the wasm bytecode output file
--skip-eei-checks skip EEI compatibility checks (default: False)
--ignore-eei-checks ignore EEI compatibility errors (default: False)
Expand Down
2 changes: 1 addition & 1 deletion erdpy/_version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "1.4.0"
__version__ = "1.5.0"
3 changes: 3 additions & 0 deletions erdpy/cli_contracts.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ def setup_parser(args: List[str], subparsers: Any) -> Any:
help="for rust projects, does not strip the symbols from the wasm output. Useful for analysing the bytecode. Creates larger wasm files. Avoid in production (default: %(default)s)")
sub.add_argument("--wasm-name", type=str,
help="for rust projects, optionally specify the name of the wasm bytecode output file")
sub.add_argument("--wasm-suffix", type=str,
help="for rust projects, optionally specify the suffix of the wasm bytecode output file")
sub.add_argument("--skip-eei-checks", action="store_true", default=False, help="skip EEI compatibility checks (default: %(default)s)")
sub.add_argument("--ignore-eei-checks", action="store_true", default=False, help="ignore EEI compatibility errors (default: %(default)s)")
sub.set_defaults(func=build)
Expand Down Expand Up @@ -214,6 +216,7 @@ def build(args: Any):
"cargo_target_dir": args.cargo_target_dir,
"wasm_symbols": args.wasm_symbols,
"wasm_name": args.wasm_name,
"wasm_suffix": args.wasm_suffix,
"skip-eei-checks": args.skip_eei_checks,
"ignore-eei-checks": args.ignore_eei_checks
}
Expand Down
2 changes: 2 additions & 0 deletions erdpy/myprocess.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ def run_process_async(
stdout_sink=None,
stderr_sink=None
) -> ReturnCode:
logger.info(f"run_process_async: {args}, in folder: {cwd}")

loop = asyncio.get_event_loop()
result = loop.run_until_complete(_async_subprocess(args, env, stdout_sink, stderr_sink, cwd))
loop.close()
Expand Down
1 change: 0 additions & 1 deletion erdpy/projects/project_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ def build(self, options: Union[Dict[str, Any], None] = None) -> List[Path]:
self._ensure_dependencies_installed()
self.perform_build()
contract_paths = self._do_after_build_custom()
contract_paths = rename_wasm_files(contract_paths, self.options.get("wasm_name"))
self._do_after_build_core()
return contract_paths

Expand Down
6 changes: 4 additions & 2 deletions erdpy/projects/project_clang.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from typing import List

from erdpy import dependencies, errors, myprocess, utils
from erdpy.projects.project_base import Project
from erdpy.projects.project_base import Project, rename_wasm_files

logger = logging.getLogger('ProjectClang')

Expand Down Expand Up @@ -109,7 +109,9 @@ def _do_after_build_custom(self) -> List[Path]:
ll_file.unlink()
except FileNotFoundError:
pass
return [output_wasm_file]

paths = rename_wasm_files([output_wasm_file], self.options.get("wasm_name"))
return paths

def _get_llvm_path(self):
return dependencies.get_module_directory('llvm')
Expand Down
6 changes: 4 additions & 2 deletions erdpy/projects/project_cpp.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from typing import List

from erdpy import dependencies, errors, myprocess, utils
from erdpy.projects.project_base import Project
from erdpy.projects.project_base import Project, rename_wasm_files

logger = logging.getLogger("ProjectCpp")

Expand Down Expand Up @@ -87,7 +87,9 @@ def _do_after_build_custom(self) -> List[Path]:
os.remove(source_file.with_suffix(".wasm"))
os.remove(source_file.with_suffix(".ll"))
os.remove(source_file.with_suffix(".o"))
return [output_wasm_file]

paths = rename_wasm_files([output_wasm_file], self.options.get("wasm_name"))
return paths

def _get_llvm_path(self):
return dependencies.get_module_directory("llvm")
Expand Down
81 changes: 24 additions & 57 deletions erdpy/projects/project_rust.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,14 @@ def get_wasm_view_folder(self):

def perform_build(self):
meta = self.has_meta()
if not meta:
raise errors.NotSupportedProject("The project does not have a meta crate")

try:
if meta:
# The meta crate handles the build process, ABI generation and
# allows contract developers to add extra
# preparation steps before building.
self.run_meta()
else:
# For backwards compatibility - build the wasm and generate the ABI
self.run_cargo()
self.generate_abi()
# The meta crate handles the build process, ABI generation and
# allows contract developers to add extra
# preparation steps before building.
self.run_meta()
except subprocess.CalledProcessError as err:
raise errors.BuildError(err.output)

Expand All @@ -50,29 +48,9 @@ def prepare_build_wasm_args(self, args: List[str]):
"--target=wasm32-unknown-unknown",
"--release",
"--out-dir",
self.get_output_folder(),
"-Z"
"unstable-options"
self.get_output_folder()
])

def run_cargo(self):
env = self.get_env()

args = [
"cargo",
"build",
]
self.prepare_build_wasm_args(args)
self.decorate_cargo_args(args)

if not self.options.get("wasm_symbols"):
env["RUSTFLAGS"] = "-C link-arg=-s"

cwd = self.path / 'wasm'
return_code = myprocess.run_process_async(args, env=env, cwd=str(cwd))
if return_code != 0:
raise errors.BuildError(f"error code = {return_code}, see output")

def run_meta(self):
cwd = self.get_meta_folder()
env = self.get_env()
Expand All @@ -89,42 +67,31 @@ def run_meta(self):
"run",
"build",
]
self.prepare_build_wasm_args(args)

for (option, value) in self.options.items():
if isinstance(value, bool):
if value:
args.extend([f"--{option}"])
else:
args.extend([f"--{option}", str(value)])
self.prepare_build_wasm_args(args)
self.decorate_cargo_args(args)

return_code = myprocess.run_process_async(args, env=env, cwd=str(cwd))
if return_code != 0:
raise errors.BuildError(f"error code = {return_code}, see output")

def decorate_cargo_args(self, args):
def decorate_cargo_args(self, args: List[str]):
target_dir = self.options.get("cargo_target_dir")
no_wasm_opt = self.options.get("no_wasm_opt")
wasm_symbols = self.options.get("wasm_symbols")
wasm_name = self.options.get("wasm_name")
wasm_suffix = self.options.get("wasm_suffix")

if target_dir:
args.extend(["--target-dir", target_dir])

def generate_abi(self):
if not self.has_abi():
return

args = [
"cargo",
"run"
]
self.decorate_cargo_args(args)

env = self.get_env()
cwd = path.join(self.directory, "abi")
sink = myprocess.FileOutputSink(self.get_abi_filepath())
return_code = myprocess.run_process_async(args, env=env, cwd=cwd, stdout_sink=sink)
if return_code != 0:
raise errors.BuildError(f"error code = {return_code}, see output")

utils.prettify_json_file(self.get_abi_filepath())
if no_wasm_opt:
args.extend(["--no-wasm-opt"])
if wasm_symbols:
args.extend(["--wasm-symbols"])
if wasm_name:
args.extend(["--wasm-name", wasm_name])
if wasm_suffix:
args.extend(["--wasm-suffix", wasm_suffix])

def has_meta(self):
return (self.get_meta_folder() / "Cargo.toml").exists()
Expand Down
2 changes: 1 addition & 1 deletion erdpy/tests/test_cli_contracts.sh
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ testWasmName() {

${ERDPY} contract clean ${SANDBOX}/myadder-rs
assertFileDoesNotExist ${SANDBOX}/myadder-rs/output/myadder-2-rs.wasm || return 1
${ERDPY} contract build ${SANDBOX}/myadder-rs --cargo-target-dir=${TARGET_DIR} --wasm-name myadder-2-rs || return 1
${ERDPY} contract build ${SANDBOX}/myadder-rs --cargo-target-dir=${TARGET_DIR} --wasm-name myadder-2-rs.wasm || return 1
assertFileExists ${SANDBOX}/myadder-rs/output/myadder-2-rs.wasm || return 1
assertFileExists ${SANDBOX}/myadder-rs/output/myadder-rs.abi.json || return 1
}
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
with open("README.md", "r") as fh:
long_description = "https://github.com/ElrondNetwork/elrond-sdk-erdpy"

VERSION = "1.4.0"
VERSION = "1.5.0"

try:
with open('./erdpy/_version.py', 'wt') as versionfile:
Expand Down

0 comments on commit a39934e

Please sign in to comment.