class CBin::Framework::Builder

Public Class Methods

new(spec, file_accessor, platform, source_dir, isRootSpec = true, build_model="Debug") click to toggle source

Debug下还待完成

# File lib/cocoapods-tdf-bin/helpers/framework_builder.rb, line 13
def initialize(spec, file_accessor, platform, source_dir, isRootSpec = true, build_model="Debug")
  @spec = spec
  @source_dir = source_dir
  @file_accessor = file_accessor
  @platform = platform
  @build_model = build_model
  @isRootSpec = isRootSpec
  #vendored_static_frameworks 只有 xx.framework  需要拼接为 xx.framework/xx by slj
  vendored_static_frameworks = file_accessor.vendored_static_frameworks.map do |framework|
    path = framework
    extn = File.extname  path
    if extn.downcase == '.framework'
      path = File.join(path,File.basename(path, extn))
    end
    path
  end

  @vendored_libraries = (vendored_static_frameworks + file_accessor.vendored_static_libraries).map(&:to_s)
end

Public Instance Methods

build() click to toggle source
# File lib/cocoapods-tdf-bin/helpers/framework_builder.rb, line 33
def build
  defines = compile
  build_sim_libraries(defines)

  defines
end
lipo_build(defines) click to toggle source
# File lib/cocoapods-tdf-bin/helpers/framework_builder.rb, line 40
def lipo_build(defines)
  UI.section("Building static Library #{@spec}") do

    cp_framework_to_source_dir
    build_static_library_for_ios

    copy_resources

  end
  framework
end

Private Instance Methods

build_sim_libraries(defines) click to toggle source

模拟器,目前只支持 debug x86-64

# File lib/cocoapods-tdf-bin/helpers/framework_builder.rb, line 78
def build_sim_libraries(defines)
  UI.message 'Building simulator libraries'

  # archs = %w[i386 x86_64]
  archs = ios_architectures_sim
  archs.map do |arch|
    xcodebuild(defines, "-sdk iphonesimulator ARCHS=\'#{arch}\' ", "build-#{arch}",@build_model)
  end
end
build_static_library_for_ios() click to toggle source

lipo合并 二进制

# File lib/cocoapods-tdf-bin/helpers/framework_builder.rb, line 100
def build_static_library_for_ios
  UI.message "Building ios libraries with archs #{ios_architectures}"

  framework_name = "#{@spec.name}.framework/#{@spec.name}"
  output = File.join(CBin::Config::Builder.instance.zip_dir,framework_name)

  build_path = Pathname("build")
  build_path.path unless build_path.exist?

  # if is_debug_model
  libs = (ios_architectures + ios_architectures_sim) .map do |arch|
    library = "build-#{arch}/#{@spec.name}.framework/#{@spec.name}"
    library
  end

  UI.message "lipo -create -output #{output} #{libs.join(' ')}"
  `lipo -create -output #{output} #{libs.join(' ')}`
end
compile() click to toggle source
# File lib/cocoapods-tdf-bin/helpers/framework_builder.rb, line 150
def compile
  defines = "GCC_PREPROCESSOR_DEFINITIONS='$(inherited)'"
  defines += ' '
  defines += @spec.consumer(@platform).compiler_flags.join(' ')

  options = ios_build_options
  # if is_debug_model
  archs = ios_architectures
  # archs = %w[arm64 armv7 armv7s]
  archs.map do |arch|
    xcodebuild(defines, "ARCHS=\'#{arch}\' OTHER_CFLAGS=\'-fembed-bitcode -Qunused-arguments\'","build-#{arch}",@build_model)
  end
  # else
  # xcodebuild(defines,options)
  # end

  defines
