How do I create a single makefile for both 32- and 64-bit?
Asked Answered
A

6

19

I have a makefile that works transparently for Linux (x86_64) and OS X Intel (x86_64). This uses 64-bit specific GCC options.

Is there a way to adjust the makefile so that I could build for 32-bit and 64-bit OS X PPC (ppc, ppc64) without having to maintain separate, arch-specific makefiles — perhaps something like a pre-processor directive that can determine the architecture before building?

Ado answered 4/11, 2010 at 11:29 Comment(0)
E
22
ARCH := $(shell getconf LONG_BIT)

CPP_FLAGS_32 := -D32_BIT ...  Some 32 specific compiler flags ...
CPP_FLAGS_64 := -D64_BIT

CPP_FLAGS := $(CPP_FLAGS_$(ARCH))  ... all the other flags ...
Emlyn answered 15/4, 2011 at 15:50 Comment(2)
-1, does not answer the question (how to differentiate pcc to x86)Mofette
If anyone knows how to do this under MinGW (Windows) without MSYS, drop a comment here and tag me.Shortwinded
L
3

Try file inclusion. This is not part of the standard Makefile syntax (the one in the Single Unix v3 specification) but is widely supported. With GNU make, this looks like this:

include otherfile

With this, you could have an x86 Makefile like this:

ARCHFLAGS = -m64 -mtune=core2
include common.mk

and a PowerPC Makefile:

ARCHFLAGS = -mcpu=g3
include common.mk

and the bulk of your compilation rules will be in one file (common.mk), using $(ARCHFLAGS) where necessary.

Libbylibeccio answered 4/11, 2010 at 12:48 Comment(2)
I use this approach for a codebase that has to build on 5 different Unix variantsCasemaker
This is very useful. There are a lot of different standards and relatively few operating systems seem to fully comply with each... do you have to read both the standards and the compliance information for each target OS, or is there an easier way to find out which systems support each feature? I've done well for myself with auto dependency generation, but that depends on 'include', and I thought that was universally supported.Revulsion
L
1

I think that you would achieve your goals with less work (and pain) by employing some kind of a build system such as cmake or GNU autotools.

Lousy answered 4/11, 2010 at 11:44 Comment(3)
I would say if your project is small and you don't have lots of library dependencies to handle on different platforms then stay the hell away from auto-tools because its hell to maintain. If its a small(ish) project and you have an idea of what the tragets will be like then you are just fine with some tuned makefiles.Norton
I would say that even if your project is small, go with the autotools. It's much better than CMake and modern automake with AM_SILENT_RULES looks almost as good. Hell to maintain? Not really.Garrettgarrick
Well, usability of computer programs has always been in the eye of the beholder :-) There is an another option which has a considerably gentler learning curve: tmake from Trolltech. Unsupported but works. Much simpler than the alternatives.Lousy
L
1

One way to work this is to:

  • have makefile fragments for each architecture (possibly cumulative): posix, win32, win32-gcc, etc.
  • have a script that runs and determines why fragments are adequate for the host
  • include those makefile fragments into the main makefile
  • allow manual override using environment variables (because things can sometimes be complicated; e.g., think of cross-compilers)

I've used this in small-to-medium size projects (2 or 3 persons working on code for a few years), and it fits the bill well.

Locoweed answered 3/1, 2011 at 17:59 Comment(1)
Just to add: the ./configure step in some projects, does something on similar lines.Jasmine
N
0

Have a look at this:

http://mad-scientist.net/make/multi-arch.html

It is somewhat dated but has good info that could be useful for you I suppose.

Norton answered 4/11, 2010 at 12:59 Comment(0)
R
0

Although it doesn't explicitly answer the CPP compilation, this method I've just created for assembly language could be easily adapted to fit.

makefile

# -----------------------------------------
PROJECT = helloworld
# Expected source files: *-32.s and *-64.s
# -----------------------------------------
BITS := $(shell getconf LONG_BIT)
OBJS = $(PROJECT).o
ifdef DEBUG
    DEBUGFLGS = -g
else
    DEBUGFLGS =
endif

%.o : %-$(BITS).s
    as $(DEBUGFLGS) -o $@   $<

$(PROJECT): $(OBJS)
    ld  -o bin/$(PROJECT)   $(OBJS)

I then add helloworld-32.s and helloworld-64.s to the project folder and everything works out by running make in the folder.

Raconteur answered 30/11, 2019 at 20:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.