def build_wheel(): whls = glob.glob('dist/*.whl') assert len(whls) == 1 check_wheel_content(whls[0], expected_distribution_name, expected_content) os.remove(whls[0]) assert not os.path.exists(whls[0]) assert os.path.exists(os.path.join(CMAKE_BUILD_DIR(), "CMakeCache.txt")) os.remove(os.path.join(CMAKE_BUILD_DIR(), "CMakeCache.txt"))
def fake_configure(*args, **kwargs): # Simulate a successful configuration creating a CMakeCache.txt tmp_dir.ensure(CMAKE_BUILD_DIR(), dir=1).join('CMakeCache.txt').write( textwrap.dedent(""" //Name of generator. CMAKE_GENERATOR:INTERNAL=Ninja """))
def test_toolset(): py_35 = sys.version_info[:2] == (3, 5) has_vs_2017 = find_visual_studio(vs_version=VS_YEAR_TO_VERSION["2017"]) if not has_vs_2017: pytest.skip("Visual Studio 15 2017 is not found") arch = platform.architecture()[0] vs_generator = "Visual Studio 15 2017" orig_generator = vs_generator if arch == "64bit": vs_generator += " Win64" @project_setup_py_test("hello-cpp", ["build", "-G", vs_generator]) def run_build(): pass tmp_dir = run_build()[0] cmakecache = tmp_dir.join(CMAKE_BUILD_DIR()).join("CMakeCache.txt") variables = get_cmakecache_variables(str(cmakecache)) generator = variables['CMAKE_GENERATOR'][1] assert generator == orig_generator var_toolset = variables['CMAKE_GENERATOR_TOOLSET'] toolset = var_toolset[1] if py_35: assert toolset == "v140" else: assert toolset == "v141"
def test_generator(generator, expected_make_program): generator_platform = { "NMake Makefiles": ["windows"], "Unix Makefiles": ["darwin", "linux"] } assert generator in generator_platform this_platform = platform.system().lower() if this_platform not in generator_platform[generator]: pytest.skip("{} generator is available only on {}".format( generator, this_platform.title())) @project_setup_py_test("hello-cpp", ["build"]) def run_build(): pass with push_env(CMAKE_GENERATOR=generator): tmp_dir = run_build()[0] cmakecache = tmp_dir.join(CMAKE_BUILD_DIR()).join("CMakeCache.txt") assert cmakecache.exists() variables = get_cmakecache_variables(str(cmakecache)) make_program = (variables["CMAKE_MAKE_PROGRAM"][1] if "CMAKE_MAKE_PROGRAM" in variables else "") assert make_program.endswith(expected_make_program) or \ make_program.endswith("%s.exe" % expected_make_program)
def test_toolset(): version = sys.version_info py_35 = (version.major == 3 and version.minor == 5) py_36_and_above = (version.major == 3 and version.minor >= 6) if not any([py_35, py_36_and_above]): pytest.skip("python version < 3.5") has_vs_2017 = find_visual_studio(vs_version=VS_YEAR_TO_VERSION["2017"]) if not has_vs_2017: pytest.skip("Visual Studio 15 2017 is not found") arch = platform.architecture()[0] vs_generator = "Visual Studio 15 2017" vs_generator += (" Win64" if arch == "64bit" else "") @project_setup_py_test("hello-cpp", ["build", "-G", vs_generator]) def run_build(): pass tmp_dir = run_build()[0] cmakecache = tmp_dir.join(CMAKE_BUILD_DIR()).join("CMakeCache.txt") variables = get_cmakecache_variables(str(cmakecache)) generator = variables['CMAKE_GENERATOR'][1] assert generator == vs_generator toolset = variables['CMAKE_GENERATOR_TOOLSET'][1] if py_35: assert toolset == "v140" elif py_36_and_above: assert toolset == "v141"
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_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_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)
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()
def test_cmake_initial_cache_as_global_option(tmpdir): project = "hello-no-language" prepare_project(project, tmpdir) initialize_git_repo_and_commit(tmpdir, verbose=True) initial_cache = tmpdir.join("initial-cache.txt") initial_cache.write( """set(MY_CMAKE_VARIABLE "1" CACHE BOOL "My cache variable")""") try: with execute_setup_py(tmpdir, ["-C%s" % str(initial_cache), "build"], disable_languages_test=True): pass except SystemExit as exc: assert exc.code == 0 cmakecache_txt = tmpdir.join(CMAKE_BUILD_DIR(), "CMakeCache.txt") assert cmakecache_txt.exists() assert get_cmakecache_variables(str(cmakecache_txt)).get( 'MY_CMAKE_VARIABLE', (None, None)) == ('BOOL', '1')
def test_hello_cleans(capfd): with push_dir(): tmp_dir = _tmpdir("test_hello_cleans") _copy_dir(tmp_dir, os.path.join(SAMPLES_DIR, "hello-cpp")) @project_setup_py_test("hello-cpp", ["build"], tmp_dir=tmp_dir) def run_build(): pass @project_setup_py_test("hello-cpp", ["clean"], tmp_dir=tmp_dir) def run_clean(): pass # Check that a project can be cleaned twice in a row run_build() print("<<-->>") run_clean() print("<<-->>") run_clean() _, clean1_out, clean2_out = \ capfd.readouterr()[0].split('<<-->>') clean1_out = clean1_out.strip() clean2_out = clean2_out.strip() assert "running clean" == clean1_out.splitlines()[0] assert "removing '{}'".format( CMAKE_INSTALL_DIR()) == clean1_out.splitlines()[1] assert "removing '{}'".format( CMAKE_BUILD_DIR()) == clean1_out.splitlines()[2] assert "removing '{}'".format(SKBUILD_DIR()) == clean1_out.splitlines()[3] assert "running clean" == clean2_out
class CleanUp(set_build_base_mixin, new_style(_clean)): """Custom implementation of ``clean`` setuptools command. Overriding clean in order to get rid if "dist" folder and etc """ skroot = dirname(SKBUILD_DIR()) CLEANFOLDERS = ( CMAKE_INSTALL_DIR(), CMAKE_BUILD_DIR(), SKBUILD_DIR(), skroot, "TMP", "__pycache__", "pip-wheel-metadata", ".eggs", "dist", "sdist", "wheel", ".pytest_cache", "docs/apiref", "docs/_build", "docs/_static", "docs/_templates", "htmlcov", ) CLEANFOLDERSRECURSIVE = ["__pycache__", "_tmp_*", "xtgeo.egg-info"] CLEANFILESRECURSIVE = ["*.pyc", "*.pyo", ".coverage", "coverage.xml"] CLEANFILES = glob("src/xtgeo/cxtgeo/cxtgeo*") CLEANFILES.extend(glob("src/xtgeo/cxtgeo/_cxtgeo*")) @staticmethod def ffind(pattern, path): result = [] for root, dirs, files in os.walk(path): for name in files: if fnmatch.fnmatch(name, pattern): result.append(os.path.join(root, name)) return result @staticmethod def dfind(pattern, path): result = [] for root, dirs, files in os.walk(path): for name in dirs: if fnmatch.fnmatch(name, pattern): result.append(os.path.join(root, name)) return result def run(self): """After calling the super class implementation, this function removes the directories specific to scikit-build ++.""" super(CleanUp, self).run() for dir_ in CleanUp.CLEANFOLDERS: if exists(dir_): print("Removing: {}".format(dir_)) if not self.dry_run and exists(dir_): rmtree(dir_) for dir_ in CleanUp.CLEANFOLDERSRECURSIVE: for pd in self.dfind(dir_, "."): print("Remove folder {}".format(pd)) rmtree(pd) for fil_ in CleanUp.CLEANFILESRECURSIVE: for pf in self.ffind(fil_, "."): print("Remove file {}".format(pf)) os.unlink(pf) for fil_ in CleanUp.CLEANFILES: if exists(fil_): print("Removing: {}".format(fil_)) if not self.dry_run and exists(fil_): os.remove(fil_)