Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ $ xcaddy build [<caddy_version>]
[--with <module[@version][=replacement]>...]
[--replace <module[@version]=replacement>...]
[--embed <[alias]:path/to/dir>...]
[--pgo <file>] # EXPERIMENTAL
```

- `<caddy_version>` is the core Caddy version to build; defaults to `CADDY_VERSION` env variable or latest.<br>
Expand All @@ -80,6 +81,8 @@ $ xcaddy build [<caddy_version>]

- `--embed` can be used to embed the contents of a directory into the Caddy executable. `--embed` can be passed multiple times with separate source directories. The source directory can be prefixed with a custom alias and a colon `:` to write the embedded files into an aliased subdirectory, which is useful when combined with the `root` directive and sub-directive.

- `--pgo` can be used to specify a file containing a profile to use for profile guided optimization. If a file named `default.pgo` is present in the current directory, it will automatically be used. This feature is new to xcaddy and is considered experimental.

#### Examples

```bash
Expand Down
11 changes: 11 additions & 0 deletions builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ type Builder struct {
Debug bool `json:"debug,omitempty"`
BuildFlags string `json:"build_flags,omitempty"`
ModFlags string `json:"mod_flags,omitempty"`
PgoProfile string `json:"pgo_profile,omitempty"` // Experimental

// Experimental: subject to change
EmbedDirs []struct {
Expand Down Expand Up @@ -76,6 +77,12 @@ func (b Builder) Build(ctx context.Context, outputFile string) error {
}
log.Printf("[INFO] absolute output file path: %s", absOutputFile)

// likewise with the PGO profile
absPgoProfile, err := filepath.Abs(b.PgoProfile)
if err != nil {
return err
}

// set some defaults from the environment, if applicable
if b.OS == "" {
b.OS = utils.GetGOOS()
Expand Down Expand Up @@ -153,6 +160,10 @@ func (b Builder) Build(ctx context.Context, outputFile string) error {
cmd, err := buildEnv.newGoBuildCommand(ctx, "build",
"-o", absOutputFile,
)
if b.PgoProfile != "" {
log.Printf("[INFO] using PGO profile %s", b.PgoProfile)
cmd.Args = append(cmd.Args, "-pgo="+absPgoProfile)
}
if err != nil {
return err
}
Expand Down
21 changes: 20 additions & 1 deletion cmd/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ func init() {
buildCommand.Flags().String("output", "", "change the output file name")
buildCommand.Flags().StringArray("replace", []string{}, "like --with but for Go modules")
buildCommand.Flags().StringArray("embed", []string{}, "embeds directories into the built Caddy executable to use with the `embedded` file-system")
buildCommand.Flags().String("pgo", "", "file containing profile for PGO (experimental)")
}

var versionCommand = &cobra.Command{
Expand All @@ -35,7 +36,8 @@ var buildCommand = &cobra.Command{
[--output <file>]
[--with <module[@version][=replacement]>...]
[--replace <module[@version]=replacement>...]
[--embed <[alias]:path/to/dir>...]`,
[--embed <[alias]:path/to/dir>...]
[--pgo <file>] # EXPERIMENTAL`,
Long: `
<caddy_version> is the core Caddy version to build; defaults to CADDY_VERSION env variable or latest.
This can be the keyword latest, which will use the latest stable tag, or any git ref such as:
Expand All @@ -52,6 +54,8 @@ Flags:
--replace is like --with, but does not add a blank import to the code; it only writes a replace directive to go.mod, which is useful when developing on Caddy's dependencies (ones that are not Caddy modules). Try this if you got an error when using --with, like cannot find module providing package.

--embed can be used to embed the contents of a directory into the Caddy executable. --embed can be passed multiple times with separate source directories. The source directory can be prefixed with a custom alias and a colon : to write the embedded files into an aliased subdirectory, which is useful when combined with the root directive and sub-directive.

--pgo is used to specify a specify a file containing a profile for profile-guided optimization (experimental)
`,
Short: "Compile custom caddy binaries",
Args: cobra.MaximumNArgs(1),
Expand All @@ -60,6 +64,7 @@ Flags:
var plugins []xcaddy.Dependency
var replacements []xcaddy.Replace
var embedDir []string
var pgo string
var argCaddyVersion string
if len(args) > 0 {
argCaddyVersion = args[0]
Expand Down Expand Up @@ -103,6 +108,19 @@ Flags:
if err != nil {
return fmt.Errorf("unable to parse --embed arguments: %s", err.Error())
}

// Experimental: If no --pgo flag is specified and a default.pgo file is found, use that for PGO
pgo, err = cmd.Flags().GetString("pgo")
if err != nil {
return fmt.Errorf("unable to parse --pgo arguments: %s", err.Error())
}
if pgo == "" {
_, err = os.Stat("default.pgo")
if err == nil {
pgo = "default.pgo"
}
}

// prefer caddy version from command line argument over env var
if argCaddyVersion != "" {
caddyVersion = argCaddyVersion
Expand All @@ -127,6 +145,7 @@ Flags:
Debug: buildDebugOutput,
BuildFlags: buildFlags,
ModFlags: modFlags,
PgoProfile: pgo,
}
for _, md := range embedDir {
if before, after, found := strings.Cut(md, ":"); found {
Expand Down
Loading