├── .gitignore ├── .goreleaser.yaml ├── LICENSE.md ├── README.md ├── app1 ├── go.mod └── main.go ├── app2 ├── Cargo.lock ├── Cargo.toml └── src │ └── main.rs └── app3 ├── build.zig ├── build.zig.zon └── src ├── main.zig └── root.zig /.gitignore: -------------------------------------------------------------------------------- 1 | .zig-cache 2 | zig-out/ 3 | target/ 4 | dist/ 5 | -------------------------------------------------------------------------------- /.goreleaser.yaml: -------------------------------------------------------------------------------- 1 | # This is an example .goreleaser.yml file with some sensible defaults. 2 | # Make sure to check the documentation at https://goreleaser.com 3 | 4 | # The lines below are called `modelines`. See `:help modeline` 5 | # Feel free to remove those if you don't want/need to use them. 6 | # yaml-language-server: $schema=https://goreleaser.com/static/schema.json 7 | # vim: set ts=2 sw=2 tw=0 fo=cnqoj 8 | version: 2 9 | project_name: example-multi-languages 10 | 11 | builds: 12 | - id: app1 13 | dir: app1 14 | binary: app1 15 | env: 16 | - CGO_ENABLED=0 17 | targets: 18 | - linux_amd64 19 | - id: app2 20 | dir: app2 21 | binary: app2 22 | builder: rust 23 | targets: 24 | - x86_64-unknown-linux-gnu 25 | - id: app3 26 | dir: app3 27 | binary: app3 28 | builder: zig 29 | targets: 30 | - x86_64-linux 31 | 32 | archives: 33 | - id: app_archive 34 | format: binary 35 | builds: 36 | - app1 37 | - app2 38 | - app3 39 | # this name template makes the OS and Arch compatible with the results of `uname`. 40 | name_template: >- 41 | {{ .Binary }}_ 42 | {{- title .Os }}_ 43 | {{- if eq .Arch "amd64" }}x86_64 44 | {{- else if eq .Arch "386" }}i386 45 | {{- else }}{{ .Arch }}{{ end }} 46 | {{- if .Arm }}v{{ .Arm }}{{ end }} 47 | 48 | nfpms: 49 | - id: combined 50 | package_name: combined 51 | builds: 52 | - app1 53 | - app2 54 | - app3 55 | vendor: blah 56 | homepage: blah.com 57 | maintainer: blah 58 | description: |- 59 | app1 and app2 60 | license: MIT 61 | formats: 62 | - deb 63 | - rpm 64 | 65 | changelog: 66 | sort: asc 67 | filters: 68 | exclude: 69 | - "^docs:" 70 | - "^test:" 71 | 72 | release: 73 | footer: >- 74 | 75 | --- 76 | 77 | Released by [GoReleaser](https://github.com/goreleaser/goreleaser). 78 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Carlos Alexandro Becker 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # example-multi-language 2 | 3 | This example uses all 3 currently available builders: Go, Rust, and Zig. 4 | -------------------------------------------------------------------------------- /app1/go.mod: -------------------------------------------------------------------------------- 1 | module app1 2 | 3 | go 1.22.10 4 | -------------------------------------------------------------------------------- /app1/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | fmt.Println("app1") 7 | } 8 | -------------------------------------------------------------------------------- /app2/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 4 4 | 5 | [[package]] 6 | name = "app2" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /app2/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "app2" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | -------------------------------------------------------------------------------- /app2/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | println!("app2"); 3 | } 4 | -------------------------------------------------------------------------------- /app3/build.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | 3 | // Although this function looks imperative, note that its job is to 4 | // declaratively construct a build graph that will be executed by an external 5 | // runner. 6 | pub fn build(b: *std.Build) void { 7 | // Standard target options allows the person running `zig build` to choose 8 | // what target to build for. Here we do not override the defaults, which 9 | // means any target is allowed, and the default is native. Other options 10 | // for restricting supported target set are available. 11 | const target = b.standardTargetOptions(.{}); 12 | 13 | // Standard optimization options allow the person running `zig build` to select 14 | // between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall. Here we do not 15 | // set a preferred release mode, allowing the user to decide how to optimize. 16 | const optimize = b.standardOptimizeOption(.{}); 17 | 18 | const lib = b.addStaticLibrary(.{ 19 | .name = "app3", 20 | // In this case the main source file is merely a path, however, in more 21 | // complicated build scripts, this could be a generated file. 22 | .root_source_file = b.path("src/root.zig"), 23 | .target = target, 24 | .optimize = optimize, 25 | }); 26 | 27 | // This declares intent for the library to be installed into the standard 28 | // location when the user invokes the "install" step (the default step when 29 | // running `zig build`). 30 | b.installArtifact(lib); 31 | 32 | const exe = b.addExecutable(.{ 33 | .name = "app3", 34 | .root_source_file = b.path("src/main.zig"), 35 | .target = target, 36 | .optimize = optimize, 37 | }); 38 | 39 | // This declares intent for the executable to be installed into the 40 | // standard location when the user invokes the "install" step (the default 41 | // step when running `zig build`). 42 | b.installArtifact(exe); 43 | 44 | // This *creates* a Run step in the build graph, to be executed when another 45 | // step is evaluated that depends on it. The next line below will establish 46 | // such a dependency. 47 | const run_cmd = b.addRunArtifact(exe); 48 | 49 | // By making the run step depend on the install step, it will be run from the 50 | // installation directory rather than directly from within the cache directory. 51 | // This is not necessary, however, if the application depends on other installed 52 | // files, this ensures they will be present and in the expected location. 53 | run_cmd.step.dependOn(b.getInstallStep()); 54 | 55 | // This allows the user to pass arguments to the application in the build 56 | // command itself, like this: `zig build run -- arg1 arg2 etc` 57 | if (b.args) |args| { 58 | run_cmd.addArgs(args); 59 | } 60 | 61 | // This creates a build step. It will be visible in the `zig build --help` menu, 62 | // and can be selected like this: `zig build run` 63 | // This will evaluate the `run` step rather than the default, which is "install". 64 | const run_step = b.step("run", "Run the app"); 65 | run_step.dependOn(&run_cmd.step); 66 | 67 | // Creates a step for unit testing. This only builds the test executable 68 | // but does not run it. 69 | const lib_unit_tests = b.addTest(.{ 70 | .root_source_file = b.path("src/root.zig"), 71 | .target = target, 72 | .optimize = optimize, 73 | }); 74 | 75 | const run_lib_unit_tests = b.addRunArtifact(lib_unit_tests); 76 | 77 | const exe_unit_tests = b.addTest(.{ 78 | .root_source_file = b.path("src/main.zig"), 79 | .target = target, 80 | .optimize = optimize, 81 | }); 82 | 83 | const run_exe_unit_tests = b.addRunArtifact(exe_unit_tests); 84 | 85 | // Similar to creating the run step earlier, this exposes a `test` step to 86 | // the `zig build --help` menu, providing a way for the user to request 87 | // running the unit tests. 88 | const test_step = b.step("test", "Run unit tests"); 89 | test_step.dependOn(&run_lib_unit_tests.step); 90 | test_step.dependOn(&run_exe_unit_tests.step); 91 | } 92 | -------------------------------------------------------------------------------- /app3/build.zig.zon: -------------------------------------------------------------------------------- 1 | .{ 2 | // This is the default name used by packages depending on this one. For 3 | // example, when a user runs `zig fetch --save `, this field is used 4 | // as the key in the `dependencies` table. Although the user can choose a 5 | // different name, most users will stick with this provided value. 6 | // 7 | // It is redundant to include "zig" in this name because it is already 8 | // within the Zig package namespace. 9 | .name = "app3", 10 | 11 | // This is a [Semantic Version](https://semver.org/). 12 | // In a future version of Zig it will be used for package deduplication. 13 | .version = "0.0.0", 14 | 15 | // This field is optional. 16 | // This is currently advisory only; Zig does not yet do anything 17 | // with this value. 18 | //.minimum_zig_version = "0.11.0", 19 | 20 | // This field is optional. 21 | // Each dependency must either provide a `url` and `hash`, or a `path`. 22 | // `zig build --fetch` can be used to fetch all dependencies of a package, recursively. 23 | // Once all dependencies are fetched, `zig build` no longer requires 24 | // internet connectivity. 25 | .dependencies = .{ 26 | // See `zig fetch --save ` for a command-line interface for adding dependencies. 27 | //.example = .{ 28 | // // When updating this field to a new URL, be sure to delete the corresponding 29 | // // `hash`, otherwise you are communicating that you expect to find the old hash at 30 | // // the new URL. 31 | // .url = "https://example.com/foo.tar.gz", 32 | // 33 | // // This is computed from the file contents of the directory of files that is 34 | // // obtained after fetching `url` and applying the inclusion rules given by 35 | // // `paths`. 36 | // // 37 | // // This field is the source of truth; packages do not come from a `url`; they 38 | // // come from a `hash`. `url` is just one of many possible mirrors for how to 39 | // // obtain a package matching this `hash`. 40 | // // 41 | // // Uses the [multihash](https://multiformats.io/multihash/) format. 42 | // .hash = "...", 43 | // 44 | // // When this is provided, the package is found in a directory relative to the 45 | // // build root. In this case the package's hash is irrelevant and therefore not 46 | // // computed. This field and `url` are mutually exclusive. 47 | // .path = "foo", 48 | 49 | // // When this is set to `true`, a package is declared to be lazily 50 | // // fetched. This makes the dependency only get fetched if it is 51 | // // actually used. 52 | // .lazy = false, 53 | //}, 54 | }, 55 | 56 | // Specifies the set of files and directories that are included in this package. 57 | // Only files and directories listed here are included in the `hash` that 58 | // is computed for this package. Only files listed here will remain on disk 59 | // when using the zig package manager. As a rule of thumb, one should list 60 | // files required for compilation plus any license(s). 61 | // Paths are relative to the build root. Use the empty string (`""`) to refer to 62 | // the build root itself. 63 | // A directory listed here means that all files within, recursively, are included. 64 | .paths = .{ 65 | "build.zig", 66 | "build.zig.zon", 67 | "src", 68 | // For example... 69 | //"LICENSE", 70 | //"README.md", 71 | }, 72 | } 73 | -------------------------------------------------------------------------------- /app3/src/main.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | 3 | pub fn main() !void { 4 | std.debug.print("app3\n", .{}); 5 | } 6 | -------------------------------------------------------------------------------- /app3/src/root.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | const testing = std.testing; 3 | 4 | export fn add(a: i32, b: i32) i32 { 5 | return a + b; 6 | } 7 | 8 | test "basic add functionality" { 9 | try testing.expect(add(3, 7) == 10); 10 | } 11 | --------------------------------------------------------------------------------