Skip to content

Commit 9d7bd8b

Browse files
authored
Merge pull request #60 from SYMSCAE/merge-windows
Merge windows branch into skpkg-migration
2 parents 6140608 + 345f7a9 commit 9d7bd8b

160 files changed

Lines changed: 14245 additions & 16887 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.clang-format‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
BasedOnStyle: Google
2+
3+
IndentWidth: 2
4+
ContinuationIndentWidth: 2
5+
TabWidth: 2
6+
UseTab: Never
7+
8+
ColumnLimit: 80
9+
10+
SortIncludes: false
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
"""Configure SCons and CxxTest for the CI matrix."""
2+
3+
import json
4+
from pathlib import Path
5+
6+
requirements = ["python"]
7+
for filename in ("build.txt", "conda.txt", "tests.txt"):
8+
for line in (Path("requirements") / filename).read_text().splitlines():
9+
spec = line.split("#", 1)[0].strip()
10+
if spec and spec != "cxxtest":
11+
requirements.append(spec)
12+
13+
Path("build").mkdir(exist_ok=True)
14+
Path("build/matrix-environment.yml").write_text(
15+
json.dumps(
16+
{
17+
"name": "test",
18+
"channels": ["conda-forge"],
19+
"dependencies": requirements,
20+
},
21+
indent=2,
22+
)
23+
+ "\n"
24+
)
25+
26+
Path("sconscript.local").write_text("""\
27+
Import('env')
28+
import os
29+
import sys
30+
31+
prefix = os.environ['CONDA_PREFIX']
32+
cxxtest = Dir('#/build/cxxtest').abspath
33+
env.Replace(CXXTEST=os.path.join(cxxtest, 'bin', 'cxxtestgen'),
34+
CXXTEST_INSTALL_DIR=cxxtest, CXXTEST_PYTHON=sys.executable)
35+
36+
if env['PLATFORM'] == 'win32':
37+
from SCons.Platform.win32 import exec_spawn
38+
39+
# The outer CI shell already activates conda and SCons configures MSVC.
40+
# /D stops each compiler/test-generator child from repeating cmd AutoRun.
41+
def spawn_without_autorun(sh, escape, cmd, args, child_env):
42+
return exec_spawn([sh, '/D', '/C', escape(' '.join(args))], child_env)
43+
44+
env['SPAWN'] = spawn_without_autorun
45+
else:
46+
env.Replace(CXX=os.environ.get('CXX', os.path.join(prefix, 'bin', 'c++')))
47+
env.Prepend(CCFLAGS=['-isystem' + os.path.join(prefix, 'include')])
48+
env.Append(LIBPATH=os.path.join(prefix, 'lib'))
49+
env.Append(LINKFLAGS='-Wl,-rpath,' + os.path.join(prefix, 'lib'))
50+
if env['PLATFORM'] == 'darwin':
51+
sdk = os.environ.get('CONDA_BUILD_SYSROOT')
52+
if sdk:
53+
env.Append(CXXFLAGS=['-isysroot', sdk])
54+
env.Append(LINKFLAGS=['-isysroot', sdk])
55+
""")

‎.github/workflows/matrix-and-codecov.yml‎

Lines changed: 97 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,102 @@ on:
1010
- published
1111
workflow_dispatch:
1212

