NAME

Alien::Xmake - Locate, Download, or Build and Install Xmake

SYNOPSIS

use Alien::Xmake;

my $xmake = Alien::Xmake->new;

print $xmake->version;         # v3.0.6
print $xmake->buildid;         # HEAD.9fdcf69f6

$xmake->show('platforms');     # @platforms = ('windows', 'linux', ...)
$xmake->show('targets', format => 'json');   # decoded JSON structure

$xmake->create('hello', template => 'console');   # scaffold a project
$xmake->configure(mode => 'debug');               # configure a build
$xmake->build;                                    # build it
$xmake->run;                                      # run the target

system $xmake->exe, '--help';
system $xmake->xrepo, qw[info libpng];

DESCRIPTION

Xmake is a lightweight, cross-platform build utility based on Lua. It uses a Lua script to maintain project builds, but is driven by a dependency-free core program written in C. Compared with Makefiles or CMake, the configuration syntax is (in the opinion of the author) much more concise and intuitive. As such, it's friendly to novices while still maintaining the flexibly required in a build system. With Xmake, you can focus on your project instead of the build.

Xmake can be used to directly build source code (like with Make or Ninja), or it can generate project source files like CMake or Meson. It also has a built-in package management system to help users integrate C/C++ dependencies.

If you want to know more, please refer to the Documentation, GitHub, or Gitee. You are also welcome to join the community.

METHODS

A thin wrapper around the xmake command line. Methods named after xmake actions (build, clean, create, ...) stream the command's output to your terminal and return true on success. Query-style methods (show, lua -l, ...) capture the output and return it to you instead. Most methods accept %options; unrecognized extra arguments can be passed with targets => [...] and args => [...] and are appended to the command line verbatim.

new( ... )

my $xmake = Alien::Xmake->new( verbose => 1 );

Creates a new instance.

build( [$target], %options )

$xmake->build;                             # build the default targets
$xmake->build('hello', all => 1);          # also build dependent targets of hello
$xmake->build( rebuild => 1, jobs => 8 );

Compiles the targets defined in xmake.lua.

clean( [$target], %options )

$xmake->clean;
$xmake->clean( all => 1 );

Removes the build artifacts. all cleans dependent targets, group restricts to a target group.

create( $name, %options )

$xmake->create('hello', template => 'console');
$xmake->create('libz', template => 'shared', language => 'c');

Generates a new project directory named $name (clone of xmake create).

configure( %options )

$xmake->configure(mode => 'debug', plat => 'windows', arch => 'x64');

Configures the current project (clone of xmake config). Accepts the shared platform/toolchain options (plat, arch, mode, kind, toolchain, toolchain_host, cross, target_os, sdk, runtimes, vs, vs_toolset, vs_sdkver, vs_runtime, ndk, ndk_stdcxx, ndk_sdkver, android_sdk, mingw, emsdk, cuda, qt, qt_host, vcpkg, wdk, build_toolver, ccache, ccachedir, debugger, trybuild, tryconfigs, require, includedirs, linkdirs, links, syslinks, rc*, fc*, ...) as well as the compiler/flag subtables cflags, cxflags, cxxflags, mflags, mmflags, mxflags, ldflags, arflags, asflags, shflags, and cuflags. Any --key=value pair can be passed via set => { key => value }.

global( %options )

$xmake->global(network => 'y', theme => 'default');
$xmake->global(vs => '2022');

Reads/writes global (user-level) configuration. Shares the platform/toolchain options from configure( ... ) that exist on global (android_sdk, build_toolver, cuda, emsdk, mingw, ndk, ndk_sdkver, qt, qt_host, vcpkg, vs, wdk).

install( [$target], %options )

$xmake->install;
$xmake->install('hello', installdir => './dist');

Installs the built binaries to a staging directory (DESTDIR).

uninstall( [$target], %options )

$xmake->uninstall;
$xmake->uninstall('hello');

Uninstalls installed binaries from the install directory. Supports installdir, bindir, libdir, includedir, group and admin.

package( [$target], %options )

$xmake->package;                                      # package release artifacts
$xmake->package('hello', outputdir => './dist');

