diff --git a/cocoapods-binary.gemspec b/cocoapods-binary.gemspec index 235e945..697aeb2 100644 --- a/cocoapods-binary.gemspec +++ b/cocoapods-binary.gemspec @@ -20,6 +20,7 @@ Gem::Specification.new do |spec| spec.add_dependency "cocoapods", ">= 1.5.0", "< 2.0" spec.add_dependency "fourflusher", "~> 2.0" + spec.add_dependency "xcpretty", "~> 0.3.0" spec.add_development_dependency 'bundler', '~> 1.3' spec.add_development_dependency 'rake' diff --git a/lib/cocoapods-binary/Main.rb b/lib/cocoapods-binary/Main.rb index 957c1fa..71bd3d4 100644 --- a/lib/cocoapods-binary/Main.rb +++ b/lib/cocoapods-binary/Main.rb @@ -24,6 +24,32 @@ def keep_source_code_for_prebuilt_frameworks! DSL.dont_remove_source_code = true end + # Add custom xcodebuild option to the prebuiling aciton + # + # You may use this for your special demands. For example: the default archs in dSYMs + # of prebuilt frameworks is 'arm64 armv7 x86_64', and no 'i386' for 32bit simulator. + # It may generate a warning when building for a 32bit simulator. You may add following + # to your podfile + # + # ` set_custom_xcodebuild_options_for_prebuilt_frameworks :simulator => "ARCHS=$(ARCHS_STANDARD)" ` + # + # @options String or Hash + # + # If is a String, it will apply for device and simulator. Use it just like in the commandline. + # If is a Hash, it should be like this: { :device => "XXXXX", :simulator => "XXXXX" } + # + def set_custom_xcodebuild_options_for_prebuilt_frameworks(options) + if options.kind_of? Hash + DSL.custom_build_options = [ options[:device] ] unless options[:device].nil? + DSL.custom_build_options_simulator = [ options[:simulator] ] unless options[:simulator].nil? + elsif options.kind_of? String + DSL.custom_build_options = [options] + DSL.custom_build_options_simulator = [options] + else + raise "Wrong type." + end + end + private class_attr_accessor :prebuild_all prebuild_all = false @@ -33,6 +59,11 @@ def keep_source_code_for_prebuilt_frameworks! class_attr_accessor :dont_remove_source_code dont_remove_source_code = false + + class_attr_accessor :custom_build_options + class_attr_accessor :custom_build_options_simulator + self.custom_build_options = [] + self.custom_build_options_simulator = [] end end end diff --git a/lib/cocoapods-binary/Prebuild.rb b/lib/cocoapods-binary/Prebuild.rb index e5a69c5..9814932 100644 --- a/lib/cocoapods-binary/Prebuild.rb +++ b/lib/cocoapods-binary/Prebuild.rb @@ -120,7 +120,7 @@ def prebuild_frameworks! output_path = sandbox.framework_folder_path_for_pod_name(target.name) output_path.mkpath unless output_path.exist? - Pod::Prebuild.build(sandbox_path, target, output_path, bitcode_enabled) + Pod::Prebuild.build(sandbox_path, target, output_path, bitcode_enabled, Podfile::DSL.custom_build_options, Podfile::DSL.custom_build_options_simulator) # save the resource paths for later installing if target.static_framework? and !target.resource_paths.empty? diff --git a/lib/cocoapods-binary/rome/build_framework.rb b/lib/cocoapods-binary/rome/build_framework.rb index 3d038f2..d2c160a 100644 --- a/lib/cocoapods-binary/rome/build_framework.rb +++ b/lib/cocoapods-binary/rome/build_framework.rb @@ -1,4 +1,5 @@ require 'fourflusher' +require 'xcpretty' CONFIGURATION = "Release" PLATFORMS = { 'iphonesimulator' => 'iOS', @@ -15,7 +16,10 @@ def build_for_iosish_platform(sandbox, target, device, simulator, - bitcode_enabled) + bitcode_enabled, + custom_build_options = [], # Array + custom_build_options_simulator = [] # Array + ) deployment_target = target.platform.deployment_target.to_s @@ -26,8 +30,11 @@ def build_for_iosish_platform(sandbox, if bitcode_enabled other_options += ['BITCODE_GENERATION_MODE=bitcode'] end - xcodebuild(sandbox, target_label, device, deployment_target, other_options) - xcodebuild(sandbox, target_label, simulator, deployment_target, other_options + ['ARCHS=x86_64', 'ONLY_ACTIVE_ARCH=NO']) + + is_succeed, _ = xcodebuild(sandbox, target_label, device, deployment_target, other_options + custom_build_options) + exit 1 unless is_succeed + is_succeed, _ = xcodebuild(sandbox, target_label, simulator, deployment_target, other_options + ['ARCHS=x86_64', 'ONLY_ACTIVE_ARCH=NO'] + custom_build_options_simulator) + exit 1 unless is_succeed # paths root_name = target.pod_name @@ -80,10 +87,14 @@ def build_for_iosish_platform(sandbox, device_dsym = "#{device_framework_path}.dSYM" if File.exist? device_dsym # lipo the simulator dsym - tmp_lipoed_binary_path = "#{output_path}/#{module_name}.draft" - lipo_log = `lipo -create -output #{tmp_lipoed_binary_path} #{device_dsym}/Contents/Resources/DWARF/#{module_name} #{simulator_framework_path}.dSYM/Contents/Resources/DWARF/#{module_name}` - puts lipo_log unless File.exist?(tmp_lipoed_binary_path) - FileUtils.mv tmp_lipoed_binary_path, "#{device_framework_path}.dSYM/Contents/Resources/DWARF/#{module_name}", :force => true + simulator_dsym = "#{simulator_framework_path}.dSYM" + if File.exist? simulator_dsym + tmp_lipoed_binary_path = "#{output_path}/#{module_name}.draft" + lipo_log = `lipo -create -output #{tmp_lipoed_binary_path} #{device_dsym}/Contents/Resources/DWARF/#{module_name} #{simulator_dsym}/Contents/Resources/DWARF/#{module_name}` + puts lipo_log unless File.exist?(tmp_lipoed_binary_path) + FileUtils.mv tmp_lipoed_binary_path, "#{device_framework_path}.dSYM/Contents/Resources/DWARF/#{module_name}", :force => true + end + # move FileUtils.mv device_dsym, output_path, :force => true end @@ -98,7 +109,23 @@ def xcodebuild(sandbox, target, sdk='macosx', deployment_target=nil, other_optio platform = PLATFORMS[sdk] args += Fourflusher::SimControl.new.destination(:oldest, platform, deployment_target) unless platform.nil? args += other_options - Pod::Executable.execute_command 'xcodebuild', args, true + log = `xcodebuild #{args.join(" ")} 2>&1` + exit_code = $?.exitstatus # Process::Status + is_succeed = (exit_code == 0) + + if !is_succeed + begin + # 64 represent command invalid. http://www.manpagez.com/man/3/sysexits/ + raise "shouldn't be handle by xcpretty" if exit_code == 64 + printer = XCPretty::Printer.new({:formatter => XCPretty::Simple, :colorize => 'auto'}) + log.each_line do |line| + printer.pretty_print(line) + end + rescue + puts log + end + end + [is_succeed, log] end @@ -117,7 +144,7 @@ class Prebuild # [Pathname] output_path # output path for generated frameworks # - def self.build(sandbox_root_path, target, output_path, bitcode_enabled = false) + def self.build(sandbox_root_path, target, output_path, bitcode_enabled = false, custom_build_options=[], custom_build_options_simulator=[]) return unless not target == nil @@ -127,8 +154,8 @@ def self.build(sandbox_root_path, target, output_path, bitcode_enabled = false) # -- build the framework case target.platform.name - when :ios then build_for_iosish_platform(sandbox, build_dir, output_path, target, 'iphoneos', 'iphonesimulator', bitcode_enabled) - when :osx then xcodebuild(sandbox, target.label) + when :ios then build_for_iosish_platform(sandbox, build_dir, output_path, target, 'iphoneos', 'iphonesimulator', bitcode_enabled, custom_build_options, custom_build_options_simulator) + when :osx then xcodebuild(sandbox, target.label, 'macosx', nil, custom_build_options) # when :tvos then build_for_iosish_platform(sandbox, build_dir, target, 'appletvos', 'appletvsimulator') # when :watchos then build_for_iosish_platform(sandbox, build_dir, target, 'watchos', 'watchsimulator') else raise "Unsupported platform for '#{target.name}': '#{target.platform.name}'" end