Skip to content

Instantly share code, notes, and snippets.

@gvanem
Last active August 21, 2020 11:02
Show Gist options
  • Select an option

  • Save gvanem/9c2fa42519e790b3bd20479f0dd7b4c7 to your computer and use it in GitHub Desktop.

Select an option

Save gvanem/9c2fa42519e790b3bd20479f0dd7b4c7 to your computer and use it in GitHub Desktop.
A GNU-makefile for Net-SNMP. Targeting MinGW32, MSVC or clang-cl. 32-bit only.
#
# Net-SNMP Makefile for MinGW32, MSVC or clang-cl.
#
# By Gisle Vanem <[email protected]>.
#
# Also found here:
# https://gist.githubusercontent.com/gvanem/9c2fa42519e790b3bd20479f0dd7b4c7/raw/9acc048f75bd7ef73598030fad3bd640dfc712da/Makefile.Windows
#
THIS_FILE = Makefile.Windows
TODAY := $(shell date +%d-%B-%Y)
comma := ,
VERSION_MAJOR = $(shell grep -m1 -oP '\[\d+\.\d+]' configure.ac | sed -e 's/\.[0-9]\]//' -e 's/\[//')
VERSION_MINOR = $(shell grep -m1 -oP '\[\d+\.\d+]' configure.ac | sed -e 's/\[[0-9].//' -e 's/\]//')
VERSION_MAJOR = 5
VERSION_MINOR = 10
VERSION = $(VERSION_MAJOR).$(VERSION_MINOR)
#
# Change these 'x_ROOT' to suite:
#
MINGW_ROOT = $(realpath $(MINGW32))
WATT32_ROOT = $(realpath $(WATT_ROOT))
LIBSSH2_ROOT ?= $(MINGW_ROOT)/src/inet/Crypto/libssh2
OPENSSL_ROOT ?= $(MINGW_ROOT)/src/inet/Crypto/OpenSSL
PCRE_ROOT ?= $(MINGW_ROOT)/src/RegExp/libpcre
REGEX_ROOT ?= $(MINGW_ROOT)/src/RegExp/regex-0.12
#
# Options:
# change to suite. Do a 'make clean' after changing any of these.
#
# The base-directory for 'install'.
#
INSTALL_BASE ?= $(realpath .)/build
#
# Disable all "write-support".
#
NETSNMP_NO_WRITE_SUPPORT ?= 0
#
# Include OpenSSL support?
#
USE_OPENSSL ?= 0
#
# Include SSH2 support?
#
USE_LIBSSH2 ?= 0
#
# Use the tracing 'wsock_trace.lib' which MUST be on %LIB path.
# For MSVC or clang-cl only.
# Ref: https://github.com/gvanem/wsock-trace
#
USE_WSOCK_TRACE ?= 1
#
# Will set 'NETSNMP_ALWAYS_DEBUG' to '0' or '1'.
#
# to-do: Will set 'NETSNMP_FEATURE_CHECKING' to '1'.
# Currently broken.
#
USE_SNMP_DEBUG ?= 0
#
# Enable Regexp searches?
#
USE_REGEX ?= 1
#
# Enable PCRE searches?
#
USE_PCRE ?= 1
#
# Build the Python module?
#
USE_PYTHON ?= 1
#
# And use Python v3?
#
USE_PYTHON3 ?= 1
#
# Use the Watt-32 tcp/ip stack? (and not Winsock2).
#
USE_WATT32 ?= 0
#
# Link to '$(STATIC_LIB)' for all programs and the 'client_intf.pyd' module?
#
USE_STATIC_LIBS ?= 0
#
# Compile many source-files in one go.
# MSVC only.
#
USE_MP_COMPILE ?= 1
#
# Use maximum warnings with 'clang-cl'. There a lots!
#
MAX_CLANG_WARNINGS ?= 0
#
# Use 'clang-format' to generate a nicer preprocessed C-output.
#
USE_CLANG_FORMAT ?= 1
#
# Use Python v3.x for 'python/netsnmp/client_intf.c' when 'USE_PYTHON=1'.
#
ifeq ($(USE_PYTHON3),1)
PYTHON = py -3
else
PYTHON = py -2
endif
PYTHON_ROOT := $(realpath $(shell $(PYTHON) -c "import sys; print(sys.prefix)"))
PYTHON_VER := $(shell $(PYTHON) -c "import sys; print(sys.version[0:3].replace('.',''))")
#
# Where to build files from 'python_build_1':
#
PY_TARGETS_DIR = $(PYTHON_ROOT)/Lib/site-packages/netsnmp
define Usage
Usage: "make -f $(THIS_FILE) CC=[cl | clang-cl | gcc] [all | clean | vclean | realclean | depend | install]"
Specify CC=gcc - use MinGW32
Specify CC=cl - use MSVC
Specify CC=clang-cl - use clang-cl
endef
export Usage
VPATH = snmplib \
snmplib/transports \
apps \
agent \
$(addprefix agent/, \
helpers \
mibgroup \
$(addprefix mibgroup/, \
mibII \
ucd-snmp \
utilities \
agent \
agentx \
snmpv3 \
target \
examples \
snmp-notification-mib/snmpNotifyFilterTable \
notification \
notification-log-mib))
ifeq ($(USE_PYTHON),1)
VPATH += python/netsnmp
endif
#
# These directories are generated by 'install'.
#
# Hence, no need to create the intermediate directories first.
#
INSTALL_DIRS = $(addprefix $(INSTALL_BASE)/, \
bin \
lib \
temp \
etc/snmp \
snmp/persist \
include/net-snmp \
include/ucd-snmp)
INSTALL_DIRS += $(addprefix $(INSTALL_BASE)/share/snmp/, \
mibs \
snmpconf-data \
snmpconf-data/snmp-data \
snmpconf-data/snmpd-data \
snmpconf-data/snmptrapd-data \
mib2c-data)
#
# The files './win32/net-snmp/net-snmp-config.h' and
# './win32/snmpsm_init.h' are NOT used.
#
# Instead these are generated by the huge 'define net_snmp_config_h'
# variable below.
#
GENERATED = include/net-snmp/net-snmp-config.h \
include/snmpsm_init.h
#
# The following ANSI-codes assumes you have MSys/Cygwin's echo with colour support.
#
BRIGHT_GREEN = \e[1;32m
BRIGHT_YELLOW = \e[1;33m
colour_msg = @echo -e "$(1)\e[0m"
green_msg = $(call colour_msg,$(BRIGHT_GREEN)$(strip $(1)))
yellow_msg = $(call colour_msg,$(BRIGHT_YELLOW)$(strip $(1)))
default: all
#
# Vendor specific flags.
#
ifeq ($(CC),gcc)
O = o
CFLAGS = -m32 -O2 -Dmingw32
LDFLAGS = -m32 -Wl,--print-map,--sort-common,--cref # -s
BUILDER = MinGW32
MSVC_TYPE = 0
USE_MP_COMPILE = 0
RCFLAGS = -O COFF -D__MINGW32__ --target=pe-i386
else ifeq ($(CC),cl)
BUILDER = MSVC
MSVC_TYPE = 1
RCFLAGS = -nologo -D_MSC_VER
else ifeq ($(CC),clang-cl)
export CL=
BUILDER = clang-cl
MSVC_TYPE = 1
USE_MP_COMPILE = 0
RCFLAGS = -nologo -D__clang__
else
$(error $(Usage))
endif
RCFLAGS += -DUSER=$(USER)
RC_FEATURES =
#
# E.g 'OBJ_DIR = MSVC_obj'
#
OBJ_DIR = $(BUILDER)_obj
ifeq ($(MSVC_TYPE),1)
O = obj
CFLAGS = -nologo -MD -W3 -Z7 -Zo- -DWIN32
LDFLAGS = -nologo -subsystem:console -verbose -incremental:no -map -debug -machine:x86
CFLAGS += -D_CRT_SECURE_NO_DEPRECATE \
-D_CRT_NONSTDC_NO_WARNINGS
select_lib = $(1)
else
select_lib = $(2)
endif
#
# Return a list of .$(O)-files from .c-files.
#
C_to_obj = $(addprefix $(OBJ_DIR)/, \
$(notdir $(1:.c=.$(O))))
#
# CFLAGS common to all 3 'BUILDER's.
#
CFLAGS += -I./include \
-I./snmplib \
-I./win32 \
-I./agent \
-I./agent/mibgroup \
# -DINSTALL_BASE=\"$(INSTALL_BASE)\"
#
# Warning control for MSVC + clang
#
ifeq ($(CC),cl)
CFLAGS += -wd4005 -wd4018 -wd4101 -wd4133 -wd4244 -wd4267
else ifeq ($(CC),clang-cl)
CFLAGS += -Wall
ifneq ($(MAX_CLANG_WARNINGS),1)
CFLAGS += -Wno-conversion \
-Wno-sign-conversion \
-Wno-sign-compare \
-Wno-conditional-uninitialized \
-Wno-double-promotion \
-Wno-documentation \
-Wno-documentation-unknown-command \
-Wno-reserved-id-macro \
-Wno-nonportable-system-include-path \
-Wno-missing-braces \
-Wno-missing-variable-declarations \
-Wno-missing-field-initializers \
-Wno-missing-prototypes \
-Wno-cast-align \
-Wno-format-nonliteral \
-Wno-unreachable-code-break \
-Wno-microsoft-redeclare-static \
-Wno-language-extension-token \
-Wno-tautological-type-limit-compare \
-Wno-unused-parameter \
-Wno-unused-macros \
-Wno-unused-variable \
-Wno-undef \
-Wno-comma \
-Wno-cast-qual \
-Wno-gnu-folding-constant \
-Wno-strict-prototypes \
-Wno-bad-function-cast \
-Wno-extra-semi-stmt \
-Wno-covered-switch-default \
-Wno-implicit-fallthrough \
-Wno-switch-enum
#
# This warning is rather important. So leave it enabled.
#
# CFLAGS += -Wno-shadow
#
endif
endif
ifeq ($(USE_SNMP_DEBUG),1)
CFLAGS += -DNETSNMP_ALWAYS_DEBUG=1 # -DNETSNMP_FEATURE_CHECKING=1
else
CFLAGS += -DNETSNMP_ALWAYS_DEBUG=0
#
# is this a good idea?
#
# CFLAGS += -DNETSNMP_NO_DEBUGGING
endif
#
# Support the SSH domain. Needs 'USE_OPENSSL=1' too.
# MinGW: libssh2.a must come before the OpenSSL libraries.
#
ifeq ($(USE_LIBSSH2),1)
ifneq ($(USE_OPENSSL),1)
$(error 'USE_LIBSSH2=1' also needs 'USE_OPENSSL=1'.)
endif
ifeq ($(USE_WATT32),1)
$(error 'USE_LIBSSH2=1' not possible with 'USE_WATT32=1'.)
endif
CFLAGS += -I$(LIBSSH2_ROOT)/include \
-DUSE_LIBSSH2 \
-DNETSNMP_TRANSPORT_SSH_DOMAIN
RC_FEATURES += SSH2-support,
DLL_LIBS = $(call select_lib, $(LIBSSH2_ROOT)/src/libssh2.lib, \
$(LIBSSH2_ROOT)/src/libssh2.a)
endif
ifeq ($(USE_OPENSSL),1)
CFLAGS += -DNETSNMP_USE_OPENSSL \
-I$(OPENSSL_ROOT)/include
RC_FEATURES += OpenSSL,
ifeq ($(USE_WATT32),1)
$(error 'USE_OPENSSL=1' not possible with 'USE_WATT32=1'.)
endif
DLL_LIBS += $(call select_lib, $(OPENSSL_ROOT)/lib32/libcrypto_imp.lib \
$(OPENSSL_ROOT)/lib32/libssl_imp.lib, \
$(OPENSSL_ROOT)/lib32/libcrypto.dll.a \
$(OPENSSL_ROOT)/lib32/libssl.dll.a)
endif
#
# I've put all .c-files into 1 .lib/.dll for easier maintanance.
#
LIB_SRC = $(addprefix snmplib/, \
asn1.c \
asprintf.c \
callback.c \
check_varbind.c \
container.c \
container_binary_array.c \
container_list_ssll.c \
container_null.c \
data_list.c \
default_store.c \
dir_utils.c \
fd_event_manager.c \
file_utils.c \
inet_ntop.c \
inet_pton.c \
int64.c \
keytools.c \
large_fd_set.c \
lcd_time.c \
md5.c \
mib.c \
mt_support.c \
oid_stash.c \
parse.c \
read_config.c \
scapi.c \
sd-daemon.c \
snmp.c \
snmpv3.c \
snmpusm.c \
snmp-tc.c \
snmp_alarm.c \
snmp_api.c \
snmp_auth.c \
snmp_client.c \
snmp_debug.c \
snmp_enum.c \
snmp_logging.c \
snmp_parse_args.c \
snmp_secmod.c \
snmp_service.c \
snmp_transport.c \
snmp_version.c \
strlcat.c \
strlcpy.c \
strtok_r.c \
system.c \
text_utils.c \
tools.c \
vacm.c \
ucd_compat.c)
ifneq ($(CC),gcc)
LIB_SRC += snmplib/closedir.c \
snmplib/opendir.c \
snmplib/readdir.c \
snmplib/getopt.c
endif
LIB_SRC += $(addprefix snmplib/transports/, \
snmpAliasDomain.c \
snmpCallbackDomain.c \
snmpIPBaseDomain.c \
snmpTCPDomain.c \
snmpTCPIPv6Domain.c \
snmpUDPDomain.c \
snmpIPv4BaseDomain.c \
snmpIPv6BaseDomain.c \
snmpUDPIPv4BaseDomain.c \
snmpUDPIPv6Domain.c \
snmpSocketBaseDomain.c \
snmpUDPBaseDomain.c \
snmpTCPBaseDomain.c)
ifeq ($(USE_LIBSSH2),1)
LIB_SRC += snmplib/transports/snmpSSHDomain.c
endif
ifeq ($(USE_OPENSSL),1)
LIB_SRC += $(addprefix snmplib/, \
cert_util.c \
snmp_openssl.c)
LIB_SRC += $(addprefix snmplib/transports/, \
snmpDTLSUDPDomain.c \
snmpTLSBaseDomain.c \
snmpTLSTCPDomain.c)
endif
ifeq ($(USE_WATT32),0)
LIB_SRC += snmplib/winpipe.c
endif
#
# I have no regex.lib. So just compile the single regex.c into LIB_OBJ.
#
ifeq ($(USE_REGEX),1)
CFLAGS += -I$(REGEX_ROOT) \
-DHAVE_REGEX_H=1 \
-DHAVE_REGCOMP=1
DLL_LIBS += $(call select_lib, $(REGEX_ROOT)/regex.lib, $(REGEX_ROOT)/libregex.a)
endif
ifeq ($(USE_PCRE),1)
CFLAGS += -I$(PCRE_ROOT) \
-DHAVE_PCRE_H=1
DLL_LIBS += $(call select_lib, $(PCRE_ROOT)/pcre.lib, $(PCRE_ROOT)/libpcre.a)
endif
LIB_OBJ = $(call C_to_obj, $(LIB_SRC))
LIB_I = $(notdir $(LIB_SRC:.c=.i))
$(LIB_OBJ) $(LIB_I): CFLAGS += -DNETSNMP_DLL_BUILDING
$(OBJ_DIR)/encode_keychange.$(O): CFLAGS += -Dssize_t=SSIZE_T
####################### Sources for snmptrapd.exe ###########################
SNMPTRAPD_SRC = \
$(addprefix apps/, snmptrapd.c snmptrapd_handlers.c \
snmptrapd_log.c) \
\
$(addprefix agent/, agent_handler.c agent_index.c agent_read_config.c \
agent_registry.c agent_trap.c auto_nlist.c kernel.c mib_modules.c \
snmp_agent.c snmp_vars.c \
mibgroup/notification-log-mib/notification_log.c) \
\
$(addprefix agent/helpers/, all_helpers.c bulk_to_next.c \
cache_handler.c debug_handler.c instance.c multiplexer.c null.c \
old_api.c read_only.c scalar.c scalar_group.c serialize.c table.c \
table_array.c table_data.c table_dataset.c table_iterator.c \
table_container.c watcher.c stash_cache.c stash_to_next.c) \
\
$(addprefix agent/mibgroup/notification/, snmpNotifyTable.c \
snmpNotifyFilterProfileTable.c) \
\
agent/mibgroup/snmp-notification-mib/snmpNotifyFilterTable/snmpNotifyFilterTable.c \
\
$(addprefix agent/mibgroup/, header_complex.c util_funcs.c) \
\
$(addprefix agent/mibgroup/agentx/, agentx_config.c subagent.c \
client.c protocol.c master.c master_admin.c) \
\
$(addprefix agent/mibgroup/agent/, nsCache.c nsDebug.c nsLogging.c \
nsModuleTable.c nsTransactionTable.c) \
\
$(addprefix agent/mibgroup/examples/, data_set.c delayed_instance.c \
example.c netSnmpHostsTable.c netSnmpHostsTable_checkfns.c \
netSnmpHostsTable_checkfns_local.c netSnmpHostsTable_access.c \
notification.c scalar_int.c ucdDemoPublic.c) \
\
$(addprefix agent/mibgroup/mibII/, at.c icmp.c interfaces.c ip.c \
ipAddr.c mta_sendmail.c route_write.c setSerialNo.c snmp_mib.c \
sysORTable.c system_mib.c tcp.c tcpTable.c udp.c udpTable.c \
vacm_context.c vacm_vars.c var_route.c vacm_conf.c) \
\
$(addprefix agent/mibgroup/snmpv3/, usmUser.c usmStats.c usmConf.c \
snmpEngine.c snmpMPDStats.c) \
\
$(addprefix agent/mibgroup/utilities/, override.c execute.c) \
\
$(addprefix agent/mibgroup/ucd-snmp/, errormib.c disk.c diskio.c \
file.c loadave.c dlmod.c proxy.c versioninfo.c \
extensible.c proc.c pass.c pass_persist.c) \
\
$(addprefix agent/mibgroup/target/, target.c snmpTargetAddrEntry.c \
snmpTargetParamsEntry.c target_counters.c) \
\
snmplib/winservice.c
####################### Sources for agentxtrap.exe ###########################
AGENTX_TRAP_SRC = \
apps/agentxtrap.c \
\
$(addprefix agent/mibgroup/agentx/, \
agentx_config.c \
subagent.c \
client.c \
protocol.c) \
\
$(addprefix agent/, \
agent_handler.c \
agent_index.c \
agent_read_config.c \
agent_registry.c \
agent_sysORTable.c \
agent_trap.c \
snmp_agent.c \
snmp_vars.c) \
\
$(addprefix agent/helpers/, \
all_helpers.c \
baby_steps.c \
bulk_to_next.c \
cache_handler.c \
debug_handler.c \
dummy.c \
instance.c \
mode_end_call.c \
multiplexer.c \
null.c \
old_api.c \
read_only.c \
row_merge.c \
scalar.c \
scalar_group.c \
serialize.c \
snmp_get_statistic.c \
stash_cache.c \
stash_to_next.c \
table.c \
table_array.c \
table_container.c \
table_data.c \
table_dataset.c \
table_generic.c \
table_iterator.c \
table_row.c \
table_tdata.c \
watcher.c)
################## Sources for standard SNMP applications ####################
APPS_SRC = $(addprefix apps/, \
snmpwalk.c \
snmptable.c \
snmpbulkget.c \
snmpbulkwalk.c \
snmpdelta.c \
snmpdf.c \
snmpget.c \
snmpgetnext.c \
snmpstatus.c \
snmptest.c \
snmptranslate.c \
snmptrap.c)
ifeq ($(NETSNMP_NO_WRITE_SUPPORT),1)
CFLAGS += -DNETSNMP_NO_WRITE_SUPPORT
else
APPS_SRC += apps/snmpset.c
endif
################## Sources for special SNMP applications ####################
#
# Impossible (?) on Windows:
#
# APPS_SRC += apps/agentxtrap.c
APPS_SRC += apps/encode_keychange.c
APPS_OBJ = $(call C_to_obj, $(APPS_SRC))
APPS_RES = $(APPS_OBJ:.$(O)=.res)
APPS_I = $(notdir $(APPS_SRC:.c=.i))
PROGRAMS = $(notdir $(APPS_SRC:.c=.exe))
#
# Not possible at the moment
#
# PROGRAMS += snmptrapd.exe \
# agentxtrap.exe
SNMPTRAPD_OBJ = $(call C_to_obj, $(SNMPTRAPD_SRC))
SNMPTRAPD_I = $(notdir $(SNMPTRAPD_SRC:.c=.i))
AGENTX_TRAP_OBJ = $(call C_to_obj, $(AGENTX_TRAP_SRC))
AGENTX_TRAP_I = $(notdir $(AGENTX_TRAP_SRC:.c=.i))
.SECONDARY: $(APPS_OBJ) $(APPS_RES)
DLL_FILE = netsnmp.dll
DEF_FILE = $(OBJ_DIR)/netsnmp.def
ifeq ($(USE_WATT32),1)
CFLAGS += -DUSE_WATT32 -I$(WATT32_ROOT)/inc -I$(WATT32_ROOT)/inc/w32-fakes
RC_FEATURES += Watt-32,
ifeq ($(USE_STATIC_LIBS),1)
CFLAGS += -DWATT32_STATIC
ifeq ($(CC),cl)
WS2_32 = $(WATT32_ROOT)/lib/x86/wattcpvc.lib
DLL_LIBS += user32.lib
else ifeq ($(CC),clang-cl)
WS2_32 = $(WATT32_ROOT)/lib/x86/wattcp_clang.lib
DLL_LIBS += user32.lib
else
WS2_32 = $(WATT32_ROOT)/lib/x86/libwatt32.a
endif
else
ifeq ($(CC),cl)
WS2_32 = $(WATT32_ROOT)/lib/x86/wattcpvc_imp.lib
else ifeq ($(CC),clang-cl)
WS2_32 = $(WATT32_ROOT)/lib/x86/wattcp_clang_imp.lib
else
WS2_32 = $(WATT32_ROOT)/lib/x86/libwatt32.dll.a
endif
endif
else
CFLAGS += -D_WINSOCK_DEPRECATED_NO_WARNINGS
endif
ifeq ($(MSVC_TYPE),1)
STATIC_LIB = netsnmp.lib
IMPORT_LIB = netsnmp_imp.lib
DLL_LIBS += advapi32.lib # iphlpapi.lib
ifeq ($(WS2_32),)
ifeq ($(USE_WSOCK_TRACE),1)
WS2_32 = wsock_trace.lib
else
WS2_32 = ws2_32.lib
endif
endif
else
STATIC_LIB = libnetsnmp.a
IMPORT_LIB = libnetsnmp.dll.a
DLL_LIBS += -liphlpapi -ladvapi32
ifeq ($(WS2_32),)
WS2_32 = -lws2_32
endif
endif
ifeq ($(USE_STATIC_LIBS),1)
APP_LIBS = $(STATIC_LIB)
APP_EX_LIBS = $(DLL_LIBS) $(WS2_32)
else
APP_LIBS = $(IMPORT_LIB)
APP_EX_LIBS = $(WS2_32)
APP_CFLAGS = -DNETSNMP_USE_DLL
endif
#
# Extend application CFLAGS depending on USE_STATIC_LIBS etc.
#
$(SNMPTRAPD_OBJ) $(SNMPTRAPD_I) \
$(APPS_OBJ) $(APPS_I): EXTRA_CFLAGS = $(APP_CFLAGS)
$(AGENTX_TRAP_OBJ) $(AGENTX_TRAP_I): EXTRA_CFLAGS = $(APP_CFLAGS) -DUSING_AGENTX_SUBAGENT_MODULE
all: $(OBJ_DIR) $(GENERATED) $(STATIC_LIB) $(DLL_FILE) $(PROGRAMS) \
python_build_$(USE_PYTHON) epilogue
epilogue:
$(call green_msg, Welcome to Net-SNMP ver. $(VERSION) $(BRIGHT_YELLOW)($(BUILDER)).)
$(OBJ_DIR):
- mkdir $@
#
# Not finished
#
install: $(OBJ_DIR)/net_snmp_install.sh
sh $<
######################## Rules for MAN-pages in 'man/' ##########################
MAN_1_DEF_FILES = $(wildcard man/*.1.def)
MAN_3_DEF_FILES = $(wildcard man/*.3.def)
MAN_5_DEF_FILES = $(wildcard man/*.5.def)
MAN_8_DEF_FILES = $(wildcard man/*.8.def)
MAN_PAGES = $(MAN_1_DEF_FILES:.1.def=.1) \
$(MAN_3_DEF_FILES:.3.def=.3) \
$(MAN_5_DEF_FILES:.5.def=.5) \
$(MAN_8_DEF_FILES:.8.def=.8)
clean_man_pages:
rm -f $(MAN_PAGES)
man_test:
@echo 'MAN_1_DEF_FILES:'
@$(foreach m, $(MAN_1_DEF_FILES), echo ' $(m)' ;)
@echo
@echo 'MAN_3_DEF_FILES:'
@$(foreach m, $(MAN_3_DEF_FILES), echo ' $(m)' ;)
@echo
@echo 'MAN_5_DEF_FILES:'
@$(foreach m, $(MAN_5_DEF_FILES), echo ' $(m)' ;)
@echo
@echo 'MAN_8_DEF_FILES:'
@$(foreach m, $(MAN_8_DEF_FILES), echo ' $(m)' ;)
@echo
@echo 'MAN_PAGES:'
@$(foreach m, $(MAN_PAGES), echo ' $(m)' ;)
docs: man_pages
man_pages: $(MAN_PAGES)
define make_man_page
$(call yellow_msg, Generating $(2)...)
sed -f $(OBJ_DIR)/sed_script < $(1) > $(2)
@echo
endef
man/%.1: man/%.1.def $(OBJ_DIR)/sed_script
$(call make_man_page, $<, $@)
man/%.3: man/%.3.def $(OBJ_DIR)/sed_script
$(call make_man_page, $<, $@)
man/%.5: man/%.5.def $(OBJ_DIR)/sed_script
$(call make_man_page, $<, $@)
man/%.8: man/%.8.def $(OBJ_DIR)/sed_script
$(call make_man_page, $<, $@)
$(OBJ_DIR)/sed_script: sedscript.in $(THIS_FILE)
cp $< $@
#################### Rules for Python-modules in 'python/netsnmp' ######################
#
# Nothing to do when 'USE_PYTHON=0'.
#
python_build_0:
#
# Copy the following files:
# python/netsnmp/client.py
# python/netsnmp/__init__.py
# $(OBJ_DIR)/client_intf.pyd
# $(OBJ_DIR)/client_intf.pdb (MSVC/clang-cl)
#
# with a flat structure into:
# $(PYTHON_ROOT)/Lib/site-packages/netsnmp
#
PY_TARGETS = python/netsnmp/client.py \
python/netsnmp/__init__.py \
$(OBJ_DIR)/client_intf.pyd
PY_CFLAGS = -DBUILDING_PY_MODULE \
-D_WINSOCK_DEPRECATED_NO_WARNINGS \
-I$(PYTHON_ROOT)/include \
$(APP_CFLAGS)
ifeq ($(MSVC_TYPE),1)
PY_LIBS = $(APP_LIBS) $(APP_EX_LIBS) $(PYTHON_ROOT)/libs/python$(PYTHON_VER).lib
PY_TARGETS += $(OBJ_DIR)/client_intf.pdb
else
PY_LIBS = $(APP_LIBS) $(APP_EX_LIBS) $(PYTHON_ROOT)/libs/libpython$(PYTHON_VER).a
endif
#
# Must copy 'netsnmp.dll' (and 'netsnmp.pdb') to '$(PY_TARGETS_DIR)' too.
#
ifeq ($(USE_STATIC_LIBS),0)
PY_TARGETS += $(DLL_FILE)
ifeq ($(MSVC_TYPE),1)
PY_TARGETS += netsnmp.pdb
endif
endif
python_build_1: $(PY_TARGETS)
- mkdir $(PY_TARGETS_DIR)
cp --update $^ $(PY_TARGETS_DIR)
netsnmp.pdb: netsnmp.dll
$(OBJ_DIR)/client_intf.$(O) client_intf.i: EXTRA_CFLAGS = $(PY_CFLAGS)
$(OBJ_DIR)/client_intf.pdb: $(OBJ_DIR)/client_intf.pyd
$(OBJ_DIR)/client_intf.pyd: $(OBJ_DIR)/client_intf.$(O) $(OBJ_DIR)/client_intf.res $(APP_LIBS) $(THIS_FILE)
$(call link_PYD, $@, $(OBJ_DIR)/client_intf.$(O) $(OBJ_DIR)/client_intf.res $(PY_LIBS))
py_test:
@echo 'PYTHON_ROOT= "$(PYTHON_ROOT)".'
@echo 'PYTHON_VER= "$(PYTHON_VER)".'
$(OBJ_DIR)/client_intf.rc: $(THIS_FILE)
$(call Generating, $@, //)
@echo '#define RC_BASENAME "client_intf.pyd"' >> $@
@echo '#define RC_DESCRIPTION "The Net-SNMP Python Interface"' >> $@
@echo '#define RC_FILETYPE VFT_DLL' >> $@
@echo "$$NETSNMP_RC_COMMON" >> $@
############### Rules for GENERATED files ##############################################
include/snmpsm_init.h:
$(call Generating, $@,//)
@echo 'extern void init_usm (void);' >> $@
include/net-snmp/net-snmp-config.h: $(THIS_FILE)
$(call Generating, $@,//)
@echo "#ifndef NET_SNMP_CONFIG_H" >> $@
@echo "#define NET_SNMP_CONFIG_H" >> $@
@echo "$$net_snmp_config_h" >> $@
@echo "#endif /* NET_SNMP_CONFIG_H */" >> $@
define net_snmp_config_h
#if defined(USE_WATT32)
#define WATT32_NO_OLDIES
#include <tcp.h> /* Includes <windows.h> and <wincrypt.h> */
#include <sys/socket.h> /* Redefines 'CMSG_DATA' from <wincrypt.h> */
#include <sys/ioctl.h> /* For 'FIONBIO' */
#include <io.h> /* For 'pipe()' */
#else
#include <winsock2.h>
#include <ws2tcpip.h>
#endif
#include <time.h> /* _SSIZE_T_DEFINED on MinGW32 */
#include <limits.h> /* PATH_MAX on MinGW32 */
#include <stdlib.h> /* _MAX_PATH on non-MinGW32 */
#include <stdint.h>
#include <string.h>
#include <io.h>
/*
* Since we use a $(DEF_FILE) file while 'NETSNMP_DLL_BUILDING' is defined,
* we DO NOT use '#define NETSNMP_IMPORT extern __declspec(dllexport)'.
*/
#if !defined(NETSNMP_DLL_BUILDING) && defined(NETSNMP_USE_DLL)
#define NETSNMP_IMPORT extern __declspec(dllimport)
#else
#define NETSNMP_IMPORT extern
#endif
#if defined(__GNUC__) || defined(___clang__)
#define NETSNMP_INLINE
#define NETSNMP_NO_INLINE
#else
#define NETSNMP_INLINE extern inline
#endif
#define NETSNMP_BIGENDIAN 0 /* We're little-endian */
#define NETSNMP_STATIC_INLINE static
#define NETSNMP_OID 8072
#define NETSNMP_ENTERPRISE_OID 8072
#define NETSNMP_NO_SYSTEMD 1
#define NETSNMP_MAX_PERSISTENT_BACKUPS 10
#define NETSNMP_PERSISTENT_DIRECTORY "$(INSTALL_BASE)/snmp/persist"
#define NETSNMP_SELECT_TIMEVAL struct timeval
#define NETSNMP_AGENT_DIRECTORY_MODE 0700
#define NETSNMP_SNMPBLOCK 1
#define NETSNMP_USE_INTERNAL_MD5 1
#define NETSNMP_DEFAULT_SNMP_VERSION 3
/* The "transport domains" we always support:
*/
#define NETSNMP_TRANSPORT_CALLBACK_DOMAIN 1
#define NETSNMP_TRANSPORT_TCP_DOMAIN 1
#define NETSNMP_TRANSPORT_UDP_DOMAIN 1
#define NETSNMP_TRANSPORT_TCP_DOMAIN 1
#define NETSNMP_TRANSPORT_UDPIPV6_DOMAIN 1
#define NETSNMP_TRANSPORT_TCPIPV6_DOMAIN 1
#if defined(NETSNMP_TRANSPORT_IPX_DOMAIN)
#include <wsipx.h>
#endif
#define NETSNMP_IOCTLSOCKET_ARG u_long
#define NETSNMP_ENABLE_IPV6 1
#define NETSNMP_SECMOD_USM 1
#define NETSNMP_USE_REVERSE_ASNENCODING 1
#define NETSNMP_DEFAULT_ASNENCODING_DIRECTION 1
#define NETSNMP_CACHEFILE ".snmp-exec-cache"
#define NETSNMP_TEMP_FILE_PATTERN "$(INSTALL_BASE)/temp/snmpdXXXXXX"
#define RETSIGTYPE void
#define NETSNMP_SYS_NAME "Win32/$(BUILDER)"
#define NETSNMP_SHELLMIBNUM 8
#define NETSNMP_MEMMIBNUM 4
#define NETSNMP_DISKMIBNUM 9
#define NETSNMP_LOADAVEMIBNUM 10
#define NETSNMP_VERSIONMIBNUM 100
#define NETSNMP_ERRORMIBNUM 101
#define NETSNMP_AGENTID 250
#define NETSNMP_WIN32ID 13
#define OSTYPE NETSNMP_WIN32ID
#define NETSNMP_OSTYPE OSTYPE
/* The assigned enterprise number for sysObjectID.
*/
#define NETSNMP_SYSTEM_MIB 1,3,6,1,4,1,8072,3,2,OSTYPE
#define NETSNMP_SYSTEM_DOT_MIB 1.3.6.1.4.1.8072.3.2.OSTYPE
#define NETSNMP_SYSTEM_DOT_MIB_LENGTH 10
/* The assigned enterprise number for notifications.
*/
#define NETSNMP_NOTIFICATION_MIB 1,3,6,1,4,1,8072,4
#define NETSNMP_NOTIFICATION_DOT_MIB 1.3.6.1.4.1.8072.4
#define NETSNMP_NOTIFICATION_DOT_MIB_LENGTH 8
#ifndef NETSNMP_PRIz
#define NETSNMP_PRIz "I64"
#endif
#if defined(NETSNMP_DLL_BUILDING)
#define RTENTRY void
#define random rand
#define srandom srand
#define SNMPSHAREPATH "$(INSTALL_BASE)/share/snmp"
#define SNMPCONFPATH "$(INSTALL_BASE)/etc/snmp"
#define SNMPDLMODPATH "$(INSTALL_BASE)/lib/dlmod"
#define SNMPLIBPATH "$(INSTALL_BASE)/lib"
#define NETSNMP_ENTERPRISE_OID 8072
#define NETSNMP_ENTERPRISE_MIB 1,3,6,1,4,1,8072
#define NETSNMP_ENTERPRISE_DOT_MIB 1.3.6.1.4.1.8072
#define NETSNMP_ENTERPRISE_DOT_MIB_LENGTH 7
#define NETSNMP_ERRORTIMELENGTH 600
#define NETSNMP_EXCACHETIME 30
#define NETSNMP_MAXCACHESIZE (200*80)
#define NETSNMP_DEFDISKMINIMUMSPACE 100000
#define NETSNMP_DEFMAXLOADAVE 12.0
#define NETSNMP_MAXREADCOUNT 100
#define NETSNMP_LASTFIELD -1
#endif /* NETSNMP_DLL_BUILDING */
#if defined(__GNUC__) || defined(__clang__)
#define NETSNMP_ATTRIBUTE_DEPRECATED __attribute__((deprecated))
#else
#define NETSNMP_ATTRIBUTE_DEPRECATED
#endif
#define USE_REVERSE_ASNENCODING 1
#define NETSNMP_SNMPV1 0xAAAA /* readable by anyone */
#define NETSNMP_SNMPV2ANY 0xA000 /* V2 Any type (includes NoAuth) */
#define NETSNMP_SNMPV2AUTH 0x8000 /* V2 Authenticated requests only */
#define NETSNMP_DEFAULT_MIBS \
"IP-MIB;IF-MIB;TCP-MIB;UDP-MIB;HOST-RESOURCES-MIB;SNMPv2-MIB;RFC1213-MIB;NOTIFICATION-LOG-MIB;" \
"UCD-SNMP-MIB;UCD-DEMO-MIB;SNMP-TARGET-MIB;NET-SNMP-AGENT-MIB;DISMAN-EVENT-MIB;SNMP-VIEW-BASED-ACM-MIB;" \
"SNMP-COMMUNITY-MIB;SNMP-FRAMEWORK-MIB;SNMP-MPD-MIB;SNMP-USER-BASED-SM-MIB;SNMP-NOTIFICATION-MIB;SNMPv2-TM"
#define DEFAULT_MIBS \
"IP-MIB:IF-MIB:TCP-MIB:UDP-MIB:SNMPv2-MIB:RFC1213-MIB"
#define NETSNMP_DEFAULT_MIBDIRS "$(INSTALL_BASE)/share/snmp/mibs"
#if defined(NETSNMP_USE_OPENSSL)
#define HAVE_LIBSSL 1
#define HAVE_LIBSSL_DTLS 1
#define NETSNMP_TRANSPORT_TLSBASE_DOMAIN 1
#define HAVE_OPENSSL_AES_H 1
#define HAVE_OPENSSL_DES_H 1
#define HAVE_OPENSSL_DH_H 1
#define HAVE_OPENSSL_EVP_H 1
#define HAVE_OPENSSL_HMAC_H 1
#define HAVE_AES_CFB128_ENCRYPT 1
#define HAVE_ASN1_STRING_GET0_DATA 1
#define HAVE_DH_GET0_KEY 1
#define HAVE_DH_GET0_PQG 1
#define HAVE_DH_SET0_PQG 1
#define HAVE_DTLSV1_METHOD 1
#define HAVE_DTLS_METHOD 1
#define HAVE_EVP_MD_CTX_FREE 1
#define HAVE_EVP_MD_CTX_NEW 1
#define HAVE_EVP_MD_CTX_CREATE 1
#define HAVE_EVP_MD_CTX_DESTROY 1
#define HAVE_EVP_SHA224 1
#define HAVE_EVP_SHA384 1
#define HAVE_TLSV1_METHOD 1
#define HAVE_TLS_METHOD 1
#define HAVE_X509_GET_SIGNATURE_NID 1
#define HAVE_X509_NAME_ENTRY_GET_DATA 1
#define HAVE_X509_NAME_ENTRY_GET_OBJECT 1
#define HAVE_AES 1
#define SECOND_APPVERIFY_COOKIE_CB_ARG_QUALIFIER const
#endif
/* These are already in <Pyconfig.h> included before this.
* Therefore avoid some warnings and do not define these here.
*/
#if !defined(BUILDING_PY_MODULE)
#define HAVE_GETPID 1
#define HAVE_IO_H 1
#define HAVE_SNPRINTF 1
#define HAVE_STRERROR 1
#endif
#define HAVE_IPHLPAPI_H 1
#define HAVE_SOCKLEN_T 1
#define HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY 1
#define HAVE_WIN32_PLATFORM_SDK 1
#define HAVE_SRAND 1
#define HAVE_STDINT_H 1
#define HAVE_INTTYPES_H 1
#define HAVE_MALLOC_H 1
#define HAVE_STRDUP 1
#define HAVE_RAND 1
#define HAVE_FCNTL_H 1
#define HAVE_LIMITS_H 1
#define HAVE_LOCALE_H 1
#define HAVE_LM_H 1
#define HAVE_STDARG_H 1
#define HAVE_STRING_H 1
#define HAVE_STDLIB_H 1
#define HAVE_SYS_STAT_H 1
#define HAVE_SYS_TYPES_H 1
#define HAVE_GETHOSTNAME 1
#define HAVE_GETHOSTBYNAME 1
#define HAVE_GETSERVBYNAME 1
#define HAVE_STRTOL 1
#define HAVE_STRTOUL 1
#define HAVE_STRTOULL 1
#define HAVE_SYS_TIMEB_H 1
#define HAVE_PROCESS_H 1
#define HAVE_SEARCH_H 1
#define HAVE_SETLOCALE 1
#define HAVE_SOCKET 1
#define HAVE_SYSTEM 1
#define HAVE_VSNPRINTF 1
#define HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID 1
#define HAVE_GETTIMEOFDAY 1 /* For non-MinGW32, see below */
#define HAVE__BEGINTHREADEX 1
#define HAVE__CPUTS 1
#define HAVE__GETCH 1
#define HAVE__GET_OSFHANDLE 1
#define HAVE__OPEN_OSFHANDLE 1
#define HAVE_WINDOWS_H 1
#if defined(USE_WATT32)
#define _MSWSOCK_ 1 /* Prevent reading <mswsock.h> */
#define HAVE_ARPA_INET_H 1
#define HAVE_CLOSESOCKET 1
#define HAVE_IP_RECVDSTADDR 1
#define HAVE_NETINET_IN_H 1
#define HAVE_NETDB_H 1
#define HAVE_NET_IF_H 1
#define HAVE_SYS_SOCKET_H 1
#define HAVE_SYS_IOCTL_H 1
#define LPHOSTENT struct hostent *
#define SOCKADDR_IN struct sockaddr_in
#define SOCKADDR struct sockaddr
#define LPSOCKADDR struct sockaddr *
#define SOCKET int
#define NFDBITS FD_SETSIZE
#define fds_bits fd_bits
// #define closesocket(sock) close_s(sock)
#define IPPORT_ECHO 7
#else
#define HAVE_U_INT64_T 1
#define HAVE_WINSOCK_H 1
#define HAVE_WINSOCK2_H 1
#define HAVE_CLOSESOCKET 1
//#define HAVE_IP_PKTINFO 1
#endif
/*
* '__MINGW32__' has 'ssize_t' as a typedef.
* But if using '<libssh2.h>' with NSVC/clang-cl, take care to define
* 'ssize_t' as a macro and not as a typedef.
*/
#if !defined(_SSIZE_T_DEFINED)
#if defined(_WIN64)
#define SSIZE_T __int64
#else
#define SSIZE_T int
#endif
#define ssize_t SSIZE_T
#endif
#define HAVE_SSIZE_T 1
#define in_addr_t unsigned long
/* Hacks for 'snmplib/transports/snmpSSHDomain.c'.
*/
#if defined(NETSNMP_DLL_BUILDING) && defined(NETSNMP_TRANSPORT_SSH_DOMAIN)
#ifndef MAXPATHLEN
#define MAXPATHLEN _MAX_PATH
#endif
#endif
#define PACKAGE_VERSION "$(VERSION)"
#define ENV_SEPARATOR ";"
#define ENV_SEPARATOR_CHAR ';'
#define config_belongs_in(x)
#define config_require(x)
#define config_arch_require(x,y)
#define config_add_mib(x)
#if defined(__MINGW32__)
#define HAVE_DIRENT_H 1
#define HAVE_READDIR 1
#define HAVE_OPENDIR 1
#define HAVE_CLOSEDIR 1
#define HAVE_GETOPT_H 1
#define HAVE_UNISTD_H 1
#define HAVE_STRNCASECMP 1
#define HAVE_STRTOK_R 1
#define HAVE_SYS_TIME_H 1
#define HAVE_SYS_PARAM_H 1
#define TIME_WITH_SYS_TIME 1
#else
typedef unsigned short mode_t;
#endif
#if !defined(__MINGW32__) && !defined(BUILDING_PY_MODULE) && !defined(WATT32_STATIC)
/*
* An improved 'gettimeofday()' for MSVC/clang-cl.
* Replaces 'snmplib/gettimeofday.c'.
*/
#define DELTA_EPOCH_IN_USEC 11644473600000000ULL
__inline uint64_t FILETIME_to_unix_epoch (const FILETIME *ft)
{
uint64_t res = (uint64_t) ft->dwHighDateTime << 32;
res |= ft->dwLowDateTime;
res /= 10; /* from 100 nano-sec periods to usec */
res -= DELTA_EPOCH_IN_USEC; /* from Win epoch to Unix epoch */
return (res);
}
struct timezone;
__inline int gettimeofday (struct timeval *tv, struct timezone *tz)
{
FILETIME ft;
uint64_t tim;
if (!tv)
{
errno = EINVAL;
return (-1);
}
GetSystemTimeAsFileTime (&ft);
tim = FILETIME_to_unix_epoch (&ft);
tv->tv_sec = (long) (tim / 1000000L);
tv->tv_usec = (long) (tim % 1000000L);
(void) tz;
return (0);
}
#endif /* !__MINGW32__ && !BUILDING_PY_MODULE */
#if defined(NETSNMP_DLL_BUILDING) && defined(USE_WATT32)
__inline int create_winpipe_transport (int *pipe_fds)
{
(void) pipe_fds;
return (-1);
}
#endif
endef
#
# This will become the content of '%APPDATA%/snmp.conf':
# (if it doesn't already exist).
#
define snmp_conf
mibdirs $(INSTALL_BASE)/share/snmp/mibs
persistentDir $(INSTALL_BASE)/snmp/persist
tempFilePattern $(INSTALL_BASE)/temp/snmpdXXXXXX
endef
#
# This will become the content of '$(OBJ_DIR)/net_snmp_install.sh' which
# gets executed by 'make install'.
#
define net_snmp_install_sh
echo "Creating $(INSTALL_BASE) distribution:"
for d in $(INSTALL_DIRS) ; do
mkdir --parents $$d
done
cp --update $(PROGRAMS) $(DLL_FILE) $(INSTALL_BASE)/bin
cp --update win32/local/*.bat local/mib2c local/traptoemail $(INSTALL_BASE)/bin
cp --update $(STATIC_LIB) $(IMPORT_LIB) $(INSTALL_BASE)/lib
cp --update local/snmpconf.dir/snmp-data/* $(INSTALL_BASE)/share/snmp/snmpconf-data/snmp-data
cp --update local/snmpconf.dir/snmpd-data/* $(INSTALL_BASE)/share/snmp/snmpconf-data/snmpd-data
cp --update local/snmpconf.dir/snmptrapd-data/* $(INSTALL_BASE)/share/snmp/snmpconf-data/snmptrapd-data
cp --update local/mib2c*.conf $(INSTALL_BASE)/share/snmp
cp --update mibs/*.txt $(INSTALL_BASE)/share/snmp/mibs
cp --update local/mib2c-conf.d/* $(INSTALL_BASE)/share/snmp/mib2c-data
#
# Copy .h-files for Net-SNMP developement
#
cp include/*.h $(INSTALL_BASE)/include
cp include/net-snmp/*.h $(INSTALL_BASE)/include/net-snmp/
cp include/ucd-snmp/*.h $(INSTALL_BASE)/include/ucd-snmp/
endef
export snmp_conf net_snmp_install_sh net_snmp_config_h
$(OBJ_DIR)/net_snmp_install.sh: $(THIS_FILE)
$(call Generating, $@,#)
@echo "#!/usr/env/sh" >> $@
@echo "$$net_snmp_install_sh" >> $@
###########################################################################################
$(STATIC_LIB): $(LIB_OBJ)
$(call make_lib, $@, $^)
$(IMPORT_LIB): $(DLL_FILE)
$(DLL_FILE): $(DEF_FILE) $(STATIC_LIB) $(OBJ_DIR)/netsnmp.res
$(call link_DLL, $@, $(STATIC_LIB) $(OBJ_DIR)/netsnmp.res $(DLL_LIBS) $(WS2_32), $(IMPORT_LIB), $(DEF_FILE))
snmptrapd.exe: $(SNMPTRAPD_OBJ) $(APP_LIBS)
$(call link_EXE, $@, $^ $(APP_EX_LIBS))
agentxtrap.exe: $(AGENTX_TRAP_OBJ) $(APP_LIBS)
$(call link_EXE, $@, $^ $(APP_EX_LIBS))
%.exe: $(OBJ_DIR)/%.$(O) $(OBJ_DIR)/%.res $(APP_LIBS)
$(call link_EXE, $@, $^ $(APP_EX_LIBS))
$(OBJ_DIR)/%.res: $(OBJ_DIR)/%.rc
$(call make_res, $@, $<)
#
# Add these 'EXTRA_x' symbols until all 'PROGRAMS' link okay using the '$(IMPORT_LIB)':
#
EXTRA_CODE = print_variable fprint_variable print_objid fprint_objid snprint_objid read_objid \
setenv strlcpy debugmsg debugmsgtoken debugmsg_oid uptime_string uptime_string_n \
zeroU64 printU64 u64Subtract clear_tree_flags debug_register_tokens setup_engineID \
hex_to_binary2 se_find_label_in_slist _build_initial_pdu_packet encode_keychange \
binary_to_hex set_enginetime
EXTRA_DATA =
ifeq ($(USE_REGEX),1)
EXTRA_CODE += re_compile_fastmap \
re_compile_pattern \
re_match \
re_match_2 \
re_search \
re_search_2 \
re_set_registers \
re_set_syntax
EXTRA_DATA += re_syntax_options \
re_max_failures
endif
#
# Needed by 'python/netsnmp/client_intf.c'
#
ifeq ($(MSVC_TYPE),1)
EXTRA_CODE += strcasecmp \
strncasecmp \
strcasestr \
strtok_r
#
# Since we link in 'snmplib/getopt.c' (but not for MinGW)
#
EXTRA_CODE += getopt
EXTRA_DATA += optind optarg optopt
endif
#
# Create a '$(OBJ_DIR)/netsnmp.def' file with 'EXPORTS' for code/data symbols prefixed
# with these prefixes:
#
SYM_PREFIXES = add_ asn_ atime_ ds_ find_ init_ generate_ get_ \
netsnmp sc_ se_ snmp_ snmpv3_ fprint_ print_ \
sprint_realloc_ usm_ winsock_ CONTAINER_ \
register_ unregister_ debug_ debugmsg copy_ \
config_ uatime_ build_ run_ skip_ count_ clear_ \
shutdown_
$(DEF_FILE): $(LIB_OBJ) $(THIS_FILE)
$(call make_def_file, $@, $(SYM_PREFIXES))
ifneq ($(EXTRA_CODE),)
echo -e '\n; EXTRA_CODE symbols:\n $(foreach e,$(EXTRA_CODE), $(e)\n)' >> $@
endif
ifneq ($(EXTRA_DATA),)
echo -e '\n; EXTRA_DATA symbols:\n $(foreach e,$(EXTRA_DATA), $(e) DATA\n)' >> $@
endif
$(CC).args: $(THIS_FILE)
$(call yellow_msg, All CFLAGS are in $@)
$(call create_resp_file, $@, $(CFLAGS))
clean: clean_$(MSVC_TYPE) clean_man_pages
- rm -f $(OBJ_DIR)/* $(GENERATED) $(DEF_FILE) link.args cpp_filter.py .depend.Windows
- rmdir $(OBJ_DIR)
clean_0:
- rm -f gcc.args
clean_1:
- rm -f cl.args clang-cl.args link.tmp vc1*.pdb $(IMPORT_LIB:.lib=.exp)
realclean vclean: clean vclean_$(MSVC_TYPE) vclean_install_base
- rm -f $(STATIC_LIB) $(IMPORT_LIB) $(DLL_FILE) $(DLL_FILE:.dll=.map) \
$(PROGRAMS) $(PROGRAMS:.exe=.map)
vclean_0:
vclean_1:
- rm -f $(DLL_FILE:.dll=.pdb) $(PROGRAMS:.exe=.pdb)
vclean_install_base:
- rm -fR $(INSTALL_BASE)/*
- rmdir $(INSTALL_BASE)
#
# Compile all $(LIB_SRC) in one go.
# A lot faster, but for MSVC only.
#
ifeq ($(USE_MP_COMPILE),1)
$(LIB_OBJ): $(LIB_SRC)
$(call c_compile_MP, $^)
endif
$(OBJ_DIR)/%.o: %.c | $(CC).args
$(CC) -c @$(CC).args $(EXTRA_CFLAGS) -o $@ $<
@echo
$(OBJ_DIR)/%.obj: %.c | $(CC).args
$(CC) -c @$(CC).args $(EXTRA_CFLAGS) -Fo./$@ $<
@echo
#
# Command to generate a nicer C/C++ preprocessed output
# with the help of 'cpp_filter.py' and optionally 'clang-format'.
#
ifeq ($(USE_CLANG_FORMAT),1)
C_FORMATER = | clang-format -style=Mozilla -assume-filename=c
endif
C_preprocess = $(CC) -E @$(CC).args $(1) | $(PYTHON) cpp_filter.py $(C_FORMATER) > $(2)
%.i: %.c FORCE cpp_filter.py $(GENERATED) $(CC).args
$(call C_preprocess, $(EXTRA_CFLAGS) $<, $@)
@echo
FORCE:
ifeq ($(CC),gcc)
#
# .$(O) -> .exe macro:
# arg1, $(1): The .exe file.
# arg2, $(2): The .$(O) file(s), extra args and libs.
#
define link_EXE
$(call green_msg, Linking $(1))
$(call create_resp_file, link.args, $(LDFLAGS) $(2))
$(CC) -o $(1) @link.args > $(1:.exe=.map)
@echo
endef
#
# .$(O) -> .dll macro:
# arg1, $(1): The .dll file.
# arg2, $(2): The .$(O) file(s), extra args and libs.
# arg3, $(3): The import-libray.
# arg4, $(4): The .def file (must come before $(2))
#
define link_DLL
$(call green_msg, Linking $(1))
$(call create_resp_file, link.args, -shared $(LDFLAGS) -Wl$(comma)--out-implib$(comma)$(strip $(3)) $(4) $(2))
$(CC) -o $(1) @link.args > $(1:.dll=.map)
@echo
endef
#
# .$(O) -> .pyd macro:
# arg1, $(1): The .pyd file.
# arg2, $(2): The .$(O) file(s), extra args and libs.
#
# Note: We only need to export 'initclient_intf'. But the below command will export everything.
# Adding a '-Wl,--exclude-symbols' will export nothing. Seems difficult to
# only export a single function.
#
define link_PYD
$(call green_msg, Linking $(1))
$(call create_resp_file, link.args, -shared $(LDFLAGS) $(2))
$(CC) -o $(1) @link.args > $(1:.pyd=.map)
@echo
endef
#
# .$(O) -> .a/.lib macro:
# arg1, $(1): The library file.
# arg2, $(2): The .$(O) files.
#
define make_lib
rm -f $(1)
ar rs $(1) $(2)
@echo
endef
#
# .rc -> .res compile macro:
# arg1: $(1): the .res file.
# arg2: $(2): the .rc to compile.
#
define make_res
windres $(RCFLAGS) -o $(1) -i $(2)
@echo
endef
else
define link_EXE
$(call green_msg, Linking $(1))
$(call create_resp_file, link.args, $(LDFLAGS) $(2))
link -out:$(strip $(1)) @link.args > link.tmp
@cat link.tmp >> $(1:.exe=.map)
@echo
endef
define link_DLL
$(call green_msg, Linking $(1))
$(call create_resp_file, link.args, -dll $(LDFLAGS) -implib:$(strip $(3)) $(2) -def:$(strip $(4)))
link -out:$(strip $(1)) @link.args > link.tmp
@cat link.tmp >> $(1:.dll=.map)
@rm -f $(3:.lib=.exp)
@echo
endef
define link_PYD
$(call green_msg, Linking $(1))
$(call create_resp_file, link.args, -dll $(LDFLAGS) $(2))
link -out:$(strip $(1)) @link.args > link.tmp
@cat link.tmp >> $(1:.pyd=.map)
@rm -f $(1:.pyd=.lib) $(1:.pyd=.exp)
@echo
endef
#
# '-ignore:4221' is for warnings like these:
# foo-bar.obj : warning LNK4221: This object file does not define any previously undefined
# public symbols, so it will not be used by any link operation that consumes this library.
#
define make_lib
lib -nologo -ignore:4221 -out:$(strip $(1)) $(2)
@echo
endef
define make_res
rc $(RCFLAGS) -fo $(1) $(2)
@echo
endef
endif
#
# For MSVC only:
#
c_compile_MP = $(CC) -MP -c $(CFLAGS) $(1) -Fo./$(OBJ_DIR)\\
#
# Create a response file $(1).
# One word from $(2) per line.
#
define create_resp_file
$(file > $(1))
$(foreach f, $(2), $(file >> $(1),$(strip $(f))) )
endef
#
# This .def-file macro uses 'nm $(LIB_OBJ)'.
#
# Simply export all symbols that matches the prefix(es).
# Only 'x86' symbols are supported at the moment.
#
# Usage:
# $(1): Name of .def-file. The .dll name is extracted from this.
# $(2): the code/data-symbol prefix(es). E.g. "snmp_ asn1_"
#
extract_code_syms = nm $(LIB_OBJ) | \
grep $(foreach s, $(2), -e ' T _$(s).*') | \
sed 's/^.* _/ /' | \
sort >> $(1)
extract_data_syms = nm $(LIB_OBJ) | \
grep $(foreach s, $(2), -e ' [BDCGR] _$(s).*') | \
sed -e 's/^.* _\([_a-zA-Z0-9]*\)/ \1 DATA/' | \
sort >> $(1)
define make_def_file
$(call Generating, $(1), ;)
@echo -e -n 'LIBRARY $(notdir $(1:.def=.dll))\nEXPORTS\n' >> $(1)
@$(call extract_code_syms, $(1), $(2))
@$(call extract_data_syms, $(1), $(2))
endef
define Generating
$(call yellow_msg, Generating $(1)...)
@ (echo -e '$(2)\n$(2) This file ($(strip $(1))) was generated at $(TODAY) from\n$(2) $(realpath $(THIS_FILE)).\n$(2) DO NOT EDIT!.\n$(2)' ) > $(1)
endef
#
# Stuff common to all .rc-files.
#
define NETSNMP_RC_COMMON
#include <winver.h>
#if defined(USER) && (USER == gv)
#define RC_PRIVATE_BUILD "The private build of <[email protected]>"
#else
#define RC_PRIVATE_BUILD ""
#endif
#if !defined(RC_COMMENT_EXTRA)
#define RC_COMMENT_EXTRA ""
#endif
#define RC_VERSION $(VERSION_MAJOR),$(VERSION_MINOR),0,0
VS_VERSION_INFO VERSIONINFO
FILEVERSION RC_VERSION
PRODUCTVERSION RC_VERSION
FILEFLAGSMASK 0x3fL
FILEOS VOS__WINDOWS32
FILESUBTYPE 0
FILEFLAGS 0
#ifdef RC_FILETYPE
FILETYPE RC_FILETYPE /* Set to 'VFT_DLL' only for "$(DLL_FILE)" */
#else
FILETYPE VFT_APP /* Otherwise assume 'VFT_APP' */
#endif
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", "Net-SNMP; http://net-snmp.sourceforge.net/"
VALUE "FileDescription", RC_DESCRIPTION
VALUE "ProductName", "Simple Network Management Protocol"
VALUE "FileVersion", "ver. $(VERSION) ($(BUILDER), 32-bit)"
VALUE "ProductVersion", "ver. $(VERSION) ($(BUILDER), 32-bit)"
VALUE "InternalName", RC_BASENAME
VALUE "OriginalFilename", RC_BASENAME
VALUE "LegalCopyright", "CMU/UCD copyright notice: (BSD like)"
VALUE "PrivateBuild", RC_PRIVATE_BUILD
VALUE "Comments", "Built on $(TODAY)" RC_COMMENT_EXTRA
VALUE "LegalTrademarks", ""
VALUE "SpecialBuild", "$(RC_FEATURES)"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
endef
export NETSNMP_RC_COMMON
$(OBJ_DIR)/netsnmp.rc: $(THIS_FILE)
$(call Generating, $@, //)
@echo '#define RC_BASENAME "$(DLL_FILE)"' >> $@
@echo '#define RC_DESCRIPTION "Net-SNMP core"' >> $@
@echo '#define RC_FILETYPE VFT_DLL' >> $@
@echo "$$NETSNMP_RC_COMMON" >> $@
#
# Create a .rc-file for an SNMP application program.
# arg1: $(1): The name of the .rc file
# arg2: $(2): The RC_DESCRIPTION.
#
# All the 'RC_DESCRIPTION' texts comes from the titles of 'man snmp_XX'
#
define Create_snmp_rc
$(call Generating, $(1), //)
@echo '#define RC_BASENAME "$(notdir $(1:.rc=.exe))"' >> $@
@echo '#define RC_DESCRIPTION "$(strip $(2))"' >> $@
@echo "$$NETSNMP_RC_COMMON" >> $@
endef
$(OBJ_DIR)/snmpwalk.rc: $(THIS_FILE)
$(call Create_snmp_rc, $@, Retrieve a subtree of management values using SNMP GETNEXT requests)
$(OBJ_DIR)/snmptable.rc: $(THIS_FILE)
$(call Create_snmp_rc, $@, Retrieve an SNMP table and display it in tabular form)
$(OBJ_DIR)/snmpbulkget.rc: $(THIS_FILE)
$(call Create_snmp_rc, $@, Communicates with a network entity using SNMP GETBULK requests)
$(OBJ_DIR)/snmpbulkwalk.rc: $(THIS_FILE)
$(call Create_snmp_rc, $@, Retrieve a subtree of management values using SNMP GETBULK requests)
$(OBJ_DIR)/snmpdelta.rc: $(THIS_FILE)
$(call Create_snmp_rc, $@, Monitor delta differences in SNMP Counter values)
$(OBJ_DIR)/snmpdf.rc: $(THIS_FILE)
$(call Create_snmp_rc, $@, Display disk space usage on a network entity via SNMP)
$(OBJ_DIR)/snmpget.rc: $(THIS_FILE)
$(call Create_snmp_rc, $@, Communicates with a network entity using SNMP GET requests)
$(OBJ_DIR)/snmpgetnext.rc: $(THIS_FILE)
$(call Create_snmp_rc, $@, Communicates with a network entity using SNMP GETNEXT requests)
$(OBJ_DIR)/snmpset.rc: $(THIS_FILE)
$(call Create_snmp_rc, $@, Communicates with a network entity using SNMP SET requests)
$(OBJ_DIR)/snmpstatus.rc: $(THIS_FILE)
$(call Create_snmp_rc, $@, Retrieves a fixed set of management information from a network entity)
$(OBJ_DIR)/snmptest.rc: $(THIS_FILE)
$(call Create_snmp_rc, $@, Communicates with a network entity using SNMP requests)
$(OBJ_DIR)/snmptranslate.rc: $(THIS_FILE)
$(call Create_snmp_rc, $@, Translate MIB OID names between numeric and textual forms)
$(OBJ_DIR)/snmptrap.rc: $(THIS_FILE)
$(call Create_snmp_rc, $@, Sends an SNMP notification to a manager)
$(OBJ_DIR)/encode_keychange.rc: $(THIS_FILE)
$(call Create_snmp_rc, $@, Collect information to build a KeyChange encoding)
cpp_filter.py: $(THIS_FILE)
$(call Generating, $@,#)
@echo "#!/usr/env/python" >> $@
@echo "from __future__ import print_function" >> $@
@echo "if 1:" >> $@
@echo "$$CPP_FILTER_PY" >> $@
@echo
define CPP_FILTER_PY
#
# A tool used in "$$(CC) -E" rule above.
# It's used to remove empty preproessor lines and make the
# output a bit more readable.
#
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')) and last_line[0] == '\r':
empty_lines += 1
continue
# print ("orig: \"%s\"" % line)
line = line.replace ("\\\\", "/")
fname = None
quote = line.find ('\"')
if quote > 0 and line.startswith("#line "):
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, end="")
#
# Print a new-line after blocks or structs
#
s = line.strip()
if s == "}" or s == "};":
print ("")
last_line = line
if empty_lines > 0:
sys.stderr.write ("Removed %d empty lines." % empty_lines)
endef
export CPP_FILTER_PY
#
# Use 'gcc -MM' to create dependencies.
#
DEP_CFLAGS = -MM $(filter -D% -I%, $(CFLAGS))
DEP_REPLACE = -e 's|^\(.*\).o: |\n$$(OBJ_DIR)\/\1.$$(O): |'
#
# Drop these.
#
DEP_REPLACE += -e 's|$(word 1,$(GENERATED))||' \
-e 's|$(word 2,$(GENERATED))||'
ALL_SOURCES = $(LIB_SRC) $(APPS_SRC) $(SNMPTRAPD_SRC) $(AGENTX_TRAP_SRC)
ifeq ($(USE_PYTHON),1)
ALL_SOURCES += python/netsnmp/client_intf.c
DEP_CFLAGS += -I$(PYTHON_ROOT)/include
DEP_REPLACE += -e 's|$(PYTHON_ROOT)|$$(PYTHON_ROOT)|'
endif
ifeq ($(USE_REGEX),1)
DEP_REPLACE += -e 's|$(REGEX_ROOT)|$$(REGEX_ROOT)|'
endif
depend: $(GENERATED)
$(call Generating, .depend.Windows,#)
gcc $(DEP_CFLAGS) $(ALL_SOURCES) | sed $(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