Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
a20290e
Change version to 12.1.0-a.0.z
lyrahgames Mar 28, 2026
a3d26a1
Update upstream submodule to 12.1.0
lyrahgames Mar 28, 2026
59a0c87
Move `README.md` to repository root
lyrahgames Mar 28, 2026
2d96531
Add upstream's readme, license, and changelog
lyrahgames Mar 28, 2026
d81da49
Tweak `manifest` files
lyrahgames Mar 28, 2026
fd03c87
Disable install of tests package in root buildfile
lyrahgames Mar 28, 2026
716b080
Update configuration variables for better defaults
lyrahgames Mar 28, 2026
8d1e2f6
Use C++20 for unit tests
lyrahgames Mar 28, 2026
90e8f0a
Remove version header generation
lyrahgames Mar 28, 2026
da2e192
Reduce and refactor smoke tests
lyrahgames Mar 28, 2026
ca28a18
Use all three CI build configs on default targets
lyrahgames Mar 28, 2026
dcb0602
Use generated config header for module consumption
lyrahgames Mar 28, 2026
9ac287d
Re-introduce MSVC workaround to fix error C7657
lyrahgames Mar 28, 2026
ac28286
Restrict CI builds
lyrahgames Mar 28, 2026
4a2f375
Tweak `buildfile` and explain module configuration
lyrahgames Mar 28, 2026
25cebab
Use `.gitignore` whitelisting
lyrahgames Mar 28, 2026
dceb615
Add `module-std-headers` CI build config
lyrahgames Mar 28, 2026
a52d6a3
Install documentation to sub-directory
lyrahgames Mar 28, 2026
54f4bb1
Add `PACKAGE-README.md`
lyrahgames Mar 29, 2026
376e994
Make tests library a utility library `libue{}`
lyrahgames Mar 29, 2026
dfdbf1c
Describe MSVC bug
lyrahgames Mar 29, 2026
73f45ac
Sanitize execution of unit tests
lyrahgames Mar 29, 2026
437a07a
Write `README.md` following packaging guidelines
lyrahgames Mar 29, 2026
4119d71
Add `buildfile` comments to explain build
lyrahgames Mar 29, 2026
c8c502d
Refactor smoke tests
lyrahgames Mar 30, 2026
9353cd4
Remove `config.fmt.disable_import_std`
lyrahgames Mar 30, 2026
55b7b35
Restrict GCC versions in CI builds
lyrahgames Mar 30, 2026
7eb74b7
Fix FreeBSD `import std;` bug
lyrahgames Mar 30, 2026
fffe7d1
Update issues and notes in `README.md`
lyrahgames Mar 30, 2026
a8c2893
Remove explicit MSVC `/utf-8` flag
lyrahgames Mar 30, 2026
9c24b4c
Remove directory glob in root `buildfile`
lyrahgames Apr 6, 2026
241ca4e
Tweak `PACKAGE-README.md`
lyrahgames Apr 6, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@
#
#*.png binary

# See: https://build2.org/article/symlinks.xhtml#windows
#
fmt/fmt/include symlink=dir
fmt/fmt/src symlink=dir
fmt/doc symlink=dir
fmt-tests/basics/test symlink=dir
fmt-tests/test-main/test symlink=dir
77 changes: 51 additions & 26 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,26 +1,51 @@
.bdep/
.vs/

# Local default options files.
#
.build2/local/

# Compiler/linker output.
#
*.d
*.t
*.i
*.ii
*.o
*.obj
*.so
*.dll
*.a
*.lib
*.exp
*.pdb
*.ilk
*.exe
*.exe.dlls/
*.exe.manifest
*.pc
# Use whitelisting and ignore everything by default.
Comment thread
Klaim marked this conversation as resolved.
#
*

# Don't ignore directories.
#
!*/

# Don't ignore Git-specific files.
#
!.git*

# Allow all files from upstream sources.
#
!upstream

# Don't ignore license and documentation files.
#
!*.md
!LICENSE

# Don't ignore default C++ file extensions.
#
!*.h
!*.c
!*.cc
!*.inl

