Skip to content

Instantly share code, notes, and snippets.

@gvanem
Last active November 28, 2019 14:13
Show Gist options
  • Select an option

  • Save gvanem/00a1b0f99b9287f0a98a93e90e969375 to your computer and use it in GitHub Desktop.

Select an option

Save gvanem/00a1b0f99b9287f0a98a93e90e969375 to your computer and use it in GitHub Desktop.
A Gnu-Makefile for Doxygen (targeting MSVC or clang-cl)
#
# GNU-makefile for Doxygen (MSVC / clang-cl, 32-bit)
#
# By G. Vanem <gvanem@yahoo.no> 2019.
#
THIS_FILE := Makefile.MSVC
DEP_FILE := .depend.MSVC
DATE := $(shell date +%d-%B-%Y)
#
# Choose your weapons.
# These can also be set on make cmd-line.
# E.g. 'make -f Makefile.MSVC USE_CLANG_CL=1 clean all'
#
# It's safest to do a 'make -f Makefile.MSVC clean all' after
# changing any of these 'USE_X' settings.
#
USE_MP_COMPILE ?= 1
USE_CLANG_FORMATER ?= 1
USE_CLANG_CL ?= 0
USE_CRT_DEBUG ?= 0
#
# Experimental:
#
USE_SQLITE3 ?= 0
USE_LIBCLANG ?= 0
#
# Only used in the C++ preprocess rule below.
#
PYTHON ?= python
#
# What to build:
#
TARGETS = Doxygen.exe Doxmlparser_metrics.exe Doxmlparser_test.exe
#
# This fails to link for some weird reason:
#
TARGETS += Doxywizard.exe
#
# Created by 'make install':
#
MAN1_FILES = $(addprefix $(OBJ_DIR)/, \
doxygen.1 \
doxyindexer.1 \
doxysearch.1 \
doxywizard.1)
TEMPLATES = $(wildcard ../templates/html/*) \
$(wildcard ../templates/latex/*) \
$(wildcard ../templates/xml/*)
#
# Set 'MDEPEND=' to NOT rebuild many things when these files changes.
#
MDEPEND = # $(THIS_FILE)
default: all
#
# Take the version-info from ../VERSION
#
VER_MAJOR = $(shell cut -d'.' -f1 ../VERSION)
VER_MINOR = $(shell cut -d'.' -f2 ../VERSION)
VER_PATCH = $(shell cut -d'.' -f3 ../VERSION)
VERSION = $(VER_MAJOR).$(VER_MINOR).$(VER_PATCH)
ver_test:
@echo '$(VER_MAJOR).$(VER_MINOR).$(VER_PATCH)'.
#
# The following ANSI-codes used in macro 'color_msg' assumes you have
# MSys/Cygwin's echo with colour support.
#
BRIGHT_GREEN = \e[1;32m
BRIGHT_YELLOW = \e[1;33m
#
# Where to copy 'Doxygen.exe' too?
#
INSTALL_BIN = $(realpath $(VSINSTALLDIR))/bin
#
# Where to copy '../doc/*.1' too?
#
INSTALL_MAN1 ?= /usr/share/man/man1
#
# Macro to create a list of .obj-files from lists of .c, .cc, and .cpp-files:
#
C_to_obj = $(addprefix $(OBJ_DIR)/, \
$(notdir $(1:.c=.obj)))
CC_to_obj = $(addprefix $(OBJ_DIR)/, \
$(notdir $(1:.cc=.obj)))
CPP_to_obj = $(addprefix $(OBJ_DIR)/, \
$(notdir $(1:.cpp=.obj)))
ifeq ($(USE_CLANG_CL),1)
CC = clang-cl
OBJ_DIR = clang_obj
else
CC = cl
OBJ_DIR = MSVC_obj
endif
LDFLAGS = -nologo -debug -incremental:no -verbose -map \
-nodefaultlib:libcmt.lib -nodefaultlib:oldnames.lib \
-nodefaultlib:uuid.lib
ifeq ($(USE_CRT_DEBUG),1)
D = d
RCFLAGS = -D_DEBUG
else
#
# Building with a '-DNDEBUG', will crash Doxywizard.exe for some reason.
# If not defined, we'll get a 'Q_ASSERT()' that triggers an abort instead.
# Nice!
#
CFLAGS = -DNDEBUG
RCFLAGS = -D_RELEASE
endif
CFLAGS += -nologo -MD$(d) -W3 -Zi -Ot -EHsc -GF -GS -FI$(OBJ_DIR)/doxy_cfg.h
#
# If set in environment, remove it (could confure 'clang-cl').
#
export CL=
CFLAGS += -I. -I$(OBJ_DIR) -I../qtools -I../libversion -I../libmd5 \
-I../liblodepng -I../libmscgen -I../vhdlparser \
-I../addon/doxmlparser/include
ifeq ($(USE_CLANG_CL),1)
#
# Little point in compiling several .cpp-files using 'clang-cl'
# since it does not compile in parallel.
#
USE_MP_COMPILE = 0
CFLAGS += -fms-compatibility
RCFLAGS += -D__clang__
#
# Turn off some annoying warnings.
#
CFLAGS += -Wno-unused-variable \
-Wno-reorder \
-Wno-return-type \
-Wno-macro-redefined \
-Wno-missing-braces \
-Wno-overloaded-virtual \
-Wno-char-subscripts \
-Wno-unused-private-field \
-Wno-undefined-internal \
-Wno-unused-function \
-Wno-deprecated-declarations \
-Wno-deprecated-register \
-Wno-sometimes-uninitialized \
-Wno-tautological-constant-out-of-range-compare
else
#
#
CFLAGS += -wd4005 -wd4018 -wd4065 -wd4101 -wd4244 -wd4267 -wd4715 -wd4838 -wd4996
RCFLAGS += -D_MSC_VER
endif
#
# Experimental:
# If 'USE_LIBCLANG=1', change this as needed:
#
ifeq ($(USE_LIBCLANG),1)
CLANG_ROOT ?= f:/MingW32/src/Languages/LLVM-Clang
CFLAGS += -I$(CLANG_ROOT)/include -I$(CLANG_ROOT)/tools/Clang/include
CLANG_LIBS = $(addprefix $(CLANG_ROOT)/gv-build/lib/, \
libclang.lib \
clangTooling.lib \
LLVMSupport.lib \
LLVMCore.lib \
LLVMOption.lib)
endif
#
# The 'QT_ROOT' is the base directory of where Qt[4|5] is installed.
# It's value should match the output of 'qmake.exe -query':
# ...
# QT_INSTALL_PREFIX:f:/Qt/59/5.9.1/msvc2015
#
# Only tested with Qt5.
#
QT_ROOT ?= $(realpath $(QTDIR))
#
# These should normally be in '%LIB%' path.
# But add them here with the '$(QT_DIR)/lib' anyway.
# Then there shuld be no chance to include 64-bit libraries
# in a 32-bit build. And vice-vesa.
#
# Only used by 'Doxywizard.exe'.
#
QT_LIBS = $(addprefix $(QT_ROOT)/lib/, \
Qt5Core$(D).lib \
Qt5Gui$(D).lib \
Qt5Widgets$(D).lib \
Qt5Xml$(D).lib)
#
# The Qt include directories we need:
#
CFLAGS += -I$(QT_ROOT)/include \
-I$(QT_ROOT)/include/QtCore \
-I$(QT_ROOT)/include/QtXml
#
# Make will search these directories for a match to the
# '$(OBJ_DIR)/%.obj: %.cpp' pattern rule below.
#
# Do NOT add '../addon/doxywizard' to VPATH.
#
VPATH = ../qtools \
../libmd5 \
../liblodepng \
../libmscgen \
../vhdlparser \
$(OBJ_DIR)
#
# .cpp sources for 'common.lib':
#
common_CPP_SRC = arguments.cpp \
cite.cpp \
clangparser.cpp \
classdef.cpp \
classlist.cpp \
cmdmapper.cpp \
condparser.cpp \
context.cpp \
cppvalue.cpp \
debug.cpp \
defgen.cpp \
define.cpp \
definition.cpp \
dia.cpp \
diagram.cpp \
dirdef.cpp \
docbookgen.cpp \
docbookvisitor.cpp \
docgroup.cpp \
docparser.cpp \
docsets.cpp \
dot.cpp \
dotcallgraph.cpp \
dotclassgraph.cpp \
dotdirdeps.cpp \
dotfilepatcher.cpp \
dotgfxhierarchytable.cpp \
dotgraph.cpp \
dotgroupcollaboration.cpp \
dotincldepgraph.cpp \
dotlegendgraph.cpp \
dotnode.cpp \
dotrunner.cpp \
doxygen.cpp \
eclipsehelp.cpp \
emoji.cpp \
entry.cpp \
filedef.cpp \
filename.cpp \
fileparser.cpp \
formula.cpp \
ftextstream.cpp \
ftvhelp.cpp \
groupdef.cpp \
htags.cpp \
htmldocvisitor.cpp \
htmlentity.cpp \
htmlgen.cpp \
htmlhelp.cpp \
image.cpp \
index.cpp \
language.cpp \
latexdocvisitor.cpp \
latexgen.cpp \
layout.cpp \
mandocvisitor.cpp \
mangen.cpp \
markdown.cpp \
memberdef.cpp \
membergroup.cpp \
memberlist.cpp \
membername.cpp \
message.cpp \
msc.cpp \
namespacedef.cpp \
objcache.cpp \
outputgen.cpp \
outputlist.cpp \
pagedef.cpp \
perlmodgen.cpp \
plantuml.cpp \
portable.cpp \
qhp.cpp \
qhpxmlwriter.cpp \
reflist.cpp \
resourcemgr.cpp \
rtfdocvisitor.cpp \
rtfgen.cpp \
rtfstyle.cpp \
searchindex.cpp \
sqlite3gen.cpp \
tagreader.cpp \
template.cpp \
textdocvisitor.cpp \
tooltip.cpp \
util.cpp \
vhdldocgen.cpp \
vhdljjparser.cpp \
xmldocvisitor.cpp \
xmlgen.cpp
common_CPP_SRC += $(addprefix ../qtools/, \
qbuffer.cpp \
qcollection.cpp \
qcstring.cpp \
qcstringlist.cpp \
qdatastream.cpp \
qdatetime.cpp \
qdir.cpp \
qdir_win32.cpp \
qfile.cpp \
qfileinfo.cpp \
qfileinfo_win32.cpp \
qfile_win32.cpp \
qgarray.cpp \
qgcache.cpp \
qgdict.cpp \
qglist.cpp \
qglobal.cpp \
qgstring.cpp \
qgvector.cpp \
qiodevice.cpp \
qmap.cpp \
qmutex.cpp \
qmutex_win32.cpp \
qregexp.cpp \
qstring.cpp \
qstringlist.cpp \
qtextcodec.cpp \
qtextstream.cpp \
qthread.cpp \
qthread_win32.cpp \
qutfcodec.cpp \
qwaitcondition_win32.cpp \
qxml.cpp)
common_CPP_SRC += ../liblodepng/lodepng.cpp \
../vhdlparser/VhdlParserIF.cpp
#
# These are generated:
#
common_CPP_SRC += $(addprefix $(OBJ_DIR)/, \
ce_parse.cpp \
configoptions.cpp \
configvalues.cpp \
doxyversion.cpp \
gitversion.cpp \
mscgen_language.cpp \
resources.cpp) \
$(LEXX_CPP_files)
common_C_SRC = portable_c.c \
../libmd5/md5.c
common_C_SRC += $(addprefix ../libmscgen/, \
gd.c \
gd_color.c \
gdfonts.c \
gdfontt.c \
gdhelpers.c \
gd_lodepng.c \
gd_security.c \
gdtables.c \
mscgen_adraw.c \
mscgen_api.c \
mscgen_gd_out.c \
mscgen_msc.c \
mscgen_null_out.c \
mscgen_ps_out.c \
mscgen_safe.c \
mscgen_svg_out.c \
mscgen_utf8.c)
common_CC_SRC = $(addprefix ../vhdlparser/, \
CharStream.cc \
ParseException.cc \
Token.cc \
TokenMgrError.cc \
VhdlParser.cc \
VhdlParserTokenManager.cc)
Doxywizard_moc_H = $(addprefix ../addon/doxywizard/, \
doxywizard.h \
expert.h \
helplabel.h \
inputbool.h \
inputint.h \
inputstring.h \
inputstrlist.h \
wizard.h)
Doxywizard_moc_SRC = $(addprefix $(OBJ_DIR)/moc_, \
$(notdir $(Doxywizard_moc_H:.h=.cpp)) )
Doxywizard_moc_OBJ = $(Doxywizard_moc_SRC:.cpp=.obj)
#
# Generated files:
#
GENERATED = $(addprefix $(OBJ_DIR)/, \
configvalues.h \
configvalues.cpp \
configoptions.cpp \
config.doc \
ce_parse.c \
ce_parse.cpp \
ce_parse.h \
ce_parse.hpp \
doxy_cfg.h \
settings.h \
lang_cfg.h \
layout_default.xml.h \
gitversion.cpp \
doxyversion.cpp \
mscgen_language.cpp \
mscgen_language.hpp \
resources.cpp)
LEX_FILES = scanner.l \
code.l \
pyscanner.l \
pycode.l \
fortranscanner.l \
fortrancode.l \
vhdlcode.l \
tclscanner.l \
pre.l \
declinfo.l \
defargs.l \
doctokenizer.l \
commentcnv.l \
commentscan.l \
constexp.l \
xmlcode.l \
sqlcode.l \
configimpl.l \
../libmscgen/mscgen_lexer.l
LEXX_CPP_files = $(addprefix $(OBJ_DIR)/, \
$(notdir $(LEX_FILES:.l=.cpp)))
LEXX_H_files = $(addprefix $(OBJ_DIR)/, \
$(notdir $(LEX_FILES:.l=.l.h)))
GENERATED += $(LEXX_CPP_files) $(LEXX_H_files)
ifeq ($(USE_SQLITE3),1)
SQLITE3_LIB = winsqlite3.lib
GENERATED += $(OBJ_DIR)/sqlite3.h
endif
#
# .cpp sources for 'Doxywizard.exe':
#
Doxywizard_CPP_SRC = $(addprefix ../addon/doxywizard/, \
doxywizard.cpp \
expert.cpp \
inputbool.cpp \
inputint.cpp \
inputstring.cpp \
inputstrlist.cpp \
wizard.cpp) \
Doxywizard_CPP_SRC += $(Doxywizard_moc_SRC)
Doxywizard_CPP_SRC += $(addprefix $(OBJ_DIR)/, \
configdoc.cpp \
config_doxyw.cpp)
Doxywizard_OBJ = $(call CPP_to_obj, $(Doxywizard_CPP_SRC)) \
$(Doxywizard_moc_OBJ)
#
# All the .obj-files for 'common.lib':
#
common_CPP_OBJ = $(call CPP_to_obj, $(common_CPP_SRC))
common_LIB_OBJ = $(call C_to_obj, $(common_C_SRC)) \
$(call CC_to_obj, $(common_CC_SRC)) \
$(common_CPP_OBJ)
#
# Put these CFLAGS before other 'CFLAGS' while compiling '$(Doxywizard_CPP_SRC)':
#
Doxywizard_CFLAGS = -I../addon/doxywizard \
-DCOMPILING_Doxywizard
VPATH += ../addon/doxmlparser/src
Doxmlparser_metrics_SRC = $(addprefix ../addon/doxmlparser/src/, \
basehandler.cpp \
compoundhandler.cpp \
dochandler.cpp \
graphhandler.cpp \
linkedtexthandler.cpp \
loamhandler.cpp \
mainhandler.cpp \
memberhandler.cpp \
paramhandler.cpp \
sectionhandler.cpp)
Doxmlparser_metrics_OBJ = $(call CPP_to_obj, $(Doxmlparser_metrics_SRC)) \
$(OBJ_DIR)/Doxmlparser_debug.obj \
$(OBJ_DIR)/Doxmlparser_metrics.obj
Doxmlparser_test_OBJ = $(call CPP_to_obj, $(Doxmlparser_metrics_SRC)) \
$(OBJ_DIR)/Doxmlparser_test.obj \
$(OBJ_DIR)/Doxmlparser_debug.obj
all: $(OBJ_DIR) $(GENERATED) $(TARGETS)
help:
$(call green_msg,Usage: $(MAKE) -f $(THIS_FILE)$(BRIGHT_YELLOW) <GOALS>)
$(call yellow_msg,<GOALS>:\e[0m all - $(BRIGHT_YELLOW)will build $(TARGETS).)
$(call color_msg, clean - $(BRIGHT_YELLOW)will remove 'OBJ_DIR/*'.)
$(call color_msg, vclean - $(BRIGHT_YELLOW)will remove all generated stuff.)
$(call color_msg, depend - $(BRIGHT_YELLOW)will use gcc to create a $(DEP_FILE).)
$(call color_msg, install - $(BRIGHT_YELLOW)will build and copy Doxygen.exe to $(INSTALL_BIN).)
install: Doxygen.exe $(MAN1_FILES)
cp --update Doxygen.exe $(INSTALL_BIN)
cp --update $(MAN1_FILES) $(INSTALL_MAN1)
Doxygen.exe: $(OBJ_DIR)/main.obj common.lib ../winbuild/iconv.lib $(OBJ_DIR)/Doxygen.res
$(call link_EXE, $@, $^ $(SQLITE3_LIB) $(CLANG_LIBS) ole32.lib shell32.lib)
Doxywizard.exe: $(Doxywizard_OBJ) common.lib $(OBJ_DIR)/Doxywizard.res
$(call link_EXE, $@, $^ $(QT_LIBS) shell32.lib)
Doxmlparser_metrics.exe: $(Doxmlparser_metrics_OBJ) common.lib $(OBJ_DIR)/Doxmlparser_metrics.res
$(call link_EXE, $@, $^)
Doxmlparser_test.exe: $(Doxmlparser_test_OBJ) common.lib $(OBJ_DIR)/Doxmlparser_test.res
$(call link_EXE, $@, $^)
$(CC).args: $(THIS_FILE)
$(call yellow_msg,All CFLAGS are in $@)
$(call create_rsp_file, $@, $(CFLAGS))
$(Doxywizard_moc_SRC): $(OBJ_DIR)/moc.args
$(OBJ_DIR)/moc.args: $(OBJ_DIR) $(THIS_FILE)
$(call yellow_msg,All MOC flags for Doxywizard_moc_SRC are in $@)
$(call create_rsp_file, $@, $(filter -D% -I%, $(Doxywizard_CFLAGS) $(CFLAGS)) \
-DQ_OS_WIN --compiler-flavor=msvc)
$(OBJ_DIR) bin:
mkdir $@
ifeq ($(USE_MP_COMPILE),1)
libmscgen_C_SRC = $(filter ../libmscgen/%.c, $(common_C_SRC))
libmscgen_C_OBJ = $(call C_to_obj, $(libmscgen_C_SRC))
$(common_CPP_OBJ): $(sort $(common_CPP_SRC)) | $(CC).args
$(call MP_compile, $(sort $(common_CPP_SRC)),)
$(libmscgen_C_OBJ): $(libmscgen_C_SRC) | $(CC).args
$(call MP_compile, $(libmscgen_C_SRC),)
$(Doxywizard_moc_OBJ): $(Doxywizard_moc_SRC) | $(CC).args
$(call MP_compile, $(Doxywizard_moc_SRC), $(Doxywizard_CFLAGS))
endif
common.lib: $(common_LIB_OBJ)
$(call create_lib, $@, $^)
#
# Use explicit rules for $(Doxywizard_CPP_SRC) and $(Doxywizard_moc_SRC):
#
$(OBJ_DIR)/config_doxyw.obj: $(OBJ_DIR)/config_doxyw.cpp $(OBJ_DIR)/config_doxyw.l.h | $(CC).args
$(call compile, $<, $@, $(Doxywizard_CFLAGS))
@echo
$(OBJ_DIR)/configdoc.obj: $(OBJ_DIR)/configdoc.cpp | $(CC).args
$(call compile, $<, $@, $(Doxywizard_CFLAGS))
@echo
$(OBJ_DIR)/%.obj: ../addon/doxywizard/%.cpp | $(CC).args
$(call compile, $<, $@, $(Doxywizard_CFLAGS))
@echo
$(OBJ_DIR)/%.obj: ../addon/doxywizard/%.cpp | $(CC).args
$(call compile, $<, $@, $(Doxywizard_CFLAGS))
@echo
$(OBJ_DIR)/moc_%.obj: $(OBJ_DIR)/moc_%.cpp | $(CC).args
$(call compile, $<, $@, $(Doxywizard_CFLAGS))
@echo
#
# Do not use 'VPATH += ../addon/doxmlparser/test' for these since there are other 'main.cpp' files.
#
$(OBJ_DIR)/Doxmlparser_debug.obj: ../addon/doxmlparser/src/debug.cpp
$(call compile, $<, $@)
$(OBJ_DIR)/Doxmlparser_metrics.obj: ../addon/doxmlparser/examples/metrics/main.cpp
$(call compile, $<, $@)
$(OBJ_DIR)/Doxmlparser_test.obj: ../addon/doxmlparser/test/main.cpp
$(call compile, $<, $@)
#
# Rules for .cpp/.cc files in VPATH:
#
$(OBJ_DIR)/%.obj: %.cpp | $(CC).args
$(call compile, $<, $@)
$(OBJ_DIR)/%.obj: %.cc | $(CC).args
$(call compile, $<, $@)
$(OBJ_DIR)/%.obj: %.c | $(CC).args
$(call compile, $<, $@)
ifeq ($(USE_CLANG_FORMATER),1)
CPP_FORMATER = | clang-format -style=Mozilla -assume-filename=cpp
endif
%.i: %.cpp FORCE $(CC).args $(GENERATED) cpp_filter.py
$(CC) @$(CC).args -E $< | $(PYTHON) cpp_filter.py $(CPP_FORMATER) > $@
@echo
%.i: ../addon/doxywizard/%.cpp FORCE $(CC).args $(GENERATED) cpp_filter.py
$(CC) -E $(Doxywizard_CFLAGS) @$(CC).args $< | $(PYTHON) cpp_filter.py $(CPP_FORMATER) > $@
@echo
FORCE:
$(OBJ_DIR)/moc_%.cpp: ../addon/doxywizard/%.h
$(call create_moc, $@, $<)
$(OBJ_DIR)/%.res: $(OBJ_DIR)/%.rc
$(call create_res, $@, $<)
$(OBJ_DIR)/Doxygen.rc: $(MDEPEND)
$(call create_rc, $@, Generates documentation from annotated sources)
$(OBJ_DIR)/Doxywizard.rc: $(MDEPEND)
$(call create_rc, $@, A Qt wizard for Doxygen, APPICON ICON DISCARDABLE "../addon/doxywizard/doxywizard.ico")
$(OBJ_DIR)/Doxmlparser_metrics.rc: $(MDEPEND)
$(call create_rc, $@, A DoxyML parser example)
$(OBJ_DIR)/Doxmlparser_test.rc: $(THIS_FILE)
$(call create_rc, $@, A DoxyML parser test program)
docs: $(MAN1_FILES)
$(OBJ_DIR)/%.1: ../doc/%.1
$(call green_msg,Generating $@)
sed -e 's|@DATE@|$(DATE)|' -e 's|@VERSION@|$(VERSION)|' < $< > $@
@echo
#
# Cannot use 'run_flex' macro for '$(OBJ_DIR)/mscgen_lexer.*' and '$(OBJ_DIR)/fortranscanner.*'.
#
$(OBJ_DIR)/mscgen_lexer.cpp: ../libmscgen/mscgen_lexer.l
$(call run_flex_stdout, $<, $@)
$(OBJ_DIR)/mscgen_lexer.l.h: ../libmscgen/mscgen_lexer.l
$(call run_scan_states, $@, $<)
$(OBJ_DIR)/fortranscanner.cpp: fortranscanner.l
$(call run_flex_stdout, $<, $@)
$(OBJ_DIR)/fortranscanner.l.h: fortranscanner.l
$(call run_scan_states, $@, $<)
$(OBJ_DIR)/config_doxyw.cpp: ../addon/doxywizard/config_doxyw.l
$(call run_flex_stdout, $<, $@)
$(OBJ_DIR)/config_doxyw.l.h: ../addon/doxywizard/config_doxyw.l
$(call run_scan_states, $@, $<)
$(OBJ_DIR)/code.cpp $(OBJ_DIR)/code.l.h: code.l
$(call run_flex, $<)
$(OBJ_DIR)/commentcnv.cpp $(OBJ_DIR)/commentcnv.l.h: commentcnv.l
$(call run_flex, $<)
$(OBJ_DIR)/commentscan.cpp $(OBJ_DIR)/commentscan.l.h: commentscan.l
$(call run_flex, $<)
$(OBJ_DIR)/configimpl.cpp $(OBJ_DIR)/configimpl.l.h: configimpl.l
$(call run_flex, $<)
$(OBJ_DIR)/constexp.cpp $(OBJ_DIR)/constexp.l.h: constexp.l
$(call run_flex, $<)
$(OBJ_DIR)/declinfo.cpp $(OBJ_DIR)/declinfo.l.h: declinfo.l
$(call run_flex, $<)
$(OBJ_DIR)/defargs.cpp $(OBJ_DIR)/defargs.l.h: defargs.l
$(call run_flex, $<)
$(OBJ_DIR)/doctokenizer.cpp $(OBJ_DIR)/doctokenizer.l.h: doctokenizer.l
$(call run_flex, $<)
$(OBJ_DIR)/fortrancode.cpp $(OBJ_DIR)/fortrancode.l.h: fortrancode.l
$(call run_flex, $<)
$(OBJ_DIR)/pre.cpp $(OBJ_DIR)/pre.l.h: pre.l
$(call run_flex, $<)
$(OBJ_DIR)/pycode.cpp $(OBJ_DIR)/pycode.l.h: pycode.l
$(call run_flex, $<)
$(OBJ_DIR)/pyscanner.cpp $(OBJ_DIR)/pyscanner.l.h: pyscanner.l
$(call run_flex, $<)
$(OBJ_DIR)/scanner.cpp $(OBJ_DIR)/scanner.l.h: scanner.l
$(call run_flex, $<)
$(OBJ_DIR)/sqlcode.cpp $(OBJ_DIR)/sqlcode.l.h: sqlcode.l
$(call run_flex, $<)
$(OBJ_DIR)/tclscanner.cpp $(OBJ_DIR)/tclscanner.l.h: tclscanner.l
$(call run_flex, $<)
$(OBJ_DIR)/vhdlcode.cpp $(OBJ_DIR)/vhdlcode.l.h: vhdlcode.l
$(call run_flex, $<)
$(OBJ_DIR)/xmlcode.cpp $(OBJ_DIR)/xmlcode.l.h: xmlcode.l
$(call run_flex, $<)
$(OBJ_DIR)/ce_parse.cpp: $(OBJ_DIR)/ce_parse.c
cp --update $< $@
$(OBJ_DIR)/ce_parse.hpp: $(OBJ_DIR)/ce_parse.h
cp --update $< $@
$(OBJ_DIR)/ce_parse.c $(OBJ_DIR)/ce_parse.h: constexp.y
$(call run_bison, $(OBJ_DIR)/ce_parse.c, $(OBJ_DIR)/ce_parse.h, $<)
$(OBJ_DIR)/mscgen_language.cpp: ../libmscgen/mscgen_language.y
$(call run_bison, $(OBJ_DIR)/mscgen_language.cpp, $(OBJ_DIR)/mscgen_language.hpp, $<)
$(OBJ_DIR)/settings.h: $(OBJ_DIR) $(MDEPEND)
$(call generate, $@)
$(file >> $@,$(settings_H))
$(OBJ_DIR)/doxy_cfg.h: $(OBJ_DIR) $(MDEPEND)
$(call generate, $@)
$(file >> $@,$(Doxy_cfg_H))
$(OBJ_DIR)/sqlite3.h: $(OBJ_DIR) $(MDEPEND)
$(call generate, $@)
$(file >> $@,$(sqlite3_H))
$(OBJ_DIR)/configvalues.h: $(OBJ_DIR) $(MDEPEND) configgen.py
$(call run_configgen, $@, -maph)
$(OBJ_DIR)/configvalues.cpp: $(OBJ_DIR) $(MDEPEND) configgen.py
$(call run_configgen, $@, -maps)
$(OBJ_DIR)/configoptions.cpp: $(OBJ_DIR) $(MDEPEND) configgen.py
$(call run_configgen, $@, -cpp)
$(OBJ_DIR)/config.doc: $(OBJ_DIR) $(MDEPEND) configgen.py
$(call run_configgen, $@, -doc)
$(OBJ_DIR)/configdoc.cpp: $(OBJ_DIR) $(MDEPEND) configgen.py
$(call run_configgen, $@, -wiz)
$(OBJ_DIR)/lang_cfg.h: $(OBJ_DIR) $(MDEPEND)
$(call generate, $@)
$(file >> $@,$(lang_cfg_H))
$(OBJ_DIR)/layout_default.xml.h: $(OBJ_DIR) $(MDEPEND)
$(call generate, $@)
$(PYTHON) to_c_cmd.py < layout_default.xml > $@
@echo
$(OBJ_DIR)/resources.cpp: res2cc_cmd.py $(TEMPLATES)
$(call green_msg,Generating $@)
$(PYTHON) res2cc_cmd.py ../templates $@
@echo
$(OBJ_DIR)/gitversion.cpp: ../libversion/gitversion.cpp.in $(OBJ_DIR) $(MDEPEND)
$(call generate, $@)
sed -e 's|@GIT_HEAD_SHA1@|no-idea|' -e 's|@GIT_IS_DIRTY@|yes|' < $< >> $@
@echo
$(OBJ_DIR)/doxyversion.cpp: ../libversion/doxyversion.cpp.in $(OBJ_DIR) $(MDEPEND)
$(call generate, $@)
sed -e 's|@DOXYGEN_VERSION@|$(VERSION)|' < $< >> $@
@echo
$(OBJ_DIR)/version.cpp:: version.py $(OBJ_DIR) $(MDEPEND)
$(call green_msg,Generating $@)
$(PYTHON) $< $@
@echo
clean:
rm -f $(OBJ_DIR)/* cl.args clang-cl.args \
link.tmp depend.args cpp_filter.py vc1*.pdb
- rmdir $(OBJ_DIR)
vclean realclean: clean
rm -f common.lib $(DEP_FILE) $(TARGETS) $(TARGETS:.exe=.map) $(TARGETS:.exe=.pdb)
#######################################################################################
cpp_filter.py: $(THIS_FILE)
$(call yellow_msg,Generating $@...)
$(file > $@,#!/usr/env/python)
$(file >> $@,#)
$(file >> $@,# DO NOT EDIT! This file was generated automatically)
$(file >> $@,# from $(realpath $(THIS_FILE)). Edit that file instead.)
$(file >> $@,#)
$(file >> $@,from __future__ import print_function)
$(file >> $@,if 1:)
$(file >> $@,$(cpp_filter_py))
DEP_CFLAGS = -DGCC_MAKE_DEPEND -std=gnu++11 --include $(OBJ_DIR)/doxy_cfg.h \
$(filter -I% -D%, $(CFLAGS) -I../addon/doxywizard)
DEP_REPLACE = -e 's@\(.*\)\.o: @\n$$(OBJ_DIR)\/\1.obj: @' \
-e 's@$(OBJ_DIR)@$$(OBJ_DIR)@' \
-e 's@$(QT_ROOT)@$$(QT_ROOT)@'
ALL_SRC = main.cpp \
$(common_CPP_SRC) \
$(common_CC_SRC) \
$(common_C_SRC)
#
# 'config_doxyw.cpp' fails to preprocess with 'g++':
#
ALL_SRC += $(filter-out $(OBJ_DIR)/config_doxyw.cpp, $(Doxywizard_CPP_SRC))
depend: $(GENERATED)
$(call yellow_msg,Generating dependencies for $(words $(ALL_SRC)) source-files. Hang on...)
$(call create_rsp_file, depend.args, $(DEP_CFLAGS) $(ALL_SRC))
$(file > $(DEP_FILE), #)
$(file >> $(DEP_FILE), # DO NOT EDIT! This file was generated automatically)
$(file >> $(DEP_FILE), # from $(realpath $(THIS_FILE)).)
$(file >> $(DEP_FILE), #)
g++ -MM @depend.args | sed $(DEP_REPLACE) >> $(DEP_FILE)
#
# GNU-make macros:
#
color_msg = @echo -e "$(1)\e[0m"
green_msg = $(call color_msg,$(BRIGHT_GREEN)$(1))
yellow_msg = $(call color_msg,$(BRIGHT_YELLOW)$(1))
compile = $(CC) $(3) @$(CC).args -c $(1) -Fo./$(strip $(2))
#
# Used by 'cl' only:
#
define MP_compile
$(call green_msg,Compiling $(words $(1)) files:)
$(call compile, $(1), $(OBJ_DIR)\\, -MP $(2))
endef
#
# Link an .exe-file:
# arg1: $(1): the .exe-file.
# arg2: $(2): the objects and libraries.
#
define link_EXE
$(call green_msg,Linking $(strip $(1))...)
link $(LDFLAGS) -out:$(strip $(1)) $(2) > link.tmp
@cat link.tmp >> $(1:.exe=.map)
@rm -f link.tmp $(1:.exe=.lib) $(1:.exe=.exp)
@echo
endef
#
# Create a static library:
# arg1: $(1): the name of the .lib-file.
# arg2: $(2): the objects.
#
define create_lib
$(call green_msg,Creating $(strip $(1)))
lib -nologo -out:$(strip $(1)) $(2)
@echo
endef
#
# Generate a .rc-file:
# arg1: $(1): the name of the .rc-file.
# arg2: $(2): the 'RC_DESCRIPTION' with no "".
# arg3: $(3): extra args like an 'APPICON ..' line
#
define create_rc
$(call generate, $(1))
$(file >> $@, #define RC_FILENAME "$(notdir $(1:.rc=.exe))")
$(file >> $@, #define RC_DESCRIPTION "$(strip $(2))")
$(file >> $@, $(rc_common))
$(file >> $@, $(3))
endef
#
# Create a .res-file from a .rc-file:
#
define create_res
rc -nologo $(RCFLAGS) -Fo./$(strip $(1)) $(2)
@echo
endef
#
# Create a responce-file:
#
define create_rsp_file
$(file > $(1))
$(foreach f, $(2), $(file >> $(1),$(strip $(f))) )
endef
define generate
$(call green_msg,Generating $(strip $(1))...)
$(file > $(1),$(warning))
endef
define warning
/*
* DO NOT EDIT! This file was automatically generated
* from $(realpath $(THIS_FILE)) at $(DATE).
* Edit that file instead.
*/
endef
#
# Run Qt's moc (Meta Object Compiler) to produce a 'moc_*.cpp' file
# from any "Mocable" .h-file (a file with a 'Q_OBJECT' statement).
#
define create_moc
$(call green_msg,Generating $(strip $(1))\e[0m from $(BRIGHT_YELLOW)$(strip $(2)))
moc @$(OBJ_DIR)/moc.args -I. -o $(1) $(2)
@echo
endef
#
# The contents of '$(OBJ_DIR)/doxy_cfg.h' used in force-including on every compile.
#
define Doxy_cfg_H
#ifndef Doxy_CFG_H
#define Doxy_CFG_H
/* This generated file gets included for every compile
* via the '-FI$(OBJ_DIR)/doxy_cfg.h' option.
*/
#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0601)
#undef _WIN32_WINNT
#define _WIN32_WINNT 0x0601
#endif
#define _CRT_SECURE_NO_WARNINGS
#define _CRT_NONSTDC_NO_WARNINGS
#define _OS_WIN32 /* Needed? */
#define WIN32
#define LIBICONV_STATIC /* We use '../winbuild/iconv*.lib' which are static libraries */
#define NOMINMAX /* Do not define 'min()' + 'max()' via the below '<windows.h>' */
/* Compiling .cpp-files for 'Doxywizard.exe':
*/
#if defined(COMPILING_Doxywizard)
#define UNICODE
#define _UNICODE
#define QT_GUI_LIB
#define QT_CORE_LIB
#define QT_NO_CAST_FROM_ASCII
#define QT_NO_CAST_TO_ASCII
#endif
/* Running 'g++ -MM'
*/
#if defined(GCC_MAKE_DEPEND)
/*
* This value should match the value in the generated
* $$(Doxywizard_moc_SRC) files.
*/
#define Q_MOC_OUTPUT_REVISION 67
#endif
#if defined(NDEBUG)
#define QT_NO_DEBUG
#define QT_NO_DEBUG_OUTPUT
#else
#define DEBUG
#endif
#define _DLGSH_INCLUDED_ /* Avoid including '<um/dlgs.h>' */
#define MSCGEN_BOOL_H /* Avoid including '../libmscgen/mscgen_bool.h' */
//#include <math.h>
#include <stdio.h>
//#include <stdlib.h>
#include <windows.h>
#undef IN
#undef OUT
#define Boolean BOOL
#endif /* Doxy_CFG_H */
endef
define settings_H
#ifndef settings_H
#define settings_H
#define USE_SQLITE3 $(USE_SQLITE3)
#define USE_LIBCLANG $(USE_LIBCLANG)
#define IS_SUPPORTED(x) ( (USE_SQLITE3 && !strcmp("USE_SQLITE3",(x))) || \
(USE_LIBCLANG && !strcmp("USE_LIBCLANG",(x))) )
#endif /* settings_H */
endef
define lang_cfg_H
#ifndef lang_cfg_H
#define lang_cfg_H
#define ENGLISH_ONLY 1
#endif /* lang_cfg_H */
endef
define sqlite3_H
#ifndef sqlite3_H
#define sqlite3_H
/* A recent Win-Kit should have a compatible Sqlite3 library
*/
#include <winsqlite/winsqlite3ext.h>
#endif /* sqlite3_H */
endef
#
# Flex macro:
# arg1: $(1): the input .l-file to generate from.
#
define run_flex
$(call green_msg,Generating flex code from $(strip $(1)))
flex --outfile=$(OBJ_DIR)/$(strip $(1:.l=.cpp)) --header-file=$(OBJ_DIR)/$(strip $(1:.l=.l.h)) $(1)
@echo
endef
#
# Flex macro ythat prints to stdout:
# arg1: $(1): the input .l-file to generate from.
# arg2: $(2): the output .cpp-file to generate.
#
define run_flex_stdout
$(call generate, $(strip $(2)))
flex --stdout $(strip $(1)) >> $(2)
@echo
endef
#
# Bison macro:
# arg1: $(1): the output .c/.cpp-file to generate.
# arg2: $(2): the output .h/.hpp-file to generate.
# arg3: $(3): the input .y-file to generate from.
#
define run_bison
$(call green_msg,Generating bison code from $(strip $(3)))
bison --yacc --output=$(strip $(1)) --defines=$(strip $(2)) $(3)
endef
#
# 'python scan_states.py' macro:
# arg1: $(1): the output .l.h-file to generate.
# arg2: $(2): the input .l-file to generate from.
#
define run_scan_states
$(call generate, $(1))
$(PYTHON) scan_states.py $(2) >> $(1)
endef
#
# 'python configgen.py -command' macro:
# arg1: $(1): the output .cpp/.h-file to generate.
# arg2: $(2): the configgen.py command; -doc|-cpp|-wiz|-maph|-maps
#
define run_configgen
$(call green_msg,Generating $(strip $(1)))
$(PYTHON) configgen.py $(2) config.xml > $(1)
@echo
endef
#
# Common content for all generated .rc-files:
#
define rc_common
#include <winver.h>
#define RC_VERSION $(VER_MAJOR),$(VER_MINOR),$(VER_PATCH),0
#define RC_VER_STR "$(VER_MAJOR).$(VER_MINOR).$(VER_PATCH)"
#if defined(__clang__)
#define RC_HOST "clang"
#else
#define RC_HOST "MSVC"
#endif
#if defined(_DEBUG)
#define RC_DEBUG "debug"
#else
#define RC_DEBUG "release"
#endif
VS_VERSION_INFO VERSIONINFO
FILEVERSION RC_VERSION
PRODUCTVERSION RC_VERSION
FILEFLAGSMASK 0x3fL
FILEFLAGS 0
FILEOS VOS__WINDOWS32
FILETYPE VFT_APP
FILESUBTYPE 0
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "FileDescription", RC_DESCRIPTION
VALUE "FileVersion", RC_VER_STR
VALUE "InternalName", RC_FILENAME " (" RC_HOST ", " RC_DEBUG ")"
VALUE "LegalCopyright", "GNU GENERAL PUBLIC LICENSE v2"
VALUE "OriginalFilename", RC_FILENAME
VALUE "ProductName", RC_FILENAME
VALUE "ProductVersion", RC_VER_STR
VALUE "Comments", "Built on $(DATE) using " RC_HOST " by <gvanem@yahoo.no>"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
endef
define cpp_filter_py
import sys, os
try:
import ntpath
except ImportError as e:
print ("Failed to import ntpath: %s" % e)
sys.exit(1)
def _win32_abspath (path):
path = ntpath.abspath (path)
return path.replace ('\\', '/')
def skip_cwd (s1, s2):
''' Skip the leading part that is in common with s1 and s2
'''
i = 0
while i < len(s1) and s1[i] == s2[i]:
i += 1
return s2[i:]
cwd = _win32_abspath (os.getcwd()) + '/'
last_line = '??'
last_fname = '??'
empty_lines = 0
while True:
line = sys.stdin.readline()
if not line:
break
if line.startswith('\n') or line.startswith('\r'):
empty_lines += 1
continue
if line.lstrip().startswith("#line"):
line = line.replace ("\\\\", "/")
fname = None
quote = line.find ('\"')
if line.startswith ("#line ") and quote > 0:
fname = _win32_abspath (line[quote:])
last_fname = fname
if line.strip() != '' and last_line != '':
if fname is None or fname != last_fname:
print (line, end="")
if line.strip() == '}' or line.strip() == '};': # Print a newline after a functions or structs
print ("")
last_line = line
if empty_lines > 0:
sys.stderr.write ("Removed %d empty lines." % empty_lines)
endef
-include $(DEP_FILE)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment