This is a KISS build tool for C projects, though it can be used for other things as well.
Way it works: you write down short configs for your projects in the form of a Perl hash and call a few methods to generate build scripts.
-
Shadow libs: all of your code is archived; thus, anything you want to reuse from any project managed by avtomat can simply be included and linked against -- no need to shuffle files around or pollute your environment variables.
-
Dependency solver: if a list of dependencies is passed to the build configuration of a library, then passing the name of that library to any subsequent build config will expand into the previously declared dependencies. This works recursively. In addition, avtomat reads dependency files generated by gcc, so includes are always checked when deciding if a file needs to be recompiled.
-
Generators: avtomat offers some metaprogramming utilities, among them is a built-in generated files and generator scripts manager. You simply specify the source script or binary, the destination file to be created, and optionally a list of dependencies for the source script or binary -- everything else is handled by the build script.
-
Avto-FFI: if a list of source or header files is provided for the purpose of creating bindings, then those files will be scanned for symbols, and bindings for other languages can later be created through a post build script. Currently, Perl 5 is supported through
FFI::Platypus
and Python support throughctypes
is being worked on; more languages will be added as needed.
Beat it.
You don't need to install all of my system utils nor match my exact environment just to use avtomat. You DO need to set ARPATH, though. Why? Because it makes the code a thousand times simpler.
To test it out:
mkdir AR
cd AR
ARPATH=$(pwd)
git clone https://github.com/Liebranca/avtomat
cd avtomat
./install.pl
And if you're happy with the software then you can just add ARPATH to your environs yourself. Then your perl scripts can just say:
use lib $ENV{'ARPATH'}.'/lib/';
use Avt; # or anything else from avtomat ;>
And because you had to make a topdir so that avtomat could use it's own local lib, bin, include, etcetera now you can uninstall the whole thing in one command:
rm -r $ARPATH
Removing ARPATH
from your environment variables is also left up to you.
First off, understand that avtomat is made for managing multiple modules within the same directory; it expects that you'll pass it one top directory and will do it's thing solely within that scope.
For visual aids, here's what's expected:
>/your/top/dir
\-->MyModule_a
\-->MyModule_b
Got it? Good.
The following script demonstrates how to write an avtomat setup.
# import ghost
use lib $ENV{'ARPATH'}.'/lib/sys/';
use Shb7;
# import avtomat
use lib $ENV{'ARPATH'}.'/lib/';
use Avt;
# set your top directory
Shb7::set_root('/your/top/dir');
# set your library and include paths
Shb7::push_libs('/your/lib/path');
Shb7::push_includes('/your/include/path');
# configure your module(s)
Avt::set_config(
# only this field is mandatory
# any other field, if skipped, means do nothing
name=>'MyModule',
# pre-build hook, passed in as a string
# it'll be pasted as-is into an INIT block
pre_build=>q{
print "hello there\n";
},
#^same, goes into an END block
post_build=>q{
print "see ya!\n";
},
# experimental: array of dependencies
# will git clone into name if missing from module
deps=>[
[ 'name',
'link-to-git-repo',
undef (reserved for post-clone hooks)
],
],
# this field is meant for passing arguments
# to the project files search function;
# for now, it's only used to exclude paths
scan=>'-x /do/not/search/here',
# x: make an executable
# so: make a shared object
# ar: make a static lib
build=>'x:my_elf',
# copy machine;
# xcpy moves files into topdir/bin
# lcpy moves files into topdir/lib
xcpy=>[qw(my_executable)],
lcpy=>[qw(my_lib.py)],
# defines files to be scanned for symbols
# these are used for the avto-FFI
xprt=>[qw(some_header.h other_header.h)],
# generated files manager
# syntax is: 'target'=>[generator,deps]
gens=>{
# additional deps are optional!
'file'=>[qw(my_script)],
# with dependencies:
# % is allowed for wildcards ;>
'file'=>[qw(other_script dep.data %.ext)],
},
# snippets that are compiled individually
# syntax is the same for both
# 'utils' are moved to [topdir]/bin
utils=>{
'my_app'=>[qw(path/src.cpp,flags)]
},
# 'tests' are run automatically
# and kept within the module's
# own test folder
tests=>{
'my_app'=>[qw(path/src.c,flags)]
},
# paths to/names of libraries
libs=>[qw(X11 SDL2 SDL2main proj/lib/)],
# self explanatory
incl=>[qw(path/to/include/)],
# unused! but reserved for later plans ;>
defs=>[qw(some_compile_time_define)],
);
#^repeat for each module
# --- * --- * ---
# invoke the triad
Avt::scan();
Avt::config();
Avt::make();
# --- * --- * ---
# to also run the generated scripts:
my @modules=Avt::MODULES;
my $root=$Shb7::Root;
for my $mod(@modules) {
print `$root/$mod/avto`;
};
The scan
,config
and make
triad will emit the following files:
-
topdir/.cache/avto-config: a serialized Perl hash containing the configurations after being processed by
config
. -
topdir/module/avto: the makescript itself, ready to be run.
-
topdir/module/.avto-cache: a serialized Perl hash containing module metadata used by the makescript.
For example scripts that set up an actual project, refer to the install.pl
files found in my repos.
Files generated by avtomat, as well as headers, version prints and related notices include this bit by default:
'Copyleft '.$AUTHOR.' '.$YEAR.'; Licensed under GNU GPL3';
Which means that if you do not agree with the license you will have to modify this bit yourself. But why would you do that? Have some morals; spread GPL.