Wie kann ich eine Datei basierend auf der Build-Konfiguration bedingt in Xcode aufnehmen?

78

Ich habe ein Xcode-Projekt mit einer großen Anzahl von Zielen, in das ich ein Einstellungspaket für Apps aufnehmen möchte, die unter den Ad-hoc- und Debug-Konfigurationen erstellt wurden, jedoch nicht unter der Release-Konfiguration.

Build-Phasen scheinen es nicht zu ermöglichen, sich von der Konfiguration abhängig zu machen (sie können natürlich vom Ziel abhängig gemacht werden, aber eine Verdoppelung der Anzahl der Ziele im Projekt würde es völlig unbrauchbar machen).

Damit bleibt das Schreiben einer benutzerdefinierten Erstellungsregel. Mein Plan ist es, das Settings.bundle von allen Zielen auszuschließen und eine Build-Regel zu erstellen, die es bedingt in das Produktpaket kopiert, aber anwendbare Beispiele sind wirklich schwer zu finden.

Für die von mir gestartete Erstellungsregel ist die Prozesseinstellung auf "Quelldateien mit übereinstimmenden Namen:" und "Settings.bundle" als Name festgelegt. Die Einstellung "Verwenden" lautet "Benutzerdefiniertes Skript:".

Mein benutzerdefiniertes Skript lautet wie folgt (mit der Einschränkung, dass sich mein Bash-Skript auf einem Frachtkult-Level befindet):

if [${CONFIGURATION} = 'Debug'] then
    cp -r ${INPUT_FILE_PATH} ${DERIVED_FILES_DIR}/.
fi

Endlich habe ich ${DERIVED_FILES_DIR}/Settings.bundle als Ausgabedatei aufgeführt.

Da ich hier bin, sollte es offensichtlich sein, dass es nicht funktioniert. Meine erste Frage ist, ob es irgendwo eine Möglichkeit gibt, die Ausgabe der Build-Regeln als Ausführung anzuzeigen, um sicherzustellen, dass 1) sie tatsächlich ausgeführt wird und 2) ich irgendwo keinen dummen Syntaxfehler habe.

Wo ist der richtige Speicherort (in Form einer Umgebungsvariablen), an den die Ausgabe kopiert werden soll?

Frank Schmitt
quelle

Antworten:

83

Ich habe es endlich herausgefunden.

Wählen Sie für jedes Ziel, für das Sie das Einstellungspaket bedingt einschließen möchten, dessen Projekt aus der Quellliste aus, wählen Sie das Ziel aus und wechseln Sie zur Registerkarte "Phasen erstellen".

Klicken Sie auf die Schaltfläche "Build-Phase hinzufügen" und wählen Sie "Run-Skript hinzufügen".

Geben Sie dann Folgendes für das Skript ein:

if [ "${CONFIGURATION}" == "Debug" ]; then
    cp -r "${PROJECT_DIR}/Settings.bundle" "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app"
fi
Frank Schmitt
quelle
2
Vielen Dank, ich habe versucht, Firebase-Projekt-Plist-Dateien für verschiedene Konfigurationen zu verwalten.
iCoder
45

Ich weiß, dass diese Frage bereits beantwortet wurde, und die Antwort war für mich sehr hilfreich, aber ich wollte auch meine eigene modifizierte Lösung herausbringen.

Meine Anforderung bestand darin, unterschiedliche Einstellungspakete für unterschiedliche Build-Konfigurationen zu haben, anstatt sie bei der Veröffentlichung nicht einzuschließen. Unter der Annahme, dass nur Debug- und Release- Konfigurationen vereinfacht werden , gehen Sie wie folgt vor:

Fügen Sie dem Projekt zunächst zwei Einstellungspakete mit dem Namen hinzu Settings-debug.bundleund Settings-release.bundleentfernen Sie diese Dateien aus der Erstellungsphase " Bundle-Ressourcen kopieren" . Fügen Sie als Nächstes eine benutzerdefinierte Build-Einstellung mit dem Namen hinzu SETTINGS_BUNDLE, die für jede Konfiguration unterschiedliche Werte hat:

Debug        ${PROJECT_DIR}/relative/path/to/Settings-debug.bundle
Release      ${PROJECT_DIR}/relative/path/to/Settings-release.bundle

Fügen Sie als Nächstes eine Run-Script-Erstellungsphase (nach Copy Bundle Resources ) mit dem Namen Copy Settings Bundle mit einer modifizierten Version des Skripts in Franks Lösung hinzu.

cp -r "${SETTINGS_BUNDLE}/" "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/Settings.bundle"

