diff --git a/recipes/scons/all/conandata.yml b/recipes/scons/all/conandata.yml new file mode 100644 index 0000000000000..c289373910ed7 --- /dev/null +++ b/recipes/scons/all/conandata.yml @@ -0,0 +1,4 @@ +sources: + "3.1.2": + url: "http://prdownloads.sourceforge.net/scons/scons-3.1.2.tar.gz" + sha256: "7801f3f62f654528e272df780be10c0e9337e897650b62ddcee9f39fde13f8fb" diff --git a/recipes/scons/all/conanfile.py b/recipes/scons/all/conanfile.py new file mode 100644 index 0000000000000..8592a1b2dabcc --- /dev/null +++ b/recipes/scons/all/conanfile.py @@ -0,0 +1,93 @@ +from conans import ConanFile, tools +from conans.errors import ConanException, ConanInvalidConfiguration +import io +import os +import shutil +import sys + + +class SConsConan(ConanFile): + name = "scons" + description = "SCons is an Open Source software construction tool—that is, a next-generation build tool" + license = "MIT" + url = "https://github.com/conan-io/conan-center-index/" + homepage = "https://scons.org" + topics = ("conan", "scons", "build", "configuration", "development") + settings = "os" # Added to let the CI test this package on all os'es + + _autotools = None + + @property + def _source_subfolder(self): + return "source_subfolder" + + def configure(self): + # Detect availability of a python interpreter + # FIXME: add a python build requirement + if not tools.which("python"): + raise ConanInvalidConfiguration("This recipe requires a python interpreter.") + + def source(self): + tools.get(**self.conan_data["sources"][self.version]) + os.rename("scons-{}".format(self.version), self._source_subfolder) + + @property + def _python_executable(self): + return "python" + + def build(self): + with tools.chdir(self._source_subfolder): + output = io.StringIO() + self.run("{} setup.py --requires".format(self._python_executable), output=output) + # Workaround for log.print_run_commands = True/False + # This requires log.run_to_output = True + if not (output.getvalue().strip().splitlines() or ["-"])[-1].startswith("-"): + raise ConanException("scons has a requirement") + self.run("{} setup.py build".format(self._python_executable)) + + def package(self): + self.copy("LICENSE*", src=self._source_subfolder, dst="licenses") + + # Mislead CI and create an empty header in the include directory + include_dir = os.path.join(self.package_folder, "include") + os.mkdir(include_dir) + tools.save(os.path.join(include_dir, "__nop.h"), "") + + with tools.chdir(self._source_subfolder): + self.run("{} setup.py install --no-compile --prefix={}".format(self._python_executable, self.package_folder)) + + tools.rmdir(os.path.join(self.package_folder, "man")) + + if tools.os_info.is_windows: + # On Windows, scons installs the scripts in the folders `Scripts" and `Lib". + # Move these to the directories "bin" and "lib". + shutil.move(os.path.join(self.package_folder, "Scripts"), + os.path.join(self.package_folder, "bin")) + # Windows has case-insensitive paths, so do Lib -> lib2 -> lib + shutil.move(os.path.join(self.package_folder, "Lib"), + os.path.join(self.package_folder, "lib2")) + shutil.move(os.path.join(self.package_folder, "lib2"), + os.path.join(self.package_folder, "lib")) + + # Check for compiled python sources + for root, _, files in os.walk(self.package_folder): + for file in files: + for ext in (".pyc", ".pyo", "pyd"): + if ext in file: + fullpath = os.path.join(root, file) + os.unlink(fullpath) + self.output.warn("Found compiled python code: {}".format(fullpath)) + if file.endswith(".egg-info"): + os.unlink(os.path.join(root, file)) + + def package_info(self): + self.cpp_info.includedirs = [] + self.cpp_info.libdirs = [] + + bindir = os.path.join(self.package_folder, "bin") + self.output.info("Appending PATH environment var: {}".format(bindir)) + self.env_info.PATH.append(bindir) + + scons_pythonpath = os.path.join(self.package_folder, "lib", "site-packages", "scons") + self.output.info("Appending PYTHONPATH environment var: {}".format(scons_pythonpath)) + self.env_info.PYTHONPATH.append(os.path.join(self.package_folder, "lib", "site-packages", "scons")) diff --git a/recipes/scons/all/test_package/SConscript b/recipes/scons/all/test_package/SConscript new file mode 100644 index 0000000000000..4292c616da88f --- /dev/null +++ b/recipes/scons/all/test_package/SConscript @@ -0,0 +1,17 @@ +# SConstruct +import os + +env = Environment() + +conan = SConscript("SConscript_conan") +if not conan: + print("File `SConscript_conan` is missing.") + print("It should be generated by running `conan install`.") + sys.exit(1) + +flags = conan["conan"] +env.MergeFlags(flags) + +print("CC is: {}".format(env.subst('$CC'))) + +test_package = env.Program(["test_package.c"]) diff --git a/recipes/scons/all/test_package/SConstruct b/recipes/scons/all/test_package/SConstruct new file mode 100644 index 0000000000000..a01f66f16099c --- /dev/null +++ b/recipes/scons/all/test_package/SConstruct @@ -0,0 +1,6 @@ +import os +SConsignFile(os.path.join(GetLaunchDir(), "db")) + +SConscript('SConscript', + variant_dir=GetLaunchDir(), + duplicate=False) diff --git a/recipes/scons/all/test_package/conanfile.py b/recipes/scons/all/test_package/conanfile.py new file mode 100644 index 0000000000000..1bb7768af5410 --- /dev/null +++ b/recipes/scons/all/test_package/conanfile.py @@ -0,0 +1,36 @@ +from conans import ConanFile, tools +from conans.errors import ConanException +from io import StringIO +import os + + +class TestPackageConan(ConanFile): + settings = "os", "compiler", "build_type", "arch" + generators = "scons" + + def build(self): + + scons_path = tools.which("scons") + if not scons_path: + raise ConanException("scons could not be found") + if not scons_path.replace("\\", "/").startswith(self.deps_cpp_info["scons"].rootpath.replace("\\", "/")): + raise ConanException("an external scons was found") + + output = StringIO() + self.run("{} --version".format(scons_path), run_environment=True, output=output) + text = output.getvalue() + if self.deps_cpp_info["scons"].version not in text: + raise ConanException("scons --version does not return correct version") + + scons_args = [ + "-j", str(tools.cpu_count()), + "-C", self.source_folder, + "-f", os.path.join(self.source_folder, "SConstruct"), + ] + + self.run("scons {}".format(" ".join(scons_args)), run_environment=True) + + def test(self): + if not tools.cross_building(self.settings): + bin_path = os.path.join(".", "test_package") + self.run(bin_path, run_environment=True) diff --git a/recipes/scons/all/test_package/test_package.c b/recipes/scons/all/test_package/test_package.c new file mode 100644 index 0000000000000..bd1b1e2929530 --- /dev/null +++ b/recipes/scons/all/test_package/test_package.c @@ -0,0 +1,7 @@ +/* hello.c */ +#include +int main(int argc, char* argv[]) +{ + printf("Hello world\n"); + return 0; +} diff --git a/recipes/scons/config.yml b/recipes/scons/config.yml new file mode 100644 index 0000000000000..e0f78f1927335 --- /dev/null +++ b/recipes/scons/config.yml @@ -0,0 +1,3 @@ +versions: + "3.1.2": + folder: all