Packages the built targets into distribution archives/installers. outputdir selects the destination, format the package format (-f, e.g. deb, rpm, nsis), all includes dependent targets, and homepage, description, url, version and shasum fill the package metadata.

pack( [$pkg], %options )

$xmake->pack('libpng', formats => ['zip', 'targz'], jobs => 4);

Bundles an installed package from the local package cache into distribution archives. outputdir selects the destination, formats the archive format(s) (zip, targz, ...), basename, autobuild and jobs tune the archive name, rebuild behavior and parallelism.

require( [$pkg], %options )

$xmake->require('libpng');
my $list = $xmake->require( list => 1 );
my $json = $xmake->require( 'libpng', depgraph => 1, format => 'json' );

Installs and manages the packages declared (or requested) for the current project.

run( [$target], %options )

$xmake->run;
$xmake->run('hello', args => [qw[--flag value]]);

Runs the build target (or the run script). debug attaches a debugger, all/group select targets, workdir sets the working directory (-w), jobs sets the parallelism and detach runs the target in the background. Extra program arguments go in args.

test( [$target], %options )

$xmake->test;
$xmake->test( 'hello', rebuild => 1 );

Runs the project's tests. group, workdir, jobs and rebuild behave as elsewhere.

update( [$version], %options )

$xmake->update;                           # update xmake itself
$xmake->update('v3.0.6', scriptonly => 1);

Updates the xmake installation. version optionally pins a version. scriptonly only updates the scripts (-s), integrate re-integrates the shell environment, force downloads even when up to date and uninstall flags the previous version for removal.

service( %options )

$xmake->service( start => 1, distcc => 1 );     # run the distcc service
$xmake->service( status => 1 );

Controls the built-in xmake services. One of start, stop, restart, status, connect, disconnect, reconnect, sync, clean; remote, distcc, ccache, add-user, rm-user, gen-token select or modify the service, host and session target a specific server/session, and logs/pull fetch server logs.

addon( [$name], %options )

$xmake->addon('gcc_flags', install => 1);
my $found = $xmake->addon('flags', search => 1);   # captured output

Installs, removes, lists or searches xmake addon packages (install, remove, list, search, upgrade). all applies an operation to every addon and force bypasses checks.

check( [$checker], %options )

my $list = $xmake->check( list => 1 );
$xmake->check('gcc_flags.logic');

Lists available checkers (captured) or runs a named check script. info explains a checker (captured).

doxygen( [$srcdir], %options )

$xmake->doxygen('./src', outputdir => './docs');

Generates Doxygen documentation for $srcdir. outputdir selects the documentation directory.

format( [$target], %options )

$xmake->format('hello', style => 'google');
$xmake->format( dry_run => 1, files => ['a.c', 'b.c'] );

Formats the project sources with clang-format. style chooses the style (google, llvm, ...), create writes a default .clang-format, dry_run only reports files that would change (-n), error treats style mismatches as errors (-e), files limits formatting to the given files, and all/group/jobs behave as elsewhere.

lua( [$script], %options )

my @scripts = $xmake->lua( list => 1 );
$xmake->lua('print(\"hello\")');

Runs a xmake Lua script. list lists the built-in scripts (captured), command runs the script argument as a command, deserialize records the output in the given format and stdin reads the script from standard input.

macro( [$name], %options )

$xmake->macro('mybuild', begin => 1);     # begin recording
$xmake->macro('mybuild', end => 1);       # and stop
my $list = $xmake->macro( list => 1 );

Records and replays the shell commands that follow (clone of xmake macro). begin/end control recording, show prints a recorded macro, list lists them (captured), delete/clear remove them and export/import move them between machines.

project( %options )

$xmake->project( kind => 'vsxmake' );
$xmake->project( kind => 'make', targets => ['hello'] );

Generates IDE/third-party project files (vs, vsxmake, make, cmake, compile_commands, ...). kind selects the generator, modes/archs restrict the configs to generate, target generates only for that target and lsp writes LSP-friendly output (compile_flags.txt or compile_commands.json).

repo( [$name], %options )

my $repos = $xmake->repo( list => 1 );
$xmake->repo('local_extra', add => 1, url => 'git@github.com:me/xmake-repo.git');

