blob: 5534d5b00ceb68ac0812b19bf9ea15098d423094 [file] [log] [blame]
Dominik Riebelingb24e5622011-12-14 21:59:37 +00001# __________ __ ___.
2# Open \______ \ ____ ____ | | _\_ |__ _______ ___
3# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
4# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
5# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
6# \/ \/ \/ \/ \/
7
8# libtools.make
9#
10# Common Makefile for tools used by Rockbox Utility.
11# Provides rules for building as library, universal library (OS X) and
12# standalone binary.
13#
14# LIBSOURCES is a list of files to build the lib
15# SOURCES is a list of files to build for the main binary
16# EXTRADEPS is a list of make targets dependencies
17#
18ifndef V
19SILENT = @
20endif
21
22# Get directory this Makefile is in for relative paths.
23TOP := $(dir $(lastword $(MAKEFILE_LIST)))
Dominik Riebeling4f3fa9a2013-05-11 17:22:44 +020024ifeq ($(OS),Windows_NT)
25mkdir = if not exist $(subst /,\,$(1)) mkdir $(subst /,\,$(1))
Dominik Riebeling17a18672014-01-05 17:08:50 +010026rm = if exist $(subst /,\,$(1)) del /q /s $(subst /,\,$(1))
Dominik Riebeling4f3fa9a2013-05-11 17:22:44 +020027else
28mkdir = mkdir -p $(1)
Dominik Riebelingf3a1a332014-01-05 16:53:17 +010029rm = rm -rf $(1)
Dominik Riebeling4f3fa9a2013-05-11 17:22:44 +020030endif
Dominik Riebelingb24e5622011-12-14 21:59:37 +000031
32# overwrite for releases
Dominik Riebeling45cda1f2013-01-01 10:51:11 +010033APPVERSION ?= $(shell $(TOP)/../tools/version.sh $(TOP)/..)
Dominik Riebeling3ee79722016-12-16 21:50:36 +010034GCCFLAGS += -DVERSION=\"$(APPVERSION)\"
Dominik Riebelingea0bfe72013-04-05 19:49:04 +020035TARGET_DIR ?= $(abspath .)/
Dominik Riebelingb24e5622011-12-14 21:59:37 +000036
Dominik Riebeling78cb7f02016-12-16 19:29:52 +010037CC := gcc
38CXX := g++
Dominik Riebeling3ee79722016-12-16 21:50:36 +010039# use either CC or CXX to link: this makes sure the compiler knows about its
40# internal dependencies. Use CXX if we have at least one c++ file, since we
41# then need to link the c++ standard library (which CXX does for us).
42ifeq ($(strip $(filter %.cpp,$(SOURCES) $(LIBSOURCES))),)
43LD := $(CC)
44else
45LD := $(CXX)
46endif
Dominik Riebeling8568a8d2013-05-10 17:45:37 +020047CPPDEFINES := $(shell echo foo | $(CROSS)$(CC) -dM -E -)
Rafaël Carrédb3afb02012-02-05 14:03:10 -050048
Dominik Riebelingb24e5622011-12-14 21:59:37 +000049BINARY = $(OUTPUT)
50# when building a Windows binary add the correct file suffix
Dominik Riebelingea0bfe72013-04-05 19:49:04 +020051ifeq ($(findstring CYGWIN,$(CPPDEFINES)),CYGWIN)
Dominik Riebelingb24e5622011-12-14 21:59:37 +000052BINARY = $(OUTPUT).exe
Dominik Riebeling3ee79722016-12-16 21:50:36 +010053GCCFLAGS += -mno-cygwin
Dominik Riebelingea0bfe72013-04-05 19:49:04 +020054COMPILETARGET = cygwin
Dominik Riebelingb24e5622011-12-14 21:59:37 +000055else
Dominik Riebelingea0bfe72013-04-05 19:49:04 +020056ifeq ($(findstring MINGW,$(CPPDEFINES)),MINGW)
Dominik Riebelingb24e5622011-12-14 21:59:37 +000057BINARY = $(OUTPUT).exe
Dominik Riebelingea0bfe72013-04-05 19:49:04 +020058COMPILETARGET = mingw
Dominik Riebeling6f4beaa2016-12-16 19:39:07 +010059# use POSIX/C99 printf on windows
Dominik Riebeling3ee79722016-12-16 21:50:36 +010060GCCFLAGS += -D__USE_MINGW_ANSI_STDIO=1
Dominik Riebelingb24e5622011-12-14 21:59:37 +000061else
Dominik Riebelingea0bfe72013-04-05 19:49:04 +020062ifeq ($(findstring APPLE,$(CPPDEFINES)),APPLE)
63COMPILETARGET = darwin
Dominik Riebeling703bc402013-04-05 20:03:45 +020064LDOPTS += $(LDOPTS_OSX)
Dominik Riebelingea0bfe72013-04-05 19:49:04 +020065else
66COMPILETARGET = posix
Dominik Riebelingb24e5622011-12-14 21:59:37 +000067endif
68endif
69endif
Dominik Riebelingea0bfe72013-04-05 19:49:04 +020070$(info Compiler creates $(COMPILETARGET) binaries)
Dominik Riebelingb24e5622011-12-14 21:59:37 +000071
Dominik Riebelingc6dcec42012-01-05 22:26:08 +000072# OS X specifics. Needs to consider cross compiling for Windows.
Dominik Riebelingea0bfe72013-04-05 19:49:04 +020073ifeq ($(findstring APPLE,$(CPPDEFINES)),APPLE)
Dominik Riebeling258e4ad2014-03-20 22:22:17 +010074# When building for 10.4+ we need to use gcc. Otherwise clang is used, so use
75# that to determine if we need to set arch and isysroot.
76ifeq ($(findstring __clang__,$(CPPDEFINES)),__clang__)
Dominik Riebeling3ee79722016-12-16 21:50:36 +010077GCCFLAGS += -mmacosx-version-min=10.5
Dominik Riebeling258e4ad2014-03-20 22:22:17 +010078else
79# when building libs for OS X 10.4+ build for both i386 and ppc at the same time.
Dominik Riebelingc6dcec42012-01-05 22:26:08 +000080# This creates fat objects, and ar can only create the archive but not operate
81# on it. As a result the ar call must NOT use the u (update) flag.
Dominik Riebeling33bda052013-06-09 19:43:37 +020082ARCHFLAGS += -arch ppc -arch i386
Dominik Riebelingb056e022011-12-16 18:35:01 +000083# building against SDK 10.4 is not compatible with gcc-4.2 (default on newer Xcode)
84# might need adjustment for older Xcode.
Dominik Riebeling703bc402013-04-05 20:03:45 +020085CC = gcc-4.0
Dominik Riebeling3ee79722016-12-16 21:50:36 +010086GCCFLAGS += -isysroot /Developer/SDKs/MacOSX10.4u.sdk -mmacosx-version-min=10.4
Dominik Riebelingb056e022011-12-16 18:35:01 +000087endif
Dominik Riebeling258e4ad2014-03-20 22:22:17 +010088endif
Dominik Riebelingb056e022011-12-16 18:35:01 +000089
Dominik Riebelingea0bfe72013-04-05 19:49:04 +020090BUILD_DIR ?= $(TARGET_DIR)build$(COMPILETARGET)
Dominik Riebelinge073bc92013-05-11 20:15:53 +020091OBJDIR = $(abspath $(BUILD_DIR))/
Dominik Riebelingb24e5622011-12-14 21:59:37 +000092
93all: $(BINARY)
94
Dominik Riebeling78cb7f02016-12-16 19:29:52 +010095OBJS := $(addsuffix .o,$(addprefix $(OBJDIR),$(notdir $(SOURCES))))
96LIBOBJS := $(addsuffix .o,$(addprefix $(OBJDIR),$(notdir $(LIBSOURCES))))
Dominik Riebelingb24e5622011-12-14 21:59:37 +000097
Dominik Riebelinge073bc92013-05-11 20:15:53 +020098# create dependency files. Make sure to use the same prefix as with OBJS!
Dominik Riebeling78cb7f02016-12-16 19:29:52 +010099$(foreach src,$(SOURCES) $(LIBSOURCES),$(eval $(addprefix $(OBJDIR),$(notdir $(src).o)): $(src)))
100$(foreach src,$(SOURCES) $(LIBSOURCES),$(eval $(addprefix $(OBJDIR),$(notdir $(src).d)): $(src)))
101DEPS = $(addprefix $(OBJDIR),$(addsuffix .d,$(notdir $(SOURCES) $(LIBSOURCES))))
Dominik Riebelinge073bc92013-05-11 20:15:53 +0200102-include $(DEPS)
Dominik Riebeling8a4075d2013-05-11 11:28:08 +0200103
Dominik Riebeling6b8f0b02011-12-14 22:00:06 +0000104# additional link dependencies for the standalone executable
105# extra dependencies: libucl
Dominik Riebeling6f4beaa2016-12-16 19:39:07 +0100106LIBUCL = libucl.a
Dominik Riebeling6b8f0b02011-12-14 22:00:06 +0000107$(LIBUCL): $(OBJDIR)$(LIBUCL)
Dominik Riebelingb24e5622011-12-14 21:59:37 +0000108
Dominik Riebeling6b8f0b02011-12-14 22:00:06 +0000109$(OBJDIR)$(LIBUCL):
Dominik Riebeling78cb7f02016-12-16 19:29:52 +0100110 $(SILENT)$(MAKE) -C $(TOP)/../tools/ucl/src TARGET_DIR=$(OBJDIR) CC=$(CC) $@
Dominik Riebelingb24e5622011-12-14 21:59:37 +0000111
112# building the standalone executable
Dominik Riebeling6f4beaa2016-12-16 19:39:07 +0100113$(BINARY): $(OBJS) $(EXTRADEPS) $(addprefix $(OBJDIR),$(EXTRALIBOBJS)) $(TARGET_DIR)lib$(OUTPUT).a
Dominik Riebeling78cb7f02016-12-16 19:29:52 +0100114 $(info LD $@)
Dominik Riebeling4f3fa9a2013-05-11 17:22:44 +0200115 $(SILENT)$(call mkdir,$(dir $@))
Dominik Riebelingb24e5622011-12-14 21:59:37 +0000116# EXTRADEPS need to be built into OBJDIR.
Dominik Riebeling3ee79722016-12-16 21:50:36 +0100117 $(SILENT)$(CROSS)$(LD) $(ARCHFLAGS) $(LDFLAGS) -o $(BINARY) \
Dominik Riebeling17a0c832011-12-15 18:44:57 +0000118 $(OBJS) $(addprefix $(OBJDIR),$(EXTRADEPS)) \
Dominik Riebeling6f4beaa2016-12-16 19:39:07 +0100119 $(addprefix $(OBJDIR),$(EXTRALIBOBJS)) lib$(OUTPUT).a $(addprefix $(OBJDIR),$(EXTRADEPS)) $(LDOPTS)
Dominik Riebelingb24e5622011-12-14 21:59:37 +0000120
Dominik Riebeling6b8f0b02011-12-14 22:00:06 +0000121# common rules
Dominik Riebeling78cb7f02016-12-16 19:29:52 +0100122$(OBJDIR)%.c.o:
123 $(info CC $<)
Dominik Riebeling4f3fa9a2013-05-11 17:22:44 +0200124 $(SILENT)$(call mkdir,$(dir $@))
Dominik Riebeling3ee79722016-12-16 21:50:36 +0100125 $(SILENT)$(CROSS)$(CC) $(ARCHFLAGS) $(GCCFLAGS) $(CFLAGS) -MMD -c -o $@ $<
Dominik Riebeling78cb7f02016-12-16 19:29:52 +0100126
127$(OBJDIR)%.cpp.o:
128 $(info CXX $<)
129 $(SILENT)$(call mkdir,$(dir $@))
Dominik Riebeling3ee79722016-12-16 21:50:36 +0100130 $(SILENT)$(CROSS)$(CXX) $(ARCHFLAGS) $(GCCFLAGS) $(CXXFLAGS) -MMD -c -o $@ $<
Dominik Riebeling6b8f0b02011-12-14 22:00:06 +0000131
132# lib rules
Dominik Riebeling6f4beaa2016-12-16 19:39:07 +0100133lib$(OUTPUT).a: $(TARGET_DIR)lib$(OUTPUT).a
134lib$(OUTPUT): $(TARGET_DIR)lib$(OUTPUT).a
Dominik Riebeling6b8f0b02011-12-14 22:00:06 +0000135
Dominik Riebeling6f4beaa2016-12-16 19:39:07 +0100136$(TARGET_DIR)lib$(OUTPUT).a: $(LIBOBJS) \
Dominik Riebeling17a0c832011-12-15 18:44:57 +0000137 $(addprefix $(OBJDIR),$(EXTRALIBOBJS))
Dominik Riebeling84205022011-12-16 21:10:29 +0000138# rules to build a DLL. Only works for W32 as target (i.e. MinGW toolchain)
139dll: $(OUTPUT).dll
140$(OUTPUT).dll: $(TARGET_DIR)$(OUTPUT).dll
141$(TARGET_DIR)$(OUTPUT).dll: $(LIBOBJS) $(addprefix $(OBJDIR),$(EXTRALIBOBJS))
Dominik Riebeling78cb7f02016-12-16 19:29:52 +0100142 $(info DLL $(notdir $@))
Dominik Riebeling4f3fa9a2013-05-11 17:22:44 +0200143 $(SILENT)$(call mkdir,$(dir $@))
Dominik Riebeling3ee79722016-12-16 21:50:36 +0100144 $(SILENT)$(CROSS)$(CC) $(ARCHFLAGS) $(GCCFLAGS) -shared -o $@ $^ \
Dominik Riebeling84205022011-12-16 21:10:29 +0000145 -Wl,--output-def,$(TARGET_DIR)$(OUTPUT).def
146
Dominik Riebelingc6dcec42012-01-05 22:26:08 +0000147# create lib file from objects
Dominik Riebeling6f4beaa2016-12-16 19:39:07 +0100148$(TARGET_DIR)lib$(OUTPUT).a: $(LIBOBJS) $(addprefix $(OBJDIR),$(EXTRALIBOBJS))
Dominik Riebeling78cb7f02016-12-16 19:29:52 +0100149 $(info AR $(notdir $@))
Dominik Riebeling4f3fa9a2013-05-11 17:22:44 +0200150 $(SILENT)$(call mkdir,$(dir $@))
Dominik Riebelingf3a1a332014-01-05 16:53:17 +0100151 $(SILENT)$(call rm,$@)
Dominik Riebeling78cb7f02016-12-16 19:29:52 +0100152 $(SILENT)$(CROSS)$(AR) rcs $@ $^
Dominik Riebelingb24e5622011-12-14 21:59:37 +0000153
154clean:
Dominik Riebelingf3a1a332014-01-05 16:53:17 +0100155 $(call rm, $(OBJS) $(OUTPUT) $(TARGET_DIR)lib$(OUTPUT)*.a $(OUTPUT).dmg)
156 $(call rm, $(OUTPUT)-* i386 ppc $(OBJDIR))
Dominik Riebelingb24e5622011-12-14 21:59:37 +0000157
Dominik Riebeling308f0992012-04-28 12:05:50 +0200158# extra tools
159BIN2C = $(TOP)/tools/bin2c
160$(BIN2C):
161 $(MAKE) -C $(TOP)/tools
162
Dominik Riebelingb24e5622011-12-14 21:59:37 +0000163# OS X specifics
Dominik Riebelingded02d82012-01-06 09:24:38 +0000164$(OUTPUT).dmg: $(OUTPUT)
Dominik Riebeling78cb7f02016-12-16 19:29:52 +0100165 $(info DMG $@)
Dominik Riebeling4f3fa9a2013-05-11 17:22:44 +0200166 $(SILENT)$(call mkdir,$(OUTPUT)-dmg))
Dominik Riebelingded02d82012-01-06 09:24:38 +0000167 $(SILENT)cp -p $(OUTPUT) $(OUTPUT)-dmg
Dominik Riebelingb24e5622011-12-14 21:59:37 +0000168 $(SILENT)hdiutil create -srcfolder $(OUTPUT)-dmg $@