def build_setup_py(dirname):
    # we want to really build the package by running setup.py
    # so any code generation would take place (for example, Cython to C code)
    # we specify the curent directory as the build-temp directory so all the generated sources
    # will be in the same directory as the other python code
    with chdir_context(dirname):
        env = environ.copy()
        env.update(PYTHONPATH=path.abspath(path.curdir))
        cmd = (
            [PYTHON_EXECUTABLE, PYTHON_SCRIPT, "setup.py", "build", "--build-temp=."]
            if name != "nt"
            else [PYTHON_SCRIPT, "setup.py", "build", "--build-temp=."]
        )
        logger.info(" ".join(cmd))
        pid = execute_assert_success(cmd, env=env)
        logger.debug(pid.get_stdout() + pid.get_stderr())
def build_dependency(filepath):
    """:returns: base directory"""
    build_dir = path.abspath(path.join("build", "dependencies"))
    ensure_directory(path.join(build_dir, "x"))
    with chdir_context(build_dir):
        basename = path.basename(filepath)
        logger.info("building {}".format(basename))
        if basename.endswith("egg"):
            # we assume that all the egg sources are pure-python and don't contain binaries
            # people obviosuly don't upload binary eggs for POSIX systems to PyPI
            # but on Windows they do, and therefore we already downloaded their source districutions
            # in a previous step in the build process of the recipe
            return path.join(build_dir, _unzip_egg(filepath))
        elif basename.endswith("zip"):
            return path.join(build_dir, _extract_and_build_zip(filepath))
        elif basename.endswith("gz"):
            return path.join(build_dir, _extract_and_build_tgz(filepath))
        else:
            raise RuntimeError()
def scan_for_files_with_setup_py(build_dir, cleanup=False):
    from . import setup

    python_files, c_extensions = [], []
    with chdir_context(build_dir):
        setup_py_mock = "_embed_recipe.py"
        setup_py_mock_json = "_embed_recipe.json"
        if not path.exists(setup_py_mock_json):
            with open(setup_py_mock, "w") as fd:
                fd.write(SETUP_PY_MOCK)
            env = environ.copy()
            env.update(PYTHONPATH=path.abspath(path.curdir))
            cmd = [PYTHON_EXECUTABLE, PYTHON_SCRIPT, setup_py_mock] if name != "nt" else [PYTHON_SCRIPT, setup_py_mock]
            logger.info(" ".join(cmd))
            pid = execute_assert_success(cmd, env=env)
            logger.debug(pid.get_stdout() + pid.get_stderr())
        with open(setup_py_mock_json) as fd:
            files = loads(fd.read())
        if cleanup:
            remove(setup_py_mock)
            remove(setup_py_mock_json)
        return files
Ejemplo n.º 4
0
    def build_console_script(self, executable, module_name, callable_name, python_source_path):
        def generate_executable_c_code():
            source_filename = '{}.c'.format(executable)
            with open(source_filename, 'wb') as fd:
                fd.write(MAIN.format(executable, module_name, callable_name))
            return source_filename

        def generate_buildsystem_for_the_executable(source_filename):
            # we need to use the same build environment we used to build the embedded python interpreter
            # and add some stuff on top of it
            from .environment import write_pystick_variable_file, get_sorted_static_libraries, get_scons_variables
            from .environment import is_64bit
            from pprint import pformat
            from jinja2 import Template

            variables = get_scons_variables(self.static_libdir, self.options)

            variables['!LIBPATH' if '!LIBPATH' in variables else 'LIBPATH'].insert(0, self.embedded_python_build_dir)
            variables['!LIBS' if '!LIBS' in variables else 'LIBS'].insert(0, 'fpython27')
            # always generate pdb
            variables['!PDB'] = source_filename.replace('.c', '.pdb')
            # our generated C code for main uses headers from the Python source code
            variables.setdefault('CPPPATH', []).append([self.embedded_python_build_dir])
            variables.setdefault('CPPPATH', []).append([path.join(python_source_path, 'Include')])
            variables.setdefault('CPPDEFINES', []).append(["Py_BUILD_CORE"])

            with open('SConstruct', 'w') as fd:
                fd.write(Template(SCONSTRUCT).render(repr=repr, sorted=sorted, environment_variables=variables, source=source_filename))

        def compile_code_and_link_with_static_library():
            run_in_another_process(scons, None)

        def _copy_executable_file_from_build_to_dist(extension):
            basename = executable + extension
            src = path.join(build_dir, basename)
            dst = path.join('dist', basename)
            ensure_directory(dst)
            copy(src, dst)
            return dst

        def copy_executable_to_dist():
            extension = dict(Windows='.exe').get(system(), '')
            return _copy_executable_file_from_build_to_dist(extension)

        def copy_pdb_to_dist():
            extension = dict(Windows='.pdb').get(system(), '')
            return _copy_executable_file_from_build_to_dist(extension)

        build_dir = path.join('build', 'executables', executable)
        ensure_directory(path.join(build_dir, executable))
        with chdir_context(build_dir):
            source_filename = generate_executable_c_code()
            generate_buildsystem_for_the_executable(source_filename)
            compile_code_and_link_with_static_library()
            run_in_another_process(scons, None)
        files = [copy_executable_to_dist()]
        if os_name == 'nt':
            files.append(copy_pdb_to_dist())
        if self.should_sign_files():
            self.signtool.sign_executables_in_directory('dist')
        return files