13+
concurrency:
14+
group: matrix-${{ github.ref }}
15+
cancel-in-progress: ${{ github.event_name != 'release' }}
16+
1317
jobs:
1418
matrix-coverage:
15-
uses: scikit-package/release-scripts/.github/workflows/_matrix-and-codecov-on-merge-to-main.yml@v0
16-
with:
17-
project: libdiffpy
18-
c_extension: true
19-
headless: false
20-
secrets:
21-
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
19+
name: C++ tests (${{ matrix.os }}, Python ${{ matrix.python-version }})
20+
runs-on: ${{ matrix.os }}
21+
timeout-minutes: 45
22+
strategy:
23+
fail-fast: false
24+
matrix:
25+
os: [ubuntu-latest, windows-latest, macos-latest, macos-15-intel]
26+
python-version: ["3.12", "3.13", "3.14"]
27+
include:
28+
- os: ubuntu-latest
29+
shell: bash -l {0}
30+
build: coverage
31+
jobs: 4
32+
- os: windows-latest
33+
shell: cmd /C CALL {0}
34+
build: fast
35+
jobs: 4
36+
- os: macos-latest
37+
shell: bash -l {0}
38+
build: fast
39+
jobs: 2
40+
- os: macos-15-intel
41+
shell: bash -l {0}
42+
build: fast
43+
jobs: 4
44+
defaults:
45+
run:
46+
shell: ${{ matrix.shell }}
47+
48+
steps:
49+
- name: Check out libdiffpy
50+
uses: actions/checkout@v6
51+
with:
52+
fetch-depth: 0
53+
54+
- name: Fetch upstream release tags
55+
run: git fetch --tags https://github.com/diffpy/libdiffpy.git
56+
57+
# CxxTest is header-only and its generator runs directly from source.
58+
# The conda-forge package is not available on every matrix platform.
59+
- name: Check out CxxTest 4.4
60+
uses: actions/checkout@v6
61+
with:
62+
repository: CxxTest/cxxtest
63+
ref: 191adddb3876ab389c0c856e1c03874bf70f8ee4
64+
path: build/cxxtest
65+
66+
- name: Prepare C++ test configuration
67+
shell: python {0}
68+
run: |
69+
import runpy
70+
runpy.run_path('.github/scripts/configure-matrix.py')
71+
72+
- name: Create build environment
73+
uses: conda-incubator/setup-miniconda@v3
74+
with:
75+
activate-environment: test
76+
channels: conda-forge
77+
conda-remove-defaults: "true"
78+
auto-update-conda: false
79+
auto-activate-base: false
80+
python-version: ${{ matrix.python-version }}
81+
environment-file: build/matrix-environment.yml
82+
channel-priority: strict
83+
84+
- name: Build and run C++ tests
85+
run: scons -j${{ matrix.jobs }} build=${{ matrix.build }} test
86+
87+
- name: Generate coverage report
88+
if: runner.os == 'Linux' && matrix.python-version == '3.14'
89+
run: >-
90+
gcovr --gcov-executable "$CONDA_PREFIX/bin/gcov"
91+
--root . --filter 'build/coverage-.*/diffpy/'
92+
--xml coverage.xml
93+
94+
- name: Save coverage report
95+
if: runner.os == 'Linux' && matrix.python-version == '3.14'
96+
uses: actions/upload-artifact@v4
97+
with:
98+
name: coverage-report
99+
path: coverage.xml
100+
if-no-files-found: error
101+
102+
- name: Upload coverage to Codecov
103+
# Fork push builds have no upstream Codecov token; keep their artifact.
104+
if: >-
105+
runner.os == 'Linux' && matrix.python-version == '3.14' &&
106+
github.repository == 'diffpy/libdiffpy'
107+
uses: codecov/codecov-action@v5
108+
with:
109+
files: coverage.xml
110+
fail_ci_if_error: true
111+
token: ${{ secrets.CODECOV_TOKEN }}

‎.github/workflows/tests-on-pr.yml‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ on:
44
pull_request:
55
workflow_dispatch:
66

7+
concurrency:
8+
group: tests-on-pr-${{ github.event.pull_request.number || github.ref }}
9+
cancel-in-progress: true
10+
711
jobs:
812
tests-on-pr:
913
runs-on: ubuntu-latest
@@ -23,7 +27,7 @@ jobs:
2327
activate-environment: test
2428
channels: conda-forge
2529
conda-remove-defaults: "true"
26-
auto-update-conda: true
30+
auto-update-conda: false
2731
auto-activate-base: false
2832

2933
- name: Conda config
@@ -53,7 +57,7 @@ jobs:
5357
- name: Build and run C++ tests with coverage
5458
run: |
5559
"$CONDA_PREFIX/bin/c++" --version
56-
scons build=coverage test
60+
scons -j4 build=coverage test
5761
5862
- name: Generate coverage report
5963
run: >-

‎.gitignore‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,3 +115,12 @@ target/
115115

116116
# Ipython Notebook
117117
.ipynb_checkpoints
118+
119+
# source distribution tarball
120+
libdiffpy-*.tar.gz
121+
122+
# Windows build artifacts (MSVC)
123+
.vs/
124+
*.exp
125+
*.lib
126+
*.dll

‎.pre-commit-config.yaml‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,12 @@ repos:
3939
hooks:
4040
- id: isort
4141
args: ["--profile", "black"]
42+
- repo: https://github.com/pre-commit/mirrors-clang-format
43+
rev: v20.1.6
44+
hooks:
45+
- id: clang-format
46+
name: clang-format (C/C++)
47+
files: \.(c|cpp|cc|cxx|h|hpp|hh)$
4248
- repo: https://github.com/pre-commit/pre-commit-hooks
4349
rev: v6.0.0
4450
hooks:

‎SConstruct‎

Lines changed: 54 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ SCons construction environment can be customized in sconscript.local script.
2222

2323
import os
2424
import platform
25+
from os.path import join as pjoin
26+
from SCons.Script import *
2527

2628
def subdictionary(d, keyset):
2729
return dict(kv for kv in d.items() if kv[0] in keyset)
@@ -31,46 +33,82 @@ DefaultEnvironment(ENV=subdictionary(os.environ, '''
3133
PATH CPATH CPLUS_INCLUDE_PATH LIBRARY_PATH LD_RUN_PATH
3234
LD_LIBRARY_PATH DYLD_LIBRARY_PATH DYLD_FALLBACK_LIBRARY_PATH
3335
MACOSX_DEPLOYMENT_TARGET
36+
HOME USERPROFILE HOMEDRIVE HOMEPATH APPDATA LOCALAPPDATA
3437
'''.split())
3538
)
3639

3740
# Create construction environment
3841
env = DefaultEnvironment().Clone()
3942

