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