# Don't ignore source generation files.
#
!*.in

# Add original source files that might have been changed.
#
!*.orig

# Don't ignore standard build2 files.
#
!buildfile
!bootstrap.build
!export.build
!root.build
!*manifest
!*testscript

# Allow specific symbolic links to directories.
#
!fmt/fmt/include
!fmt/fmt/src
!fmt/doc
!fmt-tests/basics/test
1 change: 1 addition & 0 deletions LICENSE
60 changes: 60 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# build2 Package Repository for {fmt}

This is a [build2](https://build2.org) package repository for [{fmt}](https://fmt.dev/), a modern C++ formatting library that provides a safe replacement for the `printf` family of functions.

| Package | Summary | Status |
|---|---|---|
| **[`fmt`](fmt/PACKAGE-README.md)** | C++ Formatting Library | [![cppget.org](https://img.shields.io/website/https/cppget.org/fmt.svg?down_message=offline&label=cppget.org&style=for-the-badge&up_color=blue&up_message=online)](https://cppget.org/fmt) [![queue.cppget.org](https://img.shields.io/website/https/queue.cppget.org/fmt.svg?down_message=empty&down_color=blue&label=queue.cppget.org&style=for-the-badge&up_color=orange&up_message=running)](https://queue.cppget.org/fmt) |

## Usage
If you want to use the `fmt` package in your `build2`-based project, add an appropriate repository manifest to your project's `repositories.manifest` and refer to [`fmt`'s PACKAGE README](fmt/PACKAGE-README.md).

### `repositories.manifest`
To be able to fetch the package, add one of the following prerequisites to your project's `repositories.manifest`.

**Option A: `cppget.org` (Recommended)**

Based on your project's stability requirements, choose either the [`stable` section](https://cppget.org/?about#pkg%3Acppget.org%2Fstable) for thoroughly tested versions or the [`testing` section](https://cppget.org/?about#pkg%3Acppget.org%2Ftesting) for the latest releases before they are marked as stable.
For example:

:
role: prerequisite
location: https://pkg.cppget.org/1/stable
# trust: ...

**Option B: Git Repository**

:
role: prerequisite
location: https://github.com/build2-packaging/fmt.git

## Development Setup
The development setup for this repository uses the standard `bdep`-based workflow.
For general information and guidance on package maintenance, please see the [`build2` Documentation](https://build2.org/doc.xhtml).

First, clone the repository via SSH or HTTPS.

git clone --recurse https://github.com/build2-packaging/fmt.git # HTTPS
git clone --recurse git@github.com:build2-packaging/fmt.git # SSH

Inside the repository's directory, initialize your build configuration.

bdep init -C @gcc cc config.cxx=g++ config.cxx.features.modules=true config.install.root=../.install config.dist.root=../.dist

Afterwards, use `b` or `bdep` to build, test, install, and distribute the packages.

## Issues and Notes
- To generate a Binary Module Interface (BMI) from {fmt}'s C++ module after installation, the consumer must compile the module interface unit using the same macro configuration as the original library build. These macros are internal to the module and are therefore not exported via `cxx.export.poptions`. Instead, a generated `config.h` header encapsulates the required configuration through preprocessor macros. The module interface unit is patched to include this header immediately after `module;` in the global module fragment, ensuring the correct macros are available during BMI generation.
- In non-modular compiled builds, `fmt/format-inl.h` acts as a private implementation header for `src/format.cc`. While its installation in this specific configuration is technically unnecessary, we do not explicitly exclude it to reduce complexity.
- C++ module support in GCC versions prior to 16 is incomplete and unreliable for this library. As a result, such configurations are considered unsupported and are excluded from CI.
- On FreeBSD 15 with Clang 19, there is a discrepancy between compiler capabilities and system libraries. Although `__cpp_lib_modules` is defined (indicating that libc++ has module support), the base system does not ship the required module source or metadata files. Consequently, `import std;` is not functional in this environment which is reflected in the generated `config.h`.
- Upstream unit tests currently only support C++20 and fail when compiled with newer language standards. Therefore, the `fmt-tests` package is explicitly restricted to `cxx.std = 20`.
- Currently, unit tests are only run when the library headers are available and not when `config.fmt.module_only=true`. The unit tests use standard header includes rather than module imports.
- A known [issue in MSVC](https://developercommunity.visualstudio.com/t/Separate-preprocessing-with-P-fails-wit/10707183) prevents correct processing of {fmt}'s C++ module, producing error C7657 (“private module fragment cannot be declared before a module declaration”). The workaround (`cc.reprocess=true`) is only applicable when consuming the package directly via `build2`. As a result, unit tests fail on Windows when using the installed package.

## Contributing
Contributions are welcome and greatly appreciated!
Please start by [opening an issue](https://github.com/build2-packaging/fmt/issues) to report a bug, suggest an improvement, or request a version update.
This helps us coordinate efforts and avoid duplicate work.
You are then welcome to submit a [pull request](https://github.com/build2-packaging/fmt/pulls) that references the issue.
For guidance on package maintenance, please see the [`build2` Packaging Guidelines](https://build2.org/build2-toolchain/doc/build2-toolchain-packaging.xhtml).
7 changes: 3 additions & 4 deletions buildfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# Glue buildfile that "pulls" all the packages in the project.
#
import pkgs = [dir_paths] $process.run_regex(\
cat $src_root/packages.manifest, '\s*location\s*:\s*(\S+)\s*', '\1')
import pkgs = fmt/
import tests = fmt-tests/

./: $pkgs
./: $tests: install = false
25 changes: 0 additions & 25 deletions fmt-tests/.gitignore

This file was deleted.

1 change: 1 addition & 0 deletions fmt-tests/ChangeLog.md
1 change: 1 addition & 0 deletions fmt-tests/LICENSE
1 change: 1 addition & 0 deletions fmt-tests/PACKAGE-README.md
1 change: 1 addition & 0 deletions fmt-tests/README.md
5 changes: 0 additions & 5 deletions fmt-tests/basics/.gitignore

This file was deleted.

27 changes: 13 additions & 14 deletions fmt-tests/basics/buildfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
include ../test-main/
import libs = \
fmt%lib{fmt} \
gtest%lib{gtest} \
gmock%lib{gmock}

libue{test-main}: \
test/cxx{test-main gtest-extra util} \
test/hxx{gtest-extra mock-allocator test-assert util} \
$libs

# NOTE: Maintaining explicit lists to match upstream, as it's not clear that there is intended to be a uniform pattern that can be reliably globbed.
# See individual invocations of add_fmt_test() in upstream/test/CMakeLists.txt
Expand Down Expand Up @@ -28,24 +36,15 @@ gtest_test_names = \
# TODO: scan-test - Excluded due to unresolved linker errors.

for test_name : $gtest_test_names
{
./: exe{$test_name} : test/cxx{$test_name}
exe{$test_name}: ../test-main/liba{test-main}:
{
bin.whole = true
}
}
./: exe{$test_name} : test/cxx{$test_name} libue{test-main} testscript

# END [Tests that use gtest, and do not require any additional source/headers beyond a single cc file]


# Tests using gtest but with additional prerequisites

./: exe{ranges-test} : test/cxx{ranges-test ranges-odr-test}
exe{ranges-test}: ../test-main/liba{test-main}:
{
bin.whole = true
}
./: exe{ranges-test} : \
test/cxx{ranges-test ranges-odr-test} libue{test-main} testscript

# NOTE: format-impl-test- For whatever reason, format-impl-test is tied in upstream to header-only-test, which we do not support. Attempting to compile it alone yields errors, therefore omitted.
# TODO: posix-mock-test - Excluded pending further work. Needs posix-mock.h, and has some msvc/runtime conditional logic that needs looking into.
Expand All @@ -63,7 +62,7 @@ import fmt = fmt%lib{fmt}

for test_name : $standalone_test_names
{
./: exe{$test_name} : test/cxx{$test_name} $fmt
./: exe{$test_name} : test/cxx{$test_name} $fmt testscript
}

# END [Tests which do not use gtest and therefore should link directly to fmt only and not the test-main lib]
4 changes: 4 additions & 0 deletions fmt-tests/basics/testscript
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Redirect stdout to stderr (1>&2) and let stderr through (2>|).
# Cleanup anything the test might create, recursively (&***).
#
$* 1>&2 2>| &***
4 changes: 0 additions & 4 deletions fmt-tests/build/.gitignore

This file was deleted.

2 changes: 1 addition & 1 deletion fmt-tests/build/root.build
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#
#cxx.internal.scope = current

cxx.std = latest
cxx.std = 20

using cxx

Expand Down
2 changes: 1 addition & 1 deletion fmt-tests/buildfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
./: manifest
./: manifest legal{LICENSE} doc{*.md}

# NOTE: for the moment, we need to disable all the test targets in modules-only mode, since upstream fmt does not yet properly support it.
import! [metadata, rule_hint=cxx.link] fmt_lib = fmt%lib{fmt}
Expand Down
17 changes: 14 additions & 3 deletions fmt-tests/manifest
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
: 1
name: fmt-tests
version: 11.1.4
version: 12.1.0-a.0.z
type: exe
language: c++
project: fmt
summary: Tests package for fmt upstream tests
summary: Formatting C++ library tests
license: MIT
url: https://github.com/fmtlib/fmt/

description-file: README.md
changes-file: ChangeLog.md
url: https://fmt.dev/
src-url: https://github.com/fmtlib/fmt/
email: victor.zverovich@gmail.com

package-description-file: PACKAGE-README.md
package-url: https://github.com/build2-packaging/fmt/
package-email: packaging@build2.org

depends: * build2 >= 0.17.0
depends: * bpkg >= 0.17.0
Expand Down
14 changes: 0 additions & 14 deletions fmt-tests/test-main/buildfile

This file was deleted.

1 change: 0 additions & 1 deletion fmt-tests/test-main/test

This file was deleted.

1 change: 1 addition & 0 deletions fmt/ChangeLog.md
1 change: 1 addition & 0 deletions fmt/LICENSE
55 changes: 55 additions & 0 deletions fmt/PACKAGE-README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# {fmt} - A Formatting C++ Library

{fmt} is an open-source formatting library that provides a safe replacement for the `printf` family of functions.
Errors in format strings, which are a common source of vulnerabilities in C, are reported at compile time.
Formatting of most standard types, including all containers, dates, and times is supported out-of-the-box.
Also, {fmt} provides portable Unicode support on major operating systems with UTF-8 and char strings.

# Usage
To use `fmt` in your project, add the following configurations to the respective files after you have gained access to a `build2` package repository that contains it.

### `manifest`
To make `fmt` available for import, add the following dependency to the `manifest` of each package in your project that requires it, adjusting the version constraint as appropriate.

depends: fmt ^12.1.0
Comment thread
Klaim marked this conversation as resolved.

### `buildfile`
To import the contained library, use the following declaration in your `buildfile`.

import fmt = fmt%lib{fmt}

Note also that `lib{fmt}` provides `build2` metadata that can be extracted with an immediate importation to describe its configuration.

fmt.has_header = [bool] (!$config.fmt.module_only)
fmt.has_module = [bool] $cxx.features.modules

### C++ Usage
Comment thread
Klaim marked this conversation as resolved.
If `$fmt.has_header == true`, {fmt}'s headers can be included as follows:

```c++
#include <fmt/format.h>
```

If `$fmt.has_module == true`, {fmt}'s C++ module can imported via:

```c++
import fmt;
```

## Configuration

### C++20 Modules Support
{fmt}'s C++ module support can be enabled by setting:

config.cxx.features.modules = true

By default, the library supports both module import through `import fmt;` and traditional header inclusion through, eg., `#include <fmt/format.h>`.
To enable this dual usage, all entities are attached to the global module via global module linkage (`extern "C++"`).
This ensures compatibility between module and header-based consumption.

To enforce strict module usage, use:

config.fmt.module_only = true

In this mode, header access is disabled and all entities are exclusively provided through the C++ module.
This results in full encapsulation within the module and avoids global module linkage.
Loading