File Coverage

blib/lib/App/hopen/T/Gnu/C.pm
Criterion Covered Total %
statement 53 54 98.1
branch 3 6 50.0
condition n/a
subroutine 17 18 94.4
pod n/a
total 73 78 93.5


line stmt bran cond sub pod time code
1             # App::hopen::T::Gnu::C - support GNU toolset, C language
2             package App::hopen::T::Gnu::C;
3 1     1   604 use Data::Hopen;
  1         2  
  1         60  
4 1     1   7 use strict; use warnings;
  1     1   3  
  1         20  
  1         5  
  1         2  
  1         28  
5 1     1   6 use Data::Hopen::Base;
  1         2  
  1         8  
6              
7             our $VERSION = '0.000013'; # TRIAL
8              
9 1     1   1441 use App::hopen::BuildSystemGlobals; # For $DestDir.
  1         2  
  1         101  
10             # TODO make the dirs available to nodes through the context.
11 1     1   19 use App::hopen::Util::BasedPath;
  1         2  
  1         64  
12              
13 1     1   487 use App::hopen::T::Gnu::C::CompileCmd;
  1         3  
  1         43  
14 1     1   507 use App::hopen::T::Gnu::C::LinkCmd;
  1         3  
  1         38  
15              
16 1     1   6 use Config;
  1         9  
  1         51  
17 1     1   6 use Data::Hopen qw(getparameters);
  1         3  
  1         38  
18 1     1   9 use Data::Hopen::G::GraphBuilder;
  1         2  
  1         45  
19 1     1   14 use Data::Hopen::Util::Data qw(forward_opts);
  1         2  
  1         43  
20 1     1   6 use Data::Hopen::Util::Filename;
  1         2  
  1         26  
21 1     1   5 use File::Which ();
  1         10  
  1         16  
22 1     1   4 use Path::Class;
  1         2  
  1         656  
23              
24             my $FN = Data::Hopen::Util::Filename->new; # for brevity
25             our $_CC; # Cached compiler name
26              
27             # Docs {{{1
28              
29             =head1 NAME
30              
31             App::hopen::T::Gnu::C - support for the GNU toolset, C language
32              
33             =head1 SYNOPSIS
34              
35             In a hopen file:
36              
37             use language 'C';
38              
39             # Use via Data::Hopen::G::GraphBuilder:
40             $Build->H::files(...)->C::compile->default_goal;
41              
42             The inputs come from earlier in the build graph.
43             TODO support specifying compiler arguments.
44              
45             =cut
46              
47             # }}}1
48              
49             =head1 STATIC FUNCTIONS
50              
51             Arguments to the static functions are parsed using L<Getargs::Mixed>
52             (via L<Data::Hopen/getparameters>).
53             Therefore, named arguments start with a hyphen (e.g., C<< -name=>'foo' >>,
54             not C<< name=>'foo' >>).
55              
56             =head2 compile
57              
58             Create a new compilation command. Inputs come from the build graph,
59             so parameters other than C<-name> are disregarded (TODO permit specifying
60             compilation options or object-file names). Usage:
61              
62             use language 'C';
63             $builder_or_dag->H::files('file1.c')->C::compile([-name=>'node name']);
64              
65             =cut
66              
67             sub _find_compiler; # forward
68              
69             sub compile {
70             my ($builder, %args) = getparameters('self', [qw(; name)], @_);
71             _find_compiler unless $_CC;
72             my $node = App::hopen::T::Gnu::C::CompileCmd->new(
73             compiler => $_CC,
74             forward_opts(\%args, 'name')
75             );
76              
77             hlog { __PACKAGE__, 'Built compile node', Dumper($node) } 2;
78              
79             return $node; # The builder will automatically add it
80             } #compile()
81              
82             make_GraphBuilder 'compile';
83              
84             =head2 link
85              
86             Create a new link command. Pass the name of the
87             executable. Object files are on the incoming asset-graph edges. Usage:
88              
89             use language 'C';
90             $builder_or_dag->C::link([-exe=>]'output_file_name'[, [-name=>]'node name']);
91              
92             TODO? Permit specifying that you want C<ld> or another linker instead of
93             using the compiler?
94              
95             =cut
96              
97             sub link {
98             my ($builder, %args) = getparameters('self', [qw(exe; name)], @_);
99             _find_compiler unless $_CC;
100              
101             my $dest = based_path(path => file($FN->exe($args{exe})), base => $DestDir);
102              
103             my $node = App::hopen::T::Gnu::C::LinkCmd->new(
104             linker => $_CC,
105             dest => $dest,
106             forward_opts(\%args, 'name')
107             );
108             hlog { __PACKAGE__, 'Built link node', Dumper($node) } 2;
109              
110             return $node;
111             } #link()
112              
113             make_GraphBuilder 'link';
114              
115             =head1 INTERNALS
116              
117             =head2 _find_compiler
118              
119             Find the C compiler. Called when this package is first loaded.
120              
121             TODO permit the user to specify an alternative compiler to use
122              
123             TODO should this happen when the DAG runs?
124             Maybe toolsets should get the chance to add a node to the beginning of
125             the graph, before anything else runs. TODO figure this out.
126              
127             =cut
128              
129             sub _find_compiler {
130 1     1   5 foreach my $candidate ($Config{cc}, qw[cc gcc clang]) { # TODO also c89 or xlc?
131 1         6 my $path = File::Which::which($candidate);
132 1 50       259 next unless defined $path;
133              
134 1     0   8 hlog { __PACKAGE__, 'using C compiler', $path }; # Got it
  0         0  
135 1         8 $_CC = $path;
136 1         2 last;
137             }
138              
139 1 50       45 croak "Could not find a C compiler" unless $_CC;
140             } #_find_compiler()
141              
142 1 50   1   75 BEGIN { _find_compiler if eval '$App::hopen::RUNNING'; }
143              
144             1;
145             __END__
146             # vi: set fdm=marker: #