Example #1
0
def cmake_configure(source_path='.'):
    import shlex

    from skbuild.cmaker import CMaker
    from skbuild.constants import CMAKE_BUILD_DIR

    cmaker = CMaker()
    cmake_args = shlex.split(os.getenv('CI_SETUP_CMAKE_ARGS', ''))
    cmaker.configure(cmake_args)
    return CMAKE_BUILD_DIR()
Example #2
0
def test_check_for_bad_installs(tmpdir):
    with push_dir(str(tmpdir)):
        tmpdir.ensure(CMAKE_BUILD_DIR(), "cmake_install.cmake").write(textwrap.dedent(
            """
            file(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/../hello" TYPE FILE FILES "/path/to/hello/world.py")
            """
        ))
        with pytest.raises(SKBuildError) as excinfo:
            CMaker.check_for_bad_installs()
        assert "CMake-installed files must be within the project root" in str(excinfo.value)
Example #3
0
    def build_extension(self, ext):
        extdir = os.path.abspath(
            os.path.dirname(self.get_ext_fullpath(ext.name)))

        cfg = 'Production'
        build_args = ['--config', cfg]

        cpu_count = max(2, multiprocessing.cpu_count() // 2)
        build_args += ['--', '-j{0}'.format(cpu_count)]

        project_src_path = get_project_src_path()
        build_dir = os.path.join(project_src_path, WORKING_DIR)

        # configure with the working directory python-build-wheel
        args = [
            '--python-bindings', '--auto-download', '--lib-only',
            '--name=' + WORKING_DIR
        ]
        # find correct Python include directory and library
        # works even for nonstandard Python installations
        # (e.g., on pypa/manylinux)
        args.append('-DPYTHON_VERSION_STRING:STRING=' + \
                    sys.version.split(' ')[0])
        python_version = CMaker.get_python_version()
        args.append('-DPYTHON_INCLUDE_DIR:PATH=' + \
                    CMaker.get_python_include_dir(python_version))
        args.append('-DPYTHON_LIBRARY:FILEPATH=' + \
                    CMaker.get_python_library(python_version))

        config_filename = os.path.join(project_src_path, "configure.sh")
        subprocess.check_call([config_filename] + args)

        # build the main library
        subprocess.check_call(['cmake', '--build', '.', "--target", "cvc5"] +
                              build_args,
                              cwd=build_dir)

        # build the python binding
        python_build_dir = os.path.join(build_dir, "src", "api", "python")
        subprocess.check_call(["make"], cwd=python_build_dir)
        # the build folder gets cleaned during the config, need to create it again
        # this is necessary since "build" is a python dist folder
        if not os.path.isdir(extdir):
            os.mkdir(extdir)

        # copy the library over. we need to consider other users that are not on linux
        # module is a directory called pycvc5
        pycvc5_module = os.path.join(python_build_dir, "pycvc5")
        dst_name = os.path.join(extdir, "pycvc5")
        if os.path.isdir(dst_name):
            # remove, then replace
            shutil.rmtree(dst_name)

        shutil.copytree(pycvc5_module, dst_name)
def test_make_without_configure_fails(capfd):
    src_dir = _tmpdir('test_make_without_configure_fails')
    src_dir.ensure(CMAKE_BUILD_DIR, dir=1)
    with push_dir(str(src_dir)), pytest.raises(SKBuildError) as excinfo:
        CMaker().make()
    _, err = capfd.readouterr()
    assert "An error occurred while building with CMake." in str(excinfo.value)
    assert "Error: could not load cache" in err
def test_make(configure_with_cmake_source_dir, capfd):
    tmp_dir = _tmpdir('test_make')
    with push_dir(str(tmp_dir)):

        src_dir = tmp_dir.ensure('SRC', dir=1)
        src_dir.join('CMakeLists.txt').write(textwrap.dedent(
            """
            cmake_minimum_required(VERSION 3.5.0)
            project(foobar NONE)
            file(WRITE "${CMAKE_BINARY_DIR}/foo.txt" "# foo")
            install(FILES "${CMAKE_BINARY_DIR}/foo.txt" DESTINATION ".")
            install(CODE "message(STATUS \\"Project has been installed\\")")
            message(STATUS "CMAKE_SOURCE_DIR:${CMAKE_SOURCE_DIR}")
            message(STATUS "CMAKE_BINARY_DIR:${CMAKE_BINARY_DIR}")
            """
        ))
        src_dir.ensure(CMAKE_BUILD_DIR, dir=1)

        with push_dir(str(src_dir)
                      if not configure_with_cmake_source_dir
                      else str(tmp_dir.ensure('BUILD', dir=1))):
            cmkr = CMaker()
            config_kwargs = {}
            if configure_with_cmake_source_dir:
                config_kwargs['cmake_source_dir'] = str(src_dir)
            env = cmkr.configure(**config_kwargs)
            cmkr.make(env=env)

        messages = ["Project has been installed"]

        if configure_with_cmake_source_dir:
            messages += [
                "/SRC",
                "/BUILD/{}".format(to_unix_path(CMAKE_BUILD_DIR)),
                "/BUILD/{}/./foo.txt".format(to_unix_path(CMAKE_INSTALL_DIR))
            ]
        else:
            messages += [
                "/SRC",
                "/SRC/{}".format(to_unix_path(CMAKE_BUILD_DIR)),
                "/SRC/{}/./foo.txt".format(to_unix_path(CMAKE_INSTALL_DIR)),
            ]

        out, _ = capfd.readouterr()
        for message in messages:
            assert message in out
Example #6
0
def test_make(configure_with_cmake_source_dir, capfd):
    tmp_dir = _tmpdir('test_make')
    with push_dir(str(tmp_dir)):

        src_dir = tmp_dir.ensure('SRC', dir=1)
        src_dir.join('CMakeLists.txt').write(textwrap.dedent(
            """
            cmake_minimum_required(VERSION 3.5.0)
            project(foobar NONE)
            file(WRITE "${CMAKE_BINARY_DIR}/foo.txt" "# foo")
            install(FILES "${CMAKE_BINARY_DIR}/foo.txt" DESTINATION ".")
            install(CODE "message(STATUS \\"Project has been installed\\")")
            message(STATUS "CMAKE_SOURCE_DIR:${CMAKE_SOURCE_DIR}")
            message(STATUS "CMAKE_BINARY_DIR:${CMAKE_BINARY_DIR}")
            """
        ))
        src_dir.ensure(CMAKE_BUILD_DIR, dir=1)

        with push_dir(str(src_dir)
                      if not configure_with_cmake_source_dir
                      else str(tmp_dir.ensure('BUILD', dir=1))):
            cmkr = CMaker()
            config_kwargs = {}
            if configure_with_cmake_source_dir:
                config_kwargs['cmake_source_dir'] = str(src_dir)
            env = cmkr.configure(**config_kwargs)
            cmkr.make(env=env)

        messages = ["Project has been installed"]

        if configure_with_cmake_source_dir:
            messages += [
                "/SRC",
                "/BUILD/{}".format(to_unix_path(CMAKE_BUILD_DIR)),
                "/BUILD/{}/./foo.txt".format(to_unix_path(CMAKE_INSTALL_DIR))
            ]
        else:
            messages += [
                "/SRC",
                "/SRC/{}".format(to_unix_path(CMAKE_BUILD_DIR)),
                "/SRC/{}/./foo.txt".format(to_unix_path(CMAKE_INSTALL_DIR)),
            ]

        out, _ = capfd.readouterr()
        for message in messages:
            assert message in out
def test_configure_with_cmake_args(capfd):
    tmp_dir = _tmpdir('test_configure_with_cmake_args')
    with push_dir(str(tmp_dir)):

        tmp_dir.join('CMakeLists.txt').write(textwrap.dedent(
            """
            cmake_minimum_required(VERSION 3.5.0)
            project(foobar NONE)
            # Do not complain about missing arguments passed to the main
            # project
            foreach(unused_var IN ITEMS
              ${CMAKE_EXPECTED_BAR}
              ${CMAKE_EXPECTED_FOO}
              ${PYTHON_EXECUTABLE}
              ${PYTHON_INCLUDE_DIR}
              ${PYTHON_LIBRARY}
              ${PYTHON_VERSION_STRING}
              ${SKBUILD}
              )
            endforeach()
            """
        ))

        with push_dir(str(tmp_dir)):
            cmkr = CMaker()
            cmkr.configure(clargs=[
                '-DCMAKE_EXPECTED_FOO:STRING=foo',
                '-DCMAKE_EXPECTED_BAR:STRING=bar'
            ], cleanup=False)

        cmakecache = tmp_dir.join(
            "_cmake_test_compile", "build", "CMakeCache.txt")
        assert cmakecache.exists()
        variables = get_cmakecache_variables(str(cmakecache))
        assert variables.get('CMAKE_EXPECTED_FOO', (None, None))[1] == "foo"
        assert variables.get('CMAKE_EXPECTED_BAR', (None, None))[1] == "bar"

        unexpected = "Manually-specified variables were not used by the project"
        _, err = capfd.readouterr()
        assert unexpected not in err
Example #8
0
def test_configure_with_cmake_args(capfd):
    tmp_dir = _tmpdir('test_configure_with_cmake_args')
    with push_dir(str(tmp_dir)):

        tmp_dir.join('CMakeLists.txt').write(textwrap.dedent(
            """
            cmake_minimum_required(VERSION 3.5.0)
            project(foobar NONE)
            # Do not complain about missing arguments passed to the main
            # project
            foreach(unused_var IN ITEMS
              ${CMAKE_EXPECTED_BAR}
              ${CMAKE_EXPECTED_FOO}
              ${PYTHON_EXECUTABLE}
              ${PYTHON_INCLUDE_DIR}
              ${PYTHON_LIBRARY}
              ${PYTHON_VERSION_STRING}
              ${SKBUILD}
              )
            endforeach()
            """
        ))

        with push_dir(str(tmp_dir)):
            cmkr = CMaker()
            cmkr.configure(clargs=[
                '-DCMAKE_EXPECTED_FOO:STRING=foo',
                '-DCMAKE_EXPECTED_BAR:STRING=bar'
            ], cleanup=False)

        cmakecache = tmp_dir.join(
            "_cmake_test_compile", "build", "CMakeCache.txt")
        assert cmakecache.exists()
        variables = get_cmakecache_variables(str(cmakecache))
        assert variables.get('CMAKE_EXPECTED_FOO', (None, None))[1] == "foo"
        assert variables.get('CMAKE_EXPECTED_BAR', (None, None))[1] == "bar"

        unexpected = "Manually-specified variables were not used by the project"
        _, err = capfd.readouterr()
        assert unexpected not in err
def test_make_without_build_dir_fails():
    src_dir = _tmpdir('test_make_without_build_dir_fails')
    with push_dir(str(src_dir)), pytest.raises(SKBuildError) as excinfo:
        CMaker().make()
    assert "Did you forget to run configure before make" in str(excinfo.value)
def test_get_python_library():
    python_library = CMaker.get_python_library(CMaker.get_python_version())
    assert python_library
    assert os.path.exists(python_library)
def test_get_python_version():
    assert re.match(r'^[23](\.?)[0-9]$', CMaker.get_python_version())
Example #12
0
def test_cmake_executable():
    assert CMaker().cmake_executable == CMAKE_DEFAULT_EXECUTABLE
Example #13
0
def test_get_python_include_dir():
    python_include_dir = CMaker.get_python_include_dir(CMaker.get_python_version())
    assert python_include_dir
    assert os.path.exists(python_include_dir)
Example #14
0
def test_cmake_executable():
    assert CMaker().cmake_executable == "cmake"
Example #15
0
    def build_extension(self, ext):
        extdir = os.path.abspath(
            os.path.dirname(self.get_ext_fullpath(ext.name)))
        if not os.path.isdir(extdir):
            os.mkdir(extdir)

        cfg = 'Release'
        build_args = ['--config', cfg]

        cpu_count = max(2, multiprocessing.cpu_count() // 2)
        build_args += ['--', '-j{0}'.format(cpu_count)]

        # call configure
        # default install everything?
        solvers = ["bitwuzla", "cvc5", "z3"]  # , "msat"]
        solver_path = {
            "btor": "boolector",
            "bitwuzla": "bitwuzla",
            "cvc5": "cvc5",
            "msat": "mathsat",
            "z3": "z3"
        }
        root_path = os.path.dirname(
            os.path.dirname(os.path.abspath(os.path.dirname(__file__))))
        build_dir = os.path.join(root_path, "build")

        for solver in solvers:
            solver_dir = os.path.join(root_path, "deps", solver_path[solver])
            if os.path.isdir(solver_dir):
                continue
            filename = os.path.join(root_path, "contrib",
                                    "setup-" + solver + ".sh")
            opts = ["--auto-yes"] if solver == "msat" else []
            subprocess.check_call([filename] + opts)

        # to avoid multiple build, only call reconfigure if we couldn't find the makefile
        # for python
        python_make_dir = os.path.join(build_dir, "python")
        if not os.path.isfile(os.path.join(python_make_dir, "Makefile")):
            args = ["--" + solver for solver in solvers] + ["--python"]
            args.append('-DPYTHON_VERSION_STRING:STRING=' + \
                        sys.version.split(' ')[0])
            python_version = CMaker.get_python_version()
            args.append('-DPYTHON_INCLUDE_DIR:PATH=' + \
                        CMaker.get_python_include_dir(python_version))
            args.append('-DPYTHON_LIBRARY:FILEPATH=' + \
                        CMaker.get_python_library(python_version))
            config_filename = os.path.join(root_path, "configure.sh")
            subprocess.check_call([config_filename] + args)

        # build the main library
        subprocess.check_call(
            ['cmake', '--build', '.', "--target", "smt-switch"] + build_args,
            cwd=build_dir)
        # build the python binding
        python_build_dir = os.path.join(os.path.join(build_dir, "python"),
                                        "smt_switch")
        subprocess.check_call(["make"], cwd=python_build_dir)
        # the build folder gets cleaned during the config, need to create it again
        # this is necessary since "build" is a python dist folder
        if not os.path.isdir(extdir):
            os.mkdir(extdir)
        # copy the library over. we need to consider other users that's not on linux
        lib_files = filter(
            lambda s: os.path.splitext(s)[1] != '.cxx',
            glob.glob(os.path.join(python_build_dir, "smt_switch.*")))
        assert lib_files, 'Expecting library files but found none'
        for lib_filename in lib_files:
            print(f'Copying library: {lib_filename}')
            if os.path.splitext(lib_filename)[1] == ".cxx":
                continue
            dst_filename = os.path.join(extdir, os.path.basename(lib_filename))
            shutil.copy(lib_filename, dst_filename)
Example #16
0
# Top contributors (to current version):
#   Gereon Kremer
#
# This file is part of the cvc5 project.
#
# Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
# in the top-level source directory and their institutional affiliations.
# All rights reserved.  See the file COPYING in the top-level source
# directory for licensing information.
# ############################################################################
#
# Run configure.sh and make cmake pick up whatever python interpreter this
# script is run with. Additionally, all arguments passed to this script are
# forwarded as well.
##

import subprocess
import sys

from skbuild.cmaker import CMaker

python_version = CMaker.get_python_version()
args = [
    '-DPYTHON_VERSION_STRING:STRING=' + sys.version.split(' ')[0],
    '-DPYTHON_INCLUDE_DIR:PATH=' +
    CMaker.get_python_include_dir(python_version),
    '-DPYTHON_LIBRARY:FILEPATH=' + CMaker.get_python_library(python_version),
]

subprocess.check_call(['./configure.sh', *sys.argv[1:], *args])
Example #17
0
def test_get_python_library():
    python_library = CMaker.get_python_library(CMaker.get_python_version())
    assert python_library
    assert os.path.exists(python_library)
Example #18
0
def test_get_python_version():
    assert re.match(r'^[23](\.?)[0-9]$', CMaker.get_python_version())