mirror of
https://github.com/melonDS-emu/melonDS.git
synced 2024-11-14 13:27:41 -07:00
Rewrite mac-libs.sh, should work on 10.14 now finally
This commit is contained in:
parent
1846a71265
commit
d3d5f45914
227
tools/mac-libs.rb
Executable file
227
tools/mac-libs.rb
Executable file
@ -0,0 +1,227 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
require "open3"
|
||||
require "fileutils"
|
||||
|
||||
$app_name = "melonDS"
|
||||
$build_dmg = false
|
||||
$build_dir = ""
|
||||
$bundle = ""
|
||||
$fallback_rpaths = ["/usr/local/lib", "/opt/local/lib"]
|
||||
|
||||
def frameworks_dir
|
||||
File.join($bundle, "Contents", "Frameworks")
|
||||
end
|
||||
|
||||
def executable
|
||||
File.join($bundle, "Contents", "MacOS", $app_name)
|
||||
end
|
||||
|
||||
def get_rpaths(lib)
|
||||
out = `otool -l #{lib}`.split("\n")
|
||||
rpaths = []
|
||||
|
||||
out.each_with_index do |line, i|
|
||||
if line.match(/^ *cmd LC_RPATH$/)
|
||||
rpaths << out[i + 2].strip.split(" ")[1]
|
||||
end
|
||||
end
|
||||
|
||||
return rpaths
|
||||
end
|
||||
|
||||
def get_load_libs(lib)
|
||||
`otool -L #{lib}`
|
||||
.split("\n")
|
||||
.drop(1)
|
||||
.map { |it| it.strip.gsub(/ \(.*/, "") }
|
||||
end
|
||||
|
||||
def expand_load_path(lib, path)
|
||||
if path.match(/@(rpath|loader_path|executable_path)/)
|
||||
path_type = $1
|
||||
file_name = path.gsub(/^@#{path_type}\//, "")
|
||||
|
||||
case path_type
|
||||
when "rpath"
|
||||
get_rpaths(lib).each do |rpath|
|
||||
file = File.join(rpath, file_name)
|
||||
return file, :rpath if File.exist? file
|
||||
if rpath.match? /^@executable_path(.*)/
|
||||
relative = rpath.sub(/^@executable_path/, "")
|
||||
return "#{$bundle}/Contents/MacOS#{relative}", :executable_path
|
||||
end
|
||||
end
|
||||
file = $fallback_rpaths
|
||||
.map { |it| File.join(it, file_name) }
|
||||
.find { |it| File.exist? it }
|
||||
return file, :rpath if file
|
||||
when "executable_path"
|
||||
file = File.join(File.dirname(executable), file_name)
|
||||
return file, :executable_path if File.exist? file
|
||||
when "loader_path"
|
||||
file = File.join(File.dirname(lib), file_name)
|
||||
return file, :loader_path if File.exist? file
|
||||
else
|
||||
throw "Unknown @path type"
|
||||
end
|
||||
else
|
||||
return File.absolute_path(path), :absolute
|
||||
end
|
||||
|
||||
puts lib
|
||||
puts path
|
||||
exit
|
||||
return nil
|
||||
end
|
||||
|
||||
def system_path?(path)
|
||||
path.match(/^\/usr\/lib|^\/System/) != nil
|
||||
end
|
||||
|
||||
def system_lib?(lib)
|
||||
system_path? File.dirname(lib)
|
||||
end
|
||||
|
||||
def install_name_tool(exec, action, path1, path2 = nil)
|
||||
args = ["-#{action.to_s}", path1]
|
||||
args << path2 if path2 != nil
|
||||
|
||||
FileUtils.chmod("u+w", exec)
|
||||
out, status = Open3.capture2e("install_name_tool", *args, exec)
|
||||
if status != 0
|
||||
puts out
|
||||
exit status
|
||||
end
|
||||
end
|
||||
|
||||
def fixup_libs(prog, orig_path)
|
||||
throw "fixup_libs: #{prog} doesn't exist" unless File.exist? prog
|
||||
|
||||
libs = get_load_libs(prog).map { |it| expand_load_path(orig_path, it) }.select { |it| not system_lib? it[0] }
|
||||
|
||||
libs.each do |lib|
|
||||
libpath, libtype = lib
|
||||
if File.basename(libpath) == File.basename(prog)
|
||||
if libtype == :absolute
|
||||
install_name_tool prog, :change, libpath, File.join("@rpath", File.basename(libpath))
|
||||
end
|
||||
next
|
||||
end
|
||||
|
||||
framework = libpath.match(/(.*).framework/)
|
||||
framework = framework.to_s if framework
|
||||
|
||||
if framework
|
||||
fwlib = libpath.sub(framework + "/", "")
|
||||
fwname = File.basename(framework)
|
||||
|
||||
unless libtype == :rpath
|
||||
install_name_tool prog, :change, libpath, File.join("@rpath", fwname, fwlib)
|
||||
end
|
||||
|
||||
next if File.exist? File.join(frameworks_dir, fwname)
|
||||
expath, _ = expand_load_path(orig_path, framework)
|
||||
FileUtils.cp_r(expath, frameworks_dir, preserve: true)
|
||||
fixup_libs File.join(frameworks_dir, fwname, fwlib), libpath
|
||||
else
|
||||
libname = File.basename(libpath)
|
||||
dest = File.join(frameworks_dir, libname)
|
||||
|
||||
if libtype == :absolute
|
||||
install_name_tool prog, :change, libpath, File.join("@rpath", libname)
|
||||
end
|
||||
|
||||
next if File.exist? dest
|
||||
expath, _ = expand_load_path(orig_path, libpath)
|
||||
FileUtils.copy expath, frameworks_dir
|
||||
fixup_libs dest, libpath
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if ARGV[0] == "--dmg"
|
||||
$build_dmg = true
|
||||
ARGV.shift
|
||||
end
|
||||
|
||||
if ARGV.length != 1
|
||||
puts "Usage: #{Process.argv0} [--dmg] <build-dir>"
|
||||
return
|
||||
end
|
||||
|
||||
$build_dir = ARGV[0]
|
||||
unless File.exist? $build_dir
|
||||
puts "#{$build_dir} doesn't exist"
|
||||
end
|
||||
|
||||
|
||||
$bundle = File.join($build_dir, "#{$app_name}.app")
|
||||
|
||||
unless File.exist? $bundle and File.exist? File.join($build_dir, "CMakeCache.txt")
|
||||
puts "#{$build_dir} doesn't look like a valid build directory"
|
||||
exit 1
|
||||
end
|
||||
|
||||
File.read(File.join($build_dir, "CMakeCache.txt"))
|
||||
.split("\n")
|
||||
.find { |it| it.match /Qt(.)_DIR:PATH=(.*)/ }
|
||||
|
||||
qt_major = $1
|
||||
qt_dir = $2
|
||||
qt_dir = File.absolute_path("#{qt_dir}/../../..")
|
||||
|
||||
$fallback_rpaths << File.join(qt_dir, "lib")
|
||||
|
||||
plugin_paths = [
|
||||
File.join(qt_dir, "libexec", "qt#{qt_major}", "plugins"),
|
||||
File.join(qt_dir, "plugins"),
|
||||
File.join(qt_dir, "share", "qt", "plugins")
|
||||
]
|
||||
|
||||
qt_plugins = plugin_paths.find { |file| File.exist? file }
|
||||
|
||||
if qt_plugins == nil
|
||||
puts "Couldn't find Qt plugins, tried looking for:"
|
||||
plugin_paths.each { |path| puts " - #{path}" }
|
||||
exit 1
|
||||
end
|
||||
|
||||
FileUtils.mkdir_p(frameworks_dir)
|
||||
fixup_libs(executable, executable)
|
||||
|
||||
bundle_plugins = File.join($bundle, "Contents", "PlugIns")
|
||||
|
||||
want_plugins = ["styles/libqmacstyle.dylib", "platforms/libqcocoa.dylib"]
|
||||
want_plugins.each do |plug|
|
||||
destdir = File.join(bundle_plugins, File.dirname(plug))
|
||||
FileUtils.mkdir_p(destdir)
|
||||
FileUtils.copy(File.join(qt_plugins, plug), destdir)
|
||||
fixup_libs File.join(bundle_plugins, plug), File.join(qt_plugins, plug)
|
||||
end
|
||||
|
||||
want_rpath = "@executable_path/../Frameworks"
|
||||
exec_rpaths = get_rpaths(executable)
|
||||
exec_rpaths.select { |path| path != want_rpath }.each do |path|
|
||||
install_name_tool executable, :delete_rpath, path
|
||||
end
|
||||
|
||||
unless exec_rpaths.include? want_rpath
|
||||
install_name_tool executable, :add_rpath, want_rpath
|
||||
end
|
||||
|
||||
exec_rpaths = get_rpaths(executable)
|
||||
|
||||
Dir.glob("#{frameworks_dir}/**/Headers").each do |dir|
|
||||
FileUtils.rm_rf dir
|
||||
end
|
||||
|
||||
if $build_dmg
|
||||
dmg_dir = File.join($build_dir, "dmg")
|
||||
FileUtils.mkdir_p(dmg_dir)
|
||||
FileUtils.cp_r($bundle, dmg_dir, preserve: true)
|
||||
FileUtils.ln_s("/Applications", File.join(dmg_dir, "Applications"))
|
||||
|
||||
`hdiutil create -fs HFS+ -volname melonDS -srcfolder "#{dmg_dir}" -ov -format UDBZ "#{$build_dir}/melonDS.dmg"`
|
||||
FileUtils.rm_rf(dmg_dir)
|
||||
end
|
Loading…
Reference in New Issue
Block a user