40-
# Variables definitions below work only with 0.98.1 or later.
43+
# Variables definitions below work only with 0.98.1 or later
4144
env.EnsureSConsVersion(0, 98, 1)
4245

4346
# Customizable compile variables
4447
vars = Variables('sconsvars.py')
4548

46-
vars.Add(PathVariable(
47-
'prefix',
48-
'installation prefix directory',
49-
'/usr/local'))
50-
vars.Update(env)
49+
# Set PATHs
50+
if 'PREFIX' in os.environ:
51+
vars.Add(PathVariable(
52+
'prefix',
53+
'installation prefix directory',
54+
os.environ['PREFIX']))
55+
vars.Update(env)
56+
elif 'CONDA_PREFIX' in os.environ:
57+
vars.Add(PathVariable(
58+
'prefix',
59+
'installation prefix directory',
60+
os.environ['CONDA_PREFIX']))
61+
vars.Update(env)
62+
else:
63+
vars.Add(PathVariable(
64+
'prefix',
65+
'installation prefix directory',
66+
'/usr/local'))
67+
vars.Update(env)
68+
69+
if env['PLATFORM'] == "win32":
70+
include_path = pjoin(env['prefix'], 'Library', 'include')
71+
lib_path = pjoin(env['prefix'], 'Library', 'lib')
72+
shared_path = pjoin(env['prefix'], 'Library', 'share')
73+
74+
# Windows programs started by SCons, such as python for cxxtestgen,
75+
# fail without these system variables.
76+
for k in ('SYSTEMROOT', 'SYSTEMDRIVE', 'COMSPEC', 'PATHEXT', 'TEMP', 'TMP'):
77+
if k in os.environ:
78+
env['ENV'][k] = os.environ[k]
79+
else:
80+
include_path = pjoin(env['prefix'], 'include')
81+
lib_path = pjoin(env['prefix'], 'lib')
82+
shared_path = pjoin(env['prefix'], 'share')
83+
5184
vars.Add(PathVariable(
5285
'libdir',
53-
'installation directory for compiled library [prefix/lib]',
54-
env['prefix'] + '/lib',
86+
'installation directory for compiled programs',
87+
lib_path,
5588
PathVariable.PathAccept))
5689
vars.Add(PathVariable(
5790
'includedir',
58-
'installation directory for C++ header files [prefix/include]',
59-
env['prefix'] + '/include',
91+
'installation directory for C++ header files',
92+
include_path,
6093
PathVariable.PathAccept))
6194
vars.Add(PathVariable(
6295
'datadir',
63-
'installation directory for architecture independent data [prefix/share]',
64-
env['prefix'] + '/share',
96+
'installation directory for architecture independent data',
97+
shared_path,
6598
PathVariable.PathAccept))
99+
100+
env.AppendUnique(CPPPATH=[include_path])
101+
env.AppendUnique(LIBPATH=[lib_path])
102+
103+
# Customizable build variables
66104
vars.Add(EnumVariable(
67105
'build',
68106
'compiler settings',
69107
'fast', allowed_values=('fast', 'debug', 'develop', 'coverage')))
70108
vars.Add(EnumVariable(
71109
'tool',
72110
'C++ compiler toolkit to be used',
73-
'default', allowed_values=('default', 'intelc')))
111+
'default', allowed_values=('default', 'clang', 'gcc', 'intelc')))
74112
vars.Add(BoolVariable(
75113
'enable_objcryst',
76114
'enable objcryst support, when installed', None))
@@ -83,10 +121,13 @@ vars.Add(
83121
vars.Add(BoolVariable(
84122
'test_installed',
85123
'build tests using the installed library.', False))
124+
86125
vars.Update(env)
126+
87127
env.Help(MY_SCONS_HELP % vars.GenerateHelpText(env))
88128

89129
env['has_objcryst'] = None
130+
90131
btags = [env['build'], platform.machine()]
91132
if env['profile']: btags.append('profile')
92133
builddir = env.Dir('build/' + '-'.join(btags))

‎examples/testlib.cpp‎

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,14 @@
44
// c++ testlib.cpp -ldiffpy
55
// ./a.out
66

7-
87
#include <iostream>
98
#include <diffpy/srreal/ScatteringFactorTable.hpp>
109

11-
int main(int argc, char* argv[])
12-
{
13-
using namespace diffpy::srreal;
14-
ScatteringFactorTablePtr ntbl;
15-
ntbl = ScatteringFactorTable::createByType("neutron");
16-
ntbl->lookup("Pb");
17-
std::cout << "Installation of libdiffpy shared library works!\n";
18-
return 0;
10+
int main(int argc, char* argv[]) {
11+
using namespace diffpy::srreal;
12+
ScatteringFactorTablePtr ntbl;
13+
ntbl = ScatteringFactorTable::createByType("neutron");
14+
ntbl->lookup("Pb");
15+
std::cout << "Installation of libdiffpy shared library works!\n";
16+
return 0;
1917
}

0 commit comments

Comments
 (0)