tonixxx

package module
v0.0.13 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 5, 2022 License: BSD-2-Clause-Views Imports: 16 Imported by: 0

README

tonixxx: cross-compiler shipyard

tonixxx-logo

EXAMPLE

$ cd examples/fewer

$ tonixxx boil
2018/12/30 23:22:56 Artifacts merged to ~/.tonixxx/fewer/bin

$ tree ~/.tonixxx/fewer/bin
~/.tonixxx/fewer/bin
├── freebsd-amd64
│   └── fewer
├── linux-glibc-2.24-amd64
│   └── fewer
├── linux-glibc-2.28-arm64
│   └── fewer
├── macos-amd64
│   └── fewer
├── windows-amd64
│   └── fewer.exe

API DOCUMENTATION

https://godoc.org/github.com/mcandre/tonixxx

DOWNLOAD

https://github.com/mcandre/tonixxx/releases

INSTALL FROM SOURCE

$ go install github.com/mcandre/tonixxx/cmd/tonixxx@latest

ABOUT

tonixxx assists developers in cross-compiling software projects. No need for dedicated hardware, nor dual booting, nor configuring obscure toolchains. Instead, tonixxx pours your code through arrays of Vagrant boxes, yielding robust, reliable binaries targeting assorted operating system kernel environments.

tonixxx chips away at integration surprises, testing the very limits of portability! For example, the C application fewer is written to closely match the C89/C99 standards, as opposed to newer standards, in order to support Windows and MirBSD builds. Without tonixxx, developers must rely on dedicated contributors to report any issues, compared to spotting issues early in the development process.

C89/C99 are just one way among many to structure your applications. If you really want to emphasize C11 and higher, then you can elect to drop Windows and MirBSD support. Remember, these are simply examples. tonixxx itself is agnostic of programming language and platforms, giving you the power to decide which software stacks and environments you want to end up using. It's great for automating software ports from your laptop or CI server!

See the examples directory for more demonstrative templates for building application ports.

  • C: fewer
  • C++: palindrome
  • D: potato
  • Haskell: mo
  • Rust: bronze

How to cross-compile your project with tonixxx

  1. List your build steps in a tonixxx.yaml file.
  2. Label your build bots.
  3. Run tonixxx boil.

See examples/ for more details on configuring tonixxx.yaml recipes and provisioning build bots for a variety of programming languages.

See tonixxx -help for more information on tonixxx invocation syntax.

Finally, sudo may be requisite for producing buildbot boxes for alternate architecture VM's, a known issue with vagrant-libvirt, but critically, sudo should be avoided when importing or running buildbots.

LICENSE

FreeBSD

RUNTIME REQUIREMENTS

  • Vagrant
  • vagrant-rsync-back
  • Relevant hypervisors for your configured Vagrant boxes (e.g. VirtualBox, VMware, qemu, Hyper-V)
  • Your choice of Vagrant boxes for targeted compilation, with synced folders enabled using rsync.
  • Sufficient available RAM and disk space for your Vagrant boxes

CONTRIBUTING

For more information on developing tonixxx itself, see DEVELOPMENT.md.

SEE ALSO

  • Cross-platform toolchains can be configured, though the process is fairly masochistic. May involve chroots.
  • Docker is a fantastic resource for projects targeting the Linux kernel (from different host operating systems!)
  • factorio generates Go application ports based on the standard Go toolchain
  • Go provides superb out-of-the-box cross-compilation features. As a matter of fact, tonixxx was inspired as a workaround in order to support cross-compilation for non-Go projects, including Rust, C, and C++.
  • libuv provides a cross-platform abstraction layer for C/C++ applications.
  • LLVM bitcode offers an abstract assembler format for C/C++ code.
  • mucus provides base VM's for managing alternate architectures
  • snek is a leaner, Docker-based cross-platform system
  • trust integrates CI systems with Rust ports.
  • tug automates multi-platform Docker image builds.
  • WASM provides a portable interface for C/C++ code.
  • xgo automates cross-compiling Go applications, including cgo apps with native dependencies.

DISCLAIMER

tonixxx is not magic, but simply a Go wrapper for Vagrant. It won't do the hard work of rewriting your application to support more platforms, but it will lower some barriers to cross-platform development.

  • Doesn't rely on soft links
  • Doesn't rely on sh/bat scripts
  • Doesn't erase your code when vagrant rsync-backing
  • Doesn't force you to use any particular build tools or build workflows
  • Does accelerate development and testing
  • Does support UNIX and Windows hosts, as well as UNIX and Windows targets
  • Does support configuration commenting
  • Works best with reasonably modern guests featuring preemptive multitasking
  • WSL hosts may present difficulties

