en fr

nyctergatis.com

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:

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: