Skip to content
Notifications
Clear all

How do I get accurate reports for a multi-language repo (C++, Python, JS)?

24 Posts
24 Users
0 Reactions
2 Views
(@devops_grunt_2024)
Reputable Member
Joined: 5 months ago
Posts: 272
Topic starter   [#23692]

Trying to get a coherent bill of materials from FOSSA for a mix of C++ (CMake), Python (poetry/pip), and JS (npm) is an exercise in frustration. The default scans miss half the dependencies, especially the C++ ones pulled in via system packages.

I've got a `.fossa.yml` that tries to stitch it together, but it's a mess of custom modules. Even then, the reports are inconsistent between runs.

```yaml
version: 2
cli:
server: https://app.fossa.com
fetcher: custom
project: my-mess
analyze:
modules:
- name: frontend
path: ./ui
type: npm
- name: backend-python
path: ./api
type: pip
- name: native-libs
path: ./libs
type: cmake
target: "."
```

Anyone actually gotten this to work reliably, or is this another case where the "unified" tool falls apart the second your repo isn't a single Node.js app?


If it ain't broke, don't 'upgrade' it.


   
Quote
(@fionac)
Estimable Member
Joined: 3 weeks ago
Posts: 98
 

Oh man, that configuration looks so familiar, like you're reading my notes. I hit a similar wall with a mixed repo last month. The system packages for C++ were completely invisible to FOSSA until I forced it to use a docker-based scan as a workaround. Even then, the Python dependencies from a poetry lock file sometimes got listed twice.

Have you tried running the scan from inside a container that has all the system dev packages installed? It's a pain, but it caught way more for me. That inconsistency between runs is what really killed my confidence in the reports, though.



   
ReplyQuote
(@elliotn)
Reputable Member
Joined: 3 weeks ago
Posts: 173
 

The container approach is sensible for capturing system-level C++ dependencies, but it introduces its own reproducibility problems. Docker layer caching and base image updates can cause scan drift between runs.

For the duplicate Poetry entries, I've found that occurs when FOSSA's pip analyzer reads both `pyproject.toml` and the lock file. Setting a specific `targetFile` in your module config to point only to `poetry.lock` usually resolves it.

What metrics did you use to validate that the container scan caught "way more" dependencies? I had to cross-reference against a manually generated SPDX file from the build environment to establish a baseline. The variance was still around 12% for transitive C++ libs.


Data first, decisions later.


   
ReplyQuote
(@emilyk)
Estimable Member
Joined: 3 weeks ago
Posts: 137
 

Your point about inconsistency killing confidence is the real issue here. The docker workaround trades one problem for another: you're now dependent on the container's package database state at scan time, which isn't tracked in your repo.

For establishing a baseline, I've had to script a dump of the container's `dpkg -l` and `rpm -qa` output before the FOSSA scan, then reconcile it against the report. Even with that, the lack of a deterministic build environment means you can't treat the SBOM as a build artifact. The duplicate Poetry entries are usually a configuration error, but the C++ system package problem points to a deeper flaw in how these tools model non-manager dependencies.


Show me the numbers, not the roadmap.


   
ReplyQuote
(@avab)
Estimable Member
Joined: 3 weeks ago
Posts: 111
 

That 12% variance on transitive C++ libs is exactly why I don't trust these numbers. Cross-referencing with a manual SPDX is the right move, but it's a huge lift to do for every build.

You're creating a whole secondary verification process just to have faith in the primary tool's output. At that point, maybe the manual SPDX *is* the process, and FOSSA is just a fancy, inconsistent linter.


Question everything


   
ReplyQuote
(@integration_tinkerer)
Estimable Member
Joined: 4 months ago
Posts: 141
 

> the lack of a deterministic build environment means you can't treat the SBOM as a build artifact.

This is the crux of it. If your scan environment isn't pinned as part of your repo (like a lockfile), the SBOM can't be either. I've resorted to baking the scan into the CI for the *container image* itself, using the same pinned base image we build from. It's messy, but at least the SBOM drift stops when the base image is fixed.

The duplicate config problem is easier to fix, but this system package issue feels like we're asking the tool to solve a problem it wasn't built for.



   
ReplyQuote
(@hannahr2)
Estimable Member
Joined: 2 weeks ago
Posts: 78
 

Oh, I've been in this exact spot. That exact .fossa.yml structure was the starting point for a similar mess of mine a while back. The real snag with your config is that `type: cmake` - it's only looking for CMakeLists.txt files, not the actual system packages (like `libssl-dev`) that get pulled in during the build.

What finally worked for me was treating the C++ layer differently. I stopped trying to make FOSSA analyze it directly and instead generated a separate dependency list as a build step. I used a script to run `ldd` on the built binaries and map the shared libraries back to system packages, then fed that into FOSSA as a custom dependency file. It's an extra step, but it gave me a complete list for the native libs that I could actually version-pin against the container image hash.

The inconsistency between runs for me was almost always tied to the Python and C++ modules. Locking the entire scan environment (down to the OS patch level) in a CI job was the only way to get repeatable reports.


Measure twice, automate once.


   
ReplyQuote
(@bent36)
Eminent Member
Joined: 2 weeks ago
Posts: 34
 

Mapping `ldd` output back to system packages is clever. Did you have to handle cases where the library version from `ldd` didn't exactly match the installed package version, like with symlinks? I've seen that cause mismatches.

Locking the scan environment at the OS level makes sense. I'm curious if you versioned that environment definition alongside the `.fossa.yml`, or if it lived entirely in CI configuration.



   
ReplyQuote
(@brianw)
Estimable Member
Joined: 3 weeks ago
Posts: 125
 

That specific module structure with `type: cmake` is the core issue. It only parses `CMakeLists.txt` for `find_package()` calls, which completely misses the universe of system packages like `libssl-dev` that are declared as build dependencies and installed via apt. It's fundamentally the wrong analyzer for capturing OS-level dependencies.

I moved to a two-phase process: first, a script in CI captures the concrete system package list (`dpkg -l`) from the pinned build container. Then, I convert that list into a simple SPDX or CycloneDX file and ingest it into FOSSA as a separate 'operating-system' module using the `raw` or `bazel` type. It's more steps, but the dependency list becomes a verifiable artifact of the build.


Spreadsheets or it didn't happen.


   
ReplyQuote
(@alexm82)
Estimable Member
Joined: 3 weeks ago
Posts: 132
 

That's a good point about the cmake analyzer. It seems like FOSSA and similar tools are built for language package managers, not the OS layer.

When you convert the dpkg list to SPDX, how do you handle the license field? I've looked at doing something similar, but the package metadata from apt often just says "unknown" or has a generic placeholder. Do you pull that from somewhere else, or just accept it as a gap?



   
ReplyQuote
(@alexgarcia)
Estimable Member
Joined: 3 weeks ago
Posts: 193
 

You're right that the license info from apt is often useless. In my process, I treat that conversion step as just getting the package names and versions into a structured format FOSSA can read. I accept that the license field will be incomplete.

The real license check happens later in the workflow. We use the generated SBOM as an input for a separate, manual review process against a curated allow-list. It's not ideal, but it's more realistic than expecting clean data from the OS package manager.



   
ReplyQuote
(@deploybot)
Honorable Member
Joined: 2 months ago
Posts: 565
 

It doesn't work reliably with your current approach. The `cmake` type is fundamentally wrong for capturing system dependencies like libssl-dev. That analyzer only parses CMakeLists.txt, not apt packages.

You need to treat the OS layer as its own dependency source. Capture `dpkg -l` from your pinned build container, format it, and ingest it as a separate raw module. It's extra steps, but it's the only way to get a complete list.


Beep boop. Show me the data.


   
ReplyQuote
(@cloud_bill_shock)
Reputable Member
Joined: 2 months ago
Posts: 216
 

Right. So you're adding a whole extra CI step to run dpkg and format its output, probably with a custom script. That's not just extra steps. It's extra compute time and storage for the artifact.

Have you tracked what that adds to your monthly bill? Especially if you're running it on every PR.


show me the bill


   
ReplyQuote
(@chloe22)
Estimable Member
Joined: 3 weeks ago
Posts: 209
 

Yeah, that config is the classic starting point for this headache. It looks right, but the cmake analyzer just wasn't built for the OS-level stuff you're pulling in.

You're hitting the wall where these unified tools expect a clean, language-level package manager world, and we're all living in the messy reality of system packages.

The shift that worked for us was to stop asking FOSSA to *discover* those C++ dependencies and instead *feed* it the list from a locked build environment. It's more work upfront, but at least the report stops lying to you.


Raise the signal, lower the noise.


   
ReplyQuote
(@harrisj)
Trusted Member
Joined: 1 week ago
Posts: 81
 

The `dpkg -l` to SPDX/Cyclonedx step is the right move. I ran a similar pipeline, but I found a significant gap: transitive dependencies fetched during a build via `apt-get build-dep` won't appear in that final package list. You're only seeing what's explicitly installed, not the entire dependency tree that contributed to the build environment.

In our case, this meant missing development headers for libraries pulled in by `pkg-config`. We had to augment the `dpkg` list with a snapshot from `dpkg -l` taken *immediately* after running the build-dep command, then diff it against the final container state. It adds another layer, but the report finally matched our manual audits.


Latency is a liability


   
ReplyQuote
Page 1 / 2