Skip to content

Instantly share code, notes, and snippets.

@cwchentw
Last active April 1, 2023 13:04
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save cwchentw/142652238fbce1fb91e82464be62a0ef to your computer and use it in GitHub Desktop.
Save cwchentw/142652238fbce1fb91e82464be62a0ef to your computer and use it in GitHub Desktop.
Cross-Platform Makefile for Application (Apache 2.0)
# Detect underlying system.
ifeq ($(OS),Windows_NT)
detected_OS := Windows
else
detected_OS := $(shell sh -c 'uname -s 2>/dev/null || echo not')
endif
export detected_OS
# Set default C compiler.
# Clean implict CC variable.
CC=
ifndef CC
ifeq ($(detected_OS),Windows)
CC=cl
else ifeq ($(detected_OS),Darwin)
CC=clang
else
CC=gcc
endif
endif # CC
export CC
# Clean C_STD variable.
C_STD=
ifndef C_STD
ifeq ($(CC),cl)
C_STD=
else
C_STD=c11
endif
endif # C_STD
export C_STD
# Set CFLAGS for Release target.
CFLAGS=
ifndef CFLAGS
ifeq ($(CC),cl)
CFLAGS=/W4 /sdl
else
CFLAGS:=-Wall -Wextra -std=$(C_STD)
endif
endif
# Set CFLAGS for Debug target.
ifneq (,$(DEBUG))
ifeq ($(CC),cl)
CFLAGS+=/DDEBUG /Zi /Od
else
CFLAGS+=-DDEBUG -g -O0
endif
else
ifeq ($(CC),cl)
CFLAGS+=/O2
else
CFLAGS+=-O2
endif
endif
export CFLAGS
# Set proper RM on Windows.
ifeq ($(detected_OS),Windows)
RM=del /q /f
endif
export RM
# Set proper path separator.
ifeq ($(detected_OS),Windows)
SEP=\\
else
SEP=/
endif
export SEP
# Set proper program name.
ifeq ($(detected_OS),Windows)
PROGRAM=myapp.exe
else
PROGRAM=myapp
endif
export PROGRAM
# Add your own test programs as needed.
ifeq ($(detected_OS),Windows)
TEST_PROGRAM=myapp.vbs
else
TEST_PROGRAM=myapp.bash
endif
# Modify it if more than one source files.
SOURCE=$(PROGRAM:.exe=).c
# Set object files.
ifeq ($(CC),cl)
OBJS=$(SOURCE:.c=.obj)
else
OBJS=$(SOURCE:.c=.o)
endif # OBJS
export OBJS
# Set third-party include and library path
# Modify it as needed.
ifeq ($(CC),cl)
LDFLAGS=
LDLIBS=
else
LDFLAGS=
LDLIBS=
endif
export LDFLAGS
export LDLIBS
.PHONY: all clean
all: run
test: $(PROGRAM)
ifeq ($(detected_OS),Windows)
for %%x in ($(TEST_PROGRAM)) do cscript %%x
else
for t in $(TEST_PROGRAM); do bats $$t; done
endif
run: $(PROGRAM)
.$(SEP)$(PROGRAM)
echo $$?
$(PROGRAM): $(OBJS)
ifeq ($(CC),cl)
$(CC) /Fe:$(PROGRAM) $(OBJS) $(CFLAGS) $(LDFLAGS) $(LDLIBS)
else
$(CC) -o $(PROGRAM) $(OBJS) $(CFLAGS) $(LDFLAGS) $(LDLIBS)
endif
%.obj: %.c
$(CC) /c $< $(CFLAGS)
%.o: %.c
$(CC) -c $< $(CFLAGS)
clean:
$(RM) $(PROGRAM) $(OBJS)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment