1 # Build OVM App Bundles (Python code with a statically-linked CPython
2 # interpreter.)
3 #
4 # We also build a tarball that allows the end user to build an app bundle.
5 # They need GNU Make, bash, and a C compiler. (And xargs, chmod, etc.)
6 #
7 # Tarball layout (see build/compile.sh for details):
8 #
9 # oil.tar/
10 # configure
11 # install
12 # Makefile
13 # _build/ # Intermediate files
14 # oil/ # The app name
15 # bytecode-opy.zip # Arch-independent
16 # main_name.c
17 # module_init.c # Python module initializer
18 # c-module-srcs.txt # List of Modules/ etc.
19 # native/ # App-specific modules
20 # libc.c
21 # build/
22 # static-c-modules.txt # From Python interpreter
23 # compile.sh ...
24 # detect-cc.c ...
25 # Python-2.7.13/
26 # pyconfig.h # A frozen version
27 # Python/
28 # Objects/
29 # Modules/
30 # Include/
31 #
32 #
33 # Intermediate layout:
34 #
35 # _build/
36 # cpython-full/ # Full CPython build, for dynamically
37 # # discovering Python/C dependencies
38 # c-module-toc.txt # What files each module is in
39 # oil/ # App-specific dir
40 # py-to-compile.txt
41 # all-deps-py.txt # input to compiler: _build/py-to-compile +
42 # _build/oil/py-to-compile
43 # opy-app-deps.txt # compiled with OPy, name DOESN'T match app-deps-% !
44 # all-deps-c.txt # App deps plus CPython platform deps
45 # app-deps-cpython.txt # compiled with CPython
46 # bytecode-cpython.zip
47 # bytecode-opy.zip
48 # c-module-srcs.txt
49 # main_name.c
50 # module_init.c
51 # ovm.d # Make fragment
52 # ovm, ovm-dbg # OVM executables (without bytecode)
53 # _release/
54 # oil.tar # See tarball layout above
55 # _bin/ # Concatenated App Bundles
56 # oil.ovm
57 # oil.ovm-dbg
58 # hello.ovm
59 # hello.ovm-dbg
60
61 # Needed for rules with '> $@'. Does this always work?
62 .DELETE_ON_ERROR:
63
64 # Intermediate targets aren't automatically deleted.
65 .SECONDARY:
66
67 # Don't use the built-in rules database. This makes the 'make -d' output
68 # easier to read.
69 .SUFFIXES:
70
71 # Make all directories before every build.
72 $(shell mkdir -p _bin _release _tmp _build/hello _build/oil _build/opy)
73
74 STAMP_SH := build/stamp.sh
75 ACTIONS_SH := build/ovm-actions.sh
76 COMPILE_SH := build/ovm-compile.sh
77 CLEAN_SH := build/clean.sh
78
79 # Change the bytecode compiler here.
80 #BYTECODE_ZIP := bytecode-cpython.zip
81 BYTECODE_ZIP := bytecode-opy.zip
82
83 # We want to generated the unstripped binary first, then strip it, so we can
84 # retain symbols. There doesn't seem to be a portable way to do this?
85 #
86 # The GNU toolchain has objcopy, and Clang has dsymutil.
87
88 HAVE_OBJCOPY := $(shell command -v objcopy 2>/dev/null)
89
90 # For faster testing of builds
91 #default: _bin/oil.ovm-dbg
92
93 # What the end user should build when they type 'make'.
94 default: _bin/oil.ovm
95
96 # Debug bundles and release tarballs.
97 all: \
98 _bin/hello.ovm _bin/oil.ovm \
99 _bin/hello.ovm-dbg _bin/oil.ovm-dbg \
100 _release/hello.tar _release/oil.tar
101
102 # Take care not to remove _build/oil/bytecode-opy.zip, etc.
103 clean:
104 $(CLEAN_SH) source-tarball-build
105
106 clean-repo:
107 $(CLEAN_SH) cpp
108
109 # .PHONY alias for compatibility
110 install:
111 @./install
112
113 uninstall:
114 @./uninstall
115
116 .PHONY: default all clean clean-repo install uninstall
117
118 # For debugging
119 print-%:
120 @echo $*=$($*)
121
122 # These files is intentionally NOT included in release tarballs. For example,
123 # we don't want try to rebuild _build/oil/bytecode-opy.zip, which is already
124 # included in the release tarball. Portable rules can be run on the developer
125 # machine rather than on the end-user machine.
126
127 -include build/portable-rules.mk # Must come first
128 -include build/hello.mk
129 -include build/oil.mk
130
131 #
132 # Native Builds
133 #
134
135 # Release build.
136 # This depends on the static modules
137 _build/%/ovm-opt: _build/%/module_init.c _build/%/main_name.c \
138 _build/%/c-module-srcs.txt $(COMPILE_SH)
139 $(COMPILE_SH) build-opt $@ $(filter-out $(COMPILE_SH),$^)
140
141
142 ifdef HAVE_OBJCOPY
143
144 # If possible, we want symbols for OPTIMIZED builds, for various profiling
145 # tools.
146
147 # First copy the symbols out of the binary we built.
148 # (Distro packagers might use this to create symbols packages?)
149 _build/%/ovm-opt.symbols: _build/%/ovm-opt
150 objcopy --only-keep-debug $^ $@
151
152 # Then create a stripped binary that LINKS to the symbols.
153
154 _build/%/ovm-opt.stripped: _build/%/ovm-opt _build/%/ovm-opt.symbols
155 strip -o $@ _build/$*/ovm-opt # What's the difference with debug symbols?
156 # We need a relative path since it will be _bin/oil.ovm
157 objcopy --add-gnu-debuglink=_build/$*/ovm-opt.symbols $@
158
159 else
160
161 # We don't have objcopy, which means we might be using the Clang toolchain
162 # (e.g. on OS X). We're not doing any profiling on OS X, and there's no way to
163 # link the symbols, so just strip it.
164 #
165 # We used to have 'dsymutil' but it was never tested.
166 # https://stackoverflow.com/a/33307778
167
168 _build/%/ovm-opt.stripped: _build/%/ovm-opt
169 strip -o $@ _build/$*/ovm-opt
170
171 endif
172
173 # Fast build, with symbols for debugging.
174 _build/%/ovm-dbg: _build/%/module_init.c _build/%/main_name.c \
175 _build/%/c-module-srcs.txt $(COMPILE_SH)
176 $(COMPILE_SH) build-dbg $@ $(filter-out $(COMPILE_SH),$^)
177
178 # Coverage, for paring down the files that we build.
179 # TODO: Hook this up.
180 _build/%/ovm-cov: _build/%/module_init.c _build/%/main_name.c \
181 _build/%/c-module-srcs.txt $(COMPILE_SH)
182 $(COMPILE_SH) build $@ $(filter-out $(COMPILE_SH),$^)
183
184 # App bundles.
185 _bin/%.ovm-dbg: _build/%/ovm-dbg _build/%/$(BYTECODE_ZIP)
186 cat $^ > $@
187 chmod +x $@
188
189 _bin/%.ovm: _build/%/ovm-opt.stripped _build/%/$(BYTECODE_ZIP)
190 cat $^ > $@
191 chmod +x $@
192
193 # Optimized version with symbols.
194 _bin/%.ovm-opt: _build/%/ovm-opt _build/%/$(BYTECODE_ZIP)
195 cat $^ > $@
196 chmod +x $@