class Motion::Project::CocoaPods
Constants
- PODS_ROOT
- PUBLIC_HEADERS_ROOT
- SUPPORT_FILES
- TARGET_NAME
- VERSION
Attributes
podfile[RW]
Public Class Methods
new(config, vendor_options)
click to toggle source
# File lib/motion/project/cocoapods.rb, line 80 def initialize(config, vendor_options) @config = config @vendor_options = vendor_options @use_frameworks = false case @config.deploy_platform when 'MacOSX' platform = :osx when 'iPhoneOS' platform = :ios when 'AppleTVOS' platform = :tvos when 'WatchOS' platform = :watchos else App.fail "Unknown CocoaPods platform: #{@config.deploy_platform}" end @podfile = Pod::Podfile.new(Pathname.new(Rake.original_dir) + 'Rakefile') do platform(platform, config.deployment_target) target(TARGET_NAME) install!('cocoapods', :integrate_targets => false) end cp_config.podfile = @podfile cp_config.installation_root = Pathname.new(File.expand_path(config.project_dir)) + 'vendor' if cp_config.verbose = !!ENV['COCOAPODS_VERBOSE'] require 'claide' end end
Public Instance Methods
analyzer()
click to toggle source
# File lib/motion/project/cocoapods.rb, line 320 def analyzer Pod::Installer::Analyzer.new(cp_config.sandbox, @podfile, cp_config.lockfile) end
configure_project()
click to toggle source
Adds the Pods project to the RubyMotion config as a vendored project and
# File lib/motion/project/cocoapods.rb, line 113 def configure_project if (xcconfig = self.pods_xcconfig_hash) && ldflags = xcconfig['OTHER_LDFLAGS'] @config.resources_dirs << resources_dir.to_s frameworks = installed_frameworks[:pre_built] if frameworks @config.embedded_frameworks += frameworks @config.embedded_frameworks.uniq! end if @use_frameworks configure_project_frameworks else configure_project_static_libraries end end end
configure_project_frameworks()
click to toggle source
# File lib/motion/project/cocoapods.rb, line 131 def configure_project_frameworks if (xcconfig = self.pods_xcconfig_hash) && ldflags = xcconfig['OTHER_LDFLAGS'] # Add libraries to @config.libs pods_libraries frameworks = ldflags.scan(/-framework\s+"?([^\s"]+)"?/).map { |m| m[0] } if build_frameworks = installed_frameworks[:build] build_frameworks = build_frameworks.map { |path| File.basename(path, ".framework") } frameworks.delete_if { |f| build_frameworks.include?(f) } end static_frameworks = pods_frameworks(frameworks) static_frameworks_paths = static_frameworks_paths(static_frameworks) search_path = static_frameworks_paths.inject("") { |s, path| s += " -I'#{path}' -I'#{path}/Headers'" } @vendor_options[:bridgesupport_cflags] ||= '' @vendor_options[:bridgesupport_cflags] << " #{header_search_path} #{framework_search_path} #{search_path}" @config.weak_frameworks.concat(ldflags.scan(/-weak_framework\s+([^\s]+)/).map { |m| m[0] }) @config.weak_frameworks.uniq! vendors = @config.vendor_project(PODS_ROOT, :xcode, { :target => "Pods-#{TARGET_NAME}", :products => build_frameworks.map { |name| "#{name}.framework" }, :allow_empty_products => build_frameworks.empty?, }.merge(@vendor_options)) vendor = vendors.last if vendor.respond_to?(:build_bridgesupport) static_frameworks_paths.each do |path| path = File.expand_path(path) bs_file = File.join(Builder.common_build_dir, "#{path}.bridgesupport") headers = Dir.glob(File.join(path, '**{,/*/**}/*.h')) @config.vendor_project(PODS_ROOT, :bridgesupport, { :bs_file => bs_file, :headers => headers, }.merge(@vendor_options)) end end end end
configure_project_static_libraries()
click to toggle source
# File lib/motion/project/cocoapods.rb, line 173 def configure_project_static_libraries # TODO replace this all once Xcodeproj has the proper xcconfig parser. if (xcconfig = self.pods_xcconfig_hash) && ldflags = xcconfig['OTHER_LDFLAGS'] # Collect the Pod products pods_libs = pods_libraries # Initialize ':bridgesupport_cflags', in case the use @vendor_options[:bridgesupport_cflags] ||= '' @vendor_options[:bridgesupport_cflags] << " #{header_search_path} #{framework_search_path}" frameworks = ldflags.scan(/-framework\s+"?([^\s"]+)"?/).map { |m| m[0] } pods_frameworks(frameworks) @config.weak_frameworks.concat(ldflags.scan(/-weak_framework\s+([^\s]+)/).map { |m| m[0] }) @config.weak_frameworks.uniq! @config.vendor_project(PODS_ROOT, :xcode, { :target => "Pods-#{TARGET_NAME}", :headers_dir => "Headers/Public", :products => pods_libs.map { |lib_name| "lib#{lib_name}.a" }, :allow_empty_products => pods_libs.empty?, }.merge(@vendor_options)) end end
copy_cocoapods_env_and_prefix_headers()
click to toggle source
# File lib/motion/project/cocoapods.rb, line 291 def copy_cocoapods_env_and_prefix_headers headers = Dir.glob(["#{PODS_ROOT}/*.h", "#{PODS_ROOT}/*.pch", "#{PODS_ROOT}/Target Support Files/**/*.h", "#{PODS_ROOT}/Target Support Files/**/*.pch"]) headers.each do |header| src = File.basename(header) dst = src.sub(/\.pch$/, '.h') dst_path = File.join(PUBLIC_HEADERS_ROOT, "____#{dst}") unless File.exist?(dst_path) FileUtils.mkdir_p(PUBLIC_HEADERS_ROOT) FileUtils.cp(header, dst_path) end end end
cp_config()
click to toggle source
# File lib/motion/project/cocoapods.rb, line 316 def cp_config Pod::Config.instance end
dependency(*name_and_version_requirements, &block)
click to toggle source
Deprecated.
# File lib/motion/project/cocoapods.rb, line 210 def dependency(*name_and_version_requirements, &block) @podfile.dependency(*name_and_version_requirements, &block) end
framework_public_headers_dir(framework_path)
click to toggle source
# File lib/motion/project/cocoapods.rb, line 250 def framework_public_headers_dir(framework_path) framework_name = framework_path[%r{/([^/]*)\.framework/}, 1] File.join(@config.project_dir, PUBLIC_HEADERS_ROOT, framework_name) end
framework_search_path()
click to toggle source
# File lib/motion/project/cocoapods.rb, line 471 def framework_search_path framework_search_paths.map { |p| "-F'#{File.expand_path(File.join(p, '..'))}'" }.join(' ') end
framework_search_paths()
click to toggle source
# File lib/motion/project/cocoapods.rb, line 445 def framework_search_paths @framework_search_paths ||= begin xcconfig = pods_xcconfig_hash paths = [] if search_paths = xcconfig['FRAMEWORK_SEARCH_PATHS'] search_paths = search_paths.strip unless search_paths.empty? search_paths.scan(/"([^"]+)"/) do |search_path| path = search_path.first.gsub!(/(\$\(PODS_ROOT\))|(\$\{PODS_ROOT\})/, "#{@config.project_dir}/#{PODS_ROOT}") paths << path if path end # If we couldn't parse any search paths, then presumably nothing was properly quoted, so # fallback to just assuming the whole value is one path. if paths.empty? path = search_paths.gsub!(/(\$\(PODS_ROOT\))|(\$\{PODS_ROOT\})/, "#{@config.project_dir}/#{PODS_ROOT}") paths << path if path end end end paths end @framework_search_paths end
header_search_path()
click to toggle source
# File lib/motion/project/cocoapods.rb, line 506 def header_search_path header_search_paths.map { |p| "-I'#{p}'" }.join(' ') end
header_search_paths()
click to toggle source
# File lib/motion/project/cocoapods.rb, line 475 def header_search_paths @header_search_paths ||= begin xcconfig = pods_xcconfig_hash paths = [] if search_paths = xcconfig['HEADER_SEARCH_PATHS'] search_paths = search_paths.strip unless search_paths.empty? search_paths.scan(/"([^"]+)"/) do |search_path| path = search_path.first.gsub!(/(\$\(PODS_ROOT\))|(\$\{PODS_ROOT\})/, "#{@config.project_dir}/#{PODS_ROOT}") paths << File.expand_path(path) if path end # If we couldn't parse any search paths, then presumably nothing was properly quoted, so # fallback to just assuming the whole value is one path. if paths.empty? path = search_paths.gsub!(/(\$\(PODS_ROOT\))|(\$\{PODS_ROOT\})/, "#{@config.project_dir}/#{PODS_ROOT}") paths << File.expand_path(path) if path end end end framework_search_paths.each do |framework_search_path| Dir.glob("#{framework_search_path}/*.framework/Headers").each do |framework_path| paths << framework_public_headers_dir(framework_path) end end paths end @header_search_paths end
inspect()
click to toggle source
This is the output that gets shown in `rake config`, so it should be short and sweet.
# File lib/motion/project/cocoapods.rb, line 310 def inspect cp_config.lockfile.to_hash['PODS'].map do |pod| pod.is_a?(Hash) ? pod.keys.first : pod end.inspect end
install!(update)
click to toggle source
Performs a CocoaPods
Installation.
For now we only support one Pods target, this will have to be expanded once we work on more spec support.
Let RubyMotion re-generate the BridgeSupport file whenever the list of installed pods changes.
# File lib/motion/project/cocoapods.rb, line 238 def install!(update) FileUtils.rm_rf(resources_dir) pods_installer.update = update pods_installer.install! symlink_framework_headers install_resources copy_cocoapods_env_and_prefix_headers end
install_resources()
click to toggle source
TODO this probably breaks in cases like resource bundles etc, need to test.
# File lib/motion/project/cocoapods.rb, line 270 def install_resources FileUtils.mkdir_p(resources_dir) installed_resources = [] resources.each do |file| begin dst = resources_dir + file.basename if file.exist? && !dst.exist? FileUtils.cp_r(file, resources_dir) installed_resources << dst end rescue ArgumentError => exc unless exc.message =~ /same file/ raise end end end installed_resources end
installed_frameworks()
click to toggle source
# File lib/motion/project/cocoapods.rb, line 551 def installed_frameworks return @installed_frameworks if @installed_frameworks @installed_frameworks = {} path = Pathname.new(@config.project_dir) + SUPPORT_FILES + "Pods-#{TARGET_NAME}-frameworks.sh" return @installed_frameworks unless path.exist? @installed_frameworks[:pre_built] = [] @installed_frameworks[:build] = [] File.open(path) { |f| f.each_line do |line| if matched = line.match(/install_framework\s+(.*)/) path = (matched[1].strip)[1..-2] if path.include?('${PODS_ROOT}') path = path.sub('${PODS_ROOT}', PODS_ROOT) @installed_frameworks[:pre_built] << File.join(@config.project_dir, path) @installed_frameworks[:pre_built].uniq! elsif path.include?('$BUILT_PRODUCTS_DIR') path = path.sub('$BUILT_PRODUCTS_DIR', "#{PODS_ROOT}/.build") @installed_frameworks[:build] << File.join(@config.project_dir, path) @installed_frameworks[:build].uniq! end end end } @installed_frameworks end
lib_search_path_flags()
click to toggle source
# File lib/motion/project/cocoapods.rb, line 421 def lib_search_path_flags lib_search_paths.map { |p| "-L'#{p}'" }.join(' ') end
lib_search_paths()
click to toggle source
# File lib/motion/project/cocoapods.rb, line 425 def lib_search_paths @lib_search_paths ||= begin xcconfig = pods_xcconfig_hash @lib_search_path_flags = xcconfig['LIBRARY_SEARCH_PATHS'] || "" paths = [] @lib_search_path_flags = @lib_search_path_flags.split(/\s/).map do |path| if path =~ /(\$\(inherited\))|(\$\{inherited\})|(\$CONFIGURATION_BUILD_DIR)|(\$PODS_CONFIGURATION_BUILD_DIR)/ nil else path = path.gsub(/(\$\(PODS_ROOT\))|(\$\{PODS_ROOT\})/, File.join(@config.project_dir, PODS_ROOT)) paths << path.gsub('"', '') end end.compact.join(' ') paths end @lib_search_paths end
pod(*name_and_version_requirements, &block)
click to toggle source
# File lib/motion/project/cocoapods.rb, line 205 def pod(*name_and_version_requirements, &block) @podfile.pod(*name_and_version_requirements, &block) end
pods_frameworks(frameworks)
click to toggle source
# File lib/motion/project/cocoapods.rb, line 369 def pods_frameworks(frameworks) frameworks = frameworks.dup if installed_frameworks[:pre_built] installed_frameworks[:pre_built].each do |pre_built| frameworks.delete(File.basename(pre_built, ".framework")) end end static_frameworks = [] case @config.deploy_platform when 'MacOSX' @config.framework_search_paths.concat(framework_search_paths) @config.framework_search_paths.uniq! framework_search_paths.each do |framework_search_path| frameworks.reject! do |framework| path = File.join(framework_search_path, "#{framework}.framework") if File.exist?(path) @config.embedded_frameworks << path @config.embedded_frameworks.uniq! true else false end end end when 'iPhoneOS', 'AppleTVOS', 'WatchOS' # If we would really specify these as ‘frameworks’ then the linker # would not link the archive into the application, because it does not # see any references to any of the symbols in the archive. Treating it # as a static library (which it is) with `-ObjC` fixes this. # framework_search_paths.each do |framework_search_path| frameworks.reject! do |framework| path = File.join(framework_search_path, "#{framework}.framework") if File.exist?(path) @config.libs << "-ObjC '#{File.join(path, framework)}'" @config.libs.uniq! static_frameworks << framework true else false end end end end @config.frameworks.concat(frameworks) @config.frameworks.uniq! static_frameworks end
pods_installer()
click to toggle source
Installation
# File lib/motion/project/cocoapods.rb, line 226 def pods_installer @installer ||= Pod::Installer.new(cp_config.sandbox, @podfile, cp_config.lockfile) end
pods_libraries()
click to toggle source
# File lib/motion/project/cocoapods.rb, line 338 def pods_libraries xcconfig = pods_xcconfig_hash ldflags = xcconfig['OTHER_LDFLAGS'] # Get the name of all static libraries that come pre-built with pods pre_built_static_libs = lib_search_paths.map do |path| Dir[File.join(path, '**/*.a')].map { |f| File.basename(f) } end.flatten pods_libs = [] @config.libs.concat(ldflags.scan(/-l"?([^\s"]+)"?/).map { |m| lib_name = m[0] next if lib_name.nil? if lib_name.start_with?('Pods-') # For CocoaPods 0.37.x or below. This block is marked as deprecated. pods_libs << lib_name nil elsif pre_built_static_libs.include?("lib#{lib_name}.a") "#{lib_search_path_flags} -ObjC -l#{lib_name}" elsif File.exist?("/usr/lib/lib#{lib_name}.dylib") "/usr/lib/lib#{lib_name}.dylib" else pods_libs << lib_name nil end }.compact) @config.libs.uniq! pods_libs end
pods_xcconfig()
click to toggle source
# File lib/motion/project/cocoapods.rb, line 324 def pods_xcconfig @pods_xcconfig ||= begin path = Pathname.new(@config.project_dir) + SUPPORT_FILES + "Pods-#{TARGET_NAME}.release.xcconfig" Xcodeproj::Config.new(path) if path.exist? end @pods_xcconfig end
pods_xcconfig_hash()
click to toggle source
# File lib/motion/project/cocoapods.rb, line 332 def pods_xcconfig_hash if xcconfig = pods_xcconfig xcconfig.to_hash end end
post_install(&block)
click to toggle source
# File lib/motion/project/cocoapods.rb, line 214 def post_install(&block) @podfile.post_install(&block) end
resources()
click to toggle source
Do not copy `.framework` bundles, these should be handled through RM's `embedded_frameworks` config attribute.
# File lib/motion/project/cocoapods.rb, line 524 def resources resources = [] script = Pathname.new(@config.project_dir) + SUPPORT_FILES + "Pods-#{TARGET_NAME}-resources.sh" return resources unless File.exist?(script) File.open(script) { |f| f.each_line do |line| if matched = line.match(/install_resource\s+(.*)/) path = (matched[1].strip)[1..-2] if path.start_with?('${PODS_ROOT}') path = path.sub('${PODS_ROOT}/', '') end if path.include?("$PODS_CONFIGURATION_BUILD_DIR") path = File.join(".build", File.basename(path)) end unless File.extname(path) == '.framework' resources << Pathname.new(@config.project_dir) + PODS_ROOT + path end end end } resources.uniq end
resources_dir()
click to toggle source
# File lib/motion/project/cocoapods.rb, line 547 def resources_dir Pathname.new(@config.project_dir) + PODS_ROOT + 'Resources' end
source(source)
click to toggle source
DSL
# File lib/motion/project/cocoapods.rb, line 201 def source(source) @podfile.source(source) end
static_frameworks_paths(frameworks)
click to toggle source
# File lib/motion/project/cocoapods.rb, line 510 def static_frameworks_paths(frameworks) paths = [] framework_search_paths.each do |framework_search_path| paths += Dir.glob("#{framework_search_path}/*.framework") end paths.keep_if { |path| frameworks.include?(File.basename(path, ".framework")) } paths end
symlink_framework_headers()
click to toggle source
# File lib/motion/project/cocoapods.rb, line 255 def symlink_framework_headers framework_search_paths.each do |framework_search_path| Dir.glob("#{framework_search_path}/*.framework/Headers").each do |framework_path| FileUtils.mkdir_p(framework_public_headers_dir(framework_path)) Dir.glob("#{framework_path}/*.h").each do |header_path| relative_path = "../../..#{header_path.sub(File.join(@config.project_dir, PODS_ROOT), '')}" File.symlink(relative_path, "#{framework_public_headers_dir(framework_path)}/#{File.basename(header_path)}") end end end end
use_frameworks!(flag = true)
click to toggle source
# File lib/motion/project/cocoapods.rb, line 218 def use_frameworks!(flag = true) @use_frameworks = flag @podfile.use_frameworks!(flag) end