File: vmakefile

package info (click to toggle)
golf 601.4.41-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,824 kB
  • sloc: ansic: 20,020; sh: 1,171; makefile: 292
file content (178 lines) | stat: -rwxr-xr-x 10,408 bytes parent folder | download
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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
#SPDX-License-Identifier: Apache-2.0
#Copyright 2018-2025 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_IGNORE_WARN)),1)
    GG_IGNORE_WARN=-ignore-warn
else
    GG_IGNORE_WARN=
endif

ifeq ($(strip $(GG_C_DEBUG)),1)
    _OPTIM_COMP=-g3 -DDEBUG -rdynamic 
    _OPTIM_LINK=-rdynamic
    CFLAGS_WARN_ERROR=-Werror 
else
    _OPTIM_COMP=-g3 -O3
    _OPTIM_LINK=
    CFLAGS_WARN_ERROR=
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 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
#GG_C_CFLAGS *must* be the last in order to override anything else by user action!
_CFLAGS=-fpic -fmax-errors=$(GG_C_MAXERRORS) $(GG_DIAG_OUT) $(CFLAGS_WARN_ERROR) -Wall -Wno-error=char-subscripts -Wuninitialized -Wmissing-declarations -Wformat -Werror=format-security -Wno-format-zero-length -funsigned-char -fno-semantic-interposition  $(GG_MARIADB_USED) $(GG_CURL_USED) $(GG_TREE_USED) $(GG_ARRAY_USED) $(GG_XML_USED) $(GG_PCRE2_USED) $(GG_SERVICE_USED) $(GG_CRYPTO_USED) $(GG_XML_USED) $(GG_MODULES_INCLUDE) $(GG_SERVICE_INCLUDE) $(GG_POSIXREGEX_FLAG) -DGG_ROOT="\"$(GG_ROOT)\"" -I $(CURDIR) -I $(GG_INCLUDE_PATH) -I $(GG_BLD) $(_APPMAKE) $(_OPTIM_COMP) -Wdate-time -fno-stack-protector -fno-stack-clash-protection $(_ASAN) $(GG_C_CFLAGS)




#
# 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)

#strip symbols but keep _dbg for when needed (gdb->core or addr2line)
#we have || true (i.e. surpress error in bash, but not error message)
#so as not to stop the build process, as this isn't critical. It really
#happens only if you build against live running server, something that's 
#usually only done in testing, and stripping symbols is not a priority.
define strip_sym
	if [ "$(GG_C_DEBUG)" != "1" ]; then objcopy --only-keep-debug $@ $@_dbg || true ; objcopy --strip-unneeded $@ || true ; objcopy --add-gnu-debuglink=$@_dbg $@ || true ; fi
endef