Good luck and keep coding!

Documentation

Index

Constants

View Source
const (
	// GuestTypePOSIX designates POSIXy environments.
	GuestTypePOSIX = "POSIX"

	// GuestTypeCygwin designates cygwin-like environments.
	GuestTypeCygwin = "Cygwin"

	// GuestTypeSmartOSGZ designates SmartOS global zone environments.
	GuestTypeSmartOSGZ = "SmartOSGZ"

	// GuestTypeHaiku designates Haiku environments.
	GuestTypeHaiku = "Haiku"
)
View Source
const BuildbotsBasename = "buildbot-src"

BuildbotsBasename describes the base path for housing buildbot provisioning files, which aids tonixxx in excluding these (potentially large files) from recipe clones during project builds with tonixxx up and tonixxx boil.

View Source
const ConfigBasename = "tonixxx.yaml"

ConfigBasename provides the default filename for tonixxx configuration.

View Source
const DataBasename = ".tonixxx"

DataBasename describes the base path for housing tonixxx project metadata, including user build artifacts/ and Vagrant boxes during the build process.

View Source
const DefaultMaxRunningRecipes = 1

DefaultMaxRunningRecipes constrains the number of simultaneously running Vagrant boxes, in order to reduce resource strain on limited host hardware.

View Source
const DefaultOutputDirectory = "bin"

DefaultOutputDirectory locates project-wide binary aggregation at the end of a build, relative to the tonixxx per-project metadata directory.

View Source
const MaxRecipesKey = "TONIXXX_MAX_RECIPES"

MaxRecipesKey names the host environment variable for restricting the number of simultaneously running recipes, in order to reduce resource strain on limited host hardware.

View Source
const SyncKey = "TONIXXX_SYNC"

SyncKey names the guest environment variable for introspecting a VM's synced folder guest path.

View Source
const VagrantMetadataDirectory = ".vagrant"

VagrantMetadataDirectory refers to the standard directory for housing internal Vagrant files.

View Source
const VagrantSyncedFolderCygwin = "/c/vagrant"

VagrantSyncedFolderCygwin names the guest folder synced with the host, with the guest folder in UNIX-style forwardslash notation.

View Source
const VagrantSyncedFolderHaiku = "/boot/vagrant-src"

VagrantSyncedFolderHaiku names the guest folder synced with the host for Haiku OS VMs.

View Source
const VagrantSyncedFolderPOSIX = "/vagrant"

VagrantSyncedFolderPOSIX names the guest folder synced with the host for POSIXy VMs.

View Source
const VagrantSyncedFolderSmartOSGZ = "/opt/vagrant"

VagrantSyncedFolderSmartOSGZ names the guest folder synced with the host for SmartOS global zone VMs.

View Source
const VagrantfileBasename = "Vagrantfile"

VagrantfileBasename refers to the standard configuration file basename for configuring Vagrant boxes.

View Source
const Version = "0.0.13"

Version is semver.

Variables

View Source
var ImplicitRecipeExclusions = []*regexp.Regexp{
	regexp.MustCompile(BuildbotsBasename),
	regexp.MustCompile("\\.envrc"),
}

ImplicitRecipeExclusions names file patterns to be automatically ignored when copying a tonixxx project's files to per-recipe directories.

View Source
var ProjectNamePattern = regexp.MustCompile(`^[a-zA-Z0-9\.\-_]+$`)

ProjectNamePattern constrains names in order to use names as-is for file paths while building a project.

View Source
var RecipeLabelPattern = regexp.MustCompile(`^[a-zA-Z0-9\.\-_]+$`)

RecipeLabelPattern constrains labels in order to use label as-is for file paths while building a project.

View Source
var VagrantStatusRunningPattern = regexp.MustCompile("running")

VagrantStatusRunningPattern identifies when a Vagrant box is running.

Functions

func ConfigFile

func ConfigFile() (string, error)

ConfigFile names the host path to the tonixxx default configuration file.

func DataHome

func DataHome() (string, error)

DataHome provides the path to the per-user tonixxx data directory.

Types

type AtomicDeque added in v0.0.11

type AtomicDeque struct {
	// contains filtered or unexported fields
}

AtomicDeque provides a thread-safe Deque.

func NewAtomicDeque added in v0.0.11

func NewAtomicDeque() *AtomicDeque

NewAtomicDeque constructs an AtomicDeque.

func (*AtomicDeque) Append added in v0.0.11

func (o *AtomicDeque) Append(element interface{})

Append inserts an element into the deque.

func (*AtomicDeque) Pop added in v0.0.11

func (o *AtomicDeque) Pop() interface{}

Pop queries an end element from the deque and removes the element.

