Skip to content

Adding a new subproject cause Xcode crashes #678

@maniramezan

Description

@maniramezan

Hi,

So I worked on a script to automatically generate a subproject and add it to an existing project and set up target dependency, link binary, and embedded frameworks. However, I noticed after running the script, the Xcode crashes when adding a new file to the project. When I tried to reproduce it in a simpler situation, I noticed that it's now crashing by adding any new phase under "Build phase". Following is the code sample for reproducing it and I have attached a zip file that has the script and sample code in it. For ease of use, I added the lines to clear and re-copy sample project.

By spending some time, I found the root cause of it is this line that's using the same product group as the main project instead of creating a new one, which seems to be what Xcode does. I tried the new theory with add_subproject_reference method and that fixes the issue with Xcode crash.

I was wondering if there's any specific reason the subproject is getting added to main project's product list instead of creating a new one? Or it might be something I'm doing wrong in code below for adding a subproject.

Thanks!

require("Xcodeproj")
require("pathname")

# def add_subproject_reference(main_project, subproject)
#   # We call into the private function `FileReferencesFactory.new_file_reference` instead of `FileReferencesFactory.new_reference`
#   # because it delegates into `FileReferencesFactory.new_subproject` which has the extra behavior of opening the Project which
#   # is an expensive operation for large projects.
#   #
#   ref = Xcodeproj::Project::FileReferencesFactory.send(:new_file_reference, main_project.main_group, subproject.path, :built_products)

#   basename = Pathname(subproject.path).basename
#   subproject_name = File.basename(basename, ".*")
#   ref.name = basename.to_s
#   ref.include_in_index = nil

#   product_group_ref = main_project.new(Xcodeproj::Project::PBXGroup)
#   product_group_ref.name = "Products"

#   subproject.products_group.files.each do |product_reference|
#     container_proxy = main_project.new(Xcodeproj::Project::PBXContainerItemProxy)
#     container_proxy.container_portal = ref.uuid
#     container_proxy.proxy_type = Xcodeproj::Constants::PROXY_TYPES[:reference]
#     container_proxy.remote_global_id_string = product_reference.uuid
#     container_proxy.remote_info = subproject_name.to_s

#     reference_proxy = main_project.new(Xcodeproj::Project::PBXReferenceProxy)
#     extension = File.extname(product_reference.path)[1..-1]
#     reference_proxy.file_type = Xcodeproj::Constants::FILE_TYPES_BY_EXTENSION[extension]
#     reference_proxy.path = product_reference.path
#     reference_proxy.remote_ref = container_proxy
#     reference_proxy.source_tree = "BUILT_PRODUCTS_DIR"

#     product_group_ref << reference_proxy
#   end
#
#   attribute = Xcodeproj::Project::PBXProject.references_by_keys_attributes.find { |attrb| attrb.name == :project_references }
#   project_reference = Xcodeproj::Project::ObjectDictionary.new(attribute, product_group_ref)
#   project_reference[:project_ref] = ref
#   project_reference[:product_group] = product_group_ref
#   main_project.root_object.project_references << project_reference

#   ref
# end

require("fileutils")
FileUtils.rm_rf("./Subproj")
FileUtils.cp_r("./Mainproj copy/.", ".")
subproj_target_name = "Subproj"
worksace_path = "./Mainproj.xcworkspace"
workspace = Xcodeproj::Workspace.new_from_xcworkspace(worksace_path)

mainproj = Xcodeproj::Project.open("./Mainproj/Mainproj.xcodeproj")

subproj = Xcodeproj::Project.new("./#{subproj_target_name}/#{subproj_target_name}.xcodeproj")
subproj.new_target(:framework, subproj_target_name, :ios, "11.0", nil, :swift)
subproj.main_group.new_group(subproj_target_name)

workspace_ref_subproj = Xcodeproj::Workspace::FileReference.new("./Subproj/Subproj.xcodeproj")
workspace << workspace_ref_subproj
workspace.save_as(worksace_path)
subproj.save
# mainproj_ref_subproj = add_subproject_reference(mainproj, subproj) 
mainproj_ref_subproj = Xcodeproj::Project::FileReferencesFactory.new_reference(mainproj.main_group, subproj.path, :built_products)
mainproj.targets[0].add_dependency(subproj.targets[0])
mainproj.targets[0].frameworks_build_phase.add_file_reference(
  mainproj_ref_subproj.file_reference_proxies.first,
  true
)
mainproj.save

Archive.zip

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions