1#!/usr/bin/perl 2# 3# Copyright (c) 2010 Apple Inc. All rights reserved. 4# 5# @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 6# 7# This file contains Original Code and/or Modifications of Original Code 8# as defined in and that are subject to the Apple Public Source License 9# Version 2.0 (the 'License'). You may not use this file except in 10# compliance with the License. The rights granted to you under the License 11# may not be used to create, or enable the creation or redistribution of, 12# unlawful or unlicensed copies of an Apple operating system, or to 13# circumvent, violate, or enable the circumvention or violation of, any 14# terms of an Apple operating system software license agreement. 15# 16# Please obtain a copy of the License at 17# http://www.opensource.apple.com/apsl/ and read it before using this file. 18# 19# The Original Code and all software distributed under the License are 20# distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 21# EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 22# INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 23# FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 24# Please see the License for the specific language governing rights and 25# limitations under the License. 26# 27# @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 28# 29 30use warnings; 31use strict; 32 33use Data::Dumper; 34use File::Spec; 35use IO::File; 36use File::Basename (); 37 38my $basename = File::Basename::basename($0); 39 40sub usage { 41 print "$basename: <source list> <output archive>"; 42 exit 1; 43} 44 45usage unless scalar(@ARGV) == 2; 46 47my $sourceList = $ARGV[0]; 48my $outputFile = $ARGV[1]; 49 50my $f = IO::File->new($sourceList, 'r'); 51die "$basename: $sourceList: $!\n" unless defined($f); 52 53my @objects; 54my @archs = split / /, $ENV{"ARCHS"}; 55my @sources = <$f>; 56chomp @sources; 57 58undef $f; 59 60# compiler options 61chomp(my $CC = `xcrun -sdk "$ENV{'SDKROOT'}" -find cc`); 62my @CFLAGS = ( 63 "-x assembler-with-cpp", 64 "-c", 65 "-I".$ENV{"SDKROOT"}."/System/Library/Frameworks/System.framework/PrivateHeaders", 66); 67 68chomp(my $LIBTOOL = `xcrun -sdk "$ENV{'SDKROOT'}" -find libtool`); 69my @LIBTOOLFLAGS = ( 70 "-static", 71); 72 73# architectures 74for my $arch (@archs) { 75 push(@CFLAGS, "-arch $arch"); 76} 77 78# do each compile 79my $jobs = `sysctl -n hw.ncpu` + 2; 80 81for my $src (@sources) { 82 if ($jobs == 0) { 83 if (wait != -1) { 84 $jobs++; 85 } else { 86 printf "wait exited with -1 (no children) and exhausted allowed jobs. Exiting.\n"; 87 exit 1; 88 } 89 90 if ($? != 0) { 91 printf "$CC exited with value %d\n", $? >> 8; 92 exit 1; 93 } 94 } 95 96 (my $o = $src) =~ s/\.s$/\.o/; 97 my $compileCommand = "$CC " . join(' ', @CFLAGS) . " -o $o $src"; 98 printf $compileCommand . "\n"; 99 100 $jobs--; 101 my $pid = fork(); 102 if ($pid == 0) { 103 exec($compileCommand); 104 } 105 push(@objects, $o); 106} 107 108while (wait != -1) { 109 if ($? != 0) { 110 printf "$CC exited with value %d\n", $? >> 8; 111 exit 1; 112 } 113} 114 115printf "Finished assembly, beginning link.\n"; 116 117# final link 118 119if (-f $outputFile) { 120 unlink($outputFile); 121} 122 123my $linkCommand = "$LIBTOOL " . join(' ', @LIBTOOLFLAGS) . " -o $outputFile " . join(' ', @objects); 124 125printf $linkCommand . "\n"; 126system($linkCommand); 127if ($? != 0) { 128 print "$LIBTOOL exited with value %d\n", $? >> 8; 129 exit 1; 130} 131