func (*AtomicDeque) Size added in v0.0.11

func (o *AtomicDeque) Size() int

Size queries the number of elements in the deque.

type Distillery

type Distillery struct {
	// Project distinguishes this build from other potential projects on the same host.
	//
	// Example: hello
	Project string `yaml:"project"`

	// OutputDirectory optionally specifices where build artifacts are found on guests.
	// If OutputDirectory is nil, then artifacts are not copied back to the host.
	//
	// Example: bin
	// Default: <nil>
	OutputDirectory *string `yaml:"outputdirectory"`

	// Steps enumerates build steps.
	//
	// Example: []string{"./configure", "make"}
	Steps []string `yaml:"steps"`

	// Recipes enumerates build bots.
	//
	// Example: []Recipe{Recipe{Label: "linux", Box: "ubuntu/xenial64"}}
	Recipes []Recipe `yaml:"recipes"`

	// Debug enables more logging.
	//
	// Example: true
	Debug bool `yaml:"debug"`

	// MaxRunningRecipes constrains the number of simultaneously running recipes.
	// Negative indicates no constraint.
	// Zero indicates unset configuration, which becomes DefaultMaxRunningRecipes.
	//
	// Example: 1
	MaxRunningRecipes int `yaml:"maxrunningrecipes"`
	// contains filtered or unexported fields
}

Distillery describes a multi-platform build configuration.

func Load added in v0.0.4

func Load(pth string) (*Distillery, error)

Load constructs a Distillery from a YAML file path.

func (*Distillery) Boil

func (o *Distillery) Boil() error

Boil executes configured recipes for a distillery.

func (Distillery) Clean

func (o Distillery) Clean() error

Clean destroys a project's Vagrant instances boxes and removes the project directory from ~/.tonixxx

func (Distillery) CleanRecipe

func (o Distillery) CleanRecipe(recipe Recipe, wg *sync.WaitGroup)

CleanRecipe destroys a recipe's Vagrant instance box and removes the recipe artifact directory under ~/.tonixxx

func (Distillery) Down

func (o Distillery) Down() error

Down pauses the configured Vagrant boxes.

func (Distillery) DownRecipe added in v0.0.4

func (o Distillery) DownRecipe(recipe Recipe, wg *sync.WaitGroup)

DownRecipe pauses a Vagrant box.

func (Distillery) ProjectArtifacts

func (o Distillery) ProjectArtifacts() (string, error)

ProjectArtifacts supplies the host path to the aggregated artifacts produced for a project after any Vagrant builds.

func (Distillery) ProjectData

func (o Distillery) ProjectData() (string, error)

ProjectData calculates the per-project tonixxx data directory based on a hash of the project directory absolute path.

func (*Distillery) UpdateRunningRecipe added in v0.0.11

func (o *Distillery) UpdateRunningRecipe(recipe Recipe, wg *sync.WaitGroup)

UpdateRunningRecipe collects information about a Vagrant instance.

func (*Distillery) UpdateRunningRecipes added in v0.0.4

func (o *Distillery) UpdateRunningRecipes() error

UpdateRunningRecipes collects information about Vagrant instances.

func (Distillery) Validate

func (o Distillery) Validate() error

Validate applies some semantic checks to a Distillery configuration.

type Recipe

type Recipe struct {
	// Label (required) provides a descriptor for the artifact produced by this recipe,
	// meaningful to a particular project to distinguish these artifacts
	// from those artifacts produced by sister recipes.
	//
	// Example: "minix-i386"
	Label string `yaml:"label"`

	// Box (required) describes a Vagrant box name.
	//
	// Example: "mcandre/minix"
	Box string `yaml:"box"`

	// Version (optional) describes a Vagrant box version.
	//
	// Example: "0.0.1"
	Version string `yaml:"version"`

	// Provider (optional) describes a hypervisor.
	//
	// Example: "libvirt"
	Provider string `yaml:"provider"`

	// GuestType (optional) describes the kind of guest OS.
	//
	// Defaults to GuestTypePOSIX.
	//
	// Example: "Cygwin"
	GuestType string `yaml:"guesttype"`

	// ArtifactsGuestPath (optional) names a directory path to place source files
	// into the guest before building.
	//
	// Defaults to a Vagrant rsync path based on known GuestType's.
	//
	// Example: "/vagrant"
	ArtifactsGuestPath string `yaml:"artifactguestpath"`

	// PreSteps (optional) lists any guest commands to execute before normal Steps.
	//
	// Example: []string{"sudo yum update"}
	PreSteps []string `yaml:"presteps"`

	// Steps (optional) lists the guest commands for building artifacts.
	//
	// Example: []string{"cd \"$TONIXXX_SYNC\"", "make"}
	Steps []string `yaml:"steps"`

	// PostSteps (optional) lists any guest commands to execute after normal Steps.
	//
	// Example: []string{"sudo yum clean all"}
	PostSteps []string `yaml:"poststeps"`
	// contains filtered or unexported fields
}

