| 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_BUILD_CONFIG### development |
| 18 | # ###KERNEL_BUILDER### root |
| 19 | # ###KERNEL_BUILD_OBJROOT### xnu/xnu-690.obj~2/RELEASE_PPC |
| 20 | # ###KERNEL_BUILD_DATE### Sun Oct 24 05:33:28 PDT 2004 |
| 21 | |
| 22 | use File::Basename; |
| 23 | |
| 24 | use strict; |
| 25 | |
| 26 | sub ReadFile { |
| 27 | my ($fileName) = @_; |
| 28 | my $data; |
| 29 | local $/ = undef; # Read complete files |
| 30 | |
| 31 | if (open(IN, "<$fileName")) { |
| 32 | $data=<IN>; |
| 33 | close IN; |
| 34 | return $data; |
| 35 | } |
| 36 | die "newvers: Can't read file \"$fileName\"\n"; |
| 37 | } |
| 38 | |
| 39 | sub WriteFile { |
| 40 | my ($fileName, $data) = @_; |
| 41 | |
| 42 | open (OUT, ">$fileName") or die "newvers: Can't write file \"$fileName\"\n"; |
| 43 | print OUT $data; |
| 44 | close(OUT); |
| 45 | } |
| 46 | |
| 47 | die("SRCROOT not defined") unless defined($ENV{'SRCROOT'}); |
| 48 | die("OBJROOT not defined") unless defined($ENV{'OBJROOT'}); |
| 49 | |
| 50 | my $versfile = "MasterVersion"; |
| 51 | $versfile = "$ENV{'SRCROOT'}/config/$versfile" if ($ENV{'SRCROOT'}); |
| 52 | my $BUILD_SRCROOT=$ENV{'SRCROOT'}; |
| 53 | $BUILD_SRCROOT =~ s,/+$,,; |
| 54 | my $BUILD_OBJROOT=$ENV{'OBJROOT'}; |
| 55 | $BUILD_OBJROOT =~ s,/+$,,; |
| 56 | my $BUILD_OBJPATH=$ENV{'TARGET'} || $ENV{'OBJROOT'}; |
| 57 | $BUILD_OBJPATH =~ s,/+$,,; |
| 58 | my $BUILD_DATE = `date`; |
| 59 | $BUILD_DATE =~ s/[\n\t]//g; |
| 60 | my $BUILD_CONFIG = "unknown"; |
| 61 | $BUILD_CONFIG = $ENV{'CURRENT_KERNEL_CONFIG_LC'} if defined($ENV{'CURRENT_KERNEL_CONFIG_LC'}); |
| 62 | my $BUILDER=`whoami`; |
| 63 | $BUILDER =~ s/[\n\t]//g; |
| 64 | my $RC_STRING = $ENV{'RC_ProjectNameAndSourceVersion'} . "~" . $ENV{'RC_ProjectBuildVersion'} if defined($ENV{'RC_XBS'}); |
| 65 | |
| 66 | # Handle four scenarios: |
| 67 | # SRCROOT=/tmp/xnu |
| 68 | # OBJROOT=/tmp/xnu/BUILD/obj |
| 69 | # OBJPATH=/tmp/xnu/BUILD/obj/RELEASE_X86_64 |
| 70 | # |
| 71 | # SRCROOT=/SourceCache/xnu/xnu-2706 |
| 72 | # OBJROOT=/BinaryCache/xnu/xnu-2706~3/Objects |
| 73 | # OBJPATH=/BinaryCache/xnu/xnu-2706~3/Objects/DEVELOPMENT_X86_64 |
| 74 | # RC_XBS=YES (XBS-16.3+) |
| 75 | # RC_ProjectNameAndSourceVersion=xnu-2706 |
| 76 | # RC_ProjectBuildVersion=3 |
| 77 | # |
| 78 | # SRCROOT=/SourceCache/xnu/xnu-2706 |
| 79 | # OBJROOT=/private/var/tmp/xnu/xnu-2706~2 |
| 80 | # OBJPATH=/private/var/tmp/xnu/xnu-2706~2/DEVELOPMENT_ARM_S5L8940X |
| 81 | # RC_XBS=YES (<XBS-16.3) |
| 82 | # RC_ProjectNameAndSourceVersion=xnu-2706 |
| 83 | # RC_ProjectBuildVersion=2 |
| 84 | # |
| 85 | # SRCROOT=/tmp/xnu-2800.0.1_xnu-svn.roots/Sources/xnu-2800.0.1 |
| 86 | # OBJROOT=/private/tmp/xnu-2800.0.1_xnu-svn.roots/BuildRecords/xnu-2800.0.1_install/Objects |
| 87 | # OBJPATH=/private/tmp/xnu-2800.0.1_xnu-svn.roots/BuildRecords/xnu-2800.0.1_install/Objects/DEVELOPMENT_X86_64 |
| 88 | # RC_XBS=YES (buildit) |
| 89 | # RC_BUILDIT=YES |
| 90 | # RC_ProjectNameAndSourceVersion=xnu-2800.0.1 |
| 91 | # RC_ProjectBuildVersion=1 |
| 92 | # |
| 93 | # |
| 94 | # If SRCROOT is a strict prefix of OBJPATH, we |
| 95 | # want to preserve the "interesting" part |
| 96 | # starting with "xnu". If it's not a prefix, |
| 97 | # the basename of OBJROOT itself is "interesting". |
| 98 | # Newer versions of XBS just set this to "Objects", so we |
| 99 | # need to synthesize the directory name to be more interesting. |
| 100 | # |
| 101 | |
| 102 | sub describe { |
| 103 | my ($basename) = @_; |
| 104 | |
| 105 | # get a git tag if we can |
| 106 | my $tag = `git describe --dirty 2>/dev/null`; |
| 107 | chomp $tag; |
| 108 | if ($? != 0 or $tag !~ /^xnu-([^\s\n]+)$/) { |
| 109 | return $basename; |
| 110 | } |
| 111 | |
| 112 | # If basename is just 'xnu' then replace it with the tag. Otherwise add |
| 113 | # the tag in brackets. |
| 114 | if ($basename eq 'xnu') { |
| 115 | return $tag |
| 116 | } else { |
| 117 | return "${basename}[$tag]" |
| 118 | } |
| 119 | } |
| 120 | |
| 121 | if ($BUILD_OBJPATH =~ m,^$BUILD_SRCROOT/(.*)$,) { |
| 122 | $BUILD_OBJROOT = describe(basename($BUILD_SRCROOT)) . "/" . $1; |
| 123 | } elsif ($BUILD_OBJPATH =~ m,^$BUILD_OBJROOT/(.*)$,) { |
| 124 | if (defined($RC_STRING)) { |
| 125 | $BUILD_OBJROOT = $RC_STRING . "/" . $1; |
| 126 | } else { |
| 127 | $BUILD_OBJROOT = describe(basename($BUILD_OBJROOT)) . "/" . $1; |
| 128 | } |
| 129 | } else { |
| 130 | # Use original OBJROOT |
| 131 | } |
| 132 | |
| 133 | my $rawvers = &ReadFile($versfile); |
| 134 | #$rawvers =~ s/\s//g; |
| 135 | ($rawvers) = split "\n", $rawvers; |
| 136 | my ($VERSION_MAJOR, $VERSION_MINOR, $VERSION_VARIANT) = split /\./, $rawvers; |
| 137 | die "newvers: Invalid MasterVersion \"$rawvers\"!!! " if (!$VERSION_MAJOR); |
| 138 | $VERSION_MINOR = "0" unless ($VERSION_MINOR); |
| 139 | $VERSION_VARIANT = "0" unless ($VERSION_VARIANT); |
| 140 | $VERSION_VARIANT =~ tr/A-Z/a-z/; |
| 141 | $VERSION_VARIANT =~ m/(\d+)((?:d|a|b|r|fc)?)(\d*)/; |
| 142 | my $VERSION_REVISION = $1; |
| 143 | my $stage = $2; |
| 144 | my $VERSION_PRERELEASE_LEVEL = $3; |
| 145 | $VERSION_REVISION ="0" unless ($VERSION_REVISION); |
| 146 | $stage = "r" if (!$stage || ($stage eq "fc")); |
| 147 | $VERSION_PRERELEASE_LEVEL = "0" unless ($VERSION_PRERELEASE_LEVEL); |
| 148 | |
| 149 | my $VERSION_STAGE; |
| 150 | $VERSION_STAGE = 'VERSION_STAGE_DEV' if ($stage eq 'd'); |
| 151 | $VERSION_STAGE = 'VERSION_STAGE_ALPHA' if ($stage eq 'a'); |
| 152 | $VERSION_STAGE = 'VERSION_STAGE_BETA' if ($stage eq 'b'); |
| 153 | $VERSION_STAGE = 'VERSION_STAGE_RELEASE' if ($stage eq 'r'); |
| 154 | |
| 155 | my $VERSION_SHORT = "$VERSION_MAJOR.$VERSION_MINOR.$VERSION_REVISION"; |
| 156 | my $VERSION_LONG = $VERSION_SHORT; |
| 157 | $VERSION_LONG .= "$stage$VERSION_PRERELEASE_LEVEL" if (($stage ne "r") || ($VERSION_PRERELEASE_LEVEL != 0)); |
| 158 | |
| 159 | my $file; |
| 160 | foreach $file (@ARGV) { |
| 161 | print "newvers.pl: Stamping version \"$VERSION_LONG\" into \"$file\" ..."; |
| 162 | my $data = &ReadFile($file); |
| 163 | my $count=0; |
| 164 | $count += $data =~ s/###KERNEL_VERSION_LONG###/$VERSION_LONG/g; |
| 165 | $count += $data =~ s/###KERNEL_VERSION_SHORT###/$VERSION_SHORT/g; |
| 166 | $count += $data =~ s/###KERNEL_VERSION_MAJOR###/$VERSION_MAJOR/g; |
| 167 | $count += $data =~ s/###KERNEL_VERSION_MINOR###/$VERSION_MINOR/g; |
| 168 | $count += $data =~ s/###KERNEL_VERSION_VARIANT###/$VERSION_VARIANT/g; |
| 169 | $count += $data =~ s/###KERNEL_VERSION_REVISION###/$VERSION_REVISION/g; |
| 170 | $count += $data =~ s/###KERNEL_VERSION_STAGE###/$VERSION_STAGE/g; |
| 171 | $count += $data =~ s/###KERNEL_VERSION_PRERELEASE_LEVEL###/$VERSION_PRERELEASE_LEVEL/g; |
| 172 | $count += $data =~ s/###KERNEL_BUILD_CONFIG###/$BUILD_CONFIG/g; |
| 173 | $count += $data =~ s/###KERNEL_BUILDER###/$BUILDER/g; |
| 174 | $count += $data =~ s/###KERNEL_BUILD_OBJROOT###/$BUILD_OBJROOT/g; |
| 175 | $count += $data =~ s/###KERNEL_BUILD_DATE###/$BUILD_DATE/g; |
| 176 | print " $count replacements\n"; |
| 177 | &WriteFile($file, $data); |
| 178 | } |
| 179 | |
| 180 | if (0==scalar @ARGV) { |
| 181 | print "newvers.pl: read version \"$rawvers\" from \"$versfile\"\n"; |
| 182 | print "newvers.pl: ###KERNEL_VERSION_LONG### = $VERSION_LONG\n"; |
| 183 | print "newvers.pl: ###KERNEL_VERSION_SHORT### = $VERSION_SHORT\n"; |
| 184 | print "newvers.pl: ###KERNEL_VERSION_MAJOR### = $VERSION_MAJOR\n"; |
| 185 | print "newvers.pl: ###KERNEL_VERSION_MINOR### = $VERSION_MINOR\n"; |
| 186 | print "newvers.pl: ###KERNEL_VERSION_VARIANT### = $VERSION_VARIANT\n"; |
| 187 | print "newvers.pl: ###KERNEL_VERSION_REVISION### = $VERSION_REVISION\n"; |
| 188 | print "newvers.pl: ###KERNEL_VERSION_STAGE### = $VERSION_STAGE\n"; |
| 189 | print "newvers.pl: ###KERNEL_VERSION_PRERELEASE_LEVEL### = $VERSION_PRERELEASE_LEVEL\n"; |
| 190 | print "newvers.pl: ###KERNEL_BUILD_CONFIG### = $BUILD_CONFIG\n"; |
| 191 | print "newvers.pl: ###KERNEL_BUILDER### = $BUILDER\n"; |
| 192 | print "newvers.pl: ###KERNEL_BUILD_OBJROOT### = $BUILD_OBJROOT\n"; |
| 193 | print "newvers.pl: ###KERNEL_BUILD_DATE### = $BUILD_DATE\n"; |
| 194 | } |