diff --git a/.github/workflows/cifuzz.yml b/.github/workflows/cifuzz.yml deleted file mode 100644 index 56dfae801493..000000000000 --- a/.github/workflows/cifuzz.yml +++ /dev/null @@ -1,30 +0,0 @@ -name: CIFuzz -on: [pull_request] - -permissions: - contents: read - -jobs: - Fuzzing: - runs-on: ubuntu-latest - steps: - - name: Build fuzzers - id: build - uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@92182553173581f871130c71c71b17f003d47b0a # master - with: - oss-fuzz-project-name: 'fmt' - dry-run: false - language: c++ - - name: Run fuzzers - uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@92182553173581f871130c71c71b17f003d47b0a # master - with: - oss-fuzz-project-name: 'fmt' - fuzz-seconds: 300 - dry-run: false - language: c++ - - name: Upload crash - uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3 - if: failure() && steps.build.outcome == 'success' - with: - name: artifacts - path: ./out/artifacts diff --git a/.github/workflows/doc.yml b/.github/workflows/doc.yml deleted file mode 100644 index 3098d4584961..000000000000 --- a/.github/workflows/doc.yml +++ /dev/null @@ -1,43 +0,0 @@ -name: doc - -on: [push, pull_request] - -permissions: - contents: read - -jobs: - build: - # Use Ubuntu 20.04 because doxygen 1.8.13 from Ubuntu 18.04 is broken. - runs-on: ubuntu-20.04 - - steps: - - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 - - - name: Add Ubuntu mirrors - run: | - # Github Actions caching proxy is at times unreliable - # see https://github.com/actions/runner-images/issues/7048 - printf 'http://azure.archive.ubuntu.com/ubuntu\tpriority:1\n' | sudo tee /etc/apt/mirrors.txt - curl http://mirrors.ubuntu.com/mirrors.txt | sudo tee --append /etc/apt/mirrors.txt - sudo sed -i 's~http://azure.archive.ubuntu.com/ubuntu/~mirror+file:/etc/apt/mirrors.txt~' /etc/apt/sources.list - - - name: Create build environment - run: | - sudo apt update - sudo apt install doxygen - pip install mkdocs-material==9.5.25 mkdocstrings==0.25.1 mike==2.1.1 - cmake -E make_directory ${{runner.workspace}}/build - # Workaround https://github.com/actions/checkout/issues/13: - git config --global user.name "$(git --no-pager log --format=format:'%an' -n 1)" - git config --global user.email "$(git --no-pager log --format=format:'%ae' -n 1)" - - - name: Build - working-directory: ${{runner.workspace}}/build - run: $GITHUB_WORKSPACE/support/mkdocs deploy dev - - - name: Deploy - env: - KEY: "${{secrets.KEY}}" - if: env.KEY != '' && github.ref == 'refs/heads/master' - working-directory: ${{runner.workspace}}/fmt/build/fmt.dev - run: git push https://$KEY@github.com/fmtlib/fmt.dev.git diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml deleted file mode 100644 index 5b4e213a0d3a..000000000000 --- a/.github/workflows/linux.yml +++ /dev/null @@ -1,116 +0,0 @@ -name: linux - -on: [push, pull_request] - -permissions: - contents: read - -jobs: - build: - runs-on: ubuntu-20.04 - strategy: - matrix: - cxx: [g++-4.8, g++-10, clang++-9] - build_type: [Debug, Release] - std: [11] - include: - - cxx: g++-4.8 - install: sudo apt install g++-4.8 - - cxx: g++-8 - build_type: Debug - std: 14 - install: sudo apt install g++-8 - - cxx: g++-8 - build_type: Debug - std: 17 - install: sudo apt install g++-8 - - cxx: g++-9 - build_type: Debug - std: 17 - - cxx: g++-10 - build_type: Debug - std: 17 - - cxx: g++-11 - build_type: Debug - std: 20 - install: sudo apt install g++-11 - - cxx: clang++-8 - build_type: Debug - std: 17 - cxxflags: -stdlib=libc++ - install: sudo apt install clang-8 libc++-8-dev libc++abi-8-dev - - cxx: clang++-9 - install: sudo apt install clang-9 - - cxx: clang++-9 - build_type: Debug - fuzz: -DFMT_FUZZ=ON -DFMT_FUZZ_LINKMAIN=ON - std: 17 - install: sudo apt install clang-9 - - cxx: clang++-11 - build_type: Debug - std: 20 - - cxx: clang++-11 - build_type: Debug - std: 20 - cxxflags: -stdlib=libc++ - install: sudo apt install libc++-11-dev libc++abi-11-dev - - shared: -DBUILD_SHARED_LIBS=ON - - steps: - - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 - - - name: Set timezone - run: sudo timedatectl set-timezone 'Asia/Yekaterinburg' - - - name: Add repositories for older GCC - run: | - # Below two repos provide GCC 4.8, 5.5 and 6.4 - sudo apt-add-repository 'deb http://azure.archive.ubuntu.com/ubuntu/ bionic main' - sudo apt-add-repository 'deb http://azure.archive.ubuntu.com/ubuntu/ bionic universe' - # Below two repos additionally update GCC 6 to 6.5 - # sudo apt-add-repository 'deb http://azure.archive.ubuntu.com/ubuntu/ bionic-updates main' - # sudo apt-add-repository 'deb http://azure.archive.ubuntu.com/ubuntu/ bionic-updates universe' - if: ${{ matrix.cxx == 'g++-4.8' }} - - - name: Add repositories for newer GCC - run: | - sudo apt-add-repository ppa:ubuntu-toolchain-r/test - if: ${{ matrix.cxx == 'g++-11' }} - - - name: Add Ubuntu mirrors - run: | - # Github Actions caching proxy is at times unreliable - # see https://github.com/actions/runner-images/issues/7048 - printf 'http://azure.archive.ubuntu.com/ubuntu\tpriority:1\n' | sudo tee /etc/apt/mirrors.txt - curl http://mirrors.ubuntu.com/mirrors.txt | sudo tee --append /etc/apt/mirrors.txt - sudo sed -i 's~http://azure.archive.ubuntu.com/ubuntu/~mirror+file:/etc/apt/mirrors.txt~' /etc/apt/sources.list - - - name: Create Build Environment - run: | - sudo apt update - ${{matrix.install}} - sudo apt install locales-all - cmake -E make_directory ${{runner.workspace}}/build - - - name: Configure - working-directory: ${{runner.workspace}}/build - env: - CXX: ${{matrix.cxx}} - CXXFLAGS: ${{matrix.cxxflags}} - run: | - cmake -DCMAKE_BUILD_TYPE=${{matrix.build_type}} ${{matrix.fuzz}} ${{matrix.shared}} \ - -DCMAKE_CXX_STANDARD=${{matrix.std}} -DFMT_DOC=OFF \ - -DCMAKE_CXX_VISIBILITY_PRESET=hidden -DCMAKE_VISIBILITY_INLINES_HIDDEN=ON \ - -DFMT_PEDANTIC=ON -DFMT_WERROR=ON $GITHUB_WORKSPACE - - - name: Build - working-directory: ${{runner.workspace}}/build - run: | - threads=`nproc` - cmake --build . --config ${{matrix.build_type}} --parallel $threads - - - name: Test - working-directory: ${{runner.workspace}}/build - run: ctest -C ${{matrix.build_type}} - env: - CTEST_OUTPUT_ON_FAILURE: True diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml deleted file mode 100644 index 1972cce52920..000000000000 --- a/.github/workflows/macos.yml +++ /dev/null @@ -1,54 +0,0 @@ -name: macos - -on: [push, pull_request] - -permissions: - contents: read - -jobs: - build: - strategy: - matrix: - os: [macos-13, macos-14] - build_type: [Debug, Release] - std: [11, 17, 20] - exclude: - - { os: macos-13, std: 11 } - - { os: macos-13, std: 17 } - include: - - shared: -DBUILD_SHARED_LIBS=ON - - runs-on: '${{ matrix.os }}' - - steps: - - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 - - - name: Set timezone - run: sudo systemsetup -settimezone 'Asia/Yekaterinburg' - - - name: Select Xcode 14.3 (macOS 13) - run: sudo xcode-select -s "/Applications/Xcode_14.3.app" - if: ${{ matrix.os == 'macos-13' }} - - - name: Create Build Environment - run: cmake -E make_directory ${{runner.workspace}}/build - - - name: Configure - working-directory: ${{runner.workspace}}/build - run: | - cmake -DCMAKE_BUILD_TYPE=${{matrix.build_type}} ${{matrix.shared}} \ - -DCMAKE_CXX_STANDARD=${{matrix.std}} \ - -DCMAKE_CXX_VISIBILITY_PRESET=hidden -DCMAKE_VISIBILITY_INLINES_HIDDEN=ON \ - -DFMT_DOC=OFF -DFMT_PEDANTIC=ON -DFMT_WERROR=ON $GITHUB_WORKSPACE - - - name: Build - working-directory: ${{runner.workspace}}/build - run: | - threads=`sysctl -n hw.logicalcpu` - cmake --build . --config ${{matrix.build_type}} --parallel $threads - - - name: Test - working-directory: ${{runner.workspace}}/build - run: ctest -C ${{matrix.build_type}} - env: - CTEST_OUTPUT_ON_FAILURE: True diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml deleted file mode 100644 index 014396b9461c..000000000000 --- a/.github/workflows/windows.yml +++ /dev/null @@ -1,100 +0,0 @@ -name: windows - -on: [push, pull_request] - -permissions: - contents: read - -jobs: - build: - runs-on: ${{matrix.os}} - strategy: - matrix: - # windows-2019 has MSVC 2019 installed; - # windows-2022 has MSVC 2022 installed: - # https://github.com/actions/virtual-environments. - os: [windows-2019] - platform: [Win32, x64] - toolset: [v140, v141, v142] - standard: [14, 17, 20] - shared: ["", -DBUILD_SHARED_LIBS=ON] - build_type: [Debug, Release] - exclude: - - { toolset: v140, standard: 17 } - - { toolset: v140, standard: 20 } - - { toolset: v141, standard: 14 } - - { toolset: v141, standard: 20 } - - { toolset: v142, standard: 14 } - - { platform: Win32, toolset: v140 } - - { platform: Win32, toolset: v141 } - - { platform: Win32, standard: 14 } - - { platform: Win32, standard: 20 } - - { platform: x64, toolset: v140, shared: -DBUILD_SHARED_LIBS=ON } - - { platform: x64, toolset: v141, shared: -DBUILD_SHARED_LIBS=ON } - - { platform: x64, standard: 14, shared: -DBUILD_SHARED_LIBS=ON } - - { platform: x64, standard: 20, shared: -DBUILD_SHARED_LIBS=ON } - include: - - os: windows-2022 - platform: x64 - toolset: v143 - build_type: Debug - standard: 20 - - steps: - - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 - - - name: Set timezone - run: tzutil /s "Ekaterinburg Standard Time" - - - name: Create Build Environment - run: cmake -E make_directory ${{runner.workspace}}/build - - - name: Configure - # Use a bash shell for $GITHUB_WORKSPACE. - shell: bash - working-directory: ${{runner.workspace}}/build - run: | - cmake -A ${{matrix.platform}} -T ${{matrix.toolset}} \ - -DCMAKE_CXX_STANDARD=${{matrix.standard}} \ - ${{matrix.shared}} -DCMAKE_BUILD_TYPE=${{matrix.build_type}} \ - $GITHUB_WORKSPACE - - - name: Build - working-directory: ${{runner.workspace}}/build - run: | - $threads = (Get-CimInstance Win32_ComputerSystem).NumberOfLogicalProcessors - cmake --build . --config ${{matrix.build_type}} --parallel $threads - - - name: Test - working-directory: ${{runner.workspace}}/build - run: ctest -C ${{matrix.build_type}} -V - env: - CTEST_OUTPUT_ON_FAILURE: True - - mingw: - runs-on: windows-latest - defaults: - run: - shell: msys2 {0} - strategy: - matrix: - sys: [ mingw64, ucrt64 ] - steps: - - name: Set timezone - run: tzutil /s "Ekaterinburg Standard Time" - shell: cmd - - uses: msys2/setup-msys2@d0e80f58dffbc64f6a3a1f43527d469b4fc7b6c8 # v2.23.0 - with: - release: false - msystem: ${{matrix.sys}} - pacboy: cc:p cmake:p ninja:p lld:p - - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 - - name: Configure - run: cmake -B ../build -DBUILD_SHARED_LIBS=ON -DCMAKE_BUILD_TYPE=Debug - env: { LDFLAGS: -fuse-ld=lld } - - name: Build - run: cmake --build ../build - - name: Test - run: ctest -j `nproc` --test-dir ../build - env: - CTEST_OUTPUT_ON_FAILURE: True diff --git a/.github/workflows/zig.yml b/.github/workflows/zig.yml new file mode 100644 index 000000000000..9d727851fa99 --- /dev/null +++ b/.github/workflows/zig.yml @@ -0,0 +1,37 @@ +name: Zig Build + +on: [push] + +jobs: + build: + strategy: + fail-fast: false + matrix: + targets: + - x86_64-linux-gnu + - x86_64-linux-musl + - x86-linux-gnu + - x86-linux-musl + - aarch64-linux-gnu + - aarch64-linux-musl + - riscv64-linux-musl + - mipsel-linux-musl + - mips-linux-musl + - powerpc64-linux-musl + - x86_64-macos + - aarch64-macos + - x86_64-windows + # - x86_64-windows-msvc + - x86-windows + - aarch64-windows + + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + fetch-depth: 0 + - uses: mlugg/setup-zig@v1 + + - name: Build Summary ${{ matrix.targets }} + run: zig build -DTests --summary all -freference-trace -Dtarget=${{ matrix.targets }} diff --git a/.gitignore b/.gitignore index 2635026a69db..2a702c4207a2 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,5 @@ build/ cmake_install.cmake fmt-*.cmake fmt.pc + +*zig-*/ \ No newline at end of file diff --git a/build.zig b/build.zig new file mode 100644 index 000000000000..2f7ea6bc3ef3 --- /dev/null +++ b/build.zig @@ -0,0 +1,233 @@ +//! fmtlib for Zig Package Manager (MVP) +//! Download [Zig v0.11 or higher](https://ziglang.org/download) + +const std = @import("std"); +const Path = std.Build.LazyPath; + +pub fn build(b: *std.Build) void { + const target = b.standardTargetOptions(.{}); + const optimize = b.standardOptimizeOption(.{}); + + // Options + const shared = b.option(bool, "Shared", "Build the Shared Library [default: false]") orelse false; + const tests = b.option(bool, "Tests", "Build tests [default: false]") orelse false; + + const lib = if (shared) b.addSharedLibrary(.{ + .name = "fmt", + .target = target, + .optimize = optimize, + .version = .{ + .major = 11, + .minor = 0, + .patch = 0, + }, + }) else b.addStaticLibrary(.{ + .name = "fmt", + .target = target, + .optimize = optimize, + }); + lib.addCSourceFiles(.{ + .files = src, + .flags = &.{ + "-Wall", + "-Wextra", + }, + }); + lib.addIncludePath(b.path("include")); + if (optimize == .Debug or optimize == .ReleaseSafe) + lib.bundle_compiler_rt = true + else + lib.root_module.strip = true; + if (lib.linkage == .static) + lib.pie = true; + if (lib.rootModuleTarget().abi != .msvc) + lib.linkLibCpp() // static-linking LLVM-libcxx (all platforms) + else + lib.linkLibC(); + lib.installHeadersDirectory(b.path("include"), "", .{}); + b.installArtifact(lib); + + if (tests) { + buildTest(b, .{ + .optimize = optimize, + .target = target, + .lib = lib, + .path = "test/args-test.cc", + }); + buildTest(b, .{ + .optimize = optimize, + .target = target, + .lib = lib, + .path = "test/base-test.cc", + }); + buildTest(b, .{ + .optimize = optimize, + .target = target, + .lib = lib, + .path = "test/unicode-test.cc", + }); + buildTest(b, .{ + .optimize = optimize, + .target = target, + .lib = lib, + .path = "test/assert-test.cc", + }); + buildTest(b, .{ + .optimize = optimize, + .target = target, + .lib = lib, + .path = "test/std-test.cc", + }); + buildTest(b, .{ + .optimize = optimize, + .target = target, + .lib = lib, + .path = "test/xchar-test.cc", + }); + buildTest(b, .{ + .optimize = optimize, + .target = target, + .lib = lib, + .path = "test/ostream-test.cc", + }); + buildTest(b, .{ + .optimize = optimize, + .target = target, + .lib = lib, + .path = "test/printf-test.cc", + }); + // buildTest(b, .{ + // .optimize = optimize, + // .target = target, + // .lib = lib, + // .path = "test/scan-test.cc", + // }); + buildTest(b, .{ + .optimize = optimize, + .target = target, + .lib = lib, + .path = "test/ranges-test.cc", + }); + buildTest(b, .{ + .optimize = optimize, + .target = target, + .lib = lib, + .path = "test/color-test.cc", + }); + buildTest(b, .{ + .optimize = optimize, + .target = target, + .lib = lib, + .path = "test/chrono-test.cc", + }); + buildTest(b, .{ + .optimize = optimize, + .target = target, + .lib = lib, + .path = "test/compile-test.cc", + }); + buildTest(b, .{ + .optimize = optimize, + .target = target, + .lib = lib, + .path = "test/compile-fp-test.cc", + }); + buildTest(b, .{ + .optimize = optimize, + .target = target, + .lib = lib, + .path = "test/format-test.cc", + }); + buildTest(b, .{ + .optimize = optimize, + .target = target, + .lib = lib, + .path = "test/os-test.cc", + }); + buildTest(b, .{ + .optimize = optimize, + .target = target, + .lib = lib, + .path = "test/noexception-test.cc", + }); + buildTest(b, .{ + .optimize = optimize, + .target = target, + .lib = lib, + .path = "test/posix-mock-test.cc", + }); + // don't work + // buildTest(b, .{ + // .optimize = optimize, + // .target = target, + // .lib = lib, + // .path = "test/module-test.cc", + // }); + } +} + +fn buildTest(b: *std.Build, info: BuildInfo) void { + const test_exe = b.addExecutable(.{ + .name = info.filename(), + .optimize = info.optimize, + .target = info.target, + }); + test_exe.addIncludePath(b.path("include")); + test_exe.addIncludePath(b.path("test")); + test_exe.addIncludePath(b.path("test/gtest")); + test_exe.addCSourceFile(.{ + .file = b.path(info.path), + .flags = &.{}, + }); + test_exe.addCSourceFiles(.{ + .files = test_src, + .flags = &.{ + "-Wall", + "-Wextra", + "-Wno-deprecated-declarations", + }, + }); + test_exe.defineCMacro("_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING", "1"); + test_exe.defineCMacro("GTEST_HAS_PTHREAD", "0"); + test_exe.linkLibrary(info.lib); + if (test_exe.rootModuleTarget().abi != .msvc) + test_exe.linkLibCpp() + else + test_exe.linkLibC(); + b.installArtifact(test_exe); + + const run_cmd = b.addRunArtifact(test_exe); + run_cmd.step.dependOn(b.getInstallStep()); + if (b.args) |args| { + run_cmd.addArgs(args); + } + + const run_step = b.step( + b.fmt("{s}", .{info.filename()}), + b.fmt("Run the {s} test", .{info.filename()}), + ); + run_step.dependOn(&run_cmd.step); +} + +const src: []const []const u8 = &.{ + "src/format.cc", + "src/os.cc", +}; +const test_src: []const []const u8 = &.{ + "test/gtest/gmock-gtest-all.cc", + "test/gtest-extra.cc", + "test/enforce-checks-test.cc", + "test/util.cc", +}; + +const BuildInfo = struct { + lib: *std.Build.Step.Compile, + optimize: std.builtin.OptimizeMode, + target: std.Build.ResolvedTarget, + path: []const u8, + + fn filename(self: BuildInfo) []const u8 { + var split = std.mem.splitSequence(u8, std.fs.path.basename(self.path), "."); + return split.first(); + } +};