end
copy_resources() click to toggle source
# File lib/cocoapods-tdf-bin/helpers/framework_builder.rb, line 205
def copy_resources
  resource_dir = './build/*.bundle'
  resource_dir = './build-armv7/*.bundle' if File.exist?('./build-armv7')
  resource_dir = './build-arm64/*.bundle' if File.exist?('./build-arm64')

  framework_name = "#{@spec.name}.framework"
  resource_target_dir = File.join(CBin::Config::Builder.instance.zip_dir,framework_name,"Resources")

  FileUtils.mkdir_p(resource_target_dir) unless File.exist?(resource_target_dir)

  bundles = Dir.glob(resource_dir)

  bundle_names = [@spec, *@spec.recursive_subspecs].flat_map do |spec|
    consumer = spec.consumer(@platform)
    consumer.resource_bundles.keys +
      consumer.resources.map do |r|
        File.basename(r, '.bundle') if File.extname(r) == 'bundle'
      end
  end.compact.uniq

  bundles.select! do |bundle|
    bundle_name = File.basename(bundle, '.bundle')
    bundle_names.include?(bundle_name)
  end

  if bundles.count > 0
    UI.message "Copying bundle files #{bundles}"
    bundle_files = bundles.join(' ')
    `cp -rp #{bundle_files} #{resource_target_dir} 2>&1`
  end

  real_source_dir = @source_dir
  unless @isRootSpec
    spec_source_dir = File.join(Dir.pwd,"#{@spec.name}")
    unless File.exist?(spec_source_dir)
      spec_source_dir = File.join(Dir.pwd,"Pods/#{@spec.name}")
    end
    raise "copy_resources #{spec_source_dir} no exist " unless File.exist?(spec_source_dir)

    real_source_dir = spec_source_dir
  end
  resources = [@spec, *@spec.recursive_subspecs].flat_map do |spec|
    expand_paths(real_source_dir, spec.consumer(@platform).resources)
  end.compact.uniq

  if resources.count == 0 && bundles.count == 0
    framework.delete_resources
    return
  end

  if resources.count > 0
    #把 路径转义。 避免空格情况下拷贝失败
    escape_resource = []
    resources.each do |source|
      escape_resource << Shellwords.join(source)
    end

    escape_resource_str = escape_resource.join(' ')
    escape_resource_arr = escape_resource_str.split(' ')

    escape_resource_arr = escape_resource_arr.select do | source |
      suffix = File.extname(source)
      not expand_suffix(suffix)
    end

    UI.message "Copying resources #{escape_resource_arr}"
    `cp -rp #{escape_resource_arr.join(' ')} #{resource_target_dir}`
  end
end
cp_framework_to_source_dir() click to toggle source
# File lib/cocoapods-tdf-bin/helpers/framework_builder.rb, line 54
def cp_framework_to_source_dir
  framework_name = "#{@spec.name}.framework"
  framework_dir = "./build-armv7/#{framework_name}" if File.exist?('./build-armv7')
  framework_dir = "./build-arm64/#{framework_name}" if File.exist?('./build-arm64')
  target_dir = File.join(CBin::Config::Builder.instance.zip_dir,framework_name)

  zip_dir = CBin::Config::Builder.instance.zip_dir
  FileUtils.mkdir_p(zip_dir) unless File.exist?(zip_dir)

  `cp -fa #{framework_dir} #{target_dir}`
end
cp_to_source_dir() click to toggle source
# File lib/cocoapods-tdf-bin/helpers/framework_builder.rb, line 66
def cp_to_source_dir
  framework_name = "#{@spec.name}.framework"
  target_dir = File.join(CBin::Config::Builder.instance.zip_dir,framework_name)
  FileUtils.rm_rf(target_dir) if File.exist?(target_dir)

  zip_dir = CBin::Config::Builder.instance.zip_dir
  FileUtils.mkdir_p(zip_dir) unless File.exist?(zip_dir)

  `cp -fa #{@platform}/#{framework_name} #{target_dir}`
end
expand_paths(source_dir, path_specs) click to toggle source
# File lib/cocoapods-tdf-bin/helpers/framework_builder.rb, line 275
def expand_paths(source_dir, path_specs)
  path_specs.map do |path_spec|
    Dir.glob(File.join(source_dir, path_spec))
  end
