Issue
I have a build file on OSX Lion
VPATH = src include
CFLAGS ="-I include -std=gnu99"
hello: hello.o
gcc $^ -o $@
hello.o: hello.h hello.c
gcc $(CFLAGS) -c $< -o $@
But when I try and run this make file I get the following error
ld: warning: ignoring file hello.o, file was built for unsupported file format which is not the architecture being linked (x86_64)
Undefined symbols for architecture x86_64:
"_main", referenced from:
start in crt1.10.6.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
I have tried using the flag -arch x86_64
but still get the same error.
Running the arch
command gives: i386
.
uname -a
tells me: Darwin Kernel Version 11.3.0: Thu Jan 12 18:47:41 PST 2012; root:xnu-1699.24.23~1/RELEASE_X86_64 x86_64
I've also tried to add the switch -march=x86-64
as described in this answer file was built for i386 which is not the architecture being linked (x86_64) while compiling OpenCV2.2 for iOS 4.2 on Mac OSX 10.6 but that hasn't worked for me.
The output from the command line is:
gcc -I include -std=gnu99 -m64 -c include/hello.h -o hello.o
gcc -I include -std=gnu99 -m64 hello.o -o hello
ld: warning: ignoring file hello.o, file was built for unsupported file format which is not the architecture being linked (x86_64)
Undefined symbols for architecture x86_64:
"_main", referenced from:
start in crt1.10.6.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
make: *** [hello] Error 1
Solution
- Remove all the object files.
Revise the makefile more like:
VPATH = src include CFLAGS = -I include -std=gnu99 -m64 CC = gcc LDLIBS = LDFLAGS = hello: hello.o $(CC) $(CFLAGS) $^ -o $@ hello.o: hello.c hello.h $(CC) $(CFLAGS) -c $< -o $@ $(LDFLAGS) $(LDLIBS)
Note that I've macro-ized everything on the command lines. The CFLAGS are used in all compilations. They are not enclosed in double quotes. The -m64
option requests a 64-bit build; it shouldn't be necessary, but it makes it explicit. You don't yet need the LDFLAGS or LDLIBS macros (so you could omit them without causing yourself problems), but they show how you might proceed when you do need some libraries at link time.
For my own makefiles, I do things like:
IFLAGS = -Iinclude
WFLAG1 = -Wall
WFLAG2 = -Werror
WFLAG3 = -Wextra
WFLAGS = $(WFLAG1) $(WFLAG2) $(WFLAG3)
OFLAGS = -g -O3
SFLAG1 = -std=c99
SFLAG2 = -m64
SFLAGS = $(SFLAG1) $(SFLAG2)
DFLAGS = # -Doptions
UFLAGS = # Set on make command line only
CFLAGS = $(SFLAGS) $(DFLAGS) $(IFLAGS) $(OFLAGS) $(WFLAGS) $(UFLAGS)
That way I can adjust just about any single argument to the C compiler on the command line. For example, to do 32-bit builds, I can run:
make SFLAG2=-m32
Etc. The downside is I can never remember which xFLAGn option affects which. However, a quick look at the makefile rectifies that, and I can change the compilation without modifying the makefile at all.
(I also often use CC="gcc -m64"
to force 64-bit compilations on other people's software.)
Answered By - Jonathan Leffler