J'ai un script qui
et un Makefile qui a un fichier d'horodatage spécial comme cible de création et les fichiers de configuration comme sources cibles:
SRC = $(Shell find ../config -iname "*.txt")
STAMP = $(PROJECT_TEMP_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME).stamp
$(STAMP): $(SRC)
python inject.py
touch $(STAMP)
J'ai ajouté ce Makefile en tant que "Exécuter la phase de génération de script" au-dessus de la pile des phases de génération pour la cible du projet.
La phase de construction du script a été exécutée avant la compilation de la source.
Cependant, étant donné que le script modifie le code source lors de son exécution, j'ai dû générer deux fois pour obtenir la version la plus récente du produit de génération. Voici ce que j'imagine se produire:
Après avoir lu documentation Xcode sur les phases de construction , j'ai essayé d'ajouter un fichier source qui est connu pour être mis à jour chaque fois que le script est exécuté en tant que sortie de "Exécuter les phases de construction de script", mais rien n'a changé. Étant donné que le nombre de fichiers de configuration peut varier dans mon projet, je ne veux pas spécifier chaque fichier d'entrée et de sortie.
Comment puis-je informer Xcode des modifications du fichier source effectuées pendant la "phase d'exécution de script"?
Chaque technique mentionnée jusqu'à présent est une exagération. Reproduire le commentaire de steve kim pour la visibilité:
Dans l'onglet des phases de construction, faites simplement glisser l'étape "Exécuter le script" vers un emplacement plus élevé (par exemple avant "Compiler les sources").
Testé sur XCode 6
Cette solution est probablement obsolète. Voir plutôt la réponse votée la plus élevée.
Utilisez "Cible externe":
Maintenant, la nouvelle "cible externe" s'exécute avant la cible principale commence même à collecter des informations de dépendance, de sorte que toutes les modifications apportées pendant l'exécution du script doivent être incluses dans la génération.
Il existe une autre option, légèrement plus simple, qui ne nécessite pas de cible distincte, mais elle n'est viable que si votre script a tendance à modifier les mêmes fichiers source à chaque fois.
Tout d'abord, voici une brève explication pour quiconque ne sait pas pourquoi Xcode vous oblige parfois à créer deux fois (ou à faire une construction propre) pour voir certains changements reflétés dans votre application cible. Xcode compile un fichier source si le fichier objet qu'il produit est manquant, ou si la date de dernière modification du fichier objet est antérieure à la date de dernière modification du fichier source au début de la première phase de construction. Si votre projet exécute un script qui modifie un fichier source dans une phase de génération de pré-compilation, Xcode ne remarquera pas que la date de dernière modification du fichier source a changé, il ne prendra donc pas la peine de le recompiler. Ce n'est que lorsque vous générez le projet une deuxième fois que Xcode remarquera le changement de date et recompilera le fichier.
Voici une solution simple si votre script modifie à chaque fois les mêmes fichiers source. Ajoutez simplement une phase de construction de Script d'exécution à la fin de votre processus de construction comme ceci:
touch Classes/FirstModifiedFile.m Classes/SecondModifiedFile.m
exit $?
L'exécution de touch
sur ces fichiers source à la fin de votre processus de génération garantit qu'ils auront toujours une date de dernière modification plus tardive que leurs fichiers objets, donc Xcode les recompilera à chaque fois.
À partir de Xcode 4, il semble que si vous ajoutez les fichiers générés à la section de sortie de la phase de construction, il respectera ce paramètre et ne générera pas le ... has been modified since the precompiled header was built
messages d'erreur.
C'est une bonne option si votre script ne génère à chaque fois qu'une poignée de fichiers.
Moi aussi, j'ai lutté longtemps avec ça. La réponse est d'utiliser la solution "External Target" d'ento. Il est POURQUOI ce problème se produit et comment nous l'utilisons dans la pratique ...
Les étapes de construction de Xcode4 ne s'exécutent qu'après la compilation du plist. C'est idiot, bien sûr, car cela signifie que toutes les étapes de pré-construction qui modifient le plist ne prendront pas effet. Mais si vous y réfléchissez, ils prennent effectivement effet ... sur la construction NEXT. C'est pourquoi certaines personnes ont parlé de "mise en cache" des valeurs de plist ou "Je dois faire 2 builds pour le faire fonctionner". Ce qui se passe, c'est que le plist est construit, puis votre script s'exécute. La prochaine fois que vous générez, le plist construit à l'aide de vos fichiers modifiés, d'où la deuxième génération.
la solution d'ento est le seul moyen que j'ai trouvé pour réellement faire une véritable étape de pré-construction. Malheureusement, j'ai également constaté que cela ne provoquait pas la mise à jour du plist sans une construction propre et j'ai corrigé cela. Voici comment nous avons des valeurs utilisateur basées sur les données dans la liste:
L'utilisation du toucher sur le fichier plist de l'application principale entraîne la cible principale à générer le plist à chaque fois. La raison pour laquelle nous transmettons les paramètres de génération en tant que paramètres est que notre génération de ligne de commande peut remplacer les paramètres:
Le script python utilise des fichiers de paramètres de base et permet aux fichiers de paramètres définis par l'utilisateur de remplacer les valeurs par défaut. Vous apportez une modification et elle se retrouve immédiatement dans la liste. Nous n'utilisons cela que pour les paramètres qui DOIVENT être dans le plist. Pour toute autre chose, c'est une perte d'effort .... générer un fichier json ou quelque chose de similaire à la place et le charger au moment de l'exécution :)
J'espère que cela aide ... ça a été quelques jours difficiles à comprendre cela.