Build universel pour Mac
Voici comment vous pouvez compiler un programme universel dans le
terminal, sans lancer Xcode. Nous utiliserons make
,
clang
pour compiler le code source, et lipo
pour fusionner les programmes compilés séparément pour x86 and
arm64 (M1 à M4) en un seul fichier.
Nous partons du principe que vous avez installé Xcode, qui est disponible gratuitement sur l'Apple Store, et que vous l'avez ouvert au moins une fois. La première fois que vous le lancez, il devrait vous proposer d'installer les outils de développement. Vous devriez aussi avoir des notions de base dans l'utilisation des outils de développement habituel sur Unix, tels que gcc et make.
La compilation d'un programme universel se fait en trois étapes:
- Compiler le programme pour Intel avec le compilateur
clang
en spécifiant x86_64 comme architecture cible - Compiler le programme pour Apple Silicon avec
clang
en spécifiant arm64 comme architecture cible - Fusionner les deux avec
lipo
.
Il n'y a pas besoin de spécifier explicitement l'architecture native, mais il n'y a pas de mal à le faire.
Dans le cas le plus simple avec un seul fichier source,
program.c
peut être compiler ainsi:
clang -o program.x64 -target x86_64-apple-macos13.0 program.c clang -o program.a64 -target arm64-apple-macos13.0 program.c lipo -create -output program program.x64 program.a64
Pour de plus gros programmes, nous proposons le makefile générique suivant avec des règles pour compiler séparément le code source pour chaque architecture: universal.mk
CC = clang CXX = clang++ CFLAGS_X64 = -target x86_64-apple-macos13.0 CFLAGS_A64 = -target arm64-apple-macos13.0 $(TARGET): $(TARGET).universal mv $< $@ $(TARGET).x64: $(SOURCE:.c=.x64.o) $(TARGET).a64: $(SOURCE:.c=.a64.o) %.universal: %.x64 %.a64 lipo -create -output $@ $^ %.x64: $(CC) $(CFLAGS_X64) -o $@ $^ %.a64: $(CC) $(CFLAGS_A64) -o $@ $^ %.x64.o: %.c $(CC) $(CFLAGS) $(CFLAGS_X64) -c -o $@ $< %.a64.o: %.c $(CC) $(CFLAGS) $(CFLAGS_A64) -c -o $@ $< %.x64.o: %.cpp $(CXX) $(CXXFLAGS) $(CFLAGS_X64) -c -o $@ $< %.a64.o: %.cpp $(CXX) $(CXXFLAGS) $(CFLAGS_A64) -c -o $@ $< .PHONY: clean clean: rm -f *.x64.o *.a64.o *.x64 *.a64
Pour l'utiliser avec vos fichiers file1.c
,
file2.c
, etc., créez votre makefile avec un contenu de
ce genre:
SOURCE = file1.c file2.c file3.c TARGET = program # define vpath, VPATH, CFLAGS etc. as appropriate .PHONY: main main: $(TARGET) include universal.mk
Taper make
va:
- compiler chaque fichier source .c en fichiers objet .x64.o et .a64.o
- les lier séparément en programmes .x64 et .a64
- les fusionner en un programme universel.