yonaskolb / XcodeGen

A Swift command line tool for generating your Xcode project
MIT License
7.01k stars 818 forks source link

XCodegen wrong generated .xcodeproj #1365

Closed pedroramos1449 closed 1 year ago

pedroramos1449 commented 1 year ago

I am converting my project to use XCodegen, firstly I've made my .yml file, on all my modules. Here's the project when It doesn't had xcodegen, that's the perfect way it should be:

enter image description here

Here's my yml file, that I have made for this CustoJusto, if you look closely the UIComponents shouldn't be on the main targets, but somehow it is.... Here's my CustoJusto .yml:

name: CustoJusto
include:
  - ../cj-uicomponents/iOS/UIComponents/project.yml
options:
  minimumXcodeGenVersion: 2.25
  groupSortPosition: top
  generateEmptyDirectories: true
  deploymentTarget:
    iOS: "12.3"
targets:
  CustoJusto:
    type: framework
    platform: iOS
    settings:
      PRODUCT_BUNDLE_IDENTIFIER: "pt.custojusto.custojusto"
    scheme:
      gatherCoverageData: true
    sources:
      - path: CustoJusto
        createIntermediateGroups: true
    dependencies:
      - target: UIComponents
      - target: knockerservice
      - target: CoreCustoJusto
      - target: knockercontent
      - sdk: AppTrackingTransparency.framework
      - sdk: CoreTelephony.framework
      - framework: ../cj-pro/shared/build/ios/CustoJustoProShared.xcframework

  CoreCustoJusto:
    type: framework
    platform: iOS
    sources:
      - path: CoreCustoJusto
        createIntermediateGroups: true
    dependencies:
      - sdk: Knocker.framework
      - sdk: HighlanderFoundationKit.framework
      - framework: ../cj-pro/shared/build/ios/CustoJustoProShared.xcframework

  CoreCustoJustoTests:
    type: bundle.unit-test
    platform: iOS
    sources:
      - path: Tests/CoreCustoJustoTests
        createIntermediateGroups: true

  CustoJustoUITests:
    type: bundle.ui-testing
    platform: iOS
    sources:
      - path: Tests/CustoJustoUITests
        createIntermediateGroups: true

  knockerservice:
    type: app-extension
    platform: iOS
    sources:
      - path: knockerservice
        createIntermediateGroups: true
    dependencies:
      - target: CoreCustoJusto

  knockercontent:
    type: app-extension
    platform: iOS
    sources:
      - path: knockercontent
        createIntermediateGroups: true

Here's the UIComponents .yml:


name: UIComponents
options:
  minimumXcodeGenVersion: 2.25
  groupSortPosition: top
  generateEmptyDirectories: true
  deploymentTarget:
    iOS: "15.0"
targets:
  UIComponents:
    type: framework
    platform: iOS
    settings:
      PRODUCT_BUNDLE_IDENTIFIER: "pt.custojusto.UIComponents"
    scheme:
      gatherCoverageData: true
    sources:
      - path: UIComponents
        createIntermediateGroups: true

  UIComponentsTests:
    type: bundle.unit-test
    platform: iOS
    sources:
      - path: UIComponentsTests
        createIntermediateGroups: true

But instead, with the .yml provided above, it goes like this, when generated...

enter image description here

Does anyone knows How to fix this, or can give me some hints? I'm new in this XCodegen thing, and can't find much relative to this, besides the doc.

yonaskolb commented 1 year ago

Could you clarify what you mean by "UIComponents shouldn't be on the main targets"? One that that immediately stands out though is that your CustoJusto target should have a type of application and not framework

pedroramos1449 commented 1 year ago

I mean, that this shouldn't be here :)

68747470733a2f2f692e737461636b2e696d6775722e636f6d2f37583431332e706e67

pedroramos1449 commented 1 year ago

But based on my .yml I don't have it, on my targets:

name: CustoJusto
include:
  - ../cj-uicomponents/iOS/UIComponents/project.yml
options:
  minimumXcodeGenVersion: 2.25
  groupSortPosition: top
  generateEmptyDirectories: true
  deploymentTarget:
    iOS: "12.3"
targets:
  CustoJusto:
    type: framework
    platform: iOS
    settings:
      PRODUCT_BUNDLE_IDENTIFIER: "pt.custojusto.custojusto"
    scheme:
      gatherCoverageData: true
    sources:
      - path: CustoJusto
        createIntermediateGroups: true
    dependencies:
      - target: UIComponents
      - target: knockerservice
      - target: CoreCustoJusto
      - target: knockercontent
      - sdk: AppTrackingTransparency.framework
      - sdk: CoreTelephony.framework
      - framework: ../cj-pro/shared/build/ios/CustoJustoProShared.xcframework

  CoreCustoJusto:
    type: framework
    platform: iOS
    sources:
      - path: CoreCustoJusto
        createIntermediateGroups: true
    dependencies:
      - sdk: Knocker.framework
      - sdk: HighlanderFoundationKit.framework
      - framework: ../cj-pro/shared/build/ios/CustoJustoProShared.xcframework

  CoreCustoJustoTests:
    type: bundle.unit-test
    platform: iOS
    sources:
      - path: Tests/CoreCustoJustoTests
        createIntermediateGroups: true

  CustoJustoUITests:
    type: bundle.ui-testing
    platform: iOS
    sources:
      - path: Tests/CustoJustoUITests
        createIntermediateGroups: true

  knockerservice:
    type: app-extension
    platform: iOS
    sources:
      - path: knockerservice
        createIntermediateGroups: true
    dependencies:
      - target: CoreCustoJusto

  knockercontent:
    type: app-extension
    platform: iOS
    sources:
      - path: knockercontent
        createIntermediateGroups: true
