[26461] users/pipping/merge.rb
Kevin Ballard
eridius at macports.org
Sun Jun 24 22:22:57 PDT 2007
You are aware that the Mozilla project has a script that does exactly
this, right? IIRC it's called unify.pl.
-Kevin Ballard
On Jun 24, 2007, at 6:57 AM, source_changes at macosforge.org wrote:
> Revision
> 26461
> Author
> pipping at macports.org
> Date
> 2007-06-24 06:57:23 -0700 (Sun, 24 Jun 2007)
> Log Message
>
> initial upload of <merge.rb>
>
> merge.rb is designed to merge two or more trees of single-arch
> destdirs
> into a single destdir of universal binaries.
>
> build_coreutils.sh serves as a test, 'port destroot openssl
> +universal' can
> be used as well (port install zlib +universal is required)
>
> see ./merge.rb --help for the usage
> Added Paths
>
> users/pipping/merge.rb
> Diff
>
> Added: users/pipping/merge.rb (0 => 26461)
>
> --- users/pipping/merge.rb (rev 0)
> +++ users/pipping/merge.rb 2007-06-24 13:57:23 UTC (rev 26461)
> @@ -0,0 +1,221 @@
> +#!/usr/bin/env ruby -w
> +
> +# Copyright (c) 2007 Elias Pipping
> +#
> +# Permission is hereby granted, free of charge, to any person
> obtaining a copy
> +# of this software and associated documentation files (the
> "Software"), to deal
> +# in the Software without restriction, including without
> limitation the rights
> +# to use, copy, modify, merge, publish, distribute, sublicense,
> and/or sell
> +# copies of the Software, and to permit persons to whom the
> Software is
> +# furnished to do so, subject to the following conditions:
> +#
> +# The above copyright notice and this permission notice shall be
> included in
> +# all copies or substantial portions of the Software.
> +#
> +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> EXPRESS OR
> +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
> MERCHANTABILITY,
> +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
> EVENT SHALL THE
> +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
> OTHER
> +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
> ARISING FROM,
> +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
> DEALINGS IN
> +# THE SOFTWARE.
> +
> +require 'fileutils'
> +require 'find'
> +require 'optparse'
> +require 'set'
> +
> +###
> +# we need GNU file with Apple's patches applied, available here:
> +# http://www.opensource.apple.com/darwinsource/Current/file-6.2/
> patches/
> +#
> +# Its output might span multiple lines, causing problems when
> parsing, even
> +# with `file -b`, hence we'll assume we're not passed universal
> binaries
> +# TODO: do a real check, maybe using `lipo -info` (fails on non-
> Mach-O files)
> +FILE="/usr/bin/file"
> +
> +class MergeArguments < Hash
> + def initialize(args)
> + super()
> +
> + # set up defaults
> + self[:dry_run] = false
> + self[:force] = false
> + self[:verbose] = false
> +
> + self[:exclude] = Set.new << '.svn' << 'CVS'
> + self[:root] = Dir.pwd
> +
> + opts = OptionParser.new do |opts|
> + opts.banner = "Usage: #$0 [options] <arch> <arch> [<arch> ...]"
> +
> + opts.on('-r', '--root DIRECTORY', 'specify root directory')
> do |root|
> + self[:root] = root || Dir.pwd
> + end
> +
> +# opts.on('-o', '--output DIRECTORY', 'specify output
> directory') do |out|
> +# self[:output] = File.expand_path(out) || File.join(self
> [:root], 'out')
> +# end
> +
> + opts.on('-e', '--exclude NAMES', 'specify names of files/
> directories to exclude') do |exclude|
> + self[:exclude] = Set.new
> + exclude.split(" ").each do |item|
> + self[:exclude] << item
> + end
> + end
> +
> + opts.on('-d', '--dry-run', 'perform a dry run') do
> + self[:dry_run] = true
> + end
> +
> + opts.on('-f', '--force', 'force writing, ignoring
> collisions') do
> + self[:force] = true
> + end
> +
> + opts.on('-v', '--verbose', 'enable verbose output') do
> + self[:verbose] = true
> + end
> +
> + opts.on_tail('-h', '--help', 'display this help and exit') do
> + puts opts
> + exit
> + end
> + end
> +
> + opts.parse!(args)
> + end
> +end
> +
> +arguments = MergeArguments.new(ARGV)
> +
> +ARGS=ARGV.uniq
> +
> +def true_for_all? (filepath, args, &block)
> + result=true
> + ARGS.each {|arch|
> + result=false unless yield(File.join(args[:root], arch),
> filepath, arch)
> + }
> + return result
> +end
> +
> +def lipo (filepath,architectures,args)
> + lipoargs = Array.new
> + architectures.each {|arch|
> + lipoargs << sprintf('-arch %s %s', arch, File.join(
> + args[:root], arch, filepath
> + ))
> + }
> + lipotarget=File.join(args[:root], 'out', filepath)
> + lipocmd = sprintf(
> + 'lipo %s -create -o %s',
> + lipoargs.join(' '),
> + lipotarget
> + )
> + if !File.exist?(lipotarget) or args[:force]
> + puts lipocmd if args[:verbose]
> + system lipocmd if !args[:dry_run]
> + end
> +end
> +
> +original_dir=Dir.pwd
> +processed=Set.new
> +
> +if File.directory?(File.expand_path(arguments[:root]))
> + ARGS.each {|architecture|
> + FileUtils.cd original_dir, :verbose => false
> + if File.directory? File.join(
> + File.expand_path(arguments[:root]), architecture
> + )
> + FileUtils.cd(
> + File.join(arguments[:root], architecture),
> + :verbose => arguments[:verbose]
> + )
> + Find.find('.') {|path|
> + arguments[:exclude].each {|exclude_me|
> + Find.prune if File.basename(path) == exclude_me
> + }
> + unless processed.include? path
> + my_dir=File.dirname(File.join(arguments[:root], 'out',
> path))
> + # TODO: what if ppc/foo is a dir and i386/foo is a file
> (symlink)? (1)
> + unless File.exist? my_dir
> + FileUtils.mkdir_p(
> + my_dir,
> + :verbose => arguments[:verbose],
> + :noop => arguments[:dry_run]
> + )
> + end
> + if true_for_all?(path, arguments) {|dir,filename,arch|
> + File.exist?(File.join(dir, filename))
> + }
> + unless true_for_all?(path, arguments) {|
> dir,filename,arch|
> + File.directory?(File.join(dir, filename))
> + }
> +
> + if true_for_all?(path, arguments) {|dir,filename,arch|
> + FileUtils.identical?(
> + File.join(dir, path),
> + File.join(arguments[:root], ARGS[0], path)
> + )
> + }
> + copytarget=File.join(arguments[:root],'out',path)
> + if !File.exist?(copytarget) or arguments[:force]
> + FileUtils.cp(
> + File.join(arguments[:root],ARGS[0],path),
> + copytarget,
> + :preserve => !arguments[:force],
> + :verbose => arguments[:verbose],
> + :noop => arguments [:dry_run]
> + )
> + end
> + else
> + # TODO: make this not-blindly lipo but check
> filetypes / archs
> + # TODO: beware of symlinks!
> + case File.basename path
> + when /\.dylib(\.\d*)*/, /\.so(\.\d*)*/, /\.a$/
> + lipo(path,ARGS,arguments)
> + when /\.h$/, /\.hpp$/
> + # TODO: handle header files
> + when /\.pc$/
> + # TODO: handle pkgconfig files
> + when /\.sh$/
> + # TODO: handle shell scripts
> + else
> + case %x{#{FILE} -b "#{File.join(arguments
> [:root],ARGS[0],path)}"}
> + when sprintf("Mach-O executable %s\n", ARGS[0])
> + if true_for_all?(path, arguments) {|
> dir,filename,arch|
> + %x{#{FILE} -b "#{File.join(dir,path)}"} ==
> sprintf("Mach-O executable %s\n", arch)
> + }
> + lipo(path,ARGS,arguments)
> + else
> + # one of the files is a mach-o file that
> matches its
> + # desired architecture but one of the others
> doesn't
> + end
> + # else
> + # TODO: deal with whatever else can differ
> + end
> + end
> + end
> + else
> + # TODO: at least one of the files is a directory (1)
> + end
> + else
> + # TODO: a file is not present in all trees. what's wrong?
> + end
> + processed << path
> + end
> + }
> + else
> + raise sprintf(
> + 'architecture missing from root directory: %s',
> + architecture
> + )
> + end
> + }
> +else
> + raise sprintf(
> + 'invalid root directory: %s',
> + arguments[:root]
> + )
> +end
> +
> +FileUtils.cd original_dir, :verbose => false
> Property changes on: users/pipping/merge.rb
> ___________________________________________________________________
> Name: svn:executable
> + *
> _______________________________________________
> macports-changes mailing list
> macports-changes at lists.macosforge.org
> http://lists.macosforge.org/mailman/listinfo/macports-changes
--
Kevin Ballard
http://kevin.sb.org
eridius at macports.org
http://www.tildesoft.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/macports-dev/attachments/20070624/2cd32bfe/attachment.html
More information about the macports-dev
mailing list