stdlib-js / stdlib-js/stdlib

[BUG] Fortran source files don't propagate through `library-manifest` dependency resolution outside `task: 'build'`

Aperta
#11,930 9 commenti 0 reazioni 0 assegnatari Vedi su GitHub
Lingua principale
JavaScript
Stelle
6k
Fork
1.3k
Merge medio
1g 3h
PR unite (30g)
611

Descrizione

### Description

Error is encountered when a Fortran benchmark for a Level-2+ BLAS routine whose Fortran source declares an `EXTERNAL` Fortran dependency on another stdlib package (e.g., `dgemm` calling `xerbla`, `dger` calling `xerbla`). The benchmark fails to link with a missing-symbol error for the dependency.

The underlying defect is in [@stdlib/utils/library-manifest](https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/utils/library-manifest). When the resolver is queried with any task other than `build` (notably `task: 'benchmark'`), Fortran source files belonging to dependencies are not surfaced.

Fortran sources are currently declared only inside the `build` task entry of each Fortran-using package's manifest — so when `library-manifest` walks the dependency tree under `task: 'benchmark'`, it merges each dependency's `benchmark` entry, which contains only C sources, and the dependency's `.f` files never appear in the merged result.

For example, in [blas/base/xerbla/manifest.json](https://github.com/stdlib-js/stdlib/blob/develop/lib/node_modules/%40stdlib/blas/base/xerbla/manifest.json):

- `task: 'build'`, `os: 'linux'`, `blas: ''`, `wasm: false` → `src: ["./src/xerbla.f", "./src/xerbla.c"]`
- `task: 'benchmark'`, `os: 'linux'`, `blas: ''`, `wasm: false` → `src: ["./src/xerbla.c"]` *(no `.f`)*

The native-addon build path works bc [`binding.gyp`/`include.gypi`](https://github.com/stdlib-js/stdlib/blob/develop/lib/node_modules/%40stdlib/blas/base/dger/include.gypi) calls `library-manifest` with no explicit `task`, defaulting to `task: 'build'`, where the `.f` declarations exist.

The same condition silently affects every merged Fortran benchmark for a Level-2+ BLAS routine that exercises a cross-package Fortran symbol. Level-1 BLAS Fortran benchmarks (e.g., [daxpy](https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/blas/base/daxpy/benchmark/fortran), [dscal](https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/blas/base/dscal/benchmark/fortran), [dasum](https://github.com/stdlib-js/stdlib/tree/develop/lib/node_modules/%40stdlib/blas/base/dasum/benchmark/fortran)) have no cross-package Fortran dependencies and link cleanly, which is why the gap has not surfaced more broadly.

The recurring local fix is a Makefile patch in the consuming package that hardcodes a relative path to a sibling package's `.f `file (e.g., `../../../xerbla/src/xerbla.f` inside `dger`'s benchmark Makefile). This couples one package to another package's file-tree layout. If `xerbla` is ever moved within the package tree (e.g., to `@stdlib/blas/base/utils/xerbla`), every consumer's hardcoded path silently breaks, and a contributor performing the migration has no way to discover the breakage short of running every affected benchmark. The manifest-based @stdlib/... reference model exists precisely so packages don't reach into each other's file trees this way. See @kgryte's [comment on PR #11332](https://github.com/stdlib-js/stdlib/pull/11332#issuecomment-4212459653).

A second, downstream contributor to the symptom is that [tools/scripts/compile_fortran_benchmark](https://github.com/stdlib-js/stdlib/blob/develop/tools/scripts/compile_fortran_benchmark) only resolves include directories from the manifest, while its C counterpart [tools/scripts/compile_c_benchmark](https://github.com/stdlib-js/stdlib/blob/develop/tools/scripts/compile_c_benchmark) resolves include, src, libraries, and libpath. Patching only this wrapper might be too narrow, since it wouldn't address future Fortran-linking contexts that go through library-manifest.

Per office hours discussion, the fix should live in `@stdlib/utils/library-manifest` so that Fortran source files are resolved uniformly when resolving a package's dependency tree, regardless of the `task` the caller queried.

Once the resolver is correct, downstream cleanup for the Fortran benchmark wrapper in `tools/scripts/` should consume the resolved source list (mirroring its C counterpart), and the merged Fortran benchmark Makefiles' hardcoded `SOURCE_FILES` defaults should match the C-benchmark Makefile convention.

### Related Issues

Related PRs #11332 and #11333.

### Questions

No.

### Demo

_No response_

### Reproduction

```shell
# In a checkout of stdlib develop:
cd lib/node_modules/@stdlib/blas/base/dger/benchmark/fortran
make
```

### Expected Results

Benchmark links successfully; xerbla resolves via the manifest dependency graph (`dger`'s manifest already lists `@stdlib/blas/base/xerbla` as a dependency under `task: 'benchmark'`.

### Actual Results

```shell
Undefined symbols for architecture arm64:
"_xerbla", referenced from:
_dger in ccCfvnCt.o
ld: symbol(s) not found for architecture arm64
collect2: error: ld returned 1 exit status
make: *** [benchmark.length.out] Error 1
```

Linker fails with an unresolved reference to xerbla. The dependency's `.f` source is never surfaced because `library-manifest` only declares Fortran sources under `task: 'build'`.

### Version

develop

### Environments

N/A

### Browser Version

_No response_

### Node.js / npm Version

_No response_

### Platform

Reproduces on any platform with gfortran + make (linux/macOS verified).

### Checklist

- [x] Read and understood the [Code of Conduct](https://github.com/stdlib-js/stdlib/blob/develop/CODE_OF_CONDUCT.md).
- [x] Searched for existing issues and pull requests.

Guida per i contributori

Apri la guida per i contributori

Direzione di ricerca

Reproduce the failure from lib/node_modules/@stdlib/blas/base/dger/benchmark/fortran with make, then inspect @stdlib/utils/library-manifest and the dger and xerbla manifest.json files. Check tools/scripts/compile_fortran_benchmark and the merged Fortran benchmark Makefiles against the C benchmark path. Done means benchmark dependency resolution exposes xerbla's Fortran source without hardcoded sibling paths and the benchmark links successfully.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
fortran, javascript
Ambito
build-system, tooling
Tipo di issue
Bug
Difficoltà
4/5
Tempo stimato
3-5 giorni
Stato di attività
Tranquilla
Chiarezza
Abbastanza chiara
Idoneità per principianti
48/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.