diff options
author | Michael Schwarz <michi.schwarz@gmail.com> | 2014-12-12 11:44:29 +0100 |
---|---|---|
committer | Michael Schwarz <michi.schwarz@gmail.com> | 2014-12-12 11:44:29 +0100 |
commit | f9fa53eef8e1183c4f7e3f9e0dd463ec1babdc86 (patch) | |
tree | f212ca5d7037e2eb28954fa9517191b53d6d080e | |
parent | 60b25ad13d0fdee926006bc728b031c4da1fb931 (diff) | |
download | pogojig-f9fa53eef8e1183c4f7e3f9e0dd463ec1babdc86.tar.gz pogojig-f9fa53eef8e1183c4f7e3f9e0dd463ec1babdc86.tar.bz2 pogojig-f9fa53eef8e1183c4f7e3f9e0dd463ec1babdc86.zip |
Added support for recording dependencies while compiling OpenSCAD files.
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | Makefile | 30 | ||||
-rw-r--r-- | support/lib/util.py | 20 | ||||
-rw-r--r-- | support/openscad/__init__.py | 0 | ||||
-rw-r--r-- | support/openscad/__main__.py | 37 |
5 files changed, 72 insertions, 16 deletions
@@ -2,6 +2,7 @@ *.pyc *.dxf *.stl +*.d # Generated files /src/generated/ @@ -2,8 +2,10 @@ INKSCAPE ?= inkscape OPENSCAD ?= openscad PYTHON ?= python2 +PYTHON_CMD := PYTHONPATH="support:$$PYTHONPATH" $(PYTHON) + # Used by dxf_export/main.sh -export INKSCAPE +export INKSCAPE OPENSCAD # Run generate_scad.sh to get the names of all OpenSCAD files that should be generated using that same script. GENERATED_FILES := $(addsuffix .scad,$(basename $(shell ./generate_sources.sh))) @@ -14,34 +16,32 @@ GENERATED_SCAD_FILES := $(filter %.scad, $(GENERATED_FILES)) SVG_FILES := $(shell find src -name '*.svg') $(GENERATED_SVG_FILES) # Only OpenSCAD files whose names do not start with `_' are compiled to STL. -SCAD_FILES := $(shell find src -name '*.scad') $(GENERATED_SCAD_FILES) -LIBRARY_SCAD_FILES := $(foreach i,$(SCAD_FILES),$(if $(filter _%,$(notdir $(i))),$(i))) -COMPILED_SCAD_FILES := $(filter-out $(LIBRARY_SCAD_FILES),$(SCAD_FILES)) +COMPILED_SCAD_FILES := $(foreach i,$(shell find src -name '*.scad') $(GENERATED_SCAD_FILES),$(if $(filter-out _%,$(notdir $(i))),$(i))) + +# Makefiles which are generated while compiling to record dependencies. +DEPENDENCY_FILES := $(patsubst %.scad,%.d,$(COMPILED_SCAD_FILES)) # All files that may be generated from the source files. STL_FILES := $(patsubst %.scad,%.stl,$(COMPILED_SCAD_FILES)) DXF_FILES := $(patsubst %.svg,%.dxf,$(SVG_FILES)) # Everything. Also generates files which aren't compiled to anything else. -all: $(STL_FILES) $(GENERATED_FILES) +all: $(GENERATED_FILES) $(DXF_FILES) $(STL_FILES) # Everything^-1. clean: - rm -rf $(DXF_FILES) $(STL_FILES) $(GENERATED_FILES) - -# Needs to be included after target all has been defined. --include config.mk + rm -rf $(GENERATED_FILES) $(DXF_FILES) $(STL_FILES) $(DEPENDENCY_FILES) -# Assume that any compiled OpenSCAD file may depend on any non-compiled OpenSCAD file in the same directory. -$(foreach i,$(COMPILED_SCAD_FILES),$(eval $(i): $(filter $(dir $(i))%,$(LIBRARY_SCAD_FILES) $(DXF_FILES)))) +# Include the local configuration file and the dependency files. Needs to be included after the `all' target has been defined. +-include config.mk $(DEPENDENCY_FILES) # Rule to convert an SVG file to a DXF file. %.dxf: %.svg - PYTHONPATH="support:$$PYTHONPATH" $(PYTHON) -m dxf_export $< $@ + $(PYTHON_CMD) -m dxf_export $< $@ -# Rule to compile an OpenSCAD file to an STL file. -%.stl: %.scad - $(OPENSCAD) -o $@ $< +# Rule to compile an OpenSCAD file to an STL file. We require all DXF files to exist before an OpenSCAD file can be used to generate an STL file. Additional dependencies are read from the included makefiles generated during compiling. +%.stl: %.scad | $(DXF_FILES) + $(PYTHON_CMD) -m openscad $< $@ $*.d # Rule for automaticlaly generated OpenSCAD files. $(GENERATED_FILES): generate_sources.sh diff --git a/support/lib/util.py b/support/lib/util.py index a3bc3dc..bede240 100644 --- a/support/lib/util.py +++ b/support/lib/util.py @@ -1,4 +1,4 @@ -import contextlib, subprocess, tempfile, shutil +import contextlib, subprocess, tempfile, shutil, re, os @contextlib.contextmanager @@ -16,3 +16,21 @@ def command(args): process.wait() assert not process.returncode + + +def bash_escape_string(string): + return "'{}'".format(re.sub("'", "'\"'\"'", string)) + + +def write_file(path, data): + temp_path = path + '~' + + with open(temp_path, 'wb') as file: + file.write(data) + + os.rename(temp_path, path) + + +def read_file(path): + with open(path, 'rb') as file: + return file.read() diff --git a/support/openscad/__init__.py b/support/openscad/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/support/openscad/__init__.py diff --git a/support/openscad/__main__.py b/support/openscad/__main__.py new file mode 100644 index 0000000..08b2ab6 --- /dev/null +++ b/support/openscad/__main__.py @@ -0,0 +1,37 @@ +import os, sys +from lib import util + + +def _openscad(in_path, out_path, deps_path): + util.command([os.environ['OPENSCAD'], '-o', out_path, '-d', deps_path, in_path]) + + +def _write_dependencies(path, target, dependencies): + util.write_file(path, '{}: {}\n'.format(target, ' '.join(dependencies)).encode()) + + +def main(in_path, out_path, deps_path): + cwd = os.getcwd() + + def relpath(path): + return os.path.relpath(path, cwd) + + with util.TemporaryDirectory() as temp_dir: + temp_deps_path = os.path.join(temp_dir, 'deps') + temp_mk_path = os.path.join(temp_dir, 'mk') + temp_files_path = os.path.join(temp_dir, 'files') + + _openscad(in_path, out_path, temp_deps_path) + + mk_content = '%:; echo "$@" >> {}'.format(util.bash_escape_string(temp_files_path)) + + util.write_file(temp_mk_path, mk_content.encode()) + util.command(['make', '-s', '-B', '-f', temp_mk_path, '-f', temp_deps_path]) + + deps = set(map(relpath, util.read_file(temp_files_path).decode().splitlines())) + ignored_files = set(map(relpath, [temp_deps_path, temp_mk_path, in_path, out_path])) + + _write_dependencies(deps_path, relpath(out_path), deps - ignored_files) + + +main(*sys.argv[1:]) |