Skip to content

Commit ea0b750

Browse files
committed
Add support for apple silicon.
1 parent 8f5ee88 commit ea0b750

File tree

8 files changed

+120
-26
lines changed

8 files changed

+120
-26
lines changed

.circleci/compare_bytecode_reports.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ native_platforms=(
3030
ubuntu2004-static
3131
ubuntu
3232
osx
33+
osx_intel
3334
windows
3435
)
3536
interfaces=(

.circleci/config.yml

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ commands:
8181
enum:
8282
- solcjs
8383
- native
84+
- osx_intel
8485
binary_path:
8586
type: string
8687
preset:
@@ -491,12 +492,13 @@ defaults:
491492

492493
- base_osx: &base_osx
493494
macos:
494-
xcode: "14.2.0"
495-
resource_class: macos.x86.medium.gen2
495+
xcode: "15.0.0"
496+
resource_class: macos.m1.medium.gen1
496497
environment: &base_osx_env
497498
TERM: xterm
498499
MAKEFLAGS: -j5
499500
CPUs: 5
501+
ETH_EVMONE: /usr/local/lib/libevmone.dylib
500502

501503
- base_python_small: &base_python_small
502504
docker:
@@ -1146,6 +1148,7 @@ jobs:
11461148
environment:
11471149
<<: *base_osx_env
11481150
CMAKE_BUILD_TYPE: Release
1151+
CMAKE_OPTIONS: -DCMAKE_OSX_ARCHITECTURES:STRING=x86_64;arm64
11491152
steps:
11501153
- checkout
11511154
- install_dependencies_osx
@@ -1657,6 +1660,22 @@ jobs:
16571660
binary_path: "build/solc/solc"
16581661
preset: "<< parameters.preset >>"
16591662

1663+
b_bytecode_osx_intel:
1664+
parameters:
1665+
preset:
1666+
type: string
1667+
<<: *base_osx
1668+
parallelism: 2 # For prepare_bytecode_report
1669+
steps:
1670+
- checkout
1671+
- attach_workspace:
1672+
at: .
1673+
- prepare_bytecode_report:
1674+
label: "osx_intel"
1675+
binary_type: osx_intel
1676+
binary_path: "build/solc/solc"
1677+
preset: "<< parameters.preset >>"
1678+
16601679
b_bytecode_win:
16611680
parameters:
16621681
preset:
@@ -1880,6 +1899,11 @@ workflows:
18801899
matrix: *bytecode_compare_preset_matrix
18811900
requires:
18821901
- b_osx
1902+
- b_bytecode_osx_intel:
1903+
<<: *on_all_tags_and_branches
1904+
matrix: *bytecode_compare_preset_matrix
1905+
requires:
1906+
- b_osx
18831907
- b_bytecode_ems:
18841908
<<: *on_all_tags_and_branches
18851909
matrix: *bytecode_compare_preset_matrix
@@ -1892,6 +1916,7 @@ workflows:
18921916
- b_bytecode_ubu
18931917
- b_bytecode_win
18941918
- b_bytecode_osx
1919+
- b_bytecode_osx_intel
18951920
- b_bytecode_ems
18961921

18971922
# Final artifacts

.circleci/osx_install_dependencies.sh

Lines changed: 51 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -50,33 +50,67 @@ if [ ! -f /usr/local/lib/libz3.a ] # if this file does not exists (cache was not
5050
then
5151
brew update
5252
brew upgrade
53-
brew install boost
5453
brew install cmake
5554
brew install wget
5655
brew install coreutils
5756
brew install diffutils
5857
brew install grep
59-
./scripts/install_obsolete_jsoncpp_1_7_4.sh
58+
59+
# writing to /usr/local/lib need administrative privileges.
60+
sudo ./scripts/install_obsolete_jsoncpp_1_7_4.sh
61+
62+
# boost
63+
boost_version="1.84.0"
64+
boost_package="boost_${boost_version//./_}.tar.bz2"
65+
boost_dir="boost_${boost_version//./_}"
66+
wget "https://boostorg.jfrog.io/artifactory/main/release/$boost_version/source/$boost_package"
67+
tar xf "$boost_package"
68+
rm "$boost_package"
69+
cd "$boost_dir"
70+
./bootstrap.sh --with-toolset=clang --with-libraries=thread,system,filesystem,program_options,serialization,test
71+
# the default number of jobs that b2 is taking, is the number of detected available CPU threads.
72+
sudo ./b2 -a address-model=64 architecture=arm+x86 install
73+
cd ..
74+
sudo rm -rf "$boost_dir"
6075

6176
# z3
6277
z3_version="4.12.1"
63-
z3_dir="z3-${z3_version}-x64-osx-10.16"
64-
z3_package="${z3_dir}.zip"
65-
wget "https://github.com/Z3Prover/z3/releases/download/z3-${z3_version}/${z3_package}"
66-
validate_checksum "$z3_package" 7601f844de6d906235140d0f76cca58be7ac716f3e2c29c35845aa24b24f73b9
67-
unzip "$z3_package"
78+
z3_dir="z3-z3-$z3_version"
79+
z3_package="z3-$z3_version.tar.gz"
80+
wget "https://github.com/Z3Prover/z3/archive/refs/tags/$z3_package"
81+
validate_checksum "$z3_package" a3735fabf00e1341adcc70394993c05fd3e2ae167a3e9bb46045e33084eb64a3
82+
tar xf "$z3_package"
6883
rm "$z3_package"
69-
cp "${z3_dir}/bin/libz3.a" /usr/local/lib
70-
cp "${z3_dir}/bin/z3" /usr/local/bin
71-
cp "${z3_dir}/include/"* /usr/local/include
72-
rm -r "$z3_dir"
84+
cd "$z3_dir"
85+
mkdir build
86+
cd build
87+
cmake -DCMAKE_OSX_ARCHITECTURES:STRING="x86_64;arm64" -DZ3_BUILD_LIBZ3_SHARED=false ..
88+
make -j
89+
sudo make install
90+
cd ../..
91+
rm -rf "$z3_dir"
7392

7493
# evmone
7594
evmone_version="0.11.0"
76-
evmone_package="evmone-${evmone_version}-darwin-x86_64.tar.gz"
77-
wget "https://github.com/ethereum/evmone/releases/download/v${evmone_version}/${evmone_package}"
78-
validate_checksum "$evmone_package" 83ed20676681d9a31bd30cac399ab7c615ccab8adb8087cc2c7e9cd22b4d2efc
79-
tar xzpf "$evmone_package" -C /usr/local
80-
rm "$evmone_package"
81-
95+
if [[ $(uname -m) == 'arm64' ]]
96+
then
97+
# evmone does not provide any builds for apple silicon yet. so lets just build it locally.
98+
# be aware that we are only building the arm version here, we don't build a universal binary.
99+
git clone https://github.com/ethereum/evmone.git
100+
cd evmone
101+
git checkout "v${evmone_version}"
102+
git submodule update --init
103+
cmake -S . -B build
104+
cmake --build build
105+
cd build
106+
sudo make install
107+
cd ../..
108+
rm -rf evmone
109+
else
110+
evmone_package="evmone-${evmone_version}-darwin-x86_64.tar.gz"
111+
wget "https://github.com/ethereum/evmone/releases/download/v${evmone_version}/${evmone_package}"
112+
validate_checksum "$evmone_package" 83ed20676681d9a31bd30cac399ab7c615ccab8adb8087cc2c7e9cd22b4d2efc
113+
tar xzpf "$evmone_package" -C /usr/local
114+
rm "$evmone_package"
115+
fi
82116
fi

.circleci/parallel_bytecode_report.sh

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ binary_type="$2"
3333
binary_path="$3" # This path must be absolute
3434
preset="$4"
3535

36-
[[ $binary_type == native || $binary_type == solcjs ]] || { >&2 echo "Invalid binary type: ${binary_type}"; exit 1; }
36+
[[ $binary_type == native || $binary_type == "osx_intel" || $binary_type == solcjs ]] || { >&2 echo "Invalid binary type: ${binary_type}"; exit 1; }
3737

3838
# NOTE: Locale affects the order of the globbed files.
3939
export LC_ALL=C
@@ -47,7 +47,7 @@ python3 ../scripts/isolate_tests.py ../test/
4747
# FIXME: These cases crash because of https://github.com/ethereum/solidity/issues/13583
4848
rm ./*_bytecode_too_large_*.sol ./*_combined_too_large_*.sol
4949

50-
if [[ $binary_type == native ]]; then
50+
if [[ $binary_type == native || $binary_type == "osx_intel" ]]; then
5151
interface=$(echo -e "standard-json\ncli" | circleci tests split)
5252
echo "Selected interface: ${interface}"
5353

@@ -56,6 +56,7 @@ if [[ $binary_type == native ]]; then
5656
"$binary_path" \
5757
--interface "$interface" \
5858
--preset "$preset" \
59+
--execution-arch "$binary_type" \
5960
--report-file "../bytecode-report-${label}-${interface}-${preset}.txt"
6061
else
6162
echo "Installing solc-js"

cmake/jsoncpp.cmake

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ if (WIN32 AND POLICY CMP0091 AND CMAKE_MSVC_RUNTIME_LIBRARY)
4040
list(APPEND JSONCPP_CMAKE_ARGS "-DCMAKE_MSVC_RUNTIME_LIBRARY=${CMAKE_MSVC_RUNTIME_LIBRARY}")
4141
endif()
4242

43+
string(REPLACE ";" "$<SEMICOLON>" CMAKE_OSX_ARCHITECTURES_ "${CMAKE_OSX_ARCHITECTURES}")
4344
ExternalProject_Add(jsoncpp-project
4445
PREFIX "${prefix}"
4546
DOWNLOAD_DIR "${PROJECT_SOURCE_DIR}/deps/downloads"
@@ -57,6 +58,7 @@ ExternalProject_Add(jsoncpp-project
5758
-DJSONCPP_WITH_PKGCONFIG_SUPPORT=OFF
5859
-DCMAKE_CXX_FLAGS=${JSONCPP_CXX_FLAGS}
5960
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
61+
-DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES_}
6062
${JSONCPP_CMAKE_ARGS}
6163
${byproducts}
6264
)

scripts/bytecodecompare/prepare_report.py

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ class CompilerInterface(Enum):
2626
STANDARD_JSON = 'standard-json'
2727

2828

29+
class ExecutionArchitecture(Enum):
30+
NATIVE = 'native'
31+
OSX_INTEL = 'osx_intel'
32+
33+
2934
class SettingsPreset(Enum):
3035
LEGACY_OPTIMIZE = 'legacy-optimize'
3136
LEGACY_NO_OPTIMIZE = 'legacy-no-optimize'
@@ -214,6 +219,7 @@ def parse_cli_output(source_file_name: Path, cli_output: str, exit_code: int) ->
214219

215220
def prepare_compiler_input(
216221
compiler_path: Path,
222+
execution_arch: ExecutionArchitecture,
217223
source_file_name: Path,
218224
force_no_optimize_yul: bool,
219225
interface: CompilerInterface,
@@ -224,6 +230,12 @@ def prepare_compiler_input(
224230

225231
settings = CompilerSettings.from_preset(preset)
226232

233+
command_line = []
234+
if execution_arch == ExecutionArchitecture.OSX_INTEL:
235+
command_line = ["/usr/bin/arch", "-64", "-x86_64"]
236+
else:
237+
assert execution_arch == ExecutionArchitecture.NATIVE
238+
227239
if interface == CompilerInterface.STANDARD_JSON:
228240
json_input: dict = {
229241
'language': 'Solidity',
@@ -241,7 +253,7 @@ def prepare_compiler_input(
241253
if smt_use == SMTUse.DISABLE:
242254
json_input['settings']['modelChecker'] = {'engine': 'none'}
243255

244-
command_line = [str(compiler_path), '--standard-json']
256+
command_line += [str(compiler_path), '--standard-json']
245257
compiler_input = json.dumps(json_input)
246258
else:
247259
assert interface == CompilerInterface.CLI
@@ -258,7 +270,7 @@ def prepare_compiler_input(
258270
if smt_use == SMTUse.DISABLE:
259271
compiler_options += ['--model-checker-engine', 'none']
260272

261-
command_line = [str(compiler_path)] + compiler_options
273+
command_line += [str(compiler_path)] + compiler_options
262274
compiler_input = load_source(source_file_name, smt_use)
263275

264276
return (command_line, compiler_input)
@@ -289,6 +301,7 @@ def detect_metadata_cli_option_support(compiler_path: Path):
289301

290302
def run_compiler(
291303
compiler_path: Path,
304+
execution_arch: ExecutionArchitecture,
292305
source_file_name: Path,
293306
force_no_optimize_yul: bool,
294307
interface: CompilerInterface,
@@ -298,10 +311,10 @@ def run_compiler(
298311
tmp_dir: Path,
299312
exit_on_error: bool,
300313
) -> FileReport:
301-
302314
if interface == CompilerInterface.STANDARD_JSON:
303315
(command_line, compiler_input) = prepare_compiler_input(
304316
compiler_path,
317+
execution_arch,
305318
Path(source_file_name.name),
306319
force_no_optimize_yul,
307320
interface,
@@ -325,6 +338,7 @@ def run_compiler(
325338

326339
(command_line, compiler_input) = prepare_compiler_input(
327340
compiler_path.absolute(),
341+
execution_arch,
328342
Path(source_file_name.name),
329343
force_no_optimize_yul,
330344
interface,
@@ -354,6 +368,7 @@ def run_compiler(
354368
def generate_report(
355369
source_file_names: List[str],
356370
compiler_path: Path,
371+
execution_arch: ExecutionArchitecture,
357372
interface: CompilerInterface,
358373
presets: List[SettingsPreset],
359374
smt_use: SMTUse,
@@ -373,6 +388,7 @@ def generate_report(
373388
try:
374389
report = run_compiler(
375390
compiler_path,
391+
execution_arch,
376392
Path(source_file_name),
377393
force_no_optimize_yul,
378394
interface,
@@ -422,6 +438,13 @@ def commandline_parser() -> ArgumentParser:
422438
choices=[c.value for c in CompilerInterface],
423439
help="Compiler interface to use.",
424440
)
441+
parser.add_argument(
442+
'--execution-arch',
443+
dest='execution_arch',
444+
default=ExecutionArchitecture.NATIVE.value,
445+
choices=[c.value for c in ExecutionArchitecture],
446+
help="Select the architecture of the universal binary that should be executed. (Only relevant for macOS)",
447+
)
425448
parser.add_argument(
426449
'--preset',
427450
dest='presets',
@@ -470,6 +493,7 @@ def commandline_parser() -> ArgumentParser:
470493
generate_report(
471494
glob("*.sol"),
472495
Path(options.compiler_path),
496+
ExecutionArchitecture(options.execution_arch),
473497
CompilerInterface(options.interface),
474498
[SettingsPreset(p) for preset_group in presets for p in preset_group],
475499
SMTUse(options.smt_use),

scripts/install_obsolete_jsoncpp_1_7_4.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ TEMPDIR=$(mktemp -d)
1717
cd "jsoncpp-${jsoncpp_version}"
1818
mkdir -p build
1919
cd build
20-
cmake -DARCHIVE_INSTALL_DIR=. -G "Unix Makefiles" ..
20+
cmake -DCMAKE_OSX_ARCHITECTURES:STRING="x86_64;arm64" -DARCHIVE_INSTALL_DIR=. -G "Unix Makefiles" ..
2121
make
2222
make install
2323
)

test/scripts/test_bytecodecompare_prepare_report.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99

1010
# NOTE: This test file file only works with scripts/ added to PYTHONPATH so pylint can't find the imports
1111
# pragma pylint: disable=import-error
12-
from bytecodecompare.prepare_report import CompilerInterface, FileReport, ContractReport, SettingsPreset, SMTUse, Statistics
12+
from bytecodecompare.prepare_report import ExecutionArchitecture, CompilerInterface, FileReport, ContractReport
13+
from bytecodecompare.prepare_report import SettingsPreset, SMTUse, Statistics
1314
from bytecodecompare.prepare_report import load_source, parse_cli_output, parse_standard_json_output, prepare_compiler_input
1415
# pragma pylint: enable=import-error
1516

@@ -223,6 +224,7 @@ def test_prepare_compiler_input_should_work_with_standard_json_interface(self):
223224

224225
(command_line, compiler_input) = prepare_compiler_input(
225226
Path('solc'),
227+
ExecutionArchitecture.NATIVE,
226228
SMT_SMOKE_TEST_SOL_PATH,
227229
preset=SettingsPreset.LEGACY_OPTIMIZE,
228230
force_no_optimize_yul=False,
@@ -237,6 +239,7 @@ def test_prepare_compiler_input_should_work_with_standard_json_interface(self):
237239
def test_prepare_compiler_input_should_work_with_cli_interface(self):
238240
(command_line, compiler_input) = prepare_compiler_input(
239241
Path('solc'),
242+
ExecutionArchitecture.NATIVE,
240243
SMT_SMOKE_TEST_SOL_PATH,
241244
preset=SettingsPreset.LEGACY_OPTIMIZE,
242245
force_no_optimize_yul=False,
@@ -273,6 +276,7 @@ def test_prepare_compiler_input_for_json_preserves_newlines(self):
273276

274277
(command_line, compiler_input) = prepare_compiler_input(
275278
Path('solc'),
279+
ExecutionArchitecture.NATIVE,
276280
SMT_CONTRACT_WITH_MIXED_NEWLINES_SOL_PATH,
277281
preset=SettingsPreset.VIA_IR_OPTIMIZE,
278282
force_no_optimize_yul=False,
@@ -287,6 +291,7 @@ def test_prepare_compiler_input_for_json_preserves_newlines(self):
287291
def test_prepare_compiler_input_for_cli_preserves_newlines(self):
288292
(_command_line, compiler_input) = prepare_compiler_input(
289293
Path('solc'),
294+
ExecutionArchitecture.NATIVE,
290295
SMT_CONTRACT_WITH_MIXED_NEWLINES_SOL_PATH,
291296
preset=SettingsPreset.LEGACY_OPTIMIZE,
292297
force_no_optimize_yul=True,
@@ -300,6 +305,7 @@ def test_prepare_compiler_input_for_cli_preserves_newlines(self):
300305
def test_prepare_compiler_input_for_cli_should_handle_force_no_optimize_yul_flag(self):
301306
(command_line, compiler_input) = prepare_compiler_input(
302307
Path('solc'),
308+
ExecutionArchitecture.NATIVE,
303309
SMT_SMOKE_TEST_SOL_PATH,
304310
preset=SettingsPreset.LEGACY_NO_OPTIMIZE,
305311
force_no_optimize_yul=True,
@@ -317,6 +323,7 @@ def test_prepare_compiler_input_for_cli_should_handle_force_no_optimize_yul_flag
317323
def test_prepare_compiler_input_for_cli_should_not_use_metadata_option_if_not_supported(self):
318324
(command_line, compiler_input) = prepare_compiler_input(
319325
Path('solc'),
326+
ExecutionArchitecture.NATIVE,
320327
SMT_SMOKE_TEST_SOL_PATH,
321328
preset=SettingsPreset.VIA_IR_OPTIMIZE,
322329
force_no_optimize_yul=False,

0 commit comments

Comments
 (0)