| echo Loading VS environment | echo Loading VS environment | ||||
| call "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Enterprise\\Common7\\Tools\\vsdevcmd" -arch=x64 || exit 1 | call "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Enterprise\\Common7\\Tools\\vsdevcmd" -arch=x64 || exit 1 | ||||
| echo Executing build/test script | echo Executing build/test script | ||||
| python -u build.py --cxx cl.exe --test --static || exit 1 | |||||
| python -u tools/build.py --cxx cl.exe --test --static || exit 1 | |||||
| displayName: Build and Run Unit Tests | displayName: Build and Run Unit Tests | ||||
| - publish: _build/ddslim.exe | - publish: _build/ddslim.exe | ||||
| artifact: DDSLiM Executable - Windows | artifact: DDSLiM Executable - Windows | ||||
| - script: | | - script: | | ||||
| echo Loading VS environment | echo Loading VS environment | ||||
| call "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Enterprise\\Common7\\Tools\\vsdevcmd" -arch=x64 || exit 1 | call "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Enterprise\\Common7\\Tools\\vsdevcmd" -arch=x64 || exit 1 | ||||
| python -u test.py --exe _build/ddslim -T:msvc || exit 1 | |||||
| python -u tools/test.py --exe _build/ddslim -T:msvc || exit 1 | |||||
| displayName: Smoke Tests | displayName: Smoke Tests | ||||
| - job: Windows_MSVC_VS2019 | - job: Windows_MSVC_VS2019 | ||||
| echo Loading VS environment | echo Loading VS environment | ||||
| call "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Enterprise\\Common7\\Tools\\vsdevcmd" -arch=x64 || exit 1 | call "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Enterprise\\Common7\\Tools\\vsdevcmd" -arch=x64 || exit 1 | ||||
| echo Executing build/test script | echo Executing build/test script | ||||
| python -u build.py --cxx cl.exe --test --static || exit 1 | |||||
| python -u tools/build.py --cxx cl.exe --test --static || exit 1 | |||||
| displayName: Build and Run Unit Tests | displayName: Build and Run Unit Tests | ||||
| - publish: _build/ddslim.exe | - publish: _build/ddslim.exe | ||||
| artifact: DDSLiM Executable - Windows | artifact: DDSLiM Executable - Windows | ||||
| - script: | | - script: | | ||||
| echo Loading VS environment | echo Loading VS environment | ||||
| call "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Enterprise\\Common7\\Tools\\vsdevcmd" -arch=x64 || exit 1 | call "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Enterprise\\Common7\\Tools\\vsdevcmd" -arch=x64 || exit 1 | ||||
| python -u test.py --exe _build/ddslim -T:msvc || exit 1 | |||||
| python -u tools/test.py --exe _build/ddslim -T:msvc || exit 1 | |||||
| displayName: Smoke Tests | displayName: Smoke Tests | ||||
| - job: Linux_GCC | - job: Linux_GCC | ||||
| steps: | steps: | ||||
| - script: sudo apt install -y python3-minimal g++-8 | - script: sudo apt install -y python3-minimal g++-8 | ||||
| displayName: Prepare System | displayName: Prepare System | ||||
| - script: python3 -u build.py --cxx g++-8 --test --static | |||||
| - script: python3 -u tools/build.py --cxx g++-8 --test --static | |||||
| displayName: Build and Run Unit Tests | displayName: Build and Run Unit Tests | ||||
| - publish: _build/ddslim | - publish: _build/ddslim | ||||
| artifact: DDSLiM Executable - Linux | artifact: DDSLiM Executable - Linux | ||||
| - script: python3 -u test.py --exe _build/ddslim -T:gcc-8 | |||||
| - script: python3 -u tools/test.py --exe _build/ddslim -T:gcc-8 | |||||
| displayName: Smoke Tests | displayName: Smoke Tests | ||||
| - job: macOS | - job: macOS | ||||
| steps: | steps: | ||||
| - script: brew install gcc@8 | - script: brew install gcc@8 | ||||
| displayName: Prepare System | displayName: Prepare System | ||||
| - script: python3 -u build.py --cxx g++-8 --test | |||||
| - script: python3 -u tools/build.py --cxx g++-8 --test | |||||
| displayName: Build and Run Unit Tests | displayName: Build and Run Unit Tests | ||||
| - publish: _build/ddslim | - publish: _build/ddslim | ||||
| artifact: DDSLiM Executable - macOS | artifact: DDSLiM Executable - macOS | ||||
| - script: python3 -u test.py --exe _build/ddslim -T:gcc-8 | |||||
| - script: python3 -u tools/test.py --exe _build/ddslim -T:gcc-8 | |||||
| displayName: Smoke Tests | displayName: Smoke Tests |
| import time | import time | ||||
| import sys | import sys | ||||
| HERE_DIR = Path(__file__).parent.absolute() | |||||
| ROOT = Path(__file__).parent.parent.absolute() | |||||
| INCLUDE_DIRS = [ | INCLUDE_DIRS = [ | ||||
| 'external/taywee-args/include', | 'external/taywee-args/include', | ||||
| if not opts.is_msvc: | if not opts.is_msvc: | ||||
| cmd = [ | cmd = [ | ||||
| str(opts.cxx), | str(opts.cxx), | ||||
| f'-I{HERE_DIR / "src"}', | |||||
| f'-I{ROOT / "src"}', | |||||
| '-std=c++17', | '-std=c++17', | ||||
| '-Wall', | '-Wall', | ||||
| '-Wextra', | '-Wextra', | ||||
| else: | else: | ||||
| cmd.append('-O2') | cmd.append('-O2') | ||||
| cmd.extend( | cmd.extend( | ||||
| itertools.chain.from_iterable(('-isystem', str(HERE_DIR / subdir)) | |||||
| itertools.chain.from_iterable(('-isystem', str(ROOT / subdir)) | |||||
| for subdir in INCLUDE_DIRS)) | for subdir in INCLUDE_DIRS)) | ||||
| return cmd | return cmd | ||||
| else: | else: | ||||
| '/EHsc', | '/EHsc', | ||||
| '/std:c++latest', | '/std:c++latest', | ||||
| '/DFMT_HEADER_ONLY=1', | '/DFMT_HEADER_ONLY=1', | ||||
| f'/I{HERE_DIR / "src"}', | |||||
| f'/I{ROOT / "src"}', | |||||
| str(cpp_file), | str(cpp_file), | ||||
| '/c', | '/c', | ||||
| f'/Fo{obj_file}', | f'/Fo{obj_file}', | ||||
| cmd.append('/MT') | cmd.append('/MT') | ||||
| else: | else: | ||||
| cmd.append('/MD') | cmd.append('/MD') | ||||
| cmd.extend(f'/I{HERE_DIR / subdir}' for subdir in INCLUDE_DIRS) | |||||
| cmd.extend(f'/I{ROOT / subdir}' for subdir in INCLUDE_DIRS) | |||||
| return cmd | return cmd | ||||
| def _compile_src(opts: BuildOptions, cpp_file: Path) -> Tuple[Path, Path]: | def _compile_src(opts: BuildOptions, cpp_file: Path) -> Tuple[Path, Path]: | ||||
| build_dir = HERE_DIR / '_build' | |||||
| src_dir = HERE_DIR / 'src' | |||||
| build_dir = ROOT / '_build' | |||||
| src_dir = ROOT / 'src' | |||||
| relpath = cpp_file.relative_to(src_dir) | relpath = cpp_file.relative_to(src_dir) | ||||
| obj_path = build_dir / relpath.with_name(relpath.name + opts.obj_suffix) | obj_path = build_dir / relpath.with_name(relpath.name + opts.obj_suffix) | ||||
| obj_path.parent.mkdir(exist_ok=True, parents=True) | obj_path.parent.mkdir(exist_ok=True, parents=True) | ||||
| cmd = _create_compile_command(opts, cpp_file, obj_path) | cmd = _create_compile_command(opts, cpp_file, obj_path) | ||||
| msg = f'Compile C++ file: {cpp_file}' | |||||
| msg = f'Compile C++ file: {cpp_file.relative_to(ROOT)}' | |||||
| print(msg) | print(msg) | ||||
| start = time.time() | start = time.time() | ||||
| res = subprocess.run( | res = subprocess.run( | ||||
| raise RuntimeError( | raise RuntimeError( | ||||
| f'Compile command ({cmd}) failed for {cpp_file}:\n{res.stdout.decode()}' | f'Compile command ({cmd}) failed for {cpp_file}:\n{res.stdout.decode()}' | ||||
| ) | ) | ||||
| if res.stdout: | |||||
| print(res.stdout.decode()) | |||||
| stdout: str = res.stdout.decode() | |||||
| fname_head = f'{cpp_file.name}\r\n' | |||||
| if stdout.startswith(fname_head): | |||||
| stdout = stdout[len(fname_head):] | |||||
| if stdout: | |||||
| print(stdout, end='') | |||||
| end = time.time() | end = time.time() | ||||
| print(f'{msg} - Done: {end - start:.2}s') | print(f'{msg} - Done: {end - start:.2}s') | ||||
| return cpp_file, obj_path | return cpp_file, obj_path | ||||
| def _create_archive_command(opts: BuildOptions, | def _create_archive_command(opts: BuildOptions, | ||||
| objects: Iterable[Path]) -> Tuple[Path, List[str]]: | objects: Iterable[Path]) -> Tuple[Path, List[str]]: | ||||
| if opts.is_msvc: | if opts.is_msvc: | ||||
| lib_file = HERE_DIR / '_build/libddslim.lib' | |||||
| lib_file = ROOT / '_build/libddslim.lib' | |||||
| cmd = ['lib', '/nologo', f'/OUT:{lib_file}', *map(str, objects)] | cmd = ['lib', '/nologo', f'/OUT:{lib_file}', *map(str, objects)] | ||||
| return lib_file, cmd | return lib_file, cmd | ||||
| else: | else: | ||||
| lib_file = HERE_DIR / '_build/libddslim.a' | |||||
| lib_file = ROOT / '_build/libddslim.a' | |||||
| cmd = ['ar', 'rsc', str(lib_file), *map(str, objects)] | cmd = ['ar', 'rsc', str(lib_file), *map(str, objects)] | ||||
| return lib_file, cmd | return lib_file, cmd | ||||
| out: Path = None) -> Path: | out: Path = None) -> Path: | ||||
| if out is None: | if out is None: | ||||
| basename = obj.stem | basename = obj.stem | ||||
| out = HERE_DIR / '_build/test' / (basename + '.exe') | |||||
| out = ROOT / '_build/test' / (basename + '.exe') | |||||
| out.parent.mkdir(exist_ok=True, parents=True) | out.parent.mkdir(exist_ok=True, parents=True) | ||||
| print(f'Linking executable {out}') | print(f'Linking executable {out}') | ||||
| '--static', action='store_true', help='Build a static executable') | '--static', action='store_true', help='Build a static executable') | ||||
| args = parser.parse_args(argv) | args = parser.parse_args(argv) | ||||
| all_sources = set(HERE_DIR.glob('src/**/*.cpp')) | |||||
| test_sources = set(HERE_DIR.glob('src/**/*.test.cpp')) | |||||
| main_sources = set(HERE_DIR.glob('src/**/*.main.cpp')) | |||||
| all_sources = set(ROOT.glob('src/**/*.cpp')) | |||||
| test_sources = set(ROOT.glob('src/**/*.test.cpp')) | |||||
| main_sources = set(ROOT.glob('src/**/*.main.cpp')) | |||||
| lib_sources = (all_sources - test_sources) - main_sources | lib_sources = (all_sources - test_sources) - main_sources | ||||
| build_opts, | build_opts, | ||||
| objects[next(iter(main_sources))], | objects[next(iter(main_sources))], | ||||
| lib, | lib, | ||||
| out=HERE_DIR / '_build/ddslim') | |||||
| out=ROOT / '_build/ddslim') | |||||
| if args.test: | if args.test: | ||||
| list(pool.map(run_test, test_exes)) | list(pool.map(run_test, test_exes)) |
| import sys | import sys | ||||
| ROOT = Path(__file__).parent.parent.absolute() | |||||
| class TestOptions(NamedTuple): | class TestOptions(NamedTuple): | ||||
| exe: Path | exe: Path | ||||
| toolchain: str | toolchain: str | ||||
| def run_test_dir(dir: Path, opts: TestOptions) -> bool: | def run_test_dir(dir: Path, opts: TestOptions) -> bool: | ||||
| print(f'Running test: {dir.name} ', end='') | |||||
| print(f'Running test: {dir.stem} ', end='') | |||||
| out_dir = dir / '_build' | out_dir = dir / '_build' | ||||
| if out_dir.exists(): | if out_dir.exists(): | ||||
| shutil.rmtree(out_dir) | shutil.rmtree(out_dir) | ||||
| def run_tests(opts: TestOptions) -> int: | def run_tests(opts: TestOptions) -> int: | ||||
| print('Sanity check...') | print('Sanity check...') | ||||
| subprocess.check_output([str(opts.exe), '--help']) | subprocess.check_output([str(opts.exe), '--help']) | ||||
| tests_subdir = Path(__file__).parent.absolute() / 'tests' | |||||
| tests_subdir = ROOT / 'tests' | |||||
| test_dirs = tests_subdir.glob('*.test') | test_dirs = tests_subdir.glob('*.test') | ||||
| ret = 0 | ret = 0 |