#when making source, start with compiling; then if error, check if plain diagnostic (meaning no coloring and using C generated code); 
#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 (export GG_ROOT for vdiag)
define make_source
	TFILE="$@"; SFILE="$<"; rm -f $(GG_BLD)/.setparam/$${SFILE##*/}.sp; ECODE=0; $(GG_LIBRARY_PATH)/v1 $(GG_X_FLAG) $(GG_PUBLIC_FLAG) $(GG_IGNORE_WARN) $(GG_SINGLE_FILE) -plain-diag "1" -max-errors $(GG_C_MAXERRORS) -name "$(GG_C_NAME)" $< -out   $(GG_BLD)/__$${TFILE##*/}.c || ECODE=$$? ; if [ "$$ECODE" != "0" ]; then exit 1; fi ;           >$(GG_BLD)/gg_sparam_$${SFILE##*/}.h; if [ -f "$(GG_BLD)/.setparam/$${SFILE##*/}.sp" ]; then for i in $$(cat $(GG_BLD)/.setparam/$${SFILE##*/}.sp|sort -k 1|uniq); do echo "extern gg_num _gg_aprm_$$i;">>$(GG_BLD)/gg_sparam_$${SFILE##*/}.h; done; echo "extern void **_gg_sprm_run; extern gg_num _gg_sprm_run_tot;">>$(GG_BLD)/gg_sparam_$${SFILE##*/}.h ; fi ;         GG_DIAG_OUT="" ; ECODE=0 ; rm -f $(GG_BLD)/.comperr.$${TFILE##*/} ; $(_CC) -c $(GG_BLD)/__$${TFILE##*/}.c  $(_CFLAGS) -o $@ -I`pwd` 2>$(GG_BLD)/.comperr.$${TFILE##*/} 1>&2 || ECODE="$$?" ; if [ "$$ECODE" != "0" ]; then if [ "$$GG_C_PLAINDIAG" == "1" ]; then cat $(GG_BLD)/.comperr.$${TFILE##*/}; exit -1; else GG_DIAG_OUT="-fno-diagnostics-show-caret"; $(GG_LIBRARY_PATH)/v1 $(GG_X_FLAG) $(GG_PUBLIC_FLAG) $(GG_IGNORE_WARN) $(GG_SINGLE_FILE) -plain-diag "$(GG_C_PLAINDIAG)" -max-errors $(GG_C_MAXERRORS) -name "$(GG_C_NAME)" $< -out   $(GG_BLD)/__$${TFILE##*/}.c; ECODE=0 ; $(_CC) -c $(GG_BLD)/__$${TFILE##*/}.c  $(_CFLAGS) -o $@ -I`pwd` 2>$(GG_BLD)/.comperr.$${TFILE##*/} 1>&2 || ECODE="$$?" ; export GG_ROOT ; $(GG_LIBRARY_PATH)/vdiag "$(GG_C_NAME)" $(GG_C_PLAINDIAG) < $(GG_BLD)/.comperr.$${TFILE##*/} ; 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)/.flatsrc/gg_dispatch_request.c $(GG_INCLUDE_PATH)/golf.h $(GG_HEADER_FILES) $(GG_BLD)/golfapp.h $(GG_BLD)/blds $(_OBJ_FILES)
	$(_CC) -c $(GG_BLD)/.flatsrc/gg_dispatch_request.c  $(_CFLAGS) -o $@ -I`pwd` 

$(GG_BLD)/%.o: $(GG_BLD)/.flatsrc/%.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
	TFILE="$@"; GG_BN=$${TFILE##*/} ; $(_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=$$(find $(GG_BLD)/.setparam -type f -name "*" -print0 |xargs -0 cat 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_aprm_$$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_PUBLIC_FLAG) $(GG_IGNORE_WARN) $(GG_SINGLE_FILE) -plain-diag "$(GG_C_PLAINDIAG)" -max-errors $(GG_C_MAXERRORS) -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` 

#GG_C_LFLAGS *must* be the last in order to override anything else by user action!
_LFLAGS=-Wl,--no-undefined -Wl,--rpath=$(GG_LIBRARY_PATH) -Wl,--enable-new-dtags -L$(GG_LIBRARY_PATH) $(_OPTIM_LINK) -Wl,-z,relro  $(_ASAN) $(GG_C_LFLAGS)



#libs are always specified *after* the object where they're needed. Link flags (including -L) go first.
#$@ is a file generated to hold all input files, and passed to gcc as "in file" via @. Since $@ is already in GG_BLD, can't prefix with $GG_BLD
#as it would be inaccurate (double path). gcc requires file with each item on a single line, hence foreach. This avoids 2-4000 files limit for
#a Golf application, and makes it effectively unlimited.
$(GG_BLD)/$(GG_C_NAME).srvc: $(GG_BLD)/golfsrvcapp.o $(GG_BLD)/gg_dispatch_request.o $(_OBJ_FILES) 
	$(file >$@.inarg) $(foreach F,$^,$(file >>$@.inarg,$F))
	$(_CC) -o $@ @$@.inarg $(_LFLAGS) $(GG_EVENT_STUBS) -lsrvcgolf -lfcgi $(GG_MOD_LIBS) $(GG_MODULES) $(GG_STUBS) 
	$(call strip_sym)
	rm -f $@.inarg

$(GG_BLD)/$(GG_C_NAME): $(GG_BLD)/golfsrvcapp.o $(GG_BLD)/gg_dispatch_request.o $(_OBJ_FILES) 
	$(file >$@.inarg) $(foreach F,$^,$(file >>$@.inarg,$F))
	$(_CC) -o $@ @$@.inarg $(_LFLAGS) $(GG_EVENT_STUBS) -lgolf $(GG_MOD_LIBS) $(GG_MODULES) $(GG_STUBS) 
	$(call strip_sym)
	rm -f $@.inarg