Recipe describes the user's build workflow for some target environment. By default, recipes assume "POSIX".

func (Recipe) AggregateSteps

func (o Recipe) AggregateSteps(steps []string) string

AggregateSteps constructs a logical whole command out of subcommands.

func (Recipe) ArtifactHost added in v0.0.4

func (o Recipe) ArtifactHost(effectiveOutputDirectory string) string

ArtifactHost supplies the directory where recipe-relative artifacts are first copied upon builds.

func (Recipe) Boil added in v0.0.4

func (o Recipe) Boil(effectiveOutputDirectory *string, debug bool) error

Boil executes build steps for a recipe.

The build steps may include instructions to copy select build artifacts to the SyncKey path. After a successful run of the build steps, any files in the SyncKey path are copied back to the host.

func (Recipe) Clean added in v0.0.4

func (o Recipe) Clean(wg *sync.WaitGroup)

Clean destroys a Vagrant instance and removes the per-recipe host directory.

func (Recipe) CloneHost added in v0.0.4

func (o Recipe) CloneHost() string

CloneHost supplies the directory path inside ~/.tonixxx in which a recipe's Vagrant clone resides.

func (Recipe) ConfigureEnvironmentVariable

func (o Recipe) ConfigureEnvironmentVariable(key string, value string) string

ConfigureEnvironmentVariable generates a shell command for configuring an environment variable.

func (Recipe) Destroy added in v0.0.4

func (o Recipe) Destroy() error

Destroy removes a recipe's Vagrant instance.

func (Recipe) EffectiveProvider added in v0.0.10

func (o Recipe) EffectiveProvider() string

EffectiveProvider calculates the appropriate default provider for a VM.

func (Recipe) EnsureRsync added in v0.0.4

func (o Recipe) EnsureRsync() error

EnsureRsync ensures that a Vagrant instance is running and that the host source is copied to the guest.

func (Recipe) EnsureSourceCopy added in v0.0.4

func (o Recipe) EnsureSourceCopy() error

EnsureSourceCopy ensures that project source files are copied to the clone host.

func (Recipe) EnsureVagrantfile added in v0.0.4

func (o Recipe) EnsureVagrantfile() error

EnsureVagrantfile ensures that this recipe has a Vagrantfile generated.

func (Recipe) GenerateVagrantfile

func (o Recipe) GenerateVagrantfile() string

GenerateVagrantfile supplies the text content of a Vagrantfile for instantiating a recipe.

func (Recipe) IsRunning added in v0.0.4

func (o Recipe) IsRunning() (bool, error)

IsRunning queries a Vagrant instance for running status.

func (Recipe) MergeArtifacts added in v0.0.4

func (o Recipe) MergeArtifacts(effectiveOutputDirectory string) error

MergeArtifacts copies recipe-relative build artifacts to a common, project-relative file tree.

func (Recipe) SyncedFolderGuestPath

func (o Recipe) SyncedFolderGuestPath() string

SyncedFolderGuestPath names the guest path for artifacts to be copied during building.

func (Recipe) VagrantDown added in v0.0.4

func (o Recipe) VagrantDown() error

VagrantDown ensures a recipe is halted.

func (Recipe) VagrantRsync added in v0.0.4

func (o Recipe) VagrantRsync() error

VagrantRsync copies host-clone source files into a guest in preparation for builds.

func (Recipe) VagrantRsyncBack added in v0.0.4

func (o Recipe) VagrantRsyncBack() error

VagrantRsyncBack copies guest artifacts back to a host-clone directory.

func (Recipe) VagrantSSH added in v0.0.4

func (o Recipe) VagrantSSH(step string, debug bool) error

VagrantSSH executes a guest command.

func (Recipe) VagrantStatus added in v0.0.4

func (o Recipe) VagrantStatus() (string, error)

VagrantStatus reports an instance description.

func (Recipe) VagrantUp added in v0.0.4

func (o Recipe) VagrantUp() error

VagrantUp ensures a recipe is booted.

func (Recipe) VagrantfilePath added in v0.0.4

func (o Recipe) VagrantfilePath() string

VagrantfilePath queries the path to this recipe's Vagrantfile.

func (Recipe) Validate

func (o Recipe) Validate() error

Validate applies some semantic checks to a Recipe configuration.

Directories

Path Synopsis
cmd
tonixxx command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL