summaryrefslogtreecommitdiff
path: root/common/tools/project-template
blob: 7bf98aedfad8d48430e343ea6d7a1ab6a52d17b2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
#!/usr/bin/perl
#
# Prompt the user to create a simple project template.
#
use strict;
use warnings;
use File::Find;

my @modules;
my @sources;

sub prompt_yn
{
    my $prompt = shift;
    my $rep = '';
    while (1)
    {
	print "\n$prompt [yn] ";
	$rep = <>;
	die "bye...\n" unless $rep;
	chomp $rep;
	last if $rep eq 'y' || $rep eq 'n';
	print "Please answer 'y' or 'n' and hit the enter key.\n";
    }
    return $rep eq 'y' ? 1 : 0;
}

sub prompt_str
{
    my ($prompt, $re) = @_;
    my $rep = '';
    while (1)
    {
	print "\n$prompt ";
	$rep = <>;
	die "bye...\n" unless $rep;
	chomp $rep;
	last if $rep =~ /$re/;
	print "I do not understand, please try again.\n";
    }
    return $rep;
}

sub prompt_list
{
    my ($prompt, $one, @list) = @_;
    my $rep;
    INPUT: while (1)
    {
	print "\n$prompt:\n";
	print " [$_] $list[$_]\n" for (0 .. $#list);
	$one
	    and print "enter a number: "
	    or print "enter a list of space separated number: ";
	$rep = <>;
	die "bye...\n" unless $rep;
	chomp $rep;
	my @rep = split / /, $rep;
	if ($one && scalar @rep != 1)
	{
	    print "I want one and only one response.\n";
	    next INPUT;
	}
	for (@rep)
	{
	    if (!/^\d+$/ || !exists $list[$_])
	    {
		print "I can not understand \"$_\".\n";
		next INPUT;
	    }
	}
	return @list[@rep];
    }
}

sub prompt_prog
{
    my ($var, $fh, $prompt) = @_;
    my @programs = split / +/,
	prompt_str "Please give ${prompt}programs names, separated with spaces:",
	qr/\w+(?: +\w)* */;
    print $fh "$var = ", join (' ', @programs), "\n";
    for (@programs)
    {
	my @prog_sources = scalar @sources
	    ? prompt_list ("Choose the sources to include for $_", 0, @sources)
	    : ();
	print $fh "${_}_SOURCES = ", join (' ', @prog_sources), "\n";
	my @prog_modules = scalar @modules
	    ? prompt_list ("Choose the modules to include for $_", 0, @modules)
	    : ();
	print $fh "${_}_MODULES = ", join (' ', @prog_modules), "\n";
	print $fh "\n";
    }
}

sub prompt_platform
{
    my ($ecos) = @_;
    my @platforms;
    push @platforms, 'none' unless $ecos;
    push @platforms, 'sparc', 'synthetic', 'maximus';
    return prompt_list ("For which platform do you compile?", 1, @platforms);
}

print <<EOF;
Welcome to the project template creator.  I will prompt you to learn some
coarse details about your project and I will then generate the Makefile and
the ecos.ecc.sh if needed.

EOF

# Find base.
my $base = '..';
while (!-r "$base/common/make/top.mk")
{
    $base .= '/..';
    die "I can not find the base directory.\n"
	unless -d $base && length $base < 3 * 12;
}
print "I have found the sources root in `$base'.\n";

my ($ecos, $platform);

if (scalar @ARGV && $ARGV[0] eq 'ecos.ecc.sh')
{
    @ARGV = ();
    print "\nI will only generate the ecos.ecc.sh file.\n";
    $ecos = 1;
}
else
{
    # Find modules and local sources.
    find (sub {
	/^(?:ecos|\.svn|test)$/s && ($File::Find::prune = 1)
	|| /^Module$/s && do { push @modules, $File::Find::dir };
    } , $base);
    $_ =~ s#^$base/## for @modules;

    find (sub {
	/\.c$/s && do { push @sources, $_ };
    }, 'src') if -d 'src';

    # Generate Makefile.
    die "Makefile in the ways, I will not clobber it.\n" if -f 'Makefile';

    open MAKEFILE, ">Makefile" or die "I can not open Makefile for writing.\n";

    print MAKEFILE "BASE = $base\n\n";

    $ecos = prompt_yn 'Do you want to use ecos?';
    print MAKEFILE "ECOS = y\n" if $ecos;

    $platform = prompt_platform $ecos;
    print MAKEFILE "TARGET = sparc\n" if $platform eq 'sparc';

    print MAKEFILE "\n" if $ecos || $platform eq 'sparc';

    my $host = prompt_yn 'Do you want to build host programs?';
    prompt_prog 'HOST_PROGRAMS', \*MAKEFILE, 'host ' if $host;

    my $target = $ecos || $platform ne 'none';
    prompt_prog 'TARGET_PROGRAMS', \*MAKEFILE, 'target ' if $target;

    print MAKEFILE "include \$(BASE)/common/make/top.mk\n";
    close MAKEFILE;
}

if ($ecos)
{
    # Generate ecos compact config.
    die "ecos.ecc.sh in the ways, I will not clobber it.\n" if -f 'ecos.ecc.sh';
    open ECOS, ">ecos.ecc.sh" or die "I can not open ecos.ecc.sh for writing.\n";

    $platform = prompt_platform $ecos unless defined $platform;

    my %ecos_targets = (
	sparc => 'sparc_leon',
	synthetic => 'linux',
	maximus => 'maximus',
    );
    die unless exists $ecos_targets{$platform};
    my $ecos_target = $ecos_targets{$platform};
    my $ecos_tmpl = prompt_list ("Choose template", 1, 'minimal', 'kernel',
	'default');

    print ECOS "config=\${1:-ecos-gen.ecc}\n";
    print ECOS "ecosconfig --config=\$config new $ecos_target $ecos_tmpl\n";
    print ECOS "cat >> \$config <<'EOF'\n";
    print ECOS "EOF\n";
    print ECOS "ecosconfig --config=\$config check\n";
    close ECOS;
}