| 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 $@
 |