In contrast to ecosystems like npm (JavaScript) and pip (Python), C/C++ doesn’t have a universal package manager. Since most code scanning tools work by invoking build commands or analyzing manifests and lockfiles (that are ever-present in package-managed languages), organizations that use those traditional tools tend to struggle when dealing with C/C++.
This holds true for a range of use cases, including C/C++ SBOM management, vulnerability management, and regulatory compliance. Managing license compliance in C/C++ is similarly difficult, with the added concern of several ecosystem-specific nuances related to the way code is modified and distributed.
In this post, we'll cover why accurate license inventories are hard to build for C/C++, the nuances that raise the importance of compliance, and strategies and tools that can help.
The Challenges of Managing License Compliance in C/C++
In ecosystems like JavaScript, Java, and Python, license compliance starts from a reliable source of truth. A manifest and lockfile declare every dependency and version, and a scanning tool maps each one to its license. Most software composition analysis tools were built around this model.
C/C++ has no equivalent. Package managers like Conan and vcpkg exist, but adoption is partial, and even teams that use them rarely manage every dependency that way. Instead, open source arrives through multiple paths, including:
- Vendored libraries: Source code copied directly into the repository, often without version metadata nor the original license file.
- Snippets: Individual functions or files lifted from other projects and pasted into first-party code.
- Package managers: Conan or vcpkg, usually covering only a portion of the dependency graph.
- System and build-time dependencies: Libraries installed on the build machine and pulled in through CMake, Make, or Bazel.
- Prebuilt binaries: Static and shared libraries delivered by vendors or bundled in SDKs.
- Embedded Linux build systems: Yocto and Buildroot, which assemble entire distributions from hundreds of components.
Beyond identifying the C/C++ library, which is hard enough, it’s also important to determine with precision which version you’re using, since projects sometimes relicense between releases. (And CVEs generally only impact specific versions.)
License Compliance Nuances in C/C++
Two characteristics of C/C++ development make accurate license data matter even more than it does elsewhere.
Vendored Code is Often Modified
When C/C++ teams vendor libraries, there’s often a need to make modifications, such as to improve security or functionality. Once that happens, the library is no longer an unmodified copy, and modified code often triggers licensing obligations that unmodified code doesn't. For example:
- Apache License 2.0 requires modified files to carry prominent notices stating that you changed them.
- GPL v2 requires modified files to carry notices stating that you changed them and the date of the change.
- MPL 2.0 and LGPL require your changes to the covered code to be made available under the same license when you distribute.
In other words, even if you have a list of all the C/C++ libraries in your application, your specific compliance obligations may vary significantly depending on whether those libraries have been modified.
C/C++ Applications Are Frequently Distributed
Distribution is the trigger for most open source license requirements. A web application running on your own servers generally isn’t considered distributed, which means many obligations never apply. (This is why some projects choose the AGPL, which extends source code obligations to software that users interact with over a network.)
C/C++, on the other hand, is very clearly distributed in many applications. C/C++ is part of firmware, embedded devices, medical equipment, vehicles, desktop applications, games, and SDKs, all of which are shipped to customers.
As a result, compliance programs will have to consider strategies to manage the full set of obligations that come with open source licenses: producing attribution notices, copying license texts, and making source code offers for copyleft components. (Additionally, because static linking is so common in C/C++, complying with the LGPL tends to be more burdensome. When an LGPL library is statically linked into a distributed application, the distributor must provide the library’s source code, including any modifications, along with the materials recipients need to relink the application against a modified version of the library, such as the application’s object files.)
Strategies for Managing License Compliance in C/C++
For all of the documented challenges organizations face with licensing in C/C++, there are a range of tools and best practices that can materially improve compliance programs.
First, here are some of the processes we’d recommend teams consider (particularly when they don’t have access to a scanning tool that specializes in C/C++)
- Document vendored code at the source**.** Keep a metadata file alongside each vendored library that records its origin, version, license, and any local modifications, and always retain the upstream license file.
- Keep modifications visible. Store local changes as patch files applied on top of a pristine upstream copy, so it's always clear what you changed.
- Use SPDX identifiers. Adding SPDX license identifiers to source files, or adopting the REUSE specification, makes file-level licensing machine-readable.
From a tooling perspective, certain free and open source options do exist to assist with license compliance for parts of the C/C++ ecosystem. These include ScanCode Toolkit and OSS Review Toolkit.
Ultimately, however, license compliance is most effective with a single tool that runs every detection technique simultaneously: snippet scanning for copied code, vendored dependency detection for libraries checked into the repository, and package manager analysis for Conan-managed dependencies.
This is why FOSSA has made extensive investments in improving our C/C++ support over the last 12-18 months. FOSSA now combines snippet scanning, vendored dependency detection, Conan support, binary scanning, and Yocto and Buildroot (coming soon) coverage, to produce a complete license inventory for C/C++ applications. We also actually physically download and analyze all source files to significantly improve the depth and accuracy of license detections. Additionally, FOSSA supports detecting indicators of modified code; as mentioned previously, this can have a material impact on your license compliance obligations.
This scanning coverage works alongside advanced workflows like License Concluded and automated policy enforcement to make C/C++ license compliance management much more efficient and accurate than it would be with most other tools.
For information about FOSSA’s support for C/C++, please reach out to our team.
FOSSA Head of Product Management Cortez Frazier Jr. contributed to this blog post.
