#!/usr/bin/perl -w use strict; use File::Path qw(make_path); use File::Spec; use File::Basename; use Cwd 'abs_path'; use Win32; # Copyright (C) 2007, 2009, 2014 Apple Inc. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY # OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. sub splitVersion($); die "You must supply an output path as the argument.\n" if ($#ARGV < 0); my $rawPath = $0; if ($^O eq "cygwin") { chomp($rawPath = `/usr/bin/cygpath -u "$0"`); } my $thisDirectory = dirname(abs_path($rawPath)); my $FALLBACK_VERSION_PATH = File::Spec->catfile($thisDirectory, 'VERSION'); open(FALLBACK_VERSION_FILE, '<', $FALLBACK_VERSION_PATH) or die "Unable to open $FALLBACK_VERSION_PATH: $!"; my $FALLBACK_VERSION = ; close FALLBACK_VERSION_FILE; chomp($FALLBACK_VERSION); my $COPYRIGHT_END_YEAR_PATH = File::Spec->catfile($thisDirectory, 'COPYRIGHT-END-YEAR'); open(COPYRIGHT_END_YEAR_FILE, '<', $COPYRIGHT_END_YEAR_PATH) or die "Unable to open $COPYRIGHT_END_YEAR_PATH: $!"; my $COPYRIGHT_END_YEAR = ; close COPYRIGHT_END_YEAR_FILE; chomp($COPYRIGHT_END_YEAR); # Make sure we don't have any leading or trailing quote $ARGV[0] =~ s/^\"//; $ARGV[0] =~ s/\"$//; my $OUTPUT_DIR = File::Spec->catdir(File::Spec->canonpath($ARGV[0]), 'include'); unless (-d $OUTPUT_DIR) { make_path($OUTPUT_DIR) or die "Couldn't create $OUTPUT_DIR: $!"; } my $OUTPUT_FILE = File::Spec->catfile($OUTPUT_DIR, 'autoversion.h'); # Take the initial version number from RC_ProjectSourceVersion if it # exists, otherwise fall back to the version number stored in the source. my $ENVIRONMENT_VERSION = $ENV{'RC_ProjectSourceVersion'} || $ENV{'RC_PROJECTSOURCEVERSION'}; my $PROPOSED_VERSION = $ENVIRONMENT_VERSION || $FALLBACK_VERSION; chomp($PROPOSED_VERSION); my ($BUILD_MAJOR_VERSION, $BUILD_MINOR_VERSION, $BUILD_TINY_VERSION, $BUILD_VARIANT_VERSION, $ADJUSTED_PROPOSED_VERSION, $FULL_BUILD_MAJOR_VERSION) = splitVersion($PROPOSED_VERSION); my $TINY_VERSION = $BUILD_TINY_VERSION; my $VERSION_TEXT = $ADJUSTED_PROPOSED_VERSION; my $VERSION_TEXT_SHORT = $VERSION_TEXT; my $SVN_REVISION = ''; if (!$ENVIRONMENT_VERSION) { # If we didn't pull the version number from the environment then we're doing # an engineering build and we'll stamp the build with some more information. my $BUILD_DATE = localtime(time); my $SVN_REVISION = `svn info`; $SVN_REVISION =~ m/Revision: (\d+)/; $SVN_REVISION= $1; chomp($BUILD_DATE); chomp($SVN_REVISION); $VERSION_TEXT_SHORT .= "+"; my $USER = Win32::LoginName; $VERSION_TEXT = "$VERSION_TEXT_SHORT $USER - $BUILD_DATE - r$SVN_REVISION"; } open(OUTPUT_FILE, '>', $OUTPUT_FILE) or die "Couldn't open $OUTPUT_FILE: $!"; print OUTPUT_FILE < 99); die "Second version component ($second) is too large. Must be between 0 and 999" if ($second > 999); return $first * 1000 + $second; } sub splitVersion($) { my $PROPOSED_VERSION = shift; $PROPOSED_VERSION =~ s/^\s+//g; # Get rid of any leading whitespace $PROPOSED_VERSION =~ s/\s+$//g; # Get rid of any trailing whitespace # Split out the components of the dotted version number. my @components = split(/\./, $PROPOSED_VERSION) or die "Couldn't parse $PROPOSED_VERSION"; my $componentCount = scalar(@components); my $BUILD_MAJOR_VERSION = $components[0]; # Have the minor and tiny components default to zero if not present. my $BUILD_MINOR_VERSION = 0; my $BUILD_TINY_VERSION = 0; my $BUILD_MICRO_VERSION = 0; my $BUILD_NANO_VERSION = 0; if ($componentCount > 1) { $BUILD_MINOR_VERSION = $components[1]; } if ($componentCount > 2) { $BUILD_TINY_VERSION = $components[2]; } if ($componentCount > 3) { $BUILD_MICRO_VERSION = $components[3]; } my $RETURN_NANO_VERSION = $ENV{'RC_ProjectBuildVersion'} || $ENV{'RC_PROJECTBUILDVERSION'} || $BUILD_MICRO_VERSION; if ($componentCount > 4) { $BUILD_NANO_VERSION = $components[4]; $RETURN_NANO_VERSION = $BUILD_NANO_VERSION; } # Cut the major component down to three characters by dropping any # extra leading digits, then adjust the major version portion of the # version string to match. my $originalLength = length($BUILD_MAJOR_VERSION); my $FULL_BUILD_MAJOR_VERSION = $BUILD_MAJOR_VERSION; $BUILD_MAJOR_VERSION =~ s/^.*(\d\d\d)$/$1/; my $charactersToRemove = $originalLength - length($BUILD_MAJOR_VERSION); $PROPOSED_VERSION = substr($PROPOSED_VERSION, $charactersToRemove); return ($BUILD_MAJOR_VERSION, packTwoValues($BUILD_MINOR_VERSION, $BUILD_TINY_VERSION), packTwoValues($BUILD_MICRO_VERSION, $BUILD_NANO_VERSION), $RETURN_NANO_VERSION, $PROPOSED_VERSION, $FULL_BUILD_MAJOR_VERSION); }