Manages custom package repositories. add, remove, update, clear and list select the operation (list returns captured output); global restricts the change to the global config; url and branch are used when adding.

show( [$list], %options )

my @platforms = $xmake->show('platforms');
my @targets   = $xmake->show('targets', format => 'json');
my $plain     = $xmake->show('targets', target => 'hello');

Shows information about the current project or the xmake installation.

watch( %options )

$xmake->watch( commands => 'xmake build' );
$xmake->watch( script => 'my_script.lua' );

Rebuilds (or runs) the project whenever source files change. commands holds the command to rerun (-c), script the path of the script to watch, watchdirs/plaindirs add extra watched/ignored directories, run reruns the given target and target the target to build. Arbitrary program arguments are passed via argv.

task( $name, %options )

$xmake->task('show', args => ['-l', 'toolchains']);

Generic escape hatch that runs any xmake task/plugin by name with %options, streaming output and returning success. Reach for this when a dedicated method doesn't exist yet.

version( )

my $ver = $xmake->version;

Returns the xmake version (e.g. v3.0.6).

buildid( )

my $build = $xmake->buildid;

Returns the xmake build stamp (e.g. HEAD.9fdcf69f6), if any.

config( )

my %conf  = %{ $xmake->config };
my $bin   = $xmake->config('bin');

Returns the install-time data stored by Alien::Xmake::ConfigData: the install type, install directory, and version. The details of the Alien::Xmake::ConfigData object created at install time describe the exact contents.

pkg_config( $package )

my $flags = $xmake->pkg_config('zlib');
# { cflags => '-I...', libs => '-L... -lz' }

Installs $package with xrepo install -y, then returns its compile/link flags via xrepo fetch.

install_type( )

Returns 'system' or 'shared'.

exe( )

system $xmake->exe;

Returns the full path to the Xmake executable.

xrepo( )

system $xmake->xrepo;

Returns the full path to the xrepo executable.

bin_dir( )

use Env qw[@PATH];
unshift @PATH, $xmake->bin_dir;

Returns the directory containing the Xmake executable; push it onto your PATH. For a 'system' install this step will not be required.

cflags( ), libs( ), dynamic_libs( )

Stubs returning empty values. Provided for compatibility with consumers that expect the standard Alien API surface; use pkg_config( ) or Alien::Xrepo for real flags.

alien_helper( )

use alienfile;
# ...
    [ '%{xmake}', 'install' ],

Returns a hashref of helpers: %{xmake} and %{xrepo}, suitable for use in alienfile recipes.

Alien::Base Helper

To use Xmake in your alienfiles, require this module and use %{xmake} and %{xrepo}.

use alienfile;
# ...
    [ '%{xmake}', 'install' ],
    [ '%{xrepo}', 'install ...' ]
# ...

Xmake Cookbook

Xmake is severely underrated so I'll add more nifty things here but for now just a quick example.

You're free to create your own projects, of course, but Xmake comes with the ability to generate an entire project for you:

$ xmake create -P hi    # generates a basic console project in C++ and xmake.lua build script
$ cd hi
$ xmake -y              # builds the project if required, installing defined prerequisite libs, etc.
$ xmake run             # runs the target binary which prints 'hello, world!'

xmake create is a lot like minil new in that it generates a new project for you that's ready to build even before you change anything. It even tosses a .gitignore file in. You can generate projects in C++, Go, Objective C, Rust, Swift, D, Zig, Vale, Pascal, Nim, Fortran, and more. You can also generate boilerplate projects for simple console apps, static and shared libraries, macOS bundles, GUI apps based on Qt or wxWidgets, IOS apps, and more.

See xmake create --help for a full list.

Prerequisites

Windows simply downloads an installer but elsewhere, you gotta have git, make, and a C compiler installed to build and install Xmake. If you'd like Alien::Xmake to use a pre-built or system install of Xmake, install it yourself first with one of the following:

See Also

https://xmake.io/

Demos for both xmake and xrepo in eg/.

LICENSE

Copyright (C) Sanko Robinson.

This library is free software; you can redistribute it and/or modify it under the terms found in the Artistic License 2. Other copyrights, terms, and conditions may apply to data transmitted through this module.

AUTHOR

Sanko Robinson https://github.com/sanko