Der Unterschied besteht darin, dass das kopierte Bundle immer Settings.bundle heißt unabhängig vom .

Sie müssen dann ein weiteres Skript für die Erstellungsphase hinzufügen, um Codesignaturfehler zu vermeiden, wenn die einzigen Änderungen in den Einstellungspaketen enthalten sind. Es erzwingt, dass der Code-Signaturschritt bei jedem Build ausgeführt wird. Dies sollte vor der Erstellungsphase von Quelldateien kompilieren ausgeführt werden. Ich habe mein Force Codesign angerufen .

touch "${PROJECT_DIR}/relative/path/to/main.m"
Ell Neal
quelle
1
Tolle Lösung für einen Nur-Debug-Anwendungseinstellungsbereich in der integrierten Einstellungs-App, nach dem ich gesucht habe. Vielen Dank!
BenvolioT
4
Sie können auch schreiben: cp -r "$ {PROJECT_DIR} / settings_bundle / Settings - $ {CONFIGURATION} .bundle /" "$ {BUILT_PRODUCTS_DIR} / $ {PRODUCT_NAME} .app / Settings.bundle" Dadurch können Sie das Hinzufügen von vermeiden Benutzerdefinierter Build-Eintrag und verwendet die Dateien 'settings_bundle / Settings-Debug.bundle', 'settings_bundle / Settings-Release.bundle' usw.
Kashif Hisam
Als SETTINGS_BUNDLE-Variablen habe ich $ {PROJECT_DIR} / $ {PROJECT_NAME} /Resources/Settings.bundle
Johan
1
Anstatt in der Erstellungsphase "Bundle-Ressourcen kopieren" nach Dateien zu suchen, um sie zu entfernen, entfernen Sie einfach alle Zielmitgliedschaften für die Bundle-Dateien im Dateiinspektor. Schneller.
Johan
26

Für konforme Quellen gibt es eine schlecht dokumentierte benutzerdefinierte Build-Einstellung, die hinzugefügt werden kann. Dateien können sowohl ausgeschlossen als auch von der Kompilierung eingeschlossen werden

Gehen Sie zu den Build-Einstellungen Ihres Ziels> Tippen Sie auf die Schaltfläche +> Benutzerdefinierte Einstellungen hinzufügen

Der Schlüssel ist entweder INCLUDED_SOURCE_FILE_NAMESoderEXCLUDED_SOURCE_FILE_NAMES

Der Wert ist eine durch Leerzeichen getrennte Liste von Dateipfaden

Siehe Referenz: http://lists.apple.com/archives/xcode-users/2009/Jun/msg00153.html

Kyle Redfearn
quelle
1
Ich kann bestätigen, dass das Hinzufügen von EXCLUDED_SOURCE_FILE_NAMES in Xcode 8.2..x
Eli Burke
9

(Getestet mit Xcode 9.3 )

Ich kann nicht finden, wann Xcode diese Funktion enthält, EXCLUDED_SOURCE_FILE_NAMESist aber jetzt direkt in verfügbar Build Settings > Build Options > Excluded Source File Names.

Sie müssen also keine mehr erstellen User-Defined Setting.

Siehe unten: Geben Sie hier die Bildbeschreibung ein

Diese Zeile wird automatisch in Ihre Zeile eingefügt .pbxproj. Geben Sie hier die Bildbeschreibung ein

Toldy
quelle
8

Settings.bundle wird immer in den Zielbereich kopiert, egal ob Release- oder Debug-Konfiguration. Vielleicht benötigen Sie den folgenden Code:

if [ ${CONFIGURATION} == "Release" ]; then
    rm -rf ${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/Settings.bundle
fi
Allen
quelle
4

Ich bin kein Shell-Skript-Experte, aber ich denke, Sie brauchen Platz zwischen den eckigen Klammern und der Bedingung. Das Zitieren der Variablen kann auch helfen:

if [ "${CONFIGURATION}" = "Debug" ] then
    cp -r "${INPUT_FILE_PATH}" "${DERIVED_FILES_DIR}"/.
fi

Den Speicherort verwende ich "$BUILT_PRODUCTS_DIR"/"$FULL_PRODUCT_NAME"für das Stammverzeichnis meines OS X-App-Bundles.

Stephen Chu
quelle
Dies gibt mir Syntaxfehler beim Erstellen. Franks Lösung, kopiert und eingefügt, funktionierte perfekt.
Lance
1
Um ganz fair zu sein, wurde die Antwort dieses Typen drei Monate zuvor veröffentlicht.
Welpe