You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							103 lines
						
					
					
						
							3.8 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							103 lines
						
					
					
						
							3.8 KiB
						
					
					
				
								import argparse
							 | 
						|
								import subprocess
							 | 
						|
								import os
							 | 
						|
								from shutil import copyfile
							 | 
						|
								
							 | 
						|
								def get_dependencies(file):
							 | 
						|
								    # Call otool -L file to obtain the dependencies.
							 | 
						|
								    proc = subprocess.Popen(["otool", "-L", args.binary], stdout=subprocess.PIPE)
							 | 
						|
								    result = {}
							 | 
						|
								    for line_bytes in proc.stdout:
							 | 
						|
								        line = line_bytes.decode("utf-8").strip()
							 | 
						|
								        lib = line.split()[0]
							 | 
						|
								        if (lib.startswith("@")):
							 | 
						|
								            lib = lib.split("/", 1)[1]
							 | 
						|
								        (base, file) = os.path.split(lib)
							 | 
						|
								        print(base + " // " + file)
							 | 
						|
								    
							 | 
						|
								    return result
							 | 
						|
								
							 | 
						|
								def create_package(args):
							 | 
						|
								    create_package_dirs(args.dir)
							 | 
						|
								    copy_binary_to_package_dir(args.bin, args.binary_basename, args.dir)
							 | 
						|
								    run_dylibbundler(args.bundler_binary, args.dir, args.binary_basename)
							 | 
						|
								    pass
							 | 
						|
								
							 | 
						|
								def parse_arguments():
							 | 
						|
								    parser = argparse.ArgumentParser(description='Package the storm binary on Mac OS.')
							 | 
						|
								    parser.add_argument('--bin', dest='bin', help='the binary to package', default='storm')
							 | 
						|
								    parser.add_argument('--dir', dest='dir', help='the root directory of the package (will be created if it does not exist)', default='.')
							 | 
						|
								    parser.add_argument('--dylibbundler', dest='bundler_binary', help='the binary of the dylibbundler', default='dylibbundler')
							 | 
						|
								    args = parser.parse_args()
							 | 
						|
								    args.binary_dir = os.path.split(args.bin)[0]
							 | 
						|
								    args.binary_basename = os.path.split(args.bin)[1]
							 | 
						|
								    return args
							 | 
						|
								
							 | 
						|
								def create_package_dirs(root_dir):
							 | 
						|
								    if not os.path.exists(root_dir):
							 | 
						|
								        os.makedirs(root_dir)
							 | 
						|
								    if not os.path.exists(root_dir + "/bin"):
							 | 
						|
								        os.makedirs(root_dir + "/bin")
							 | 
						|
								    if not os.path.exists(root_dir + "/lib"):
							 | 
						|
								        os.makedirs(root_dir + "/bin")
							 | 
						|
								    pass
							 | 
						|
								
							 | 
						|
								def copy_binary_to_package_dir(binary, binary_basename, root_dir):
							 | 
						|
								    copyfile(binary, root_dir + "/bin/storm")
							 | 
						|
								    pass
							 | 
						|
								
							 | 
						|
								def run_dylibbundler(bundler_binary, root_dir, binary_basename):
							 | 
						|
								    command = [bundler_binary, "-cd", "-od", "-b", "-p", "@executable_path/../lib", "-x", root_dir + "/bin/" + binary_basename, "-d", root_dir + "/lib"]
							 | 
						|
								    print("executing " + str(command))
							 | 
						|
								    #proc = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
							 | 
						|
								    pass
							 | 
						|
								
							 | 
						|
								def fix_paths(root_dir, binary_basename):
							 | 
						|
								    fix_paths_file(root_dir + "/bin/" + binary_basename)
							 | 
						|
								    for file in os.listdir(root_dir + "/lib"):
							 | 
						|
								        fix_paths_file(root_dir + "/lib/" + file)
							 | 
						|
								        pass
							 | 
						|
								    pass
							 | 
						|
								
							 | 
						|
								def fix_paths_file(file):
							 | 
						|
								    print("fixing paths for " + file)
							 | 
						|
								    fixable_deps = get_fixable_deps(file)
							 | 
						|
								    for (path, lib) in fixable_deps:
							 | 
						|
								        change_fixable_dep(file, path, lib)
							 | 
						|
								
							 | 
						|
								native_libs = ["libc++.1.dylib", "libSystem.B.dylib"]
							 | 
						|
								
							 | 
						|
								def get_fixable_deps(file):
							 | 
						|
								    # Call otool -L file to obtain the dependencies.
							 | 
						|
								    proc = subprocess.Popen(["otool", "-L", file], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
							 | 
						|
								    result = []
							 | 
						|
								    for line_bytes in proc.stdout:
							 | 
						|
								        line = line_bytes.decode("utf-8").strip()
							 | 
						|
								        lib = line.split()[0]
							 | 
						|
								        if lib.startswith("@rpath/"):
							 | 
						|
								            result.append(("@rpath", lib.split("/", 1)[1]))
							 | 
						|
								        elif lib.startswith("/"):
							 | 
						|
								            path_file = os.path.split(lib)
							 | 
						|
								            if path_file[1] not in native_libs:
							 | 
						|
								                result.append((path_file[0], path_file[1]))
							 | 
						|
								    return result
							 | 
						|
								
							 | 
						|
								def change_fixable_dep(file, path, lib):
							 | 
						|
								    # Call install_name_tool to change the fixable dependencies
							 | 
						|
								    command = ["install_name_tool", "-change", path + "/" + lib, "@executable_path/../lib/" + lib, file]
							 | 
						|
								    print("executing " + str(command))
							 | 
						|
								    proc = subprocess.Popen(command, stdout=subprocess.PIPE)
							 | 
						|
								    #print ("after call to install_name_tool")
							 | 
						|
								    #proc = subprocess.Popen(["otool", "-L", file], stdout=subprocess.PIPE)
							 | 
						|
								    #for line_bytes in proc.stdout:
							 | 
						|
								    #    line = line_bytes.decode("utf-8").strip()
							 | 
						|
								    #    print(line)
							 | 
						|
								    pass
							 | 
						|
								
							 | 
						|
								if __name__ == "__main__":
							 | 
						|
								    args = parse_arguments()
							 | 
						|
								
							 | 
						|
								    #create_package(args)
							 | 
						|
								    fix_paths(args.dir, args.binary_basename)
							 | 
						|
								
							 | 
						|
								    
							 |