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 "-isysroot", $ENV{'SDKROOT'} || "/", 66 "-I".$ENV{"SDKROOT"}."/System/Library/Frameworks/System.framework/PrivateHeaders", 67); 68 69chomp(my $LIBTOOL = `xcrun -sdk "$ENV{'SDKROOT'}" -find libtool`); 70my @LIBTOOLFLAGS = ( 71 "-static", 72); 73 74# architectures 75for my $arch (@archs) { 76 push(@CFLAGS, "-arch $arch"); 77} 78 79# do each compile 80my $jobs = `sysctl -n hw.ncpu` + 2; 81 82for my $src (@sources) { 83 if ($jobs == 0) { 84 if (wait != -1) { 85 $jobs++; 86 } else { 87 printf "wait exited with -1 (no children) and exhausted allowed jobs. Exiting.\n"; 88 exit 1; 89 } 90 91 if ($? != 0) { 92 printf "$CC exited with value %d\n", $? >> 8; 93 exit 1; 94 } 95 } 96 97 (my $o = $src) =~ s/\.s$/\.o/; 98 my $compileCommand = "$CC " . join(' ', @CFLAGS) . " -o $o $src"; 99 printf $compileCommand . "\n"; 100 101 $jobs--; 102 my $pid = fork(); 103 if ($pid == 0) { 104 exec($compileCommand); 105 } 106 push(@objects, $o); 107} 108 109while (wait != -1) { 110 if ($? != 0) { 111 printf "$CC exited with value %d\n", $? >> 8; 112 exit 1; 113 } 114} 115 116printf "Finished assembly, beginning link.\n"; 117 118# final link 119 120if (-f $outputFile) { 121 unlink($outputFile); 122} 123 124my $linkCommand = "$LIBTOOL " . join(' ', @LIBTOOLFLAGS) . " -o $outputFile " . join(' ', @objects); 125 126printf $linkCommand . "\n"; 127system($linkCommand); 128if ($? != 0) { 129 print "$LIBTOOL exited with value %d\n", $? >> 8; 130 exit 1; 131} 132