diff options
Diffstat (limited to 'Makefile')
| -rw-r--r-- | Makefile | 299 |
1 files changed, 299 insertions, 0 deletions
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..1975007 --- /dev/null +++ b/Makefile @@ -0,0 +1,299 @@ +# Use bash as the shell +SHELL = /bin/bash + +LOCAL_CONFIG_EXISTS = $(shell (test -e config.local.mk && echo 1) || echo 0) +ifeq "${LOCAL_CONFIG_EXISTS}" "1" + CONFIG_MK_FILE = config.local.mk + #CONFIG_MK_FILE = config.windows.mk +else + CONFIG_MK_FILE = config.mk +endif + +include $(CONFIG_MK_FILE) + +BUILD_TB ?= 0 +BUILD_PATH_LIB ?= $(BUILD_PATH)-lib + +CXX_LD ?= $(CXX) + +CXXFLAGS += -MMD -MP +CXXFLAGS_LIB = $(CXXFLAGS) -fpic +LDFLAGS_LIB = $(LDFLAGS) -shared -Wl,-soname,libspecs.so +BISONFLAGS += --warnings -Wall #-Wcex + +# Find all source files in the source directory +SOURCES_BIN = $(shell find $(SRC_PATH) -name '*.cpp' -not -ipath '*/tb/*') +SOURCES_LIB = $(shell find $(SRC_PATH) -name '*.cpp' -not -ipath '*/tb/*' -not -name 'main.cpp' -not -ipath '*/parser/*.cpp') +SOURCES_TB = $(shell find $(SRC_PATH) -name '*.cpp' -ipath '*/tb/*') +SOURCES_TB_MAIN = $(shell find $(SRC_PATH) -name 'alltestbenches.cpp' -ipath '*/tb/*') +SOURCES_ALLFILES = $(shell find $(SRC_PATH) -name '*.cpp' -or -name '*.h') + +# Add the whole source directory tree to INCLUDES +INCLUDES += $(addprefix -I,$(shell find $(SRC_PATH) -type d)) + +# Find all bison/flex source files +# - Note: bison/flex sources must have a matching filename +FLEX_SOURCES = $(shell find $(SRC_PATH) -name '*.l') +BISON_SOURCES = $(shell find $(SRC_PATH) -name '*.y') + +# Set the object filenames from the cpp sources +OBJECTS_BIN = $(SOURCES_BIN:$(SRC_PATH)/%.cpp=$(BUILD_PATH)/%.o) +ifeq ($(BUILD_TB), 1) + OBJECTS_BIN += $(SOURCES_TB:$(SRC_PATH)/%.cpp=$(BUILD_PATH)/%.o) + CXXFLAGS += -DBUILD_TB +else + OBJECTS_BIN += $(SOURCES_TB_MAIN:$(SRC_PATH)/%.cpp=$(BUILD_PATH)/%.o) +endif + +# Add the objects filenames from the bison/flex sources +OBJECTS_PARSE = $(FLEX_SOURCES:$(SRC_PATH)/%.l=$(BUILD_PATH)/%.yy.o) +OBJECTS_PARSE += $(BISON_SOURCES:$(SRC_PATH)/%.y=$(BUILD_PATH)/%.tab.o) + +# Same without main (without testbenches) +OBJECTS_LIB = $(SOURCES_LIB:$(SRC_PATH)/%.cpp=$(BUILD_PATH_LIB)/%.o) + +# Set the dependency files that will be used to add header dependencies +DEPS = $(OBJECTS_BIN:.o=.d) +DEPS_PARSE = $(OBJECTS_PARSE:.o=.d) +DEPS_LIB = $(OBJECTS_LIB:.o=.d) + +# Set other dependencies that should trigger rebuilding .o files +ADDITIONAL_DEPS = Makefile $(CONFIG_MK_FILE) + +# Find the latest trace according to modification time +LATEST_TRACE_NAME = $(shell ls -1rt --group-directories-first traces | tail -1) + +# Be verbose +V ?= 0 + +# Set/Unset the Q flag according to the V flag +ifeq ($(V),1) + Q = + QQ = @ +else + Q = @ + QQ = @ +endif + +# Clear known suffixes rules +.SUFFIXES: + +# Define phony targets +.PHONY: todos format waves newwaves print-% help cleandoc cleanoldtraces \ + cleantraces cleanall clean compiledb view-doc upload-doc doc readme \ + all bin lib + +# Instruct make not to remove intermediate files from bison/flex compilation +.SECONDARY: $(FLEX_SOURCES:$(SRC_PATH)/%.l=$(BUILD_PATH)/%.yy.h) +.SECONDARY: $(FLEX_SOURCES:$(SRC_PATH)/%.l=$(BUILD_PATH)/%.yy.cpp) +.SECONDARY: $(FLEX_SOURCES:$(SRC_PATH)/%.l=$(BUILD_PATH)/%.tab.h) +.SECONDARY: $(BISON_SOURCES:$(SRC_PATH)/%.y=$(BUILD_PATH)/%.tab.cpp) + +# Default rule +all: bin + +# Build executable +bin: $(BIN_NAME) + +# Build shared library +lib: $(LIB_NAME) + +# Link all objects together into executable +$(BIN_NAME): $(OBJECTS_BIN) $(OBJECTS_PARSE) + @echo "Linking binary" + $(Q)$(CCACHE) $(CXX_LD) $(OBJECTS_BIN) $(OBJECTS_PARSE) $(LDFLAGS) -o $@ + @echo "Done" + +# Link all objects together into library +$(LIB_NAME): $(OBJECTS_LIB) + @echo "Linking library" + $(Q)$(CCACHE) $(CXX_LD) $(OBJECTS_LIB) $(LDFLAGS_LIB) -o $@ + @echo "Done" + +# Objects depend on their directories +$(OBJECTS_PARSE): $(ADDITIONAL_DEPS) | $(dir $(OBJECTS_PARSE)) + +# Objects depend on their directories +$(OBJECTS_BIN): $(ADDITIONAL_DEPS) | $(dir $(OBJECTS_BIN)) $(OBJECTS_PARSE) + +# Objects depend on their directories +$(OBJECTS_LIB): $(ADDITIONAL_DEPS) | $(dir $(OBJECTS_LIB)) + +# Rule to create the $(BUILD_PATH) directory +$(BUILD_PATH)/: + $(Q)mkdir -p $@ + +# Rule to create a subdirectory in $(BUILD_PATH) +$(BUILD_PATH)/%/: + $(Q)mkdir -p $@ + +# Rule to create the $(BUILD_PATH_LIB) directory +$(BUILD_PATH_LIB)/: + $(Q)mkdir -p $@ + +# Rule to create a subdirectory in $(BUILD_PATH_LIB) +$(BUILD_PATH_LIB)/%/: + $(Q)mkdir -p $@ + +# Default .cpp → .o compilation rule +$(BUILD_PATH)/%.o: $(SRC_PATH)/%.cpp + @echo "Compiling $<" + $(Q)$(CCACHE) $(CXX) $(CXXFLAGS) $(INCLUDES) -c $< -o $@ + +# Default .cpp → .o compilation rule for library +$(BUILD_PATH_LIB)/%.o: $(SRC_PATH)/%.cpp + @echo "Compiling $<" + $(Q)$(CCACHE) $(CXX) $(CXXFLAGS_LIB) $(INCLUDES) -MMD -MP -c $< -o $@ + +# Special .cpp compilation rule for flex generated sources +%.yy.o: %.yy.cpp %.tab.h + @echo "Compiling $<" + $(Q)$(CCACHE) $(CXX) $(CXXFLAGS) $(INCLUDES) -iquote"$(dir $@)" -c $< -o $@ + +# Special .cpp compilation rule for bison generated sources +%.tab.o: %.tab.cpp %.yy.h + @echo "Compiling $<" + $(Q)$(CCACHE) $(CXX) $(CXXFLAGS) $(INCLUDES) -iquote"$(dir $@)" -c $< -o $@ + +# Default .l → .yy.cpp compilation rule +$(BUILD_PATH)/%.yy.cpp: $(SRC_PATH)/%.l | $(dir $($@)) + @echo "Lexing $<" + $(Q)flex --header-file="$(@:.cpp=.h)" -o $@ $< + +# Default .y → .tab.{h,cpp} compilation rule +$(BUILD_PATH)/%.tab.cpp: $(SRC_PATH)/%.y $(BUILD_PATH)/%.yy.cpp | $(dir $($@)) + @echo "Bisoning $<" + $(Q)bison $(BISONFLAGS) --defines="$(@:.cpp=.h)" -o $@ -d $< + +# Dependency rule for .tab.h (bison output, needed to compile flex output) +%.tab.h: | %.tab.cpp + @: + +# Dependency rule for .yy.h (bison output, needed to compile flex output) +%.yy.h: | %.yy.cpp + @: + +#$(ADDITIONAL_DEPS): +#@: + +# Add dependency files, if they exist +-include $(DEPS) +-include $(DEPS_LIB) +-include $(DEPS_PARSE) + +# Generation of documentation using Doxygen +doc: + @echo "Generating documentation" + @mkdir -p doc/html + @cp -r doc/resources/ doc/html/ + $(Q)doxygen doc/Doxyfile + #$(Q)tar -c -f doc/pcm-doc.tar.xz -C doc/html . + +# Regenerate compile_commands.json for YouCompleteMe +compiledb: compile_commands.json + +# Regenerate compile_commands.json for YouCompleteMe +compile_commands.json: clean + @echo "Generating compile_commands.json" + $(Q)compiledb --verbose make -j8 + $(Q)sed -i '/"-MMD"\|"-MP"/d' $@ + +# Clean build artifacts +clean: + @echo "Removing build artifacts" + $(QQ)#[ ! -d 'build' ] || rm -rf build/ + $(QQ)#[ ! -d 'build-lib' ] || rm -rf build-lib/ + $(Q)[ ! -d "$(BUILD_PATH)" ] || rm -rf "$(BUILD_PATH)" + $(Q)[ ! -d "$(BUILD_PATH_LIB)" ] || rm -rf "$(BUILD_PATH_LIB)" + +# Remove any product of the build (build, trace, doc, bin) +cleanall: clean cleantraces cleandoc + @echo "Removing binary" + $(Q)rm -f Pout.obj Pout.png detector_trace.txt + $(Q)rm -f sim specs libspecs.so + +# Clean all traces +cleantraces: + @echo "Removing all traces" + $(Q)find traces/ -maxdepth 1 -type f -and -iname '*.vcd' -delete + +# Clean all traces but the newest +cleanoldtraces: + @echo "Removing all traces but newest" + $(Q)find traces/ -maxdepth 1 -iname '*.vcd' -and -type f -and ! -iname "$(LATEST_TRACE_NAME)" -delete + +# Clean documentation output +cleandoc: + @echo "Removing generated documentation" + $(Q)rm -rf doc/html doc/pcm-doc.tar.xz + +# Show the latest trace with a blank GTKWave config +newwaves: + @echo "Opening latest trace file" + @mkdir -p traces/configs + @bash utils/openwave.sh "traces/$(LATEST_TRACE_NAME)" + +# Show the latest trace with a menu to select which GTKWave config to use +waves: + @echo "Opening latest trace file" + @mkdir -p traces/configs + @bash utils/openwave.sh "traces/$(LATEST_TRACE_NAME)" traces/configs + +test: + @echo "Running all tests" + $(Q)./specs -t waveguide + $(Q)./specs -t splitter + $(Q)./specs -t merger + $(Q)./specs -t detector + $(Q)./specs -t directional_coupler + $(Q)./specs -t phaseshifter + $(Q)./specs -t mzi + $(Q)./specs -t pcm + $(Q)#./specs -t ring + $(Q)#./specs -t ac_add_drop + $(Q)#./specs -t ac_crow + $(Q)#./specs -t mesh + +rc: all + ./${BIN_NAME} -fcircuits/rc_mohab.cir + + +# TODO: add a gate so we don't accidentally "mess up" the working +# directory by shadowing real changes. Maybe do a commit or something +# like this ? or check the git status whether there are changes ? +# Automatic formatting should be automatically run on write, but if +# modifying a file with a different format and re-formatting, changes +# seen by git could be far from obvious to re-read later +# Run clang-format on the source (in place) +format: + @echo "Formatting source" + @clang-format -i $(SOURCES_ALLFILES) + +# Print all TODOs found in the source and other files +todos: + @echo "TODO (from code):" + @find $(SRC_PATH) -type f | xargs awk '/TODO:/ {split($$0, arr, "TODO:"); content = arr[2]; print "- " content, "("FILENAME":"FNR")"}' || true + @#find module_definitions/ -type f | xargs awk '/TODO:/ {split($$0, arr, "TODO:"); content = arr[2]; print "- " content, "("FILENAME":"FNR")"}' || true + @find utils/ -type f | xargs awk '/TODO:/ {split($$0, arr, "TODO:"); content = arr[2]; print "- " content, "("FILENAME":"FNR")"}' || true + @cat todo.txt || true + +# Print a given variable +print-%: + $(Q)echo $* = $($*) + +# FIXME: cannot have ":" in rule descriptions +# Show this help prompt +help: + @ echo + @ echo ' Usage:' + @ echo '' + @ echo ' make <target> [flags...]' + @ echo '' + @ echo ' Targets:' + @ echo '' + @ awk '/^#/{ comment = substr($$0,3) } comment && /^[a-zA-Z][a-zA-Z0-9_-]+ ?:/{ print " ", $$1, comment }' $(MAKEFILE_LIST) | column -t -s ':' | sort + @ echo '' + @ echo ' Flags:' + @ echo '' + @awk '/^#/{ comment = substr($$0,3) } comment && /^[a-zA-Z][a-zA-Z0-9_-]*/ && /\??=/ && /[01]$$/{ print " " $$1 " (default = " $$3 ")",":",comment }' $(MAKEFILE_LIST) | column -t -s ':' | sort + @ echo '' |
