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 0.876 second using v1.01-cache-2.11-cpan-364913b4093 )