makefile fixes, moved the linking subsystem to driver-rule-reckoning
[henge/webcc.git] / Makefile
1 ################################################################################
2 # Desc: Web Cross Compiler
3 # Author: Ken Grimes
4 # Date: 2016
5 ################################################################################
6 # This makefile manages a build environment targeting native platforms with gcc
7 # and web platforms with either emscripten or binaryen (js or wasm).
8 ################################################################################
9 # Each .c file is automatically compiled into an environment-dependent object
10 # file of compiler-specific format (.o for gcc, .bc for llvm/emcc/em++).
11 ################################################################################
12 # The default rule to be built if none specified
13 default: all
14 # webcc's root
15 ROOT_DIR := .
16 # source directory to find compilable language files in
17 SRC_DIR := $(ROOT_DIR)/src
18 # directory where files with 'main' functions live (can be in SRC_DIR)
19 DRIVER_DIR := $(SRC_DIR)/bin
20 # make configuration directory
21 CONF_DIR := $(ROOT_DIR)/make
22 # Source languages handled by this build system. These languages are capable of
23 # being compiled to an intermediary format for binary output by one of the
24 # provided compilersfor each language
25 LANGS := c cpp go
26 # Source-to-source languages handled by this build system
27 SLANGS := y rl
28 # Language-specific compilers and flags passed in from environment
29 c_C := $(strip $(notdir $(CC)))
30 c_FLAGS := $(strip $(CFLAGS)) -I$(SRC_DIR)
31 c_SRCL := y
32 cpp_C := $(strip $(notdir $(CXX)))
33 cpp_FLAGS := $(strip $(CXXFLAGS)) $(c_FLAGS)
34 go_C := gccgo
35 go_FLAGS := $(c_FLAGS)
36 # Source to source languages
37 # Bison
38 y_C := bison
39 y_FLAGS := -d
40 y_STEM := tab
41 y_TRG := c h
42 # Ragel
43 rl_C := ragel
44 rl_FLAGS := -C
45 rl_TRG := c
46 # Compiler-specific associations. Each compiler has a binary object suffix
47 # (OBJ), an archiver (AR), and an archiver object suffix (AROBJ). Each compiler
48 # may optionally have defined a linker (LD), and a binary output suffix (OUT).
49 cc_OBJ := o
50 cc_LD := $(LD)
51 cc_AR := $(AR)
52 cc_AROBJ := a
53 cc_DBG := gdb
54 $(cpp_C)_LD := $(cc_LD)
55 gcc_OBJ := $(cc_OBJ)
56 gcc_LD := $(cc_LD)
57 ngcc_AR := $(cc_AR)
58 gcc_AROBJ := $(cc_AROBJ)
59 gcc_DBG := $(cc_DBG)
60 emcc_OBJ := bc
61 emcc_AR := emar
62 emcc_AROBJ := $(emcc_OBJ) #emar is just a python script that reparses shit for emcc
63 emcc_OUT := .js
64 g++_OBJ := $(cc_OBJ)
65 em++_OBJ := $(emcc_OBJ)
66 em++_AR := $(emcc_AR)
67 em++_AROBJ := $(emcc_AROBJ)
68 em++_OUT := $(emcc_OUT)
69 gccgo_OBJ := o
70 gccgo_LD := $(cc_LD)
71 gccgo_AR := $(cc_AR)
72 gccgo_AROBJ := $(cc_AROBJ)
73 # Shell functions to determine what libraries can be linked by the compiler
74 cc_LDLIBS := $(shell ldconfig -p | sed -e 's@\-*[0-9\.]*\.so.*$$@@g' -e 's@\tlib@@g' -e '/[\t ]/d')
75 gcc_LDLIBS := $(cc_LDLIBS)
76 emcc_LDLIBS :=
77 g++_LDLIBS := $(cc_LDLIBS)
78 em++_LDLIBS :=
79 go_LDLIBS := $(cc_LDLIBS)
80 # location to build cross-compilation libraries in, not intended to be installed
81 # in the host system
82 LIB_DIR := $(ROOT_DIR)/lib$(shell uname -m)/$($(c_C)_OBJ)
83 LIBDL_DIR := $(LIB_DIR)/.cache
84 LIBINC_DIR := $(ROOT_DIR)/include
85 # The makefile MUST be capable of generating these directories and all of their
86 # contents. These directories are removed during the 'scrub' rule
87 MAKE_DIRS := $(LIB_DIR) $(LIBDL_DIR)
88 # Set up lib inclusions, and scan for built libs
89 c_FLAGS += -I$(LIBINC_DIR)
90 c_OBJ := $($(c_C)_OBJ)
91 # Modules are any directories other than 'DRIVER_MODULE' in 'SRC_DIR' and
92 # produce a single archive in 'SRC_DIR' containing all of the module's symbols
93 MODULES := $(patsubst $(SRC_DIR)/%/,%,$(filter-out $(DRIVER_DIR)/%,$(shell ls -d $(SRC_DIR)/*/)))
94
95 # Include the make libraries
96 include make/lib/*.mk
97
98 # If available, invoke the premake system
99 ifdef PREMAKE_SOURCE_COMPILER
100 $(eval $(call PREMAKE_SOURCE_COMPILER,))
101 else
102 $(info Warning: No premake system found, source-to-source languages (e.g. bison) not functional)
103 endif
104
105 # Backup the CVS password and CVSROOT environment vars in case we change them
106 $(if $(wildcard ~/.cvspass),\
107 $(eval CVSPASS_BAK := $(file <~/.cvspass)))
108 $(if $(CVSROOT),\
109 $(eval CVSROOT_BAK := $(CVSROOT)))
110
111 # The recursive library dependecy traversal constructs a tree ordered by nested
112 # dependency depth. when linking, this order is reversed.
113 # Initialize each language and look for its files
114 ifdef LANG_INIT
115 $(foreach lang,$(LANGS),\
116 $(eval $(call LANG_INIT,$(lang)))\
117 )
118 else
119 $(error No LANG_INIT available, no languages can be compiled)
120 endif
121
122 # Create module object rules for each module
123 $(foreach module,$(MODULES),\
124 $(eval $(call MODULE_ARCRULE,$(module)))\
125 )
126 $(if $(c_DBG),$(eval MAKE_DIRS += .$(c_DBG)/))
127
128 # Create lang-specific rules for producing final (linked) targets
129 $(foreach lang,$(LANGS),\
130 $(foreach drvsrc,$($(lang)_DRV_SRC),\
131 $(eval $(call SRC_LANG_DRVRULE,$(drvsrc),$(lang)))\
132 ))
133
134 # Create driver rules for each driver we found, let users call make specifying
135 # the basename of the driver file, and just route to the correct e we
136 # made in the last paragraph
137 DRV_FNAMES := $(notdir $(DRV_SRC))
138 .PHONY: all $(basename $(DRV_NAMES))
139 $(foreach fname,$(DRV_FNAMES),\
140 $(eval $(basename $(fname)): \
141 $(filter %/$(basename $(fname))$($(lastword $(subst ., ,$(fname))_OUT)),$(DRV_TRG)))\
142 )
143 all: $(basename $(DRV_FNAMES))
144 @echo Build Complete
145
146 # Rule to make any dirs that we're in charge of
147 $(sort $(MAKE_DIRS)):
148 @mkdir -p $@
149
150 # Cleaning rules.
151 # Clean destroys all object files and internal module archives.
152 CLEAN_TARGETS := $(sort $(foreach mtarg,$(MAKE_TARGETS),$(if $(wildcard $(mtarg)),$(mtarg))))
153 clean: $(BUILTLIBS:%=clean_%)
154 $(if $(CLEAN_TARGETS),rm $(CLEAN_TARGETS))
155
156 # Scrub destroys all distributable binaries
157 SCRUB_TARGETS := $(sort $(foreach starg,$(SCRUB_TARGETS),$(if $(wildcard $(starg)),$(starg))))
158 scrub: clean
159 $(if $(SCRUB_TARGETS),rm $(SCRUB_TARGETS))
160
161 # Purge destroys all distributables created by a distributable binary
162 # (e.g. assets)
163
164 # Uninstall destroys all objects and directories that cannot be recreated by
165 # this make file
166 uninstall: scrub
167 rm -Rf $(MAKE_DIRS)