web-dev-qa-db-fra.com

Comment puis-je inclure conditionnellement un fichier basé sur la configuration de construction dans Xcode?

J'ai un projet Xcode avec un grand nombre de cibles où j'aimerais inclure un ensemble de paramètres pour les applications construites sous les configurations Ad-hoc et Debug, mais pas sous la configuration Release.

Les phases de construction ne semblent pas permettre de se conditionner à la configuration (elles peuvent évidemment être conditionnelles à la cible, mais doubler le nombre de cibles dans le projet le rendrait complètement inutilisable).

Cela laisse écrire une règle de construction personnalisée. Mon plan consiste à exclure le fichier Settings.bundle de toutes les cibles et à créer une règle de build qui le copie conditionnellement dans le package du produit, mais les exemples applicables sont vraiment difficiles à trouver.

La règle de génération que j'ai commencée a le paramètre Process défini sur "Fichiers source avec des noms correspondant:" et Settings.bundle comme nom. Le paramètre Using est "Script personnalisé:".

Mon script personnalisé est le suivant (avec la mise en garde que mes scripts bash sont à un niveau culte):

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

Enfin, j'ai ${DERIVED_FILES_DIR}/Settings.bundle répertorié comme fichier de sortie.

Depuis que je suis ici, il devrait être évident que cela ne fonctionne pas. Ma première question est de savoir s'il y a un endroit où je peux voir la sortie des règles de construction comme exécutée pour m'assurer que 1) elle est réellement exécutée et que 2) je n'ai pas d'erreur de syntaxe stupide quelque part.

En outre, quel est l'emplacement approprié (sous la forme d'une variable d'environnement) pour copier la sortie?

72
Frank Schmitt

Je l'ai finalement compris.

Pour chaque cible pour laquelle vous souhaitez inclure conditionnellement le groupe de paramètres, choisissez son projet dans la liste source, choisissez la cible et passez à l'onglet "Phases de construction".

Cliquez sur le bouton "Ajouter une phase de construction" et choisissez "Ajouter un script d'exécution".

Saisissez ensuite les informations suivantes pour le script:

if [ "${CONFIGURATION}" == "Debug" ]; then
    cp -r "${PROJECT_DIR}/Settings.bundle" "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app"
fi
76
Frank Schmitt

Je sais que cette question a déjà reçu une réponse, et la réponse m'a été très utile, mais je voulais également lancer ma propre solution modifiée.

Mon exigence était d'avoir différents ensembles de paramètres pour différentes configurations de build, plutôt que de ne pas simplement l'inclure à la sortie. En supposant une approche simpliste des configurations de débogage uniquement et Release , voici comment fais le:

Commencez par ajouter 2 ensembles de paramètres au projet, nommés Settings-debug.bundle et Settings-release.bundle, puis supprimez ces fichiers de la phase de génération Copy Bundle Resources. Ajoutez ensuite un paramètre de génération défini par l'utilisateur appelé SETTINGS_BUNDLE, qui a des valeurs différentes pour chaque configuration:

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

Ajoutez ensuite une phase de construction du script d'exécution (après Copy Bundle Resources) nommée Copy Settings Bundle avec une version modifiée du script dans la solution de Frank.

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

La différence ici est que le bundle copié est toujours nommé Settings.bundle quel que soit le nom de la source.

Vous devez ensuite ajouter un autre script de phase de génération pour éviter les erreurs de signature de code lorsque les seules modifications se trouvent dans les ensembles de paramètres. Il force l'étape de signature de code à se produire sur chaque génération. Cela devrait exécuter avant la phase de construction de compilation des fichiers source . J'ai appelé le mien Force Codesign.

touch "${PROJECT_DIR}/relative/path/to/main.m"
44
Ell Neal

Pour les sources conformes, il existe un paramètre de génération défini par l'utilisateur mal documenté qui peut être ajouté. Les fichiers peuvent être exclus et inclus de la compilation

Accédez aux paramètres de construction de votre cible> appuyez sur le bouton +> Ajouter un paramètre défini par l'utilisateur

La clé est soit INCLUDED_SOURCE_FILE_NAMES ou EXCLUDED_SOURCE_FILE_NAMES

La valeur est une liste de chemins de fichiers séparés par des espaces

Voir référence: http://lists.Apple.com/archives/xcode-users/2009/Jun/msg00153.html

21
Kyle Redfearn

Settings.bundle est toujours copié dans la zone de destination, qu'il s'agisse d'une configuration Release ou Debug. Donc, vous avez peut-être besoin du code suivant:

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

Je ne suis pas un expert du script Shell, mais je pense que vous avez besoin d'espace entre les crochets et la condition. En outre, la citation des variables peut aider:

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

Quant à l'emplacement, j'utilise "$BUILT_PRODUCTS_DIR"/"$FULL_PRODUCT_NAME" pour la racine de mon bundle d'applications OS X.

3
Stephen Chu

(Testé avec Xcode 9.3 )

Je ne trouve pas quand Xcode a inclus cette fonctionnalité mais EXCLUDED_SOURCE_FILE_NAMES est désormais directement disponible dans Build Settings > Build Options > Excluded Source File Names.

Vous n'avez donc plus besoin de créer un User-Defined Setting.

Voir ci-dessous: enter image description here

Il ajoutera automatiquement cette ligne dans votre .pbxproj. enter image description here

3
Toldy