1#!/usr/bin/perl
2#
3# This tool is used to stamp kernel version information into files at kernel
4# build time.  Each argument provided on the command line is the path to a file
5# that needs to be updated with the current verison information.  The file
6# xnu/config/MasterVersion is read to determine the version number to use.
7# Each file is read, and all occurrences of the following strings are replaced
8# in-place like so:
9#   ###KERNEL_VERSION_LONG###               1.2.3b4
10#   ###KERNEL_VERSION_SHORT###              1.2.3
11#   ###KERNEL_VERSION_MAJOR###              1
12#   ###KERNEL_VERSION_MINOR###              2
13#   ###KERNEL_VERSION_VARIANT###            3b4
14#   ###KERNEL_VERSION_REVISION###           3
15#   ###KERNEL_VERSION_STAGE###              VERSION_STAGE_BETA	(see libkern/version.h)
16#   ###KERNEL_VERSION_PRERELEASE_LEVEL###   4
17#   ###KERNEL_BUILDER###                    root
18#   ###KERNEL_BUILD_OBJROOT###              xnu/xnu-690.obj~2/RELEASE_PPC
19#   ###KERNEL_BUILD_DATE###                 Sun Oct 24 05:33:28 PDT 2004
20
21use File::Basename;
22
23use strict;
24
25sub ReadFile {
26  my ($fileName) = @_;
27  my $data;
28  local $/ = undef;   # Read complete files
29
30  if (open(IN, "<$fileName")) {
31    $data=<IN>;
32    close IN;
33    return $data;
34  }
35  die "newvers: Can't read file \"$fileName\"\n";
36}
37
38sub WriteFile {
39  my ($fileName, $data) = @_;
40
41  open (OUT, ">$fileName") or die "newvers: Can't write file \"$fileName\"\n";
42  print OUT  $data;
43  close(OUT);
44}
45
46die("SRCROOT not defined") unless defined($ENV{'SRCROOT'});
47die("OBJROOT not defined") unless defined($ENV{'OBJROOT'});
48
49my $versfile = "MasterVersion";
50$versfile = "$ENV{'SRCROOT'}/config/$versfile" if ($ENV{'SRCROOT'});
51my $BUILD_SRCROOT=$ENV{'SRCROOT'};
52$BUILD_SRCROOT =~ s,/+$,,;
53my $BUILD_OBJROOT=$ENV{'OBJROOT'};
54$BUILD_OBJROOT =~ s,/+$,,;
55my $BUILD_OBJPATH=$ENV{'TARGET'} || $ENV{'OBJROOT'};
56$BUILD_OBJPATH =~ s,/+$,,;
57my $BUILD_DATE = `date`;
58$BUILD_DATE =~ s/[\n\t]//g;
59my $BUILDER=`whoami`;
60$BUILDER =~ s/[\n\t]//g;
61
62# Handle two scenarios:
63# SRCROOT=/tmp/xnu
64# OBJROOT=/tmp/xnu/BUILD/obj
65# OBJPATH=/tmp/xnu/BUILD/obj/RELEASE_X86_64
66#
67# SRCROOT=/SourceCache/xnu/xnu-1234
68# OBJROOT=/tmp/xnu/xnu-1234~1.obj
69# OBJPATH=/tmp/xnu/xnu-1234~1.obj/RELEASE_X86_64
70#
71# If SRCROOT is a strict prefix of OBJPATH, we
72# want to preserve the "interesting" part
73# starting with "xnu". If it's not a prefix,
74# the basename of OBJROOT itself is "interesting".
75
76if ($BUILD_OBJPATH =~ m,^$BUILD_SRCROOT/(.*)$,) {
77    $BUILD_OBJROOT = basename($BUILD_SRCROOT) . "/" . $1;
78} elsif ($BUILD_OBJPATH =~ m,^$BUILD_OBJROOT/(.*)$,) {
79    $BUILD_OBJROOT = basename($BUILD_OBJROOT) . "/" . $1;
80} else {
81    # Use original OBJROOT
82}
83
84my $rawvers = &ReadFile($versfile);
85#$rawvers =~ s/\s//g;
86($rawvers) = split "\n", $rawvers;
87my ($VERSION_MAJOR, $VERSION_MINOR, $VERSION_VARIANT) = split /\./, $rawvers;
88die "newvers: Invalid MasterVersion \"$rawvers\"!!! " if (!$VERSION_MAJOR);
89$VERSION_MINOR = "0" unless ($VERSION_MINOR);
90$VERSION_VARIANT = "0" unless ($VERSION_VARIANT);
91$VERSION_VARIANT =~ tr/A-Z/a-z/;
92$VERSION_VARIANT =~ m/(\d+)((?:d|a|b|r|fc)?)(\d*)/;
93my $VERSION_REVISION = $1;
94my $stage = $2;
95my $VERSION_PRERELEASE_LEVEL = $3;
96$VERSION_REVISION ="0" unless ($VERSION_REVISION);
97$stage = "r" if (!$stage || ($stage eq "fc"));
98$VERSION_PRERELEASE_LEVEL = "0" unless ($VERSION_PRERELEASE_LEVEL);
99
100my $VERSION_STAGE;
101$VERSION_STAGE = 'VERSION_STAGE_DEV'     if ($stage eq 'd');
102$VERSION_STAGE = 'VERSION_STAGE_ALPHA'   if ($stage eq 'a');
103$VERSION_STAGE = 'VERSION_STAGE_BETA'    if ($stage eq 'b');
104$VERSION_STAGE = 'VERSION_STAGE_RELEASE' if ($stage eq 'r');
105
106my $VERSION_SHORT = "$VERSION_MAJOR.$VERSION_MINOR.$VERSION_REVISION";
107my $VERSION_LONG = $VERSION_SHORT;
108$VERSION_LONG .= "$stage$VERSION_PRERELEASE_LEVEL" if (($stage ne "r") || ($VERSION_PRERELEASE_LEVEL != 0));
109
110my $file;
111foreach $file (@ARGV) {
112  print "newvers.pl: Stamping version \"$VERSION_LONG\" into \"$file\" ...";
113  my $data = &ReadFile($file);
114  my $count=0;
115  $count += $data =~ s/###KERNEL_VERSION_LONG###/$VERSION_LONG/g;
116  $count += $data =~ s/###KERNEL_VERSION_SHORT###/$VERSION_SHORT/g;
117  $count += $data =~ s/###KERNEL_VERSION_MAJOR###/$VERSION_MAJOR/g;
118  $count += $data =~ s/###KERNEL_VERSION_MINOR###/$VERSION_MINOR/g;
119  $count += $data =~ s/###KERNEL_VERSION_VARIANT###/$VERSION_VARIANT/g;
120  $count += $data =~ s/###KERNEL_VERSION_REVISION###/$VERSION_REVISION/g;
121  $count += $data =~ s/###KERNEL_VERSION_STAGE###/$VERSION_STAGE/g;
122  $count += $data =~ s/###KERNEL_VERSION_PRERELEASE_LEVEL###/$VERSION_PRERELEASE_LEVEL/g;
123  $count += $data =~ s/###KERNEL_BUILDER###/$BUILDER/g;
124  $count += $data =~ s/###KERNEL_BUILD_OBJROOT###/$BUILD_OBJROOT/g;
125  $count += $data =~ s/###KERNEL_BUILD_DATE###/$BUILD_DATE/g;
126  print " $count replacements\n";
127  &WriteFile($file, $data);
128}
129
130if (0==scalar @ARGV) {
131  print "newvers.pl: read version \"$rawvers\" from \"$versfile\"\n";
132  print "newvers.pl: ###KERNEL_VERSION_LONG### = $VERSION_LONG\n";
133  print "newvers.pl: ###KERNEL_VERSION_SHORT### = $VERSION_SHORT\n";
134  print "newvers.pl: ###KERNEL_VERSION_MAJOR### = $VERSION_MAJOR\n";
135  print "newvers.pl: ###KERNEL_VERSION_MINOR### = $VERSION_MINOR\n";
136  print "newvers.pl: ###KERNEL_VERSION_VARIANT### = $VERSION_VARIANT\n";
137  print "newvers.pl: ###KERNEL_VERSION_REVISION### = $VERSION_REVISION\n";
138  print "newvers.pl: ###KERNEL_VERSION_STAGE### = $VERSION_STAGE\n";
139  print "newvers.pl: ###KERNEL_VERSION_PRERELEASE_LEVEL### = $VERSION_PRERELEASE_LEVEL\n";
140  print "newvers.pl: ###KERNEL_BUILDER### = $BUILDER\n";
141  print "newvers.pl: ###KERNEL_BUILD_OBJROOT### = $BUILD_OBJROOT\n";
142  print "newvers.pl: ###KERNEL_BUILD_DATE### = $BUILD_DATE\n";
143}
144