end
expand_suffix(suffix) click to toggle source
# File lib/cocoapods-tdf-bin/helpers/framework_builder.rb, line 281
def expand_suffix(suffix)
  case suffix
  when '.storyboard'        then true
  when '.xib'               then true
  when '.xcdatamodel'       then true
  when '.xcdatamodeld'      then true
  when '.xcmappingmodel'    then true
  else                      false
  end
end
framework() click to toggle source
# File lib/cocoapods-tdf-bin/helpers/framework_builder.rb, line 292
def framework
  @framework ||= begin
                   framework = Framework.new(@spec.name, @platform.name.to_s)
                   framework.make
                   framework
                 end
end
ios_architectures() click to toggle source
# File lib/cocoapods-tdf-bin/helpers/framework_builder.rb, line 123
def ios_architectures
  # >armv7
  #   iPhone4
  #   iPhone4S
  # >armv7s   去掉
  #   iPhone5
  #   iPhone5C
  # >arm64
  #   iPhone5S(以上)
  # >i386
  #   iphone5,iphone5s以下的模拟器
  # >x86_64
  #   iphone6以上的模拟器
  archs = %w[arm64 armv7]
  # archs = %w[x86_64 arm64 armv7s i386]
  # @vendored_libraries.each do |library|
  #   archs = `lipo -info #{library}`.split & archs
  # end
  archs
end
ios_architectures_sim() click to toggle source
# File lib/cocoapods-tdf-bin/helpers/framework_builder.rb, line 144
def ios_architectures_sim

  archs = %w[x86_64]
  archs
end
ios_build_options() click to toggle source
# File lib/cocoapods-tdf-bin/helpers/framework_builder.rb, line 119
def ios_build_options
  "ARCHS=\'#{ios_architectures.join(' ')}\' OTHER_CFLAGS=\'-fembed-bitcode -Qunused-arguments\'"
end
is_debug_model() click to toggle source
# File lib/cocoapods-tdf-bin/helpers/framework_builder.rb, line 169
def is_debug_model
  @build_model == "Debug"
end
static_libs_in_sandbox(build_dir = 'build') click to toggle source
# File lib/cocoapods-tdf-bin/helpers/framework_builder.rb, line 89
def static_libs_in_sandbox(build_dir = 'build')
  file = Dir.glob("#{build_dir}/lib#{target_name}.a")
  unless file
    UI.warn "file no find = #{build_dir}/lib#{target_name}.a"
  end
  file
end
target_name() click to toggle source
# File lib/cocoapods-tdf-bin/helpers/framework_builder.rb, line 173
def target_name
  #区分多平台,如配置了多平台,会带上平台的名字
  # 如libwebp-iOS
  if @spec.available_platforms.count > 1
    "#{@spec.name}-#{Platform.string_name(@spec.consumer(@platform).platform_name)}"
  else
    @spec.name
  end
end
xcodebuild(defines = '', args = '', build_dir = 'build', build_model = 'Debug') click to toggle source
# File lib/cocoapods-tdf-bin/helpers/framework_builder.rb, line 183
      def xcodebuild(defines = '', args = '', build_dir = 'build', build_model = 'Debug')

        unless File.exist?("Pods.xcodeproj") #cocoapods-generate v2.0.0
          command = "xcodebuild #{defines} #{args} CONFIGURATION_BUILD_DIR=#{File.join(File.expand_path("..", build_dir), File.basename(build_dir))} clean build -configuration #{build_model} -target #{target_name} -project ./Pods/Pods.xcodeproj 2>&1"
        else
          command = "xcodebuild #{defines} #{args} CONFIGURATION_BUILD_DIR=#{build_dir} clean build -configuration #{build_model} -target #{target_name} -project ./Pods.xcodeproj 2>&1"
        end

        UI.message "command = #{command}"
        output = `#{command}`.lines.to_a

        if $CHILD_STATUS.exitstatus != 0
          raise <<~EOF
            Build command failed: #{command}
            Output:
            #{output.map { |line| "    #{line}" }.join}
          EOF

          Process.exit
        end
      end