Alien-Xmake-Project
view release on metacpan or search on metacpan
eg/xmake_project.pl view on Meta::CPAN
# This is a full walkthrough of Alien::Xmake::Project. Instead of hand-writing xmake.lua (Lua),
# describe the project with chained Perl method calls, save() the generated build file, and drive
# every stage (configure, build, clean) through the returned Alien::Xmake handle. The demo is
# self-contained (no external packages), so it builds offline with whatever compiler is present.
my $dir = Path::Tiny->tempdir;
my $orig = getcwd;
chdir $dir or die "chdir $dir: $!";
# src/main.cpp for the demo
path('src')->mkpath;
path('src/main.cpp')->spew_utf8(<<~'CPP');
#include <cstdio>
#include <string>
int main() {
std::puts("hello from Alien::Xmake::Project");
return 0;
}
CPP
my $p = Alien::Xmake::Project->new(
file => 'xmake.lua', # where save() writes the build file
yes => 1 # auto-confirm prompts (never hang on a TTY)
eg/xmake_project.pl view on Meta::CPAN
->add_files('src/main.cpp')
->add_defines('DEMO_VERSION="0.1.0"')
# when() scopes a group of statements behind a compile-time predicate
# (is_plat / is_os / is_arch / is_mode / ... or any Lua expression).
->when( 'is_plat("windows")', sub ($t) { $t->add_defines('WIN32_LEAN_AND_MEAN') } );
# write the build file and show what we generated
$p->save;
say 'Wrote xmake.lua';
say path('xmake.lua')->slurp_utf8;
# Drive it via Alien::Xmake handle
say 'Configuring (release)...';
die 'configure failed' unless $p->configure( mode => 'release' );
say 'Building...';
die 'build failed' unless $p->build;
say 'Running...';
$p->xmake->run;
say 'Querying available platforms...';
say " - $_" for $p->show('platforms');
t/001_project.t view on Meta::CPAN
my $comp = $x->component('runtime')->set_default('true')->on_installcmd('function (component) end');
isa_ok $comp, ['Alien::Xmake::Project::XpackComponent'], 'xpack component returns a builder';
my $tc = $p->toolchain('gcc')->set_kind('cross');
isa_ok $tc, ['Alien::Xmake::Project::Toolchain'], 'toolchain returns a Toolchain builder';
my $pk = $p->package('mypkg')->set_homepage('https://example.com')->on_install( 'windows', 'function (package) end' );
isa_ok $pk, ['Alien::Xmake::Project::Package'], 'package returns a Package builder';
my $n = $p->namespace( 'nn', 'add_rules("mode.release")' );
isa_ok $n, ['Alien::Xmake::Project::Namespace'], 'namespace returns a Namespace builder';
$p->save;
ok -f "$dir/xmake.lua", 'save wrote the build file';
my $lua = path("$dir/xmake.lua")->slurp_utf8;
like $lua, qr/set_project\("dsl"\)/, 'project line emitted';
like $lua, qr/set_xmakever\("2\.9\.1"\)/, 'xmakever emitted';
like $lua, qr/add_requires\("zlib", \{\["system"\]=true\}\)/, 'project require with opts emitted';
like $lua, qr/add_rules\("mode\.release", "mode\.debug"\)/, 'project rules emitted';
like $lua, qr/target\("cli"\)/, 'target emitted';
like $lua, qr/set_kind\("binary"\)/, 'kind emitted';
like $lua, qr/add_files\("src\/main\.cpp"\)/, 'files emitted';
like $lua, qr/set_languages\("c\+\+20"\)/, 'languages emitted';
like $lua, qr/set_warnings\("all"\)/, 'warnings emitted';
like $lua, qr/add_packages\("zlib"\)/, 'packages emitted';
t/001_project.t view on Meta::CPAN
ok $p->set_languages('c11') eq $p, 'root set_languages chains';
ok $p->set_toolchains('gcc') eq $p, 'root set_toolchains chains';
my $t = $p->target('lib');
ok $t->set_kind('static')->add_files('*.c') eq $t, 'policy target built';
ok $t->set_policy( 'build.merge_archive', !0 ) eq $t, 'set_policy chains';
ok $t->set_policy( 'build.ccache', !0 ) eq $t, 'set_policy(ccache) chains';
ok $t->add_rules( 'c++.unity_build', { batchsize => 16, uniqueid => 'UNITY' } ) eq $t, 'unity_build rule chains';
ok $t->set_configvar( 'PACKAGE_VERSION', '1.2.3', { quote => true } ) eq $t, 'set_configvar chains';
ok $t->add_configfiles( 'config.h.in', { variables => { PACKAGE_VERSION => '1.2.3' } } ) eq $t, 'add_configfiles chains';
$p->save;
my $lua = path("$dir/t8.lua")->slurp_utf8;
like $lua, qr/add_defines\("GLOBAL_DEF"\)/, 'root add_defines emitted';
like $lua, qr/set_arch\("x64"\)/, 'root set_arch emitted';
like $lua, qr/set_languages\("c11"\)/, 'root set_languages emitted';
like $lua, qr/set_toolchains\("gcc"\)/, 'root set_toolchains emitted';
like $lua, qr/set_policy\("build\.merge_archive", true\)/, 'policy rendered bare true';
like $lua, qr/set_policy\("build\.ccache", true\)/, 'ccache policy rendered';
like $lua, qr/add_rules\("c\+\+\.unity_build", \{\["batchsize"\]="16", \["uniqueid"\]="UNITY"\}\)/, 'unity rule + opts rendered';
like $lua, qr/set_configvar\("PACKAGE_VERSION", "1\.2\.3", \{\["quote"\]=true\}\)/, 'configvar rendered';
like $lua, qr/add_configfiles\("config\.h\.in",/, 'configfiles emitted';
like $lua, qr/\["PACKAGE_VERSION"\]="1\.2\.3"/, 'configfiles variable rendered';
};
#
subtest 'DSL project configures and builds' => sub {
mkdir "$dir/src" or die $!;
path("$dir/src/main.cpp")->spew_utf8("int main(){ return 0; }\n");
my $p = Alien::Xmake::Project->new( file => "$dir/xmake.lua" );
$p->add_requires('zlib');
$p->target('cli')->set_kind('binary')->add_files('src/main.cpp')->add_packages('zlib');
$p->save;
chdir $dir or die $!;
my $x = $p->xmake;
ok ref($x) eq 'Alien::Xmake', 'xmake returns an Alien::Xmake handle';
ok $x->configure( mode => 'release' ), 'configure reads the DSL-generated file';
my $targets = $x->show( 'targets', format => 'json' );
is $targets, ['cli'], 'targets reflect the DSL project';
ok $x->build, 'build succeeds from the DSL project';
my $ti = $x->target_info('cli');
is $ti->{kind}, 'binary', 'target_info reflects the DSL target';
ok $x->clean, 'clean from the DSL project';
chdir $old or die "chdir $old: $!";
};
#
subtest 'xpack packs install archives' => sub {
my $todo = todo 'xpack fails on Windows without proper archivers and this is not that important...';
mkdir "$dir/src" unless -d "$dir/src";
path("$dir/src/packmain.cpp")->spew_utf8("int main(){ return 0; }\n");
my $p = Alien::Xmake::Project->new( file => "$dir/pack.lua" );
my $t = $p->target('app');
$t->set_kind('binary')->add_files('src/packmain.cpp');
my $xp = $p->xpack('my_pack');
$xp->set_formats( 'zip', 'targz' );
$xp->set_title('Pack Demo');
$xp->set_author('Alien::Xmake');
$xp->add_targets('app');
$p->save;
my $lua = path("$dir/pack.lua")->slurp_utf8;
like $lua, qr/includes\("\@builtin\/xpack"\)/, 'xpack include emitted';
like $lua, qr/xpack\("my_pack"\)/, 'xpack wrapper emitted';
like $lua, qr/set_formats\("zip", "targz"\)/, 'formats emitted';
like $lua, qr/add_targets\("app"\)/, 'bundle target emitted';
chdir $dir or die $!;
my $x = $p->xmake;
ok $x->configure( mode => 'release' ), 'configure (xpack project)';
ok $x->build('app'), 'build before pack';
ok $x->pack( 'my_pack', jobs => 2 ), 'xmake pack runs';
ok -e "$dir/build/xpack/my_pack/my_pack.zip", 'zip archive produced';
t/001_project.t view on Meta::CPAN
ok !( $parsed_bool->{debug} ? 1 : 0 ), 'boolean false round-trips falsy';
# A plain integer scalar is intentionally rendered as a quoted string.
my $lua_int = Alien::Xmake::Project::Util::_lua_value( { count => 5 } );
like $lua_int, qr/\["count"\]\s*=\s*"5"/, 'plain integer scalar is quoted';
};
#
subtest 'DSL project convenience execution methods' => sub {
my $conv_dir = path( tempdir( CLEANUP => 1 ) );
mkdir "$conv_dir/src" or die $!;
path("$conv_dir/src/main.cpp")->spew_utf8("int main(){ return 0; }\n");
my $p = Alien::Xmake::Project->new( file => "$conv_dir/xmake.lua" );
$p->target('conv_cli')->set_kind('binary')->add_files('src/main.cpp');
chdir $conv_dir or die $!;
ok $p->configure( mode => 'release' ), 'direct configure auto-saves and succeeds';
ok -f "$conv_dir/xmake.lua", 'xmake.lua auto-saved';
ok $p->build, 'direct build succeeds';
my $ti = $p->target_info('conv_cli');
is $ti->{kind}, 'binary', 'direct target_info returns info';
ok $p->project('compile_commands'), 'direct project(compile_commands) succeeds';
ok -f "$conv_dir/compile_commands.json", 'compile_commands.json generated';
( run in 2.896 seconds using v1.01-cache-2.11-cpan-364913b4093 )