Skip to content

Instantly share code, notes, and snippets.

@gvanem
Last active January 24, 2018 22:06
Show Gist options
  • Save gvanem/cb9337074774e73a85e7efdad5084586 to your computer and use it in GitHub Desktop.
Save gvanem/cb9337074774e73a85e7efdad5084586 to your computer and use it in GitHub Desktop.
GNU-makefile for GPedict: https://github.com/csete/gpredict.git
#
# Gpredict Makefile for MinGW, MSVC and clang-cl.
# Needs GNUmake v4+.
#
# By G. Vanem <gvanem@yahoo.no> 2016.
#
THIS_FILE = Makefile.Windows
#
# Ideally use:
# cd ../Git-latest
# git describe | grep -oe '[0-9\.]*' | sed etc.
#
VERSION_MAJOR = 2
VERSION_MINOR = 0
VERSION_MICRO = 12
VERSION = $(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_MICRO)
DATE := $(shell date +%d-%B-%Y)
PYTHON ?= python
#
# Change paths to suite (Glib 1.x and GTK 1.x are NOT supported).
#
# GooCanvas is available from:
# http://sourceforge.net/projects/goocanvas/
#
# Set it's INCLUDE-root in the Gtk+/Glib tree below.
#
GTK_ROOT ?= f:/ProgramFiler/Gtk-Plus/Gtk3-3.6.4
USE_CRT_DEBUG ?= 0
USE_NLS ?= 0
USE_WSOCK_TRACE ?= 1
USE_GUI_FLAG ?= 0
USE_MANIFEST ?= 0
USE_GNU_INDENT ?= 0
USE_CLANG_FORMAT ?= 1
VPATH = ../win32 sgpsdp nxjson
define USAGE
Usage: "make -f $(THIS_FILE) [CC=gcc | cl | clang-cl] [all | clean | vclean | depend]")
Specify CC=gcc - use MinGW
Specify CC=cl - use MSVC
Specify CC=clang-cl - use clang-cl
endef
#
# The following codes used in macro 'colour_msg' assumes you have
# MSys/Cygwin's echo with colour support.
#
LIGHT_RED = \e[1;31m
LIGHT_GREEN = \e[1;32m
LIGHT_YELLOW = \e[1;33m
colour_msg = @echo -e "$(1)\e[0m"
ifeq ($(CC),gcc)
USE_MANIFEST = 0
CFLAGS = -m32 -O2 -Wall
LDFLAGS = -m32 -s -Wl,--print-map,--sort-common,--cref
O = o
OBJ_DIR = MinGW_obj
ex_lib_names = $(1)
else ifeq ($(CC),cl)
O = obj
OBJ_DIR = MSVC_obj
ex_lib_names = $(2)
else ifeq ($(CC),clang-cl)
export CL=
O = obj
OBJ_DIR = Clang_obj
ex_lib_names = $(2)
else
$(error $(USAGE))
endif
ifeq ($(CC),gcc)
CFLAGS += --include ./build-config.h
ifeq ($(USE_GUI_FLAG),1)
LDFLAGS += -Wl,--subsystem,windows
endif
else
CFLAGS = -nologo -FI./build-config.h
LDFLAGS = -nologo -debug -verbose -incremental:no -map
ifeq ($(USE_GUI_FLAG),1)
LDFLAGS += -subsystem:windows
endif
endif
RCFLAGS = -I../win32 -I$(OBJ_DIR) \
-DVERMAJ=$(VERSION_MAJOR) \
-DVERMIN=$(VERSION_MINOR) \
-DVERBLD=$(VERSION_MICRO)
default: all
ifeq ($(USE_MANIFEST),1)
SOURCES = manifest.c
$(PROGRAM): LDFLAGS += -manifest
define add_manifest
mt -nologo -manifest $(1).manifest -outputresource:"$(strip $(1));1"
endef
manifest.c: $(THIS_FILE)
$(call colour_msg,Generating $(LIGHT_GREEN)$@)
$(file > $@, $(MANIFEST_C))
define MANIFEST_C
/*
* This file was generated by $(realpath $(THIS_FILE)) at $(DATE).
* DO NOT EDIT!
*/
#pragma comment (linker, "/manifestdependency:type='win32'")
#pragma comment (linker, "/manifestdependency:name='Microsoft.VC140.CRT'")
#pragma comment (linker, "/manifestdependency:version='19.11.25507.1'")
#pragma comment (linker, "/manifestdependency:processorArchitecture='$(CPU)'")
#pragma comment (linker, "/manifestdependency:publicKeyToken='1fc8b3b9a1e18e3b'")
endef
else
RCFLAGS += -DRC_NO_MANIFEST
endif
CFLAGS += -I. -I./$(OBJ_DIR) -I../win32 \
-I$(GTK_ROOT)/lib/glib-2.0/include \
-I$(GTK_ROOT)/lib/gtk-2.0/include \
-I$(GTK_ROOT)/include \
-I$(GTK_ROOT)/include/glib-2.0 \
-I$(GTK_ROOT)/include/gtk-2.0 \
-I$(GTK_ROOT)/include/gdk-pixbuf-2.0 \
-I$(GTK_ROOT)/include/cairo \
-I$(GTK_ROOT)/include/pango-1.0 \
-I$(GTK_ROOT)/include/atk-1.0 \
-I$(GTK_ROOT)/include/goocanvas-2.0.2/goocanvas
ifeq ($(CC),gcc)
CFLAGS += -Wno-deprecated-declarations -Wno-format
else
CFLAGS += -Zi -W3 -EHa -GF -DWIN32
ifeq ($(CC),cl)
CFLAGS += -wd4018 -wd4996 -wd4244
else
CFLAGS += -Wno-deprecated-declarations
endif
ifeq ($(USE_CRT_DEBUG),1)
CFLAGS += -MDd -Od -Oi- -RTCs -RTCu -GS
else
CFLAGS += -MD -Ox -Oy -GS- # -DNDEBUG
endif
endif
SOURCES += about.c \
compat.c \
first-time.c \
gpredict-help.c \
gpredict-utils.c \
gtk-event-list-popup.c \
gtk-event-list.c \
gtk-freq-knob.c \
gtk-polar-view-popup.c \
gtk-rig-ctrl.c \
gtk-rot-ctrl.c \
gtk-rot-knob.c \
gtk-sat-data.c \
gtk-sat-list-popup.c \
gtk-sat-list.c \
gtk-sat-map-ground-track.c \
gtk-sat-map-popup.c \
gtk-sat-map.c \
gtk-sat-module-popup.c \
gtk-sat-module-tmg.c \
gtk-sat-module.c \
gtk-sat-popup-common.c \
gtk-sat-selector.c \
gtk-single-sat.c \
gtk-sky-glance.c \
gui.c \
loc-tree.c \
locator.c \
main.c \
map-selector.c \
map-tools.c \
menubar.c \
mod-cfg-get-param.c \
mod-cfg.c \
mod-mgr.c \
orbit-tools.c \
pass-popup-menu.c \
pass-to-txt.c \
predict-tools.c \
print-pass.c \
qth-data.c \
qth-editor.c \
radio-conf.c \
rotor-conf.c \
sat-cfg.c \
sat-info.c \
sat-log-browser.c \
sat-log.c \
sat-monitor.c \
sat-pass-dialogs.c \
sat-pref-conditions.c \
sat-pref-debug.c \
sat-pref-formats.c \
sat-pref-general.c \
sat-pref-interfaces.c \
sat-pref-layout.c \
sat-pref-list-view.c \
sat-pref-map-view.c \
sat-pref-modules.c \
sat-pref-multi-pass.c \
sat-pref-polar-view.c \
sat-pref-predict.c \
sat-pref-qth-editor.c \
sat-pref-qth.c \
sat-pref-refresh.c \
sat-pref-rig-editor.c \
sat-pref-rig.c \
sat-pref-rot-editor.c \
sat-pref-rot.c \
sat-pref-single-pass.c \
sat-pref-single-sat.c \
sat-pref-sky-at-glance.c \
sat-pref-tle.c \
sat-pref.c \
sat-vis.c \
save-pass.c \
strnatcmp.c \
time-tools.c \
tle-tools.c \
tle-update.c \
trsp-conf.c \
trsp-update.c
SOURCES += gtk-azel-plot.c \
gtk-polar-plot.c \
gtk-polar-view.c
SOURCES += $(addprefix sgpsdp/, \
sgp4sdp4.c \
sgp_in.c \
sgp_math.c \
sgp_obs.c \
sgp_time.c \
solar.c)
SOURCES += nxjson/nxjson.c \
../win32/win32-fetch.c
OBJECTS = $(addprefix $(OBJ_DIR)/, \
$(notdir $(SOURCES:.c=.$(O))))
EX_LIBS = $(call ex_lib_names, \
$(addprefix $(GTK_ROOT)/lib/, \
libgoocanvas-2.0.a \
libgdk-3.dll.a \
libgdk_pixbuf-2.0.dll.a \
libgtk-3.dll.a \
libpango-1.0.dll.a \
libatk-1.0.dll.a \
libcairo.dll.a \
libpangocairo-1.0.dll.a), \
$(addprefix $(GTK_ROOT)/lib/, \
gdk-win32-3.0.lib \
gdk_pixbuf-2.0.lib \
gtk-win32-3.0.lib \
pango-1.0.lib \
atk-1.0.lib \
cairo.lib \
pangocairo-1.0.lib \
libgoocanvas-2.0.a))
EX_LIBS += $(call ex_lib_names, \
$(addprefix $(GTK_ROOT)/lib/, \
libglib-2.0.dll.a \
libgmodule-2.0.dll.a \
libgobject-2.0.dll.a \
libgthread-2.0.dll.a), \
$(addprefix $(GTK_ROOT)/lib/, \
glib-2.0.lib \
gmodule-2.0.lib \
gobject-2.0.lib \
gthread-2.0.lib))
ifeq ($(USE_NLS),1)
EX_LIBS += $(GTK_ROOT)/lib/libintl.dll.a
CFLAGS += -DENABLE_NLS
endif
EX_LIBS += $(call ex_lib_names, -lwininet, wininet.lib)
ifeq ($(USE_WSOCK_TRACE),1)
EX_LIBS += $(call ex_lib_names, -lwsock_trace, wsock_trace.lib)
else
EX_LIBS += $(call ex_lib_names, -lws2_32, ws2_32.lib)
endif
PROGRAM = ../gpredict.exe
GENERATED = $(CC).args build-config.h
ifneq ($(CC),gcc)
GENERATED += $(OBJ_DIR)/unistd.h $(OBJ_DIR)/sys/time.h
endif
################################################################################
all: prelude $(OBJ_DIR) $(GENERATED) $(PROGRAM) copy_files
@echo 'Welcome to Gpredict (CC=$(CC)).'
prelude:
@echo 'Building Gpredict $(VERSION).'
cl.args clang-cl.args: $(THIS_FILE)
$(call colour_msg,All CFLAGS are in $(LIGHT_GREEN)$@)
$(call make_resp_file, $@, $(CFLAGS) -Fo$(OBJ_DIR)\\)
gcc.args: $(THIS_FILE)
$(call colour_msg,All CFLAGS are in $(LIGHT_GREEN)$@)
$(call make_resp_file, $@, $(CFLAGS))
$(OBJ_DIR) $(OBJ_DIR)/sys:
- @mkdir $@
../gpredict.exe: $(OBJECTS) $(OBJ_DIR)/gpredict.res
$(call link_EXE, $@, $^ $(EX_LIBS))
$(call add_manifest, $@)
clean:
rm -f $(OBJ_DIR)/*.$(O) $(OBJ_DIR)/gpredict.res $(GENERATED) depend.args vc1*.pdb
rm -f manifest.c $(PROGRAM).manifest cpp_filter.py $(notdir $(SOURCES:.c=.i))
- rmdir $(OBJ_DIR)/sys $(OBJ_DIR)
vclean realclean: clean
rm -f $(PROGRAM) $(PROGRAM:.exe=.map) $(PROGRAM:.exe=.pdb) .depend.Windows
@echo 'Remember to "make -f $(THIS_FILE) depend" before a normal make.'
$(OBJ_DIR)/unistd.h: $(OBJ_DIR)
$(call colour_msg,Generating $(LIGHT_GREEN)$@)
@echo '/* Dummy <unistd.h> for MSVC */' > $@
$(OBJ_DIR)/sys/time.h: $(OBJ_DIR)/sys
$(call colour_msg,Generating $(LIGHT_GREEN)$@)
@echo '/* Dummy <sys/time.h> for MSVC */' > $@
@echo '#include <time.h>' >> $@
$(OBJ_DIR)/gpredict.res: ../win32/gpredict.rc $(OBJ_DIR)/gpredict.exp.manifest
$(call make_res, $@, $<)
$(OBJ_DIR)/gpredict.exp.manifest: ../win32/gpredict.exe.manifest
sed -e 's/VERSION_STRL/$(VERSION).0/' < $< > $@
build-config.h: $(THIS_FILE)
$(call colour_msg,Generating $(LIGHT_YELLOW)$@)
@echo "$$BUILD_CONFIG_H_FILE" > $@
$(OBJ_DIR)/%.obj: %.c
$(CC) -c @$(CC).args $<
$(OBJ_DIR)/%.o: %.c
$(CC) -c @gcc.args -o $@ $<
define BUILD_CONFIG_H_FILE
/*
* This file was generated by $(realpath $(THIS_FILE)) at $(DATE).
* DO NOT EDIT!
*/
#ifndef _GPREDICT_CONFIG_H
#define _GPREDICT_CONFIG_H
#define GETTEXT_PACKAGE "gpredict"
#if defined(RC_INVOKED)
/* to-do: put all the versioning junk here and
* generate an $(OBJ_DIR)/gpredict.rc.
*/
#else /* Rest of file */
#define GDK_VERSION_MIN_REQUIRED GDK_VERSION_3_4
#define _USE_MATH_DEFINES /* for 'M_PI' in MSVC's <math.h> */
#define WIN32_LEAN_AND_MEAN /* Do not include unneeded files in <windows.h> */
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0501
#endif
#if defined(_MSC_VER) || defined(__clang__)
#define _CRT_SECURE_NO_DEPRECATE
#define _CRT_NONSTDC_NO_DEPRECATE
#endif
#include <string.h>
#if !defined(ENABLE_NLS)
#include <libintl.h>
#include <glib/gi18n.h>
#undef sprintf
#undef fprintf
#undef snprintf
#undef vsnprintf
#undef setlocale
#include <stdio.h>
#include <locale.h>
#undef _
#undef Q_
#define _(String) String
#define Q_(String) String
#endif
#if defined(_MSC_VER) || defined(__clang__)
#include <glib.h>
#include <glib/gstdio.h>
#undef fopen
#define g_fopen(fname, mode) (fopen) (fname, mode)
#define strncasecmp(s1, s2, n) _strnicmp(s1, s2, n)
#endif
#define VERSION "$(VERSION)"
#endif /* RC_INVOKED */
#endif /* _GPREDICT_CONFIG_H */
endef
export BUILD_CONFIG_H_FILE
#
# Include these for 'copy_files' target.
#
include ../data/Makefile.am
include ../data/satdata/Makefile.am
include ../pixmaps/maps/Makefile.am
include ../pixmaps/icons/Makefile.am
include ../pixmaps/logos/Makefile.am
#
# Destination directories:
#
GP_DIRS = $(addprefix share/gpredict/, \
data \
data/satdata \
pixmaps/icons \
pixmaps/logos \
pixmaps/maps)
#
# Source files:
#
GP_DATA = $(addprefix data/, $(gpredict_dat_DATA))
GP_SAT_DATA = $(addprefix data/satdata/, $(gpredict_sat_DATA))
GP_ICONS = $(addprefix pixmaps/icons/, $(gpredict_icons_DATA))
GP_LOGOS = $(addprefix pixmaps/logos/, $(gpredict_logos_DATA))
GP_MAPS = $(addprefix pixmaps/maps/, $(gpredict_maps_DATA))
GP_SHARE_FILES =$(GP_DATA) $(wildcard $(GP_SAT_DATA)) $(GP_ICONS) $(GP_LOGOS) $(GP_MAPS))
copy_files:
$(call colour_msg,$(LIGHT_GREEN)Copying $(words $(GP_SHARE_FILES)) needed files into $(LIGHT_RED)../share)
cd .. ; \
cp --update COPYING doc/COPYING.txt ; \
cp --update NEWS doc/NEWS.txt ; \
mkdir --parents $(GP_DIRS) ; \
cp --update $(GP_DATA) share/gpredict/data ; \
cp --update $(GP_SAT_DATA) share/gpredict/data/satdata ; \
cp --update $(GP_ICONS) share/gpredict/pixmaps/icons ; \
cp --update $(GP_LOGOS) share/gpredict/pixmaps/logos ; \
cp --update $(GP_MAPS) share/gpredict/pixmaps/maps
#
# Link macro:
# arg1, $(1): The name of the produced EXE.
# arg2, $(2): The rest of the link arguments.
#
define link_EXE
$(call colour_msg,Linking $(LIGHT_GREEN)$(strip $(1)))
$(call link_EXE_$(CC), $(1), $(2))
endef
define link_EXE_cl
link $(LDFLAGS) -out:$(strip $(1)) $(2) > link.tmp
cat link.tmp >> $(1:.exe=.map)
rm -f link.tmp
endef
link_EXE_gcc = $(CC) $(LDFLAGS) -o $(1) $(2) > $(1:.exe=.map)
link_EXE_clang-cl = $(call link_EXE_cl, $(1), $(2))
#
# Make a .res file:
# arg1, $(1): The .res-file
# arg2, $(2): The .rc-file
#
define make_res
$(call colour_msg,Generating resource $(LIGHT_YELLOW)$(strip $(1)))
$(call make_res_$(CC), $(1), $(2))
@echo
endef
make_res_gcc = windres -O COFF --target=pe-i386 $(RCFLAGS) -o $(1) $(2)
make_res_cl = rc -nologo -r $(RCFLAGS) -fo $(1) $(2)
make_res_clang-cl = $(call make_res_cl, $(1), $(2))
#
# Make a response file:
# arg1, $(1): The name of the response file
# arg2, $(2): The content for the response file.
#
define make_resp_file
$(file > $(1))
$(foreach f, $(2), $(file >> $(1),$(strip $(f))) )
endef
cpp_filter.py: $(GENERATED) $(THIS_FILE)
@echo 'Generating $@...'
$(file > $@,#!/usr/env/python)
$(file >> $@,#)
$(file >> $@,# DO NOT EDIT! This file was generated automatically from)
$(file >> $@,# $(realpath $(THIS_FILE)))
$(file >> $@,# at $(DATE).)
$(file >> $@,# Edit that files instead.)
$(file >> $@,#)
$(file >> $@,if 1:)
$(file >> $@,$(CPP_FILTER_PY))
#
# Command to generate a nicer C preprocessed output
# with the help of 'cpp_filter.py' and optionally 'GNU indent' or 'clang-format'.
#
ifeq ($(USE_GNU_INDENT),1)
C_FORMATER = | indent -st
else ifeq ($(USE_CLANG_FORMAT),1)
C_FORMATER = | clang-format -style=Mozilla -assume-filename=c
else
C_FORMATER =
endif
C_preprocess = $(CC) -E @$(CC).args $(1) | $(PYTHON) cpp_filter.py $(C_FORMATER) > $(2)
%.i: %.c FORCE cpp_filter.py
$(call C_preprocess, $<, $@)
@echo
FORCE: ;
define CPP_FILTER_PY
#
# A tool used in "$$(CC) -E" rules in Common.Windows.
# It's used to remove empty preproessor lines and make the
# output a bit more readable.
#
import sys, os
try:
import ntpath
except ImportError, 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')) and last_line[0] == '\r':
empty_lines += 1
continue
line = line.replace ("\\\\", "/")
line = line.replace ('\\', '/')
fname = None
quote = line.find ('\"')
if line.startswith ("#line ") and quote > 0:
fname = _win32_abspath (line[quote:])
last_fname = fname
line = line [:quote] + skip_cwd (cwd, fname)
if line.strip() != '' and last_line != '':
if fname is None or fname != last_fname:
print (line),
last_line = line
if empty_lines > 0:
sys.stderr.write ("Removed %d empty lines." % empty_lines)
endef
DEP_REPLACE = sed -e 's/\(.*\)\.o: /\n$$(OBJ_DIR)\/\1.$$(O): /' \
-e 's@$(GTK_ROOT)@$$(GTK_ROOT)@'
DEP_CFLAGS = -MM $(filter -I%, $(CFLAGS))
depend: $(GENERATED)
$(call colour_msg,$(LIGHT_GREEN)Generating dependencies for $(words $(SOURCES)) source-files...)
$(call make_resp_file, depend.args, $(DEP_CFLAGS) $(SOURCES))
$(file > .depend.Windows, #)
$(file >> .depend.Windows, # DO NOT EDIT! This file was generated automatically)
$(file >> .depend.Windows, # from $(realpath $(THIS_FILE)))
$(file >> .depend.Windows, # at $(DATE).)
$(file >> .depend.Windows, #)
gcc @depend.args $(SOURCES) | $(DEP_REPLACE) >> .depend.Windows
-include .depend.Windows
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment