App-ArduinoBuilder
view release on metacpan or search on metacpan
lib/App/ArduinoBuilder.pm view on Meta::CPAN
# We are first adding all the includes path for all the library before building any of them.
for my $l ($lib_config->keys()) {
my $lib_dir = $lib_config->get($l);
fatal "Library directory does not exist for library '${l}': ${lib_dir}" unless -d $lib_dir;
my $lib_properties_file = catfile($lib_dir, 'library.properties');
my $has_lib_properties = -f $lib_properties_file;
my $recursive_lib = $has_lib_properties && -d catdir($lib_dir, 'src');
# These config entry (and any other added to $lib_config) are undocummented and should never be
# set by the user.
$lib_config->set($l.'.is_flat' => !$recursive_lib);
if ($recursive_lib) {
$config->append('includes', '"-I'.catdir($lib_dir, 'src').'"');
} else {
$config->append('includes', "\"-I${lib_dir}\"");
}
if ($has_lib_properties) {
my $lib_properties = App::ArduinoBuilder::Config->new(file => $lib_properties_file);
$lib_config->set($l.'.name' => $lib_properties->get('name', default => $l));
}
}
# TODO: we are ignoring the dot_a_linkage properties of the libraries (unclear what it brings)
# and also the precompiled
if ($run_step->('libraries')) {
info 'Building libraries...';
$builder->run_hook('libraries.prebuild');
for my $l (@all_libs) {
# Todo: we could add "lib-$l" pseudo-steps, but we need to take care of the --only
# interaction with the 'libraries' step.
info ' Building library %s...', $lib_config->get("${l}.name");
my $base_dir = $lib_config->get($l);
my $output_dir = catdir($config->get('build.path'), 'libs', $l);
my $built_lib;
if ($lib_config->get("${l}.is_flat")) {
my $utility_dir = catdir($base_dir, 'utility');
my @dirs = ($base_dir, (-d $utility_dir ? $utility_dir : ()));
$built_lib = $builder->build_object_files(\@dirs, $output_dir, [], $force->('libraries'), 1);
} else {
$built_lib = $builder->build_object_files(catdir($base_dir, 'src'), $output_dir, [], $force->('libraries'));
}
info ($built_lib ? ' Success' : ' Already up-to-date');
$built_something |= $built_lib;
}
$builder->run_hook('libraries.postbuild');
}
$config->append('includes', '"-I'.$config->get('builder.source.path').'"');
if ($run_step->('sketch')) {
info 'Building sketch...';
$builder->run_hook('sketch.prebuild');
# TODO: add configuration option for the ignored directories and also a way to
# build only the code inside the src/ directory
my $built_sketch = $builder->build_object_files(
$config->get('builder.source.path'), catdir($config->get('build.path'), 'sketch'),
[], $force->('sketch'), !$config->get('builder.source.is_recursive'));
info ($built_sketch ? ' Success' : ' Already up-to-date');
$built_something |= $built_sketch;
$builder->run_hook('sketch.postbuild');
}
# Bug: there is a similar bug to the one in build_archive: if a source file is
# removed, we wonât remove itâs object file. I guess we could try to detect it.
# Meanwhile itâs probably acceptable to ask for a cleanup from time to time.
my @object_files = find_all_files_with_extensions(catdir($config->get('build.path'), 'sketch'), ['o']);
for my $l (@all_libs) {
push @object_files, find_all_files_with_extensions(catdir($config->get('build.path'), 'libs', $l), ['o']);
}
debug 'Object files: '.join(', ', @object_files);
info 'Linking binary...';
if (($built_something && $run_step->('link')) || $force->('link')) {
$built_something = 1;
$builder->run_hook('linking.prelink');
$builder->link_executable(\@object_files, 'core.a');
$builder->run_hook('linking.postlink');
info ' Success';
} else {
info ' Already up-to-date';
}
info 'Extracting binary data';
if (($built_something && $run_step->('objcopy')) || $force->('objcopy')) {
$builder->run_hook('objcopy.preobjcopy');
$builder->objcopy();
$builder->run_hook('objcopy.postobjcopy');
info ' Success';
} else {
info ' Already up-to-date';
}
info 'Computing binary sketch size';
if (($built_something && $run_step->('size')) || $force->('size')) {
$builder->compute_binary_size();
# Not printing 'Success' here because the command already has an output.
} else {
info ' No new binary built';
}
info 'Success!';
}
sub discover {
my ($config) = @_;
if ($config->get('builder.forced_port.forced', default => 0)) {
info 'Skipping board discovery';
return;
}
info 'Running board discovery...';
my @ports = App::ArduinoBuilder::Discovery::discover($config);
# Discovery can be run more than once, as the port of a board can be changed
# after upload. So we override any previous discovered ports.
$config->set('builder.internal.ports' => \@ports, allow_override =>1);
if (@ports) {
debug 'Found port%s: %s', (@ports > 1 ? 's' : ''), join(', ', map { $_->get('upload.port.label') } @ports);
} else {
warning 'No port found.';
}
}
sub select_port {
( run in 1.055 second using v1.01-cache-2.11-cpan-39bf76dae61 )