Skip to content

Commit

Permalink
Support for target os different from current os added
Browse files Browse the repository at this point in the history
  • Loading branch information
gsalzer committed Apr 16, 2022
1 parent 8483426 commit 486481d
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 18 deletions.
10 changes: 9 additions & 1 deletion solcx/__init__.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
from solcx.install import (
compile_solc,
get_compilable_solc_versions,
get_executable,
get_installable_solc_versions,
get_installed_solc_versions,
get_solcx_install_folder,
import_installed_solc,
install_solc,
install_solc_pragma,
set_target_os,
set_solc_version,
set_solc_version_pragma,
)
from solcx.main import compile_files, compile_source, compile_standard, get_solc_version, link_code
from solcx.main import (
compile_files,
compile_source,
compile_standard,
get_solc_version,
link_code
)
60 changes: 43 additions & 17 deletions solcx/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,22 @@
SOLCX_BINARY_PATH_VARIABLE = "SOLCX_BINARY_PATH"

_default_solc_binary = None
_target_os = None


def set_target_os(platform: Optional[str] = None):
"""
Set the target platform for the solc binaries. If unset, it defaults to the current os.
"""
global _target_os
if platform is None or platform in ("linux", "macosx", "windows"):
_target_os = platform
else:
raise OSError(f"Unsupported target OS: '{platform}' - py-solc-x supports 'linux', 'macosx', or 'windows'.")


def _get_target_os() -> str:
return _target_os if _target_os else _get_os_name()


def _get_os_name() -> str:
Expand All @@ -72,7 +88,7 @@ def _convert_and_validate_version(version: Union[str, Version]) -> Version:

def _unlink_solc(solc_path: Path) -> None:
solc_path.unlink()
if _get_os_name() == "windows":
if _get_target_os() == "windows":
shutil.rmtree(solc_path.parent)


Expand All @@ -92,12 +108,17 @@ def get_solcx_install_folder(solcx_binary_path: Union[Path, str] = None) -> Path
Path
Subdirectory where `solc` binaries are are saved.
"""
if os.getenv(SOLCX_BINARY_PATH_VARIABLE):
return Path(os.environ[SOLCX_BINARY_PATH_VARIABLE])
elif solcx_binary_path is not None:
return Path(solcx_binary_path)
if _get_target_os() == _get_os_name():
if os.getenv(SOLCX_BINARY_PATH_VARIABLE):
return Path(os.environ[SOLCX_BINARY_PATH_VARIABLE])
elif solcx_binary_path is not None:
return Path(solcx_binary_path)
else:
path = Path.home().joinpath(".solcx")
path.mkdir(exist_ok=True)
return path
else:
path = Path.home().joinpath(".solcx")
path = Path.home().joinpath(f".solcx-{_get_target_os()}")
path.mkdir(exist_ok=True)
return path

Expand Down Expand Up @@ -188,7 +209,7 @@ def get_executable(

version = _convert_and_validate_version(version)
solc_bin = get_solcx_install_folder(solcx_binary_path).joinpath(f"solc-v{version}")
if _get_os_name() == "windows":
if _get_target_os() == "windows":
solc_bin = solc_bin.joinpath("solc.exe")
if not solc_bin.exists():
raise SolcNotInstalled(
Expand Down Expand Up @@ -344,7 +365,7 @@ def get_compilable_solc_versions(headers: Optional[Dict] = None) -> List[Version
List
List of Versions objects of installable `solc` versions.
"""
if _get_os_name() == "windows":
if _get_target_os() == "windows":
raise OSError("Compiling from source is not supported on Windows systems")

version_list = []
Expand Down Expand Up @@ -430,7 +451,8 @@ def install_solc(
else:
version = _convert_and_validate_version(version)

os_name = _get_os_name()
target_os = _get_target_os()
this_os = _get_os_name()
process_lock = get_process_lock(str(version))

with process_lock:
Expand All @@ -439,7 +461,7 @@ def install_solc(
LOGGER.info(f"solc {version} already installed at: {path}")
return version

data = requests.get(BINARY_DOWNLOAD_BASE.format(_get_os_name(), "list.json"))
data = requests.get(BINARY_DOWNLOAD_BASE.format(target_os, "list.json"))
if data.status_code != 200:
raise ConnectionError(
f"Status {data.status_code} when getting solc versions from solc-bin.ethereum.org"
Expand All @@ -449,17 +471,17 @@ def install_solc(
except KeyError:
raise SolcInstallationError(f"Solc binary for v{version} is not available for this OS")

if os_name == "linux":
if target_os == "linux":
_install_solc_unix(version, filename, show_progress, solcx_binary_path)
elif os_name == "macosx":
elif target_os == "macosx":
_install_solc_unix(version, filename, show_progress, solcx_binary_path)
elif os_name == "windows":
elif target_os == "windows":
_install_solc_windows(version, filename, show_progress, solcx_binary_path)

try:
_validate_installation(version, solcx_binary_path)
except SolcInstallationError as exc:
if os_name != "windows":
if target_os != "windows" and target_os == this_os:
exc.args = (
f"{exc.args[0]} If this issue persists, you can try to compile from "
f"source code using `solcx.compile_solc('{version}')`.",
Expand Down Expand Up @@ -490,6 +512,8 @@ def compile_solc(
Version
installed solc version
"""
if _get_os_name() != _get_target_os():
raise OSError("Cross-compiling is not supported")
if _get_os_name() == "windows":
raise OSError("Compiling from source is not supported on Windows systems")

Expand Down Expand Up @@ -537,7 +561,7 @@ def compile_solc(
" while attempting to build solc from the source.\n"
"This is likely due to a missing or incorrect version of a build dependency."
)
if _get_os_name() == "macosx":
if _get_target_os() == "macosx":
err_msg = (
f"{err_msg}\n\nFor suggested installation options: "
"https://github.com/iamdefinitelyahuman/py-solc-x/wiki/Installing-Solidity-on-OSX" # noqa: E501
Expand Down Expand Up @@ -598,7 +622,7 @@ def _download_solc(url: str, show_progress: bool) -> bytes:
def _install_solc_unix(
version: Version, filename: str, show_progress: bool, solcx_binary_path: Union[Path, str, None]
) -> None:
download = BINARY_DOWNLOAD_BASE.format(_get_os_name(), filename)
download = BINARY_DOWNLOAD_BASE.format(_get_target_os(), filename)
install_path = get_solcx_install_folder(solcx_binary_path).joinpath(f"solc-v{version}")

content = _download_solc(download, show_progress)
Expand All @@ -611,7 +635,7 @@ def _install_solc_unix(
def _install_solc_windows(
version: Version, filename: str, show_progress: bool, solcx_binary_path: Union[Path, str, None]
) -> None:
download = BINARY_DOWNLOAD_BASE.format(_get_os_name(), filename)
download = BINARY_DOWNLOAD_BASE.format(_get_target_os(), filename)
install_path = get_solcx_install_folder(solcx_binary_path).joinpath(f"solc-v{version}")

temp_path = _get_temp_folder()
Expand All @@ -629,6 +653,8 @@ def _install_solc_windows(


def _validate_installation(version: Version, solcx_binary_path: Union[Path, str, None]) -> None:
if _get_target_os() != _get_os_name():
return
binary_path = get_executable(version, solcx_binary_path)
try:
installed_version = wrapper._get_solc_version(binary_path)
Expand Down

1 comment on commit 486481d

@gsalzer
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adds the feature mentioned in issue ApeWorX#143 of the original py-solc-x repo

Please sign in to comment.