Clang: Cannot Use ‘Precompiled-header’ Output With Multiple -arch Options
I took me a while to figure out what was going on:
clang: cannot use 'precompiled-header' output with multiple -arch options
For once, Stack Overflow was of little help.
Here is an excerpt of the GNU Makefile
I’m using to compile my project:
define build
CC-$(platform)-$(2)?=$(CC-$(platform))
$(bindir)/$(platformdir)-$(2)$($(3)-dirsuffix)/$(1)_%: $(srcdir)/$(1)/%.c $(common)
mkdir -p $$(@D)
$$(CC-$(platform)-$(2)) $(cflags) $($(3)-cflags) $(CFLAGS) -o $$@ $$^ $($(3)-ldflags) $(LDFLAGS)
endef
$(foreach library,$(libraries),\
$(foreach arch,$(archs),\
$(foreach configuration,$(configurations),\
$(eval $(call build,$(library),$(arch),$(configuration))))))
In my case,
-
$(platform)
is set to ‘mac
’ -
$(archs)
consists in a single ‘x86+x64
’ value -
CC-mac-x86+x64
is set to ‘$(CC-mac) -arch i386 -arch x86_64
’
After having debugged that little beast for a while, I finally realized that $(common)
contains both path to header (.h
) and source (.c
) files.
Inspecting the make
invocation reveals something like:
cc -arch i386 -arch x86_64 -I/some/include/path -DSOME_MACRO -O2 -g -o out foo.c bar.c baz.c baz.h
GCC
swallows that without problems but apparently clang
is totally confused.
The solution is to filter out header files from the list of files being compiled:
define build
CC-$(platform)-$(2)?=$(CC-$(platform))
$(bindir)/$(platformdir)-$(2)$($(3)-dirsuffix)/$(1)_%: $(srcdir)/$(1)/%.c $(MyCertificate.c) $(edk_c_src) $(common)
mkdir -p $$(@D)
$$(CC-$(platform)-$(2)) $(cflags) $($(3)-cflags) $(CFLAGS) -o $$@ $$(filter-out %.h,$$^) $($(3)-ldflags) $(LDFLAGS)
endef
See the $(filter-out pattern...,text)
function in GNU Make
’s manual.
Obvious right?! Hope it saves you precious minutes.