mirror of
https://github.com/conan-io/conan-center-index.git
synced 2025-08-10 00:11:44 +00:00
197 lines
8.9 KiB
Python
197 lines
8.9 KiB
Python
from conan import ConanFile, conan_version
|
|
from conan.tools.build import cross_building
|
|
from conan.tools.env import Environment
|
|
from conan.tools.files import chdir, copy, get, replace_in_file
|
|
from conan.tools.layout import basic_layout
|
|
from conan.tools.scm import Version
|
|
import json
|
|
import os
|
|
|
|
required_conan_version = ">=1.52.0"
|
|
|
|
|
|
class EmSDKConan(ConanFile):
|
|
name = "emsdk"
|
|
description = "Emscripten SDK. Emscripten is an Open Source LLVM to JavaScript compiler"
|
|
url = "https://github.com/conan-io/conan-center-index"
|
|
homepage = "https://github.com/kripken/emscripten"
|
|
topics = ("emsdk", "emscripten", "sdk")
|
|
license = "MIT"
|
|
settings = "os", "arch", "compiler", "build_type"
|
|
|
|
short_paths = True
|
|
|
|
@property
|
|
def _settings_build(self):
|
|
return getattr(self, "settings_build", self.settings)
|
|
|
|
def layout(self):
|
|
basic_layout(self, src_folder="src")
|
|
|
|
def requirements(self):
|
|
self.requires("nodejs/16.3.0")
|
|
# self.requires("python") # FIXME: Not available as Conan package
|
|
# self.requires("wasm") # FIXME: Not available as Conan package
|
|
|
|
def package_id(self):
|
|
del self.info.settings.compiler
|
|
del self.info.settings.build_type
|
|
|
|
def source(self):
|
|
get(self, **self.conan_data["sources"][self.version],
|
|
destination=self.source_folder, strip_root=True)
|
|
|
|
@property
|
|
def _relative_paths(self):
|
|
return ["bin", os.path.join("bin", "upstream", "emscripten")]
|
|
|
|
@property
|
|
def _paths(self):
|
|
return [os.path.join(self.package_folder, path) for path in self._relative_paths]
|
|
|
|
@property
|
|
def _emsdk(self):
|
|
return os.path.join(self.package_folder, "bin")
|
|
|
|
@property
|
|
def _emscripten(self):
|
|
return os.path.join(self.package_folder, "bin", "upstream", "emscripten")
|
|
|
|
@property
|
|
def _em_config(self):
|
|
return os.path.join(self.package_folder, "bin", ".emscripten")
|
|
|
|
@property
|
|
def _em_cache(self):
|
|
return os.path.join(self.package_folder, "bin", ".emscripten_cache")
|
|
|
|
def generate(self):
|
|
env = Environment()
|
|
env.prepend_path("PATH", self._paths)
|
|
env.define_path("EMSDK", self._emsdk)
|
|
env.define_path("EMSCRIPTEN", self._emscripten)
|
|
env.define_path("EM_CONFIG", self._em_config)
|
|
env.define_path("EM_CACHE", self._em_cache)
|
|
env.vars(self, scope="emsdk").save_script("emsdk_env_file")
|
|
|
|
@staticmethod
|
|
def _chmod_plus_x(filename):
|
|
if os.name == "posix":
|
|
os.chmod(filename, os.stat(filename).st_mode | 0o111)
|
|
|
|
def _tools_for_version(self):
|
|
ret = {}
|
|
# Select release-upstream from version (wasm-binaries)
|
|
with open(os.path.join(self.source_folder, "emscripten-releases-tags.json"), "r") as f:
|
|
data = json.load(f)
|
|
ret["wasm"] = f"releases-upstream-{data['releases'][self.version]}-64bit"
|
|
# Select python and node versions
|
|
with open(os.path.join(self.source_folder, "emsdk_manifest.json"), "r") as f:
|
|
data = json.load(f)
|
|
tools = data["tools"]
|
|
if self.settings.os == "Windows":
|
|
python = next((it for it in tools if (it["id"] == "python" and not it.get("is_old", False))), None)
|
|
ret["python"] = f"python-{python['version']}-64bit"
|
|
node = next((it for it in tools if (it["id"] == "node" and not it.get("is_old", False))), None)
|
|
ret["nodejs"] = f"node-{node['version']}-64bit"
|
|
return ret
|
|
|
|
def build(self):
|
|
with chdir(self, self.source_folder):
|
|
emsdk = "emsdk.bat" if self._settings_build.os == "Windows" else "./emsdk"
|
|
self._chmod_plus_x("emsdk")
|
|
|
|
# Install required tools
|
|
required_tools = self._tools_for_version()
|
|
for key, value in required_tools.items():
|
|
if key != 'nodejs':
|
|
self.run(f"{emsdk} install {value}")
|
|
self.run(f"{emsdk} activate {value}")
|
|
|
|
def package(self):
|
|
copy(self, "LICENSE", src=self.source_folder, dst=os.path.join(self.package_folder, "licenses"))
|
|
copy(self, "*", src=self.source_folder, dst=os.path.join(self.package_folder, "bin"))
|
|
emscripten = os.path.join(self.package_folder, "bin", "upstream", "emscripten")
|
|
toolchain = os.path.join(emscripten, "cmake", "Modules", "Platform", "Emscripten.cmake")
|
|
# FIXME: conan should add the root of conan package requirements to CMAKE_PREFIX_PATH (LIBRARY/INCLUDE -> ONLY; PROGRAM -> NEVER)
|
|
# allow to find conan libraries
|
|
replace_in_file(self, toolchain,
|
|
"set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)",
|
|
"set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH)")
|
|
replace_in_file(self, toolchain,
|
|
"set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)",
|
|
"set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE BOTH)")
|
|
replace_in_file(self, toolchain,
|
|
"set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)",
|
|
"set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE BOTH)")
|
|
if not cross_building(self):
|
|
self.run("embuilder build MINIMAL", env=["conanemsdk", "conanrun"]) # force cache population
|
|
# the line below forces emscripten to accept the cache as-is, even after re-location
|
|
# https://github.com/emscripten-core/emscripten/issues/15053#issuecomment-920950710
|
|
os.remove(os.path.join(self._em_cache, "sanity.txt"))
|
|
|
|
def _define_tool_var(self, value):
|
|
suffix = ".bat" if self.settings.os == "Windows" else ""
|
|
path = os.path.join(self._emscripten, f"{value}{suffix}")
|
|
self._chmod_plus_x(path)
|
|
return path
|
|
|
|
def package_info(self):
|
|
self.cpp_info.bindirs = self._relative_paths
|
|
self.cpp_info.includedirs = []
|
|
self.cpp_info.libdirs = []
|
|
self.cpp_info.resdirs = []
|
|
|
|
# If we are not building for Emscripten, probably we don't want to inject following environment variables,
|
|
# but it might be legit use cases... until we find them, let's be conservative.
|
|
if not hasattr(self, "settings_target") or self.settings_target is None:
|
|
return
|
|
|
|
if self.settings_target.os != "Emscripten":
|
|
self.output.warning(f"You've added {self.name}/{self.version} as a build requirement, while os={self.settings_target.os} != Emscripten")
|
|
return
|
|
|
|
toolchain = os.path.join(self.package_folder, "bin", "upstream", "emscripten", "cmake", "Modules", "Platform", "Emscripten.cmake")
|
|
self.conf_info.prepend("tools.cmake.cmaketoolchain:user_toolchain", toolchain)
|
|
|
|
self.buildenv_info.define_path("EMSDK", self._emsdk)
|
|
self.buildenv_info.define_path("EMSCRIPTEN", self._emscripten)
|
|
self.buildenv_info.define_path("EM_CONFIG", self._em_config)
|
|
self.buildenv_info.define_path("EM_CACHE", self._em_cache)
|
|
|
|
compiler_executables = {
|
|
"c": self._define_tool_var("emcc"),
|
|
"cpp": self._define_tool_var("em++"),
|
|
}
|
|
self.conf_info.update("tools.build:compiler_executables", compiler_executables)
|
|
self.buildenv_info.define_path("CC", compiler_executables["c"])
|
|
self.buildenv_info.define_path("CXX", compiler_executables["cpp"])
|
|
self.buildenv_info.define_path("AR", self._define_tool_var("emar"))
|
|
self.buildenv_info.define_path("NM", self._define_tool_var("emnm"))
|
|
self.buildenv_info.define_path("RANLIB", self._define_tool_var("emranlib"))
|
|
self.buildenv_info.define_path("STRIP", self._define_tool_var("emstrip"))
|
|
|
|
self.cpp_info.builddirs = [
|
|
os.path.join("bin", "releases", "src"),
|
|
os.path.join("bin", "upstream", "emscripten", "cmake", "Modules"),
|
|
os.path.join("bin", "upstream", "emscripten", "cmake", "Modules", "Platform"),
|
|
os.path.join("bin", "upstream", "emscripten", "system", "lib", "libunwind", "cmake", "Modules"),
|
|
os.path.join("bin", "upstream", "emscripten", "system", "lib", "libunwind", "cmake"),
|
|
os.path.join("bin", "upstream", "emscripten", "tests", "cmake", "target_library"),
|
|
os.path.join("bin", "upstream", "lib", "cmake", "llvm"),
|
|
]
|
|
|
|
if Version(conan_version).major < 2:
|
|
self.env_info.PATH.extend(self._paths)
|
|
self.env_info.CONAN_CMAKE_TOOLCHAIN_FILE = toolchain
|
|
self.env_info.EMSDK = self._emsdk
|
|
self.env_info.EMSCRIPTEN = self._emscripten
|
|
self.env_info.EM_CONFIG = self._em_config
|
|
self.env_info.EM_CACHE = self._em_cache
|
|
self.env_info.CC = compiler_executables["c"]
|
|
self.env_info.CXX = compiler_executables["cpp"]
|
|
self.env_info.AR = self._define_tool_var("emar")
|
|
self.env_info.NM = self._define_tool_var("emnm")
|
|
self.env_info.RANLIB = self._define_tool_var("emranlib")
|
|
self.env_info.STRIP = self._define_tool_var("emstrip")
|