jsorge commented 1 year ago

What I think may be going on here is that the UIComponents is a separate project, is that correct? And that you want the other project to be embedded in the CustoJusto project and referenced by the app target?

pedroramos1449 commented 1 year ago

UIComponents is just a module, I want it to be in the Frameworks and Libraries, like it is, on the image on top. But I don't want it to be on the app targets... wich somehow xcodegen is inserting it there, with out I writed to do It :)

Sorry for not being explicit

jsorge commented 1 year ago

Ah so is what you're after is a pre-compiled version of UIComponents to be linked with the app? If that's the case XcodeGen won't do that for you. It made a target with the sources specified in the UIComponents manifest.

The only way I can think of getting around this would be to make a script to build the framework binary and then point your manifest to the path of that built product. It sounds like a lot more work to me and personally I'm totally fine with a target like UIComponents in my projects. I see that you're using CocoaPods, is UIComponents a private local pod that you're building?

pedroramos1449 commented 1 year ago

"what you're after is a pre-compiled version of UIComponents to be linked with the app" - No, we're just generating it with xcodegen, just like the application target.

UIComponents is a local Module, that I created a project.yml and was generated with xcodegen, but it is considered a dependency of the app. We only use pods to get external libraries after we generate the entire project with xcodegen.

jsorge commented 1 year ago

Okay, so going back to your very first screenshot at the top of the thread: there is no target called UIComponents on the sidebar, but there is a UIComponents.framework in the frameworks section. So my question is this: how – before XcodeGen – did UIComponents.framework get built and linked?

pedroramos1449 commented 1 year ago

"UIComponents" is a module just like any other and has been added as a dependency in the target of the app. Each module contains a framework. Since it is a local dependency, the module code is always compiled at the same time as the app, and the framework is updated accordingly.

Here's the project structure before xcodegen :) :

Captura de ecrã 2023-06-19, às 09 31 20

jsorge commented 1 year ago

Aha this screenshot is perfect. Thank you!

Xcode doesn't have a module definition beyond how Swift modules get compiled (so a Swift target can produce a Swift module – that's it). That's as "standard" as it gets.

What you have above is an Xcode project (or maybe a workspace, I can't see the top icon in that sidebar), which itself contains other Xcode projects (that's the blue icons above). So in the Finder there's a project called UIComponents.xcodeproj, and another called SharedFrontent.xcodeproj, etc. Each of those projects contains their own targets which may produce frameworks/apps, run tests, etc.

XcodeGen does not support embedding of Xcode projects inside of other Xcode projects, nor does it support Xcode workspaces. Workspaces could be made by generating the series of projects and then an Xcode workspace file in a script (which I don't think would be too much work but may not be what you're after).

I hope this is helpful!

pedroramos1449 commented 1 year ago

Another exame:

Before XCodeGen: image (1)

After XCodeGen:

image

I need to make it before equals to after, but still didn't find any solution. :(

pedroramos1449 commented 1 year ago

I solved the problem above. But now the including on project.yml is putting a copy of the modules I have dependency with:

image

As you've seen in the image, on the CustoJusto Module, there is a cj-pro-core folder with both cj-sharedfrontend and cj-uicomponents. Thos are copies from the Modules above. How can I remove it, with out losing the dependency on them?

The Main project.yml file:

name: CustoJusto include:

  • ../cj-uicomponents/iOS/UIComponents/project.yml
  • ../cj-sharedfrontend/SharedFrontend/project.yml options: minimumXcodeGenVersion: 2.25 groupSortPosition: top generateEmptyDirectories: true deploymentTarget: iOS: "12.3" targets: CustoJusto: type: application platform: iOS settings: PRODUCT_BUNDLE_IDENTIFIER: "pt.custojusto.custojusto" scheme: gatherCoverageData: true sources:

    • path: CustoJusto createIntermediateGroups: true dependencies:
    • target: UIComponents
    • target: knockerservice
    • target: knockercontent
    • sdk: AppTrackingTransparency.framework
    • sdk: CoreTelephony.framework
    • framework: ../cj-pro/shared/build/ios/CustoJustoProShared.xcframework

    CoreCustoJusto: type: framework platform: iOS sources:

    • path: CoreCustoJusto createIntermediateGroups: true dependencies:
    • target: SharedFrontend
    • sdk: Knocker.framework
    • sdk: HighlanderFoundationKit.framework
    • framework: ../cj-pro/shared/build/ios/CustoJustoProShared.xcframework

    CoreCustoJustoTests: type: bundle.unit-test platform: iOS sources:

    • path: Tests/CoreCustoJustoTests createIntermediateGroups: true

    CustoJustoUITests: type: bundle.ui-testing platform: iOS sources:

    • path: Tests/CustoJustoUITests createIntermediateGroups: true

    knockerservice: type: app-extension platform: iOS sources:

    • path: knockerservice createIntermediateGroups: true dependencies:
    • target: CoreCustoJusto

    knockercontent: type: app-extension platform: iOS sources:

    • path: knockercontent createIntermediateGroups: true`