-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathvmakefile
executable file
·159 lines (117 loc) · 8.41 KB
/
vmakefile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#SPDX-License-Identifier: Apache-2.0
#Copyright 2019 Gliim LLC.
#Licensed under Apache License v2. See LICENSE file.
#On the web http://golf-lang.com/ - this file is part of Golf framework.
#variable names for Golf start with GG_ (GG_C_ being compiling-related) and _ (internal)
#
# Golf make file
#
#
# Setting of build variables
#
SHELL:=/bin/bash
export GG_EXPLAIN
_SYSTEMID=$(shell $$GG_LIBRARY_PATH/sys showid)
# c/linker flags
_CC=gcc
#ASAN (internal)
ifeq ($(strip $(GG_C_ASAN)),1)
_ASAN=-fsanitize=address -fsanitize-recover=address
else
_ASAN=
endif
ifeq ($(strip $(GG_C_DEBUG)),1)
_OPTIM_COMP=-g3 -DDEBUG -rdynamic
_OPTIM_LINK=-rdynamic
else
_OPTIM_COMP=-O3
_OPTIM_LINK=
endif
_APPMAKE=-DGG_APPMAKE=1
GG_SERVICE_TARGET=$(GG_BLD)/$(GG_C_NAME).srvc
GG_TARGET=$(GG_BLD)/$(GG_C_NAME)
ifeq ($(strip $(_SYSTEMID)),opensuse)
GG_SERVICE_INCLUDE=-I /usr/include/fastcgi
else
GG_SERVICE_INCLUDE=
endif
#If --single-file is used, then each request handler must be in its own file and own directory as per request path
#Without it, then each .golf file can have any number of request handlers, but they must start with file name, so still organized
ifeq ($(strip $(GG_C_SINGLE_FILE)),1)
GG_SINGLE_FILE=-single-file
else
GG_SINGLE_FILE=
endif
#If --public is used, then all request handlers are publicly accessible unless private
#Without --public, they are all private unless public
ifeq ($(strip $(GG_C_PUBLIC)),1)
GG_PUBLIC_FLAG=-public
else
GG_PUBLIC_FLAG=
endif
#If opt-mem is used, then optimize memory (lower speed!)
ifeq ($(strip $(GG_C_OPTMEM)),1)
GG_OPTMEM_FLAG=-optmem
else
GG_OPTMEM_FLAG=
endif
#If c-lines is used, then show all diagnostics
GG_DIAG_OUT=
ifeq ($(strip $(GG_C_SKIPLINES)),1)
GG_X_FLAG=-x
else
GG_X_FLAG=
endif
ifeq ($(strip $(GG_C_POSIXREGEX)),1)
GG_POSIXREGEX_FLAG=-DGG_C_POSIXREGEX
else
GG_POSIXREGEX_FLAG=
endif
#even though GG_DIAG_OUT is set to "", at run time it will have value from make_source macro. This is because of how makefile assignments work with = (and not :=)
#ignoring char-subscripts (such as str[str[0]] is fine because golf checks for boundaries
_CFLAGS=-fpic -std=gnu99 -fmax-errors=$(GG_C_MAXERRORS) $(GG_DIAG_OUT) -Werror -Wall -Wno-error=char-subscripts -Wuninitialized -Wmissing-declarations -Wformat -Wno-format-zero-length -funsigned-char $(GG_MARIADB_USED) $(GG_CURL_USED) $(GG_TREE_USED) $(GG_PCRE2_USED) $(GG_SERVICE_USED) $(GG_CRYPTO_USED) $(GG_MODULES_INCLUDE) $(GG_SERVICE_INCLUDE) -DGG_OSNAME_ID=$(GG_OSNAME_ID) $(GG_POSIXREGEX_FLAG) -I $(shell pwd) -I $(GG_INCLUDE_PATH) $(GG_C_CFLAGS) -I $(GG_BLD) $(_APPMAKE) $(_OPTIM_COMP) $(_ASAN)
#
# Rules for building
#
all: $(GG_SERVICE_TARGET) $(GG_TARGET)
#clean files. *.golfo is produced by GOLF, the result is generated/object files
clean:
if [ -d "$(GG_BLD)" ]; then find $(GG_BLD)/ -name "*" -type f \( -name "*.o" -or -name "*.c" -or -name "*.h" \) -exec rm -f {} \; ; fi
#include $(GG_BLD)/source.golf
#obtain GG_SOURCE_FILES, GG_SOURCE_C_FILES and GG_HEADER_FILES from generated source.golf
ifneq (clean,$(filter clean,$(MAKECMDGOALS)))
include $(GG_BLD)/source.golf
endif
GG_HEADER_FILES:=$(GG_HEADER_FILES)
#string subst: short for $(patsubst %.golf,%.o,$(GG_SOURCE_FILES)) which finds whitespace-separated word in $(GG_SOURCE_FILES) that match %.golf and replaces them with %.o
#the same for C files in GG_SOURCE_C_FILES
_OBJ_FILES=$(GG_SOURCE_FILES:%.golf=$(GG_BLD)/%.o) $(GG_SOURCE_C_FILES:%.c=$(GG_BLD)/%.oc)
#when making source, start with compiling; then if error, check if plain diagnostic; if not, recompile with error processed by vdiag script to produce highlights (in which
#case we don't use caret, we produce one ourselves instead of gcc)
#use ECODE (as exit code) to make sure non-zero exit code doesn't stop the build rule. Also use basename of the source file in .comperr... in order not to mix up output from different source files when makefile runs in parallel
define make_source
rm -f $(GG_BLD)/.setparam/$$(basename $<).sp; $(GG_LIBRARY_PATH)/v1 $(GG_X_FLAG) $(GG_OPTMEM_FLAG) $(GG_PUBLIC_FLAG) $(GG_SINGLE_FILE) -plain-diag "1" -name "$(GG_C_NAME)" $< -out $(GG_BLD)/__$$(basename $@).c
echo "">$(GG_BLD)/gg_sparam_$$(basename $<).h; if [ -f "$(GG_BLD)/.setparam/$$(basename $<).sp" ]; then for i in $$(cat $(GG_BLD)/.setparam/$$(basename $<).sp|sort -k 1|uniq); do echo "extern gg_num _gg_sprm_$$i;">>$(GG_BLD)/gg_sparam_$$(basename $<).h; done; echo "extern void **_gg_sprm_run; extern gg_num _gg_sprm_run_tot;">>$(GG_BLD)/gg_sparam_$$(basename $<).h ; fi
GG_DIAG_OUT="" ; ECODE=0 ; rm -f $(GG_BLD)/.comperr.$$(basename $@) ; $(_CC) -c $(GG_BLD)/__$$(basename $@).c $(_CFLAGS) -o $@ -I`pwd` 2>$(GG_BLD)/.comperr.$$(basename $@) 1>&2 || ECODE="$$?" ; if [ "$$ECODE" != "0" ]; then if [ "$$GG_C_PLAINDIAG" == "1" ]; then cat $(GG_BLD)/.comperr.$$(basename $@); exit -1; else GG_DIAG_OUT="-fno-diagnostics-show-caret"; $(GG_LIBRARY_PATH)/v1 $(GG_X_FLAG) $(GG_OPTMEM_FLAG) $(GG_PUBLIC_FLAG) $(GG_SINGLE_FILE) -plain-diag "$(GG_C_PLAINDIAG)" -name "$(GG_C_NAME)" $< -out $(GG_BLD)/__$$(basename $@).c; ECODE=0 ; $(_CC) -c $(GG_BLD)/__$$(basename $@).c $(_CFLAGS) -o $@ -I`pwd` 2>$(GG_BLD)/.comperr.$$(basename $@) 1>&2 || ECODE="$$?" ; $(GG_LIBRARY_PATH)/vdiag "$(GG_C_NAME)" $(GG_C_PLAINDIAG) < $(GG_BLD)/.comperr.$$(basename $@) ; fi ; fi
endef
#the rest if compilation of source files and producing object files and libraries needed for apache,
#do not change these
$(GG_BLD)/gg_dispatch_request.o: $(GG_BLD)/gg_dispatch_request.golf $(GG_INCLUDE_PATH)/golf.h $(GG_HEADER_FILES) $(GG_BLD)/golfapp.h $(GG_BLD)/blds $(_OBJ_FILES)
$(call make_source)
$(GG_BLD)/%.o: %.golf $(GG_INCLUDE_PATH)/golf.h $(GG_HEADER_FILES) $(GG_BLD)/golfapp.h $(GG_BLD)/blds
$(call make_source)
$(GG_BLD)/%.oc: %.c $(GG_INCLUDE_PATH)/golf.h $(GG_HEADER_FILES) $(GG_BLD)/golfapp.h $(GG_BLD)/blds
GG_BN=$$(basename $@) ; $(_CC) -c $${GG_BN%.*}.c $(_CFLAGS) -o $@ -I`pwd`
#does not need to depend on golfsrvcapp.c because it makes it. There's a dependency on params (blds) and list of files to be made (_OBJ_FILES)
#because now we have hash list there that accounts for all request name. If we didn't have this, adding new .golf file would not be picked up until
#the next next time something changes on the gg command line! /dev/null is used to suppress error message if there are no parameters in project.
$(GG_BLD)/golfsrvcapp.o: $(GG_BLD)/blds $(GG_BLD)/.reqlist $(_OBJ_FILES)
rm -f $(GG_BLD)/gg_sparam.h.new; GG_SPAR_LIST=$$(cat $(GG_BLD)/.setparam/* 2>/dev/null|sort -k 1|uniq); tot_sprm=0; for i in $$GG_SPAR_LIST; do ((tot_sprm=tot_sprm+1)); done; echo "$$tot_sprm" > $(GG_BLD)/.gg_sparam; for i in $$GG_SPAR_LIST; do echo "$$i" >> $(GG_BLD)/.gg_sparam; done; echo "gg_ipar _gg_sprm_par[$$tot_sprm] = {">>$(GG_BLD)/gg_sparam.h.new; j=0; for i in $$GG_SPAR_LIST; do if [ "$$j" != "0" ]; then echo ",">>$(GG_BLD)/gg_sparam.h.new; fi; echo "{.name=\"$$i\", .type=GG_DEFNONE}">>$(GG_BLD)/gg_sparam.h.new; ((j=j+1)); done; echo "};">>$(GG_BLD)/gg_sparam.h.new; j=0; for i in $$GG_SPAR_LIST; do echo "gg_num _gg_sprm_$$i=$$j;">>$(GG_BLD)/gg_sparam.h.new; ((j=j+1)); done; echo "void *_gg_sprm_run[$$j];">>$(GG_BLD)/gg_sparam.h.new; echo "gg_num _gg_sprm_run_tot=$$j;">>$(GG_BLD)/gg_sparam.h.new; _ISDIFF=$$(diff $(GG_BLD)/gg_sparam.h.new $(GG_BLD)/gg_sparam.h 2>/dev/null) || true ; if [[ "$$_ISDIFF" != "" || ! -f $(GG_BLD)/gg_sparam.h ]]; then mv $(GG_BLD)/gg_sparam.h.new $(GG_BLD)/gg_sparam.h ; else rm -rf $(GG_BLD)/gg_sparam.h.new; fi
$(GG_LIBRARY_PATH)/v1 $(GG_X_FLAG) $(GG_OPTMEM_FLAG) $(GG_PUBLIC_FLAG) $(GG_SINGLE_FILE) -plain-diag "$(GG_C_PLAINDIAG)" -main -name "$(GG_C_NAME)" -max-upload "$(GG_C_MAXUPLOAD)" -app-path "$(GG_C_RESTPATH)" -trace "$(GG_C_TRACE)" -out $(GG_BLD)/golfsrvcapp.c
$(_CC) -c $(GG_BLD)/golfsrvcapp.c $(_CFLAGS) -DCMOD -o $@ -I`pwd`
_LDFLAGS=-Wl,--no-undefined -Wl,--rpath=$(GG_LIBRARY_PATH) $(GG_C_LFLAGS) -L$(GG_LIBRARY_PATH) $(_OPTIM_LINK) $(_ASAN)
#libs are always specified *after* the object where they're needed. Link flags (including -L) go first.
$(GG_BLD)/$(GG_C_NAME).srvc: $(GG_BLD)/golfsrvcapp.o $(GG_BLD)/gg_dispatch_request.o $(_OBJ_FILES) $(GG_BLD)/gg_dispatch_request.o
$(_CC) -o $@ $^ $(_LDFLAGS) $(GG_EVENT_STUBS) -lsrvcgolf -lfcgi $(GG_MOD_LIBS) $(GG_MODULES) $(GG_STUBS)
$(GG_BLD)/$(GG_C_NAME): $(GG_BLD)/golfsrvcapp.o $(GG_BLD)/gg_dispatch_request.o $(_OBJ_FILES) $(GG_BLD)/gg_dispatch_request.o
$(_CC) -o $@ $^ $(_LDFLAGS) $(GG_EVENT_STUBS) -lgolf $(GG_MOD_LIBS) $(GG_MODULES) $(GG_STUBS)