Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding a new subproject cause Xcode crashes #678

Open
maniramezan opened this issue Apr 28, 2019 · 1 comment · May be fixed by #728
Open

Adding a new subproject cause Xcode crashes #678

maniramezan opened this issue Apr 28, 2019 · 1 comment · May be fixed by #728

Comments

@maniramezan
Copy link

maniramezan commented Apr 28, 2019

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

@dinsen
Copy link

dinsen commented Jul 24, 2019

I'm also having this issue.

For now I use a function like @maniramezan posed above.

maniramezan added a commit to maniramezan/Xcodeproj-1 that referenced this issue Nov 8, 2019
@maniramezan maniramezan linked a pull request Nov 8, 2019 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants
@dinsen @maniramezan and others