Skip to content

Instantly share code, notes, and snippets.

@urraka
Created November 17, 2014 20:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save urraka/18d4de32f68c3fe5c468 to your computer and use it in GitHub Desktop.
Save urraka/18d4de32f68c3fe5c468 to your computer and use it in GitHub Desktop.
# overridable variables:
# * project -> defaults to parent dir basename
# * src-root -> defaults to src
# * out-root -> defaults to bin
# * debug -> define it to anything for debug mode
# * platform -> possible values are win32,osx,linux,ios,iossim
# * inc, inc-* -> where * is the platform
# * lib, lib-* -> where * is the platform
# * flg, flg-* -> where * is the platform
# * ios.version -> installed sdk version
# * ios.version.min -> minimum sdk version
# * ios.plist -> file that will be copied as Info.plist
# * ios.bundle.files -> additional files to put along the executable file
project ?= $(notdir $(shell pwd))
src-root ?= src
out-root ?= bin
cxx ?= g++
cc ?= gcc
# try to detect platform if not given
ifndef platform
ifeq ($(shell uname | grep 'MINGW32_NT' -c),1)
platform ?= win32
endif
ifeq ($(shell uname | grep 'Linux' -c),1)
platform ?= linux
endif
ifeq ($(shell uname | grep 'Darwin' -c),1)
platform ?= osx
endif
endif # platform
# define extra stuff for ios
ifeq ($(platform),ios)
ios := true
ios.version.min ?= 4.0
ios.version ?= $(shell xcodebuild -showsdks | grep iphoneos | sed "s|.*iphoneos||")
ios.xcode.path := $(shell xcode-select --print-path)
ios.dev.path := $(ios.xcode.path)/Platforms/iPhoneOS.platform/Developer
ios.sdk.path := $(ios.dev.path)/SDKs/iPhoneOS$(ios.version).sdk
ios.arch := armv7
ios.flags := -isysroot $(ios.sdk.path) -arch $(ios.arch) -miphoneos-version-min=$(ios.version.min)
endif
ifeq ($(platform),iossim)
ios := true
ios.version.min ?= 4.0
ios.version ?= $(shell xcodebuild -showsdks | grep iphoneos | sed "s|.*iphoneos||")
ios.xcode.path := $(shell xcode-select --print-path)
ios.dev.path := $(ios.xcode.path)/Platforms/iPhoneSimulator.platform/Developer
ios.sdk.path := $(ios.dev.path)/SDKs/iPhoneSimulator$(ios.version).sdk
ios.arch := i386
ios.flags := -isysroot $(ios.sdk.path) -arch $(ios.arch) -mios-simulator-version-min=$(ios.version.min)
endif
ifdef ios
flg += $(ios.flags)
endif
# set the name of the output executable
binary-postfix-win32 := .exe
$(eval binary-postfix := $$(binary-postfix-$(platform)))
out-file := $(project)$(binary-postfix)
# define _DEBUG if compiling on debug mode and add some extra flags
ifdef debug
flg += -g -D_DEBUG -Wall
out-dir := $(out-root)/$(platform)-d
else
flg += -g -O3 -Wall
out-dir := $(out-root)/$(platform)
endif
# consolidate all the platform specific options into inc,lib,flg variables
$(eval inc += $$(inc-$(platform)))
$(eval lib += $$(lib-$(platform)))
$(eval flg += $$(flg-$(platform)))
# find all directories under src-root and set matching directories for dependency and object files
src-dirs := $(shell find $(src-root) -depth -type d)
obj-dirs := $(patsubst $(src-root)%,$(out-dir)/obj%,$(src-dirs))
dep-dirs := $(patsubst $(src-root)%,$(out-dir)/dep%,$(src-dirs))
# make a list of directories to be created
out-dirs := $(out-dir)/ $(obj-dirs) $(dep-dirs)
ifdef ios
out-dirs += $(out-dir)/bundle
out-dirs += $(out-dir)/bundle/Documents
out-dirs += $(out-dir)/bundle/Library
out-dirs += $(out-dir)/bundle/tmp
out-dirs += $(out-dir)/bundle/$(project).app
endif
# define extensions used for c++
cxx-ext := cpp cxx cc
ifdef ios
cxx-ext += m mm
endif
# find all source files under the source directories and make matching lists of dependency and objects files
src-cxx := $(foreach d,$(src-dirs),$(foreach e,$(cxx-ext),$(wildcard $d/*.$e)))
src-cc := $(foreach d,$(src-dirs),$(wildcard $d/*.c))
obj-cxx := $(patsubst $(src-root)%,$(out-dir)/obj%.o,$(src-cxx))
obj-cc := $(patsubst $(src-root)%,$(out-dir)/obj%.o,$(src-cc))
dep-cxx := $(patsubst $(src-root)%,$(out-dir)/dep%.d,$(src-cxx))
dep-cc := $(patsubst $(src-root)%,$(out-dir)/dep%.d,$(src-cc))
# main target on ios is ios.bundle
ifdef ios
out-file := bundle/$(project).app/$(out-file)
ios.outdir := $(out-dir)/bundle/$(project).app
ios.bundle: $(out-dir)/$(out-file) $(ios.outdir)/Info.plist \
$(addprefix $(ios.outdir)/,$(ios.bundle.files)) | $(out-dirs)
.PHONY: ios.bundle
ifdef ios.plist
$(ios.outdir)/Info.plist: $(ios.plist)
cp -f $(ios.plist) $@
else
doctype := <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" \
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
$(ios.outdir)/Info.plist: makefile
@echo '<?xml version="1.0" encoding="UTF-8"?>' > $@
@echo '$(doctype)' >> $@
@echo '<plist version="1.0">' >> $@
@echo ' <dict>' >> $@
@echo ' <key>CFBundleDevelopmentRegion</key>' >> $@
@echo ' <string>English</string>' >> $@
@echo ' <key>CFBundleDisplayName</key>' >> $@
@echo ' <string>$(project)</string>' >> $@
@echo ' <key>CFBundleExecutable</key>' >> $@
@echo ' <string>$(project)</string>' >> $@
@echo ' <key>CFBundleIconFile</key>' >> $@
@echo ' <string>Icon.png</string>' >> $@
@echo ' <key>CFBundleIdentifier</key>' >> $@
@echo ' <string>com.example.$(project)</string>' >> $@
@echo ' <key>CFBundleInfoDictionaryVersion</key>' >> $@
@echo ' <string>6.0</string>' >> $@
@echo ' <key>CFBundleName</key>' >> $@
@echo ' <string>$(project)</string>' >> $@
@echo ' <key>CFBundlePackageType</key>' >> $@
@echo ' <string>APPL</string>' >> $@
@echo ' <key>CFBundleSignature</key>' >> $@
@echo ' <string>????</string>' >> $@
@echo ' <key>CFBundleShortVersionString</key>' >> $@
@echo ' <string>1.0</string>' >> $@
@echo ' <key>CFBundleVersion</key>' >> $@
@echo ' <string>1.0.0</string>' >> $@
@echo ' <key>UIStatusBarStyle</key>' >> $@
@echo ' <string>UIStatusBarStyleBlackOpaque</string>' >> $@
@echo ' <key>LSRequiresIPhoneOS</key>' >> $@
@echo ' <true/>' >> $@
@echo ' </dict>' >> $@
@echo '</plist>' >> $@
endif # ios.plist
define ios.copyfiles
$(ios.outdir)/$1: $1
cp -rf "$1" "$(ios.outdir)/"
endef
$(foreach f,$(ios.bundle.files),$(eval $(call ios.copyfiles,$f)))
endif # ios
# target for main executable
$(out-dir)/$(out-file): $(build.extra) $(obj-cxx) $(obj-cc) | $(out-dirs)
@echo "Linking $@..."
@$(cxx) -o $@ $(obj-cxx) $(obj-cc) $(lib) $(flg)
# create required directories
$(out-dirs):
@mkdir -p $@
# make-obj(compiler,source)
define make-obj
$(out-dir)/obj/$2.o: $(src-root)/$2 | $(out-dirs)
@echo "Compiling $$<..."
@$1 -o $$@ -MF"$(out-dir)/dep/$2.d" -MMD -MP \
-MT"$(out-dir)/dep/$2.d $(out-dir)/obj/$2.o" $(inc) $(flg) -c $$<
endef
# create a rule for each source file using make-obj template
$(foreach s,$(src-cxx),$(eval $(call make-obj,$(cxx),$(patsubst $(src-root)/%,%,$s))))
$(foreach s,$(src-cc),$(eval $(call make-obj,$(cc),$(patsubst $(src-root)/%,%,$s))))
# include generated dependency files if they exist
ifneq ($(MAKECMDGOALS),clean)
-include $(dep-cxx) $(dep-cc)
endif
# cleanup
clean:
@rm -rf $(out-root)
@rm -rf $(clean.extra)
.PHONY: clean
libs.root ?= libs
libs.root := $(libs.root)/$(platform)
libs.all := $(patsubst libs.%.link,libs.%,$(filter libs.%.link,$(.VARIABLES)))
libs.all: $(libs.all)
# parameters:
# $1: libs.x
# $2: $(libs.x.file)
# $3: $(libs.x.dir)
# $4: $(libs.x.src)
# $5: $(libs.x.dst)
# $6: $(libs.x.build)
define libs.install.files
$(if $6,cd $(libs.root)/$1.tmp/$3; $6,)
$(subst ^, ,$(join $(addprefix cp^-rf^$(libs.root)/$1.tmp/$3/,$4),$(patsubst %,^%;,$(addprefix $(libs.root)/,$5))))
endef
define libs.install.gz
cd $(libs.root)/$1.tmp; tar -xf $2
$(call libs.install.files,$1,$2,$3,$4,$5,$6)
-rm -rf $(libs.root)/$1.tmp/$3
-rm -rf $(libs.root)/$1.tmp/$3
endef
libs.install.tgz = $(libs.install.gz)
define libs.install.dmg
hdiutil attach $(libs.root)/$1.tmp/$2 -mountpoint $(libs.root)/$1.tmp/$3
$(call libs.install.files,$1,$2,$3,$4,$5,$6)
hdiutil detach $(libs.root)/$1.tmp/$3
endef
define libs.install.zip
cd $(libs.root)/$1.tmp; unzip -q -o $2
$(call libs.install.files,$1,$2,$3,$4,$5,$6)
-rm -rf $(libs.root)/$1.tmp/$3
-rm -rf $(libs.root)/$1.tmp/$3
endef
define libs.install
$1:
mkdir -p $(libs.root)/lib
mkdir -p $(libs.root)/include
mkdir -p $(libs.root)/$1.tmp
echo "Downloading $$($1.file)..."
curl -L -s $$($1.link) -o $(libs.root)/$1.tmp/$$($1.file)
$$(call libs.install$$(suffix $$($1.file)),$1,$$($1.file),$$($1.dir),$$($1.src),$$($1.dst),$$($1.build))
-rm -rf $(libs.root)/$1.tmp
-rm -rf $(libs.root)/$1.tmp
endef
$(foreach i,$(libs.all),$(eval $(call libs.install,$i)))
libs.clean:
@rm -rf $(libs.root)
.PHONY: libs.clean libs.all $(libs.all)
inc += -Isrc
flg += -DGLM_FORCE_RADIANS -fno-exceptions -fno-rtti -std=c++11
ios.bundle.files := res
build.extra := res/spritesheet.png
#-----------------------------#
#----------- win32 -----------#
#-----------------------------#
inc-win32 += -Ilibs/win32/include -Ilibs/win32/include/freetype2
flg-win32 += -mwindows
lib-win32 += -lmingw32
lib-win32 += libs/win32/lib/GLEW.a
lib-win32 += libs/win32/lib/freetype.a
lib-win32 += libs/win32/lib/SDL2main.a
lib-win32 += libs/win32/lib/SDL2.a
lib-win32 += -lm -ldinput8 -ldxguid -ldxerr8 -luser32 -lgdi32
lib-win32 += -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion
lib-win32 += -luuid -lopengl32 -static-libgcc -static-libstdc++
#-----------------------------#
#------------ osx ------------#
#-----------------------------#
inc-osx += -Ilibs/osx/include -Ilibs/osx/include/freetype2
flg-osx += -D_THREAD_SAFE
lib-osx += libs/osx/lib/GLEW.a
lib-osx += libs/osx/lib/freetype.a
lib-osx += libs/osx/lib/SDL2.a
lib-osx += libs/osx/lib/SDL2main.a
lib-osx += -lm -liconv -lobjc
lib-osx += -framework OpenGL
lib-osx += -framework ForceFeedback
lib-osx += -framework Cocoa
lib-osx += -framework Carbon
lib-osx += -framework IOKit
lib-osx += -framework CoreAudio
lib-osx += -framework AudioToolbox
lib-osx += -framework AudioUnit
#-----------------------------#
#------- ios simulator -------#
#-----------------------------#
inc-iossim += -Ilibs/iossim/include -Ilibs/iossim/include/freetype2
flg-iossim += -D_THREAD_SAFE
lib-iossim += libs/iossim/lib/freetype.a
lib-iossim += libs/iossim/lib/SDL2.a
lib-iossim += libs/iossim/lib/SDL2main.a
lib-iossim += -lm -liconv -lobjc
lib-iossim += -framework Foundation
lib-iossim += -framework UIKit
lib-iossim += -framework OpenGLES
lib-iossim += -framework QuartzCore
lib-iossim += -framework CoreAudio
lib-iossim += -framework AudioToolbox
lib-iossim += -framework CoreGraphics
#-----------------------------#
#------------ ios ------------#
#-----------------------------#
inc-ios += -Ilibs/ios/include -Ilibs/ios/include/freetype2
flg-ios += -D_THREAD_SAFE
lib-ios += libs/ios/lib/freetype.a
lib-ios += libs/ios/lib/SDL2.a
lib-ios += libs/ios/lib/SDL2main.a
lib-ios += -lm -liconv -lobjc
lib-ios += -framework Foundation
lib-ios += -framework UIKit
lib-ios += -framework OpenGLES
lib-ios += -framework QuartzCore
lib-ios += -framework CoreAudio
lib-ios += -framework AudioToolbox
lib-ios += -framework CoreGraphics
include build.makefile
#-----------------------------#
#----- extra build steps -----#
#-----------------------------#
res/spritesheet.png: $(wildcard res/spritesheet/*.png)
cd res/spritesheet; \
ls -1 | texpack -o ../spritesheet -p1 -r --pretty
glsl := src/gfx/glsl/glsl.h
clean.extra += $(glsl)
src/gfx/gfx.cpp: src/gfx/glsl/glsl.h
define make-glsl
$1: $1.in $2
@echo Compiling $1...
@( \
cat $1.in | sed -e '/%GLSL%/,$$$$d'; \
for i in $2; do \
echo ; \
echo "const char *$$$$(basename $$$$i .glsl) = "; \
cat $$$$i | \
sed -e 's/\\/\\\\/g' | \
sed -e 's/"/\\"/g' | \
sed -e 's/^/\t"/g' | \
sed -e 's/$$$$/\\n"/g' | \
sed -e '$$$$s/$$$$/;/'; \
done; \
echo ; \
cat $1.in | sed -e '1,/%GLSL%/d'; \
) > $1
ifeq ($(platform),win32)
@sed -i 's/$$$$/\r/' $1
endif
endef
$(foreach f,$(glsl),$(eval $(call make-glsl,$f,$(wildcard $(dir $f)*.glsl))))
#-----------------------------#
#--- external dependencies ---#
#-----------------------------#
ifdef ios
ios.cflags := -g -O2 -pipe -no-cpp-precomp $(ios.flags)
ios.ldflags := $(ios.flags)
endif
# glew
ifndef ios
libs.glew.link := http://sourceforge.net/projects/glew/files/glew/1.9.0/glew-1.9.0.tgz/download
libs.glew.file := glew-1.9.0.tgz
libs.glew.dir := glew-1.9.0
libs.glew.src := lib/libGLEW.a include/*
libs.glew.dst := lib/GLEW.a include/
libs.glew.build := $(MAKE) -j
endif
ifeq ($(platform),win32)
libs.glew.src := lib/libglew32.a include/*
endif
# freetype
libs.freetype.link := http://sourceforge.net/projects/freetype/files/freetype2/2.5.3/freetype-2.5.3.tar.gz/download
libs.freetype.file := freetype-2.5.3.tar.gz
libs.freetype.dir := freetype-2.5.3
libs.freetype.src := .dist/lib/libfreetype.a .dist/include/*
libs.freetype.dst := lib/freetype.a include/
libs.freetype.build := ./configure --prefix=`pwd`/.dist --with-zlib=no --with-bzip2=no --with-png=no; \
$(MAKE) -j; \
$(MAKE) install;
ifdef ios
libs.freetype.build := ./configure --prefix=`pwd`/.dist --with-zlib=no --with-bzip2=no --with-png=no \
--disable-shared --enable-static --host=$(ios.arch)-apple-darwin \
CFLAGS="$(ios.cflags)" CPPFLAGS="$(ios.cflags)" LDFLAGS="$(ios.ldflags)"; \
$(MAKE) -j; \
$(MAKE) install
endif
# sdl2
ifeq ($(platform),win32)
libs.sdl2.link := http://www.libsdl.org/release/SDL2-devel-2.0.3-mingw.tar.gz
libs.sdl2.file := SDL2-2.0.3.tar.gz
libs.sdl2.dir := SDL2-2.0.3
libs.sdl2.src := i686-w64-mingw32/lib/libSDL2.a i686-w64-mingw32/lib/libSDL2main.a i686-w64-mingw32/include/SDL2
libs.sdl2.dst := lib/SDL2.a lib/SDL2main.a include/
libs.sdl2.build := cd i686-w64-mingw32/include/SDL2; mv SDL_platform.h SDL_platform.h.tmp; \
sed SDL_platform.h.tmp -e "121,132s|^|//|g" > SDL_platform.h; rm -f SDL_platform.h.tmp;
else
libs.sdl2.link := https://www.libsdl.org/release/SDL2-2.0.3.tar.gz
libs.sdl2.file := SDL2-2.0.3.tar.gz
libs.sdl2.dir := SDL2-2.0.3
libs.sdl2.src := .dist/lib/libSDL2.a .dist/lib/libSDL2main.a .dist/include/SDL2
libs.sdl2.dst := lib/SDL2.a lib/SDL2main.a include/
libs.sdl2.build := ./configure --prefix=`pwd`/.dist --disable-shared --enable-static; $(MAKE) -j; $(MAKE) install
endif
ifdef ios
libs.sdl2.build := ./configure --prefix=`pwd`/.dist --disable-shared --enable-static --host=armv7-apple-darwin \
CFLAGS="$(ios.cflags)" CPPFLAGS="$(ios.cflags)" CXXFLAGS="$(ios.cflags)" LDFLAGS="$(ios.ldflags)"; \
cp include/SDL_config_iphoneos.h include/SDL_config.h; \
sed -i "" -e "s|^EXTRA_CFLAGS.*|EXTRA_CFLAGS=-I./include|g" Makefile; \
sed -i "" -e "s|^EXTRA_LDFLAGS.*|EXTRA_LDFLAGS=-lm|g" Makefile; \
$(MAKE) -j; \
$(MAKE) install;
endif
# glm
libs.glm.link := http://sourceforge.net/projects/ogl-math/files/glm-0.9.5.4/glm-0.9.5.4.zip/download
libs.glm.file := glm-0.9.5.4.zip
libs.glm.dir := glm
libs.glm.src := glm
libs.glm.dst := include/
# rapidjson
libs.rapidjson.link := https://github.com/miloyip/rapidjson/archive/master.zip
libs.rapidjson.file := rapidjson-master.zip
libs.rapidjson.dir := rapidjson-master
libs.rapidjson.src := include/rapidjson
libs.rapidjson.dst := include/
include libs.makefile
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment