Skip to content

Instantly share code, notes, and snippets.

@gvanem
Last active March 15, 2020 21:03
Show Gist options
  • Select an option

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

Select an option

Save gvanem/b6917fbfbd116acaf3f800ca27050cff to your computer and use it in GitHub Desktop.
GNU makefile for MPIR targeting MinGW + MSVC + clang-cl. Ref: https://github.com/BrianGladman/mpir.git
#
# MPIR Makefile for MinGW + MSVC + clang-cl.
#
# by G. Vanem <[email protected]> 2004-2020.
#
comma := ,
DATE = $(shell date +%d-%B-%Y)
VER_MAJOR := $(shell grep -m1 __GNU_MP_VERSION gmp-h.in | cut -d' ' -f3)
VER_MINOR := $(shell grep -m1 __GNU_MP_VERSION_MINOR gmp-h.in | cut -d' ' -f3)
VER_PATCH := $(shell grep -m1 __GNU_MP_VERSION_PATCHLEVEL gmp-h.in | cut -d' ' -f3)
VERSION = $(VER_MAJOR).$(VER_MINOR).$(VER_PATCH)
THIS_FILE = Makefile.Windows
MDEPEND = $(THIS_FILE)
#
# Noe: 'cxx' and 'tests/cxx' are not in VPATH.
#
VPATH = mpf mpq mpz mpn mpn/generic printf scanf msvc tune \
tests $(addprefix tests/, fft mpf mpn mpq mpz misc rand)
#
# Do 'make vclean' after changing any of these options.
#
USE_FAT_BINARY ?= 0 # Doesn't work yet
USE_CRT_DEBUG ?= 0
USE_ASM ?= 1
USE_DLLs_FOR_TEST ?= 0
USE_X86_SSE2 ?= 1
USE_MP_COMPILE ?= 1
USE_DEF_FILE ?= 0
USE_CLANG_FORMATER ?= 1
USE_MAX_WARNINGS ?= 0
USE_MAKE_TRACE ?= 0
NAIL_BITS ?= 0
CLANG_ROOT_32_BIT ?= f:/ProgramFiler/LLVM-9-32bit
CLANG_ROOT_64_BIT ?= f:/ProgramFiler/LLVM-9-64bit
#
# Change this to match your MSVC compiler.
#
MSVC_DIR = msvc/vs19
#
# Only used for the '%.i: %.c' rule below.
#
PYTHON ?= py -3
#
# Undefine any '%CL' env-var. It just confuses 'clang-cl'.
#
export CL=
#
# The following codes used in macro 'colour_msg' assumes you have
# MSys/Cygwin's echo with colour support.
#
BRIGHT_GREEN = \e[1;32m
BRIGHT_WHITE = \e[1;37m
colour_msg = @echo -e "$(1)\e[0m"
green_msg = $(call colour_msg,$(BRIGHT_GREEN)$(strip $(1)))
green_msg0 = $(call colour_msg,$(BRIGHT_GREEN)$(1))
white_msg = $(call colour_msg,$(BRIGHT_WHITE)$(strip $(1)))
asm_to_obj = $(addprefix $(OBJ_DIR)/$(strip $(2)), $(notdir $(1:.asm=.$(O))))
c_to_obj = $(addprefix $(OBJ_DIR)/$(strip $(2)), $(notdir $(1:.c=.$(O))))
cc_to_obj = $(addprefix $(OBJ_DIR)/$(strip $(2)), $(notdir $(1:.cc=.$(O))))
c_to_i = $(strip $(2))$(notdir $(1:.c=.i))
cc_to_i = $(strip $(2))$(notdir $(1:.cc=.i))
ifeq ($(USE_MAKE_TRACE),1)
trace = $(call white_msg, $(1))
endif
ifeq ($(CPU),x86)
BITS = 32
else ifeq ($(CPU),x64)
BITS = 64
else
$(error Uknown CPU: $(CPU).)
endif
ifeq ($(MAKECMDGOALS),help)
CC = cl
endif
LIMB_BITS = $(BITS)
#
# Library names depend on '$(CC)' and '$(CPU)'.
#
ifeq ($(CC),gcc)
MPIR_STAT_LIB = libmpir_$(CPU).a
MPIR_IMP_LIB = libmpir_$(CPU).dll.a
MPIR_TEST_LIB = libmpir_test_$(CPU).a
else
MPIR_STAT_LIB = mpir_$(CPU).lib
MPIR_IMP_LIB = mpir_imp_$(CPU).lib
MPIR_TEST_LIB = mpir_test_$(CPU).lib
endif
#
# Yet Another Assembler, yasm.exe MUST be on PATH.
#
AS = yasm.exe
ifeq ($(CC),cl)
ASFLAGS += -g cv8
INSTALL_ROOT = $(realpath $(VSINSTALLDIR))
OBJ_DIR = MSVC_obj
RCFLAGS = -D_MSC_VER
O = obj
DEF = -def:$(strip $(1))
else ifeq ($(CC),clang-cl)
ASFLAGS += -g cv8
INSTALL_ROOT = $(realpath $(VSINSTALLDIR))
OBJ_DIR = clang_obj
RCFLAGS = -D__clang__
O = obj
DEF = -def:$(strip $(1))
else ifeq ($(CC),gcc)
ASFLAGS += -g dwarf2
INSTALL_ROOT = $(realpath $(MINGW32))
OBJ_DIR = MinGW_obj
RCFLAGS = -O COFF -D__MINGW32__
DEF = $(1)
O = o
USE_ASM = 0
else
$(warning Set CC=[gcc | cl | clang-cl] when invoking make.)
$(error Do "make -f Makefile.Windows help" for targets)
endif
#
# Only 'cl' supports Multi-compile; option '-MP' below.
#
ifneq ($(CC),cl)
USE_MP_COMPILE = 0
endif
#
# 'USE_ASM' not possible for 64-bit yet.
#
ifeq ($(BITS),64)
USE_ASM = 0
endif
#
# Flags for 'yasm'.
#
ASFLAGS += -DDLL -f win$(BITS)
#
# Use these CFLAGS only when compiling 'mpir_$(CPU).dll' sources.
#
MPIR_CFLAGS = -DMSC_BUILD_DLL=1
GENERATED = config.h mpir.h gmp.h longlong.h
#
# Flags specific to '$(CC)':
#
GCC_CFLAGS = -Wall -m$(BITS) -DHAVE_GETTIMEOFDAY
MSVC_CFLAGS = -nologo -Zi -EHsc -GF -fp:precise -Zc:wchar_t,forScope
CLANG_CFLAGS = -nologo -Zi -EHsc -GF
ifeq ($(USE_CRT_DEBUG),1)
GCC_CFLAGS += -O0 -g
MSVC_CFLAGS += -MDd -Od -Oi- -Oy- -GS -Gd -RTC1 -RTCu -Gs0
CLANG_CFLAGS += -MDd -Od -Oi- -Oy- -GS -Gd -RTC1 -RTCu -Gs0
CFLAGS += -D_DEBUG # -DDEBUG
else
GCC_CFLAGS += -O3 -fomit-frame-pointer
MSVC_CFLAGS += -MD -O2 -Oi -Oy -GS-
CLANG_CFLAGS += -MD -O2 -Oi -Oy -GS-
CFLAGS += -D_RELEASE -DNDEBUG
endif
ifeq ($(USE_MAX_WARNINGS),0)
GCC_CFLAGS += -Wno-unused-variable \
-Wno-format \
-Wno-deprecated \
-Wno-parentheses \
-Wno-unused-value \
-Wno-unused-but-set-variable \
-Wno-maybe-uninitialized
MSVC_CFLAGS += -W2 -wd4005 -wd4127 -wd4146 -wd4214 -wd4273
CLANG_CFLAGS += -W2
ifeq ($(BITS),64)
MSVC_CFLAGS += -wd4244
CC_WARN = -Wno-incompatible-pointer-types
endif
else
MSVC_CFLAGS += -W3
CLANG_CFLAGS += -Wall
endif
CLANG_CFLAGS += -Wno-unused-variable \
-Wno-unused-function \
-Wno-format \
-Wno-switch \
-Wno-macro-redefined \
-Wno-deprecated-declarations \
-Wno-microsoft-include \
-Wno-nonportable-include-path \
-Wno-sometimes-uninitialized \
-Wno-incompatible-pointer-types \
-Wno-implicit-function-declaration
CFLAGS += -I. -I./tests -I./tune -DHAVE_CONFIG_H -D_WIN32_WINNT=0x601
ifeq ($(USE_X86_SSE2),1)
CFLAGS += -I./mpn/x86/pentium4/sse2
else
CFLAGS += -I./mpn/x86
endif
ifneq ($(CC),gcc)
CFLAGS += -I./msvc
endif
#
# Force-include 'MPIR-benchmarks/win_timing.h' to avid the mess in 'msvc/win_timing.h'.
#
ifeq ($(CC),gcc)
CFLAGS += --include MPIR-benchmarks/win_timing.h
else
CFLAGS += -FI./MPIR-benchmarks/win_timing.h
endif
#
# Avoid defining 'min()/max()' macros via '<windows.h>'. That creates
# havoc when including '<mpirxx.h>' after '<windows.h>' or '<winsock2.h'> etc.
#
CFLAGS += -DNOMINMAX
#
# Add this CFLAGS when using 'mpir_$(CPU).dll' in test programs.
# But it doesn't work for e.g. 'tune.exe'. So just drop it.
#
# Since '#ifdef MSC_BUILD_DLL' is tested before this in 'gmp.h',
# it does not hurt to add this here for all .c/.cc rules.
#
# BTW: 'MSC_USE_DLL' and 'MSC_BUILD_DLL' does nothing for 'gcc'.
#
ifeq ($(USE_DLLs_FOR_TEST),1)
$(error Do not set 'USE_DLLs_FOR_TEST=1' as this fails for some programs.)
CFLAGS += -DMSC_USE_DLL=1
endif
#
# What to build:
#
TARGETS = mpir_$(CPU).dll $(MPIR_IMP_LIB) $(MPIR_STAT_LIB)
#
# Use a static 'libstdc++.a' for MinGW.
#
ifeq ($(CC),gcc)
LDFLAGS = -static -m$(BITS) -Wl,--print-map
else ifeq ($(CC),clang-cl)
LDFLAGS = -nologo -incremental:no -nodefaultlib:oldnames.lib -debug -lldmap
else
LDFLAGS = -nologo -incremental:no -nodefaultlib:oldnames.lib -debug -verbose -map
endif
#
# Select correct '-libpath' settings depending on '$(CPU)':
#
ifneq ($(CC),gcc)
VC_ROOT = $(realpath $(VCToolkitInstallDir))
CRT_DIR = $(VC_ROOT)/lib/$(CPU)
#
# The path for the CRT library (msvcrt.lib):
#
LDFLAGS += -libpath:$(CRT_DIR)
#
# 'WindowsKits' root is in $(WK_ROOT) and
# 'WindowsKits' version is in $(WK_VER).
# E.g.:
# WK_ROOT=f:\ProgramFiler-x86\WindowsKits
# WK_VER=10.0.10586.0
#
# Hence the User-Mode libraries for 'x86' is in:
# $(WK_ROOT)/Lib/$(WK_VER)/um/x86/
#
LDFLAGS += -libpath:$(realpath $(WK_ROOT)/Lib/$(WK_VER)/um/$(CPU))
#
# Ditto mess for the UCRT libraries: for 'x86' the UCRT libs are in:
# $(WK_ROOT)/Lib/$(WK_VER)/ucrt/x86/
#
LDFLAGS += -libpath:$(realpath $(WK_ROOT)/Lib/$(WK_VER)/ucrt/$(CPU))
endif
default: all
#
# Libraries for test programs.
#
TEST_LIBS = $(MPIR_TEST_LIB)
ifeq ($(USE_DLLs_FOR_TEST),1)
TEST_LIBS += $(MPIR_IMP_LIB)
else
TEST_LIBS += $(MPIR_STAT_LIB)
endif
BASE_SRC = assert.c errno.c extract-dbl.c invalid.c memory.c mp_bpl.c mp_clz_tab.c \
mp_dv_tab.c mp_get_fns.c mp_minv_tab.c mp_set_fns.c randbui.c randclr.c \
randdef.c randiset.c randlc2s.c randlc2x.c randmt.c randmts.c randmui.c \
rands.c randsd.c randsdui.c tal-reent.c version.c primesieve.c
ifeq ($(USE_CRT_DEBUG),1)
BASE_SRC += tal-debug.c # For WANT_TMP_DEBUG=1
BASE_SRC += tal-notreent.c # For WANT_TMP_NOTREENTRANT=1
endif
FFT_SRC = $(addprefix fft/, \
adjust.c adjust_sqrt2.c butterfly_lshb.c butterfly_rshb.c combine_bits.c div_2expmod_2expp1.c \
fermat_to_mpz.c fft_mfa_trunc_sqrt2.c fft_mfa_trunc_sqrt2_inner.c fft_negacyclic.c fft_radix2.c \
fft_trunc.c fft_trunc_sqrt2.c ifft_mfa_trunc_sqrt2.c ifft_negacyclic.c ifft_radix2.c \
ifft_trunc.c ifft_trunc_sqrt2.c mulmod_2expp1.c mul_2expmod_2expp1.c mul_fft_main.c \
mul_mfa_trunc_sqrt2.c mul_trunc_sqrt2.c normmod_2expp1.c revbin.c split_bits.c)
PRINTF_SRC = $(addprefix printf/, \
asprintf.c asprntffuns.c doprnt.c doprntf.c doprnti.c fprintf.c obprintf.c \
obprntffuns.c obvprintf.c printf.c printffuns.c repl-vsnprintf.c snprintf.c \
snprntffuns.c sprintf.c sprintffuns.c vasprintf.c vfprintf.c vprintf.c \
vsnprintf.c vsprintf.c)
SCANF_SRC = $(addprefix scanf/, \
doscan.c fscanf.c fscanffuns.c scanf.c sscanf.c sscanffuns.c vfscanf.c \
vscanf.c vsscanf.c)
MPN_SRC = $(addprefix mpn/generic/, \
add.c addadd_n.c addsub_n.c add_1.c add_err1_n.c add_err2_n.c \
andn_n.c and_n.c binvert.c bdivmod.c comb_tables.c cmp.c com_n.c dc_bdiv_q.c \
dc_bdiv_qr.c dc_bdiv_qr_n.c dc_bdiv_q_n.c dc_divappr_q.c \
dc_div_q.c dc_div_qr.c dc_div_qr_n.c divexact.c \
matrix22_mul1_inverse_vector.c hgcd_matrix.c hgcd_reduce.c hgcd_appr.c hgcd_jacobi.c \
hgcd_step.c hgcd2_jacobi.c \
divexact_byff.c divexact_byfobm1.c divisible_p.c divrem.c divrem_2.c \
divrem_euclidean_qr_1.c divrem_euclidean_qr_2.c divrem_euclidean_r_1.c \
divrem_hensel_qr_1.c divrem_hensel_qr_1_1.c divrem_hensel_qr_1_2.c \
divrem_hensel_rsh_qr_1.c divrem_hensel_r_1.c dump.c fib2_ui.c fib_table.c \
gcd.c gcdext.c gcdext_1.c gcdext_lehmer.c gcd_1.c jacobi.c \
gcd_subdiv_step.c get_d.c get_str.c hamdist.c hgcd.c hgcd2.c \
invert.c inv_divappr_q.c inv_divappr_q_n.c inv_div_q.c inv_div_qr.c \
inv_div_qr_n.c iorn_n.c ior_n.c jacobi_2.c jacobi_base.c matrix22_mul.c \
mod_1_1.c mod_1_2.c mod_1_3.c \
mp_bases.c mul.c mulhigh_n.c mullow_basecase.c mullow_n.c mullow_n_basecase.c \
mulmid.c mulmid_basecase.c mulmid_n.c mulmod_2expm1.c mulmod_2expp1_basecase.c \
mulmod_bexpp1.c mul_n.c nand_n.c neg_n.c nior_n.c \
perfect_square_p.c popcount.c pow_1.c preinv_mod_1.c \
random.c random2.c randomb.c redc_1.c redc_2.c rootrem.c rootrem_basecase.c \
rrandom.c rsh_divrem_hensel_qr_1.c rsh_divrem_hensel_qr_1_1.c \
rsh_divrem_hensel_qr_1_2.c sb_bdiv_q.c sb_bdiv_qr.c sb_divappr_q.c sb_div_q.c \
sb_div_qr.c scan0.c scan1.c set_str.c sizeinbase.c sqrtrem.c \
sub.c subadd_n.c sub_1.c sub_err1_n.c sub_err2_n.c \
sumdiff_n.c tdiv_q.c tdiv_qr.c toom3_mul.c toom3_mul_n.c toom42_mulmid.c \
toom4_mul.c toom4_mul_n.c toom8h_mul.c toom8_sqr_n.c toom_couple_handling.c \
toom_eval_dgr3_pm1.c toom_eval_dgr3_pm2.c toom_eval_pm1.c toom_eval_pm2.c \
toom_eval_pm2exp.c toom_eval_pm2rexp.c toom_interpolate_16pts.c urandomb.c \
urandomm.c xnor_n.c xor_n.c zero.c preinv_divrem_1.c powm.c powlo.c redc_n.c)
ifeq ($(USE_ASM),0)
MPN_SRC += $(addprefix mpn/generic/, \
addmul_1.c add_n.c copyd.c copyi.c divrem_1.c divexact_1.c \
divexact_by3c.c lshift.c mod_1.c mod_34lsub1.c mul_1.c mul_basecase.c \
rshift.c submul_1.c sub_n.c modexact_1c_odd.c sqr_basecase.c)
endif
MPF_SRC = $(addprefix mpf/, \
abs.c add.c add_ui.c ceilfloor.c clear.c clears.c cmp.c cmp_d.c cmp_si.c \
cmp_ui.c cmp_z.c div.c div_2exp.c div_ui.c dump.c eq.c fits_si.c fits_sint.c \
fits_slong.c fits_sshort.c fits_ui.c fits_uint.c fits_ulong.c \
fits_ushort.c get_d.c get_dfl_prec.c get_d_2exp.c get_prc.c get_si.c \
get_str.c get_ui.c init.c init2.c inits.c inp_str.c int_p.c iset.c \
iset_d.c iset_si.c iset_str.c iset_ui.c mul.c mul_2exp.c mul_ui.c neg.c \
out_str.c pow_ui.c random2.c reldiff.c rrandomb.c set.c set_d.c set_dfl_prec.c \
set_prc.c set_prc_raw.c set_q.c set_si.c set_str.c set_ui.c set_z.c size.c \
sqrt.c sqrt_ui.c sub.c sub_ui.c swap.c trunc.c ui_div.c ui_sub.c urandomb.c)
MPQ_SRC = $(addprefix mpq/, \
abs.c aors.c canonicalize.c clear.c clears.c cmp.c cmp_si.c cmp_ui.c div.c \
equal.c get_d.c get_den.c get_num.c get_str.c init.c inits.c inp_str.c \
inv.c md_2exp.c mul.c neg.c out_str.c set.c set_d.c set_den.c set_f.c \
set_num.c set_si.c set_str.c set_ui.c set_z.c swap.c)
MPZ_SRC = $(addprefix mpz/, \
abs.c add.c add_ui.c and.c aorsmul.c aorsmul_i.c array_init.c bin_ui.c bin_uiui.c \
cdiv_q.c cdiv_qr.c cdiv_qr_ui.c cdiv_q_ui.c cdiv_r.c cdiv_r_ui.c cdiv_ui.c \
cfdiv_q_2exp.c cfdiv_r_2exp.c clear.c clears.c clrbit.c cmp.c cmpabs.c \
cmpabs_d.c cmpabs_ui.c cmp_d.c cmp_si.c cmp_ui.c com.c combit.c cong.c \
cong_2exp.c cong_ui.c divegcd.c divexact.c dive_ui.c divis.c divis_2exp.c \
divis_ui.c dump.c export.c fac_ui.c fdiv_q.c fdiv_qr.c fdiv_qr_ui.c \
fdiv_q_ui.c fdiv_r.c fdiv_r_ui.c fdiv_ui.c fib2_ui.c fib_ui.c fits_si.c \
fits_sint.c fits_slong.c fits_sshort.c fits_ui.c fits_uint.c fits_ulong.c \
fits_ushort.c gcd.c gcdext.c gcd_ui.c getlimbn.c get_d.c get_d_2exp.c get_si.c \
get_str.c get_sx.c get_ui.c get_ux.c hamdist.c import.c init.c init2.c inits.c \
inp_raw.c inp_str.c invert.c ior.c iset.c iset_d.c iset_si.c iset_str.c \
iset_sx.c iset_ui.c iset_ux.c jacobi.c kronsz.c kronuz.c kronzs.c kronzu.c \
lcm.c lcm_ui.c likely_prime_p.c lucnum2_ui.c lucnum_ui.c millerrabin.c \
miller_rabin.c mod.c mul.c mul_2exp.c mul_si.c mul_ui.c neg.c nextprime.c \
next_prime_candidate.c nthroot.c n_pow_ui.c out_raw.c out_str.c perfpow.c perfsqr.c \
popcount.c powm.c powm_ui.c pow_ui.c pprime_p.c probable_prime_p.c realloc.c \
realloc2.c remove.c root.c rootrem.c rrandomb.c scan0.c scan1.c set.c setbit.c \
set_d.c set_f.c set_q.c set_si.c set_str.c set_sx.c set_ui.c set_ux.c size.c \
sizeinbase.c sqrt.c sqrtrem.c sub.c sub_ui.c swap.c tdiv_q.c tdiv_qr.c tdiv_qr_ui.c \
tdiv_q_2exp.c tdiv_q_ui.c tdiv_r.c tdiv_r_2exp.c tdiv_r_ui.c tdiv_ui.c trial_division.c \
tstbit.c ui_pow_ui.c ui_sub.c urandomb.c urandomm.c xor.c 2fac_ui.c mfac_uiui.c oddfac_1.c \
primorial_ui.c prodlimbs.c)
FFT_OBJ = $(FFT_SRC:.c=.$(O))
BASE_OBJ = $(notdir $(BASE_SRC:.c=.$(O)))
# BASE_OBJ = $(call c_to_obj, $(BASE_SRC)), mpir_base/) I.e. '$(BASE_SRC)' goes into '$(OBJ_DOR)/mpir_base/*.$(O)'
MPF_OBJ = $(MPF_SRC:.c=.$(O))
MPN_OBJ = $(MPN_SRC:.c=.$(O))
MPQ_OBJ = $(MPQ_SRC:.c=.$(O))
MPZ_OBJ = $(MPZ_SRC:.c=.$(O))
PRINTF_OBJ = $(PRINTF_SRC:.c=.$(O))
SCANF_OBJ = $(SCANF_SRC:.c=.$(O))
MPIR_OBJ = $(FFT_OBJ) $(BASE_OBJ) $(MPF_OBJ) $(MPN_OBJ) $(MPQ_OBJ) $(MPZ_OBJ) $(PRINTF_OBJ) $(SCANF_OBJ) $(ASM_OBJ)
$(MPIR_OBJ): EXTRA_CFLAGS += $(MPIR_CFLAGS)
#
# Source for $(MPIR_TEST_LIB):
#
TEST_LIB_SRC = $(addprefix tests/, \
misc.c trace.c memory.c refmpn.c refmpf.c refmpq.c refmpz.c) \
$(addprefix tune/, \
common.c divrem1div.c divrem1inv.c divrem2div.c divrem2inv.c \
jacbase1.c jacbase2.c jacbase3.c jacbase4.c mod_1_div.c mod_1_inv.c modlinv.c \
noop.c powm_mod.c powm_redc.c fac_ui_large.c fac_ui_small.c \
set_strb.c set_strs.c gcdextos.c gcdextod.c preinv_divrem_1.c \
gcdext_single.c gcdext_double.c)
TEST_LIB_SRC += $(addprefix tune/, \
hgcd_appr_lehmer.c \
hgcd_lehmer.c \
hgcd_reduce_1.c \
hgcd_reduce_2.c)
#
# Why is this .c-file here?
#
TEST_LIB_SRC += tests/cxx/clocale.c
ifeq ($(CC),gcc)
TEST_LIB_SRC += tune/freq.c \
tune/time.c \
msvc/getrusage.c
else
TEST_LIB_SRC += msvc/getopt.c \
MPIR-benchmarks/win_timing.c
endif
TEST_LIB_OBJ = $(call c_to_obj, $(TEST_LIB_SRC))
TEST_LIB_I = $(call c_to_i, $(TEST_LIB_SRC))
#
# $(TEST_LIB_SRC) must be compiled as cdecl.
#
ifneq ($(CC),gcc)
$(TEST_LIB_OBJ) $(TEST_LIB_I): # EXTRA_CFLAGS += -Gd
endif
#
# Source for test programs:
#
TESTS_SRC = $(addprefix tests/, \
t-bswap.c \
t-constants.c \
t-count_zeros.c \
t-gmpmax.c \
t-hightomask.c \
t-modlinv.c \
t-parity.c \
t-popc.c \
t-sub.c)
TESTS_SRC += $(addprefix tests/fft/, \
t-adjust.c \
t-adjust_sqrt2.c \
t-butterfly.c \
t-butterfly_lshB.c \
t-butterfly_rshB.c \
t-butterfly_sqrt2.c \
t-butterfly_twiddle.c \
t-div_2expmod_2expp1.c \
t-fft_ifft_mfa_trunc_sqrt2.c \
t-fft_ifft_negacyclic.c \
t-fft_ifft_radix2.c \
t-fft_ifft_trunc.c \
t-fft_ifft_trunc_sqrt2.c \
t-mulmod_2expp1.c \
t-mul_2expmod_2expp1.c \
t-mul_fft_main.c \
t-mul_mfa_trunc_sqrt2.c \
t-mul_trunc_sqrt2.c \
t-normmod_2expp1.c \
t-split_combine_bits.c)
TESTS_SRC += $(addprefix tests/misc/, \
t-locale.c \
t-printf.c \
t-scanf.c)
TESTS_SRC += $(addprefix tests/mpf/, \
t-add.c \
t-cmp_d.c \
t-cmp_si.c \
t-conv.c \
t-div.c \
t-dm2exp.c \
t-eq.c \
t-fits.c \
t-get_d.c \
t-get_d_2exp.c \
t-get_si.c \
t-get_ui.c \
t-gsprec.c \
t-inp_str.c \
t-int_p.c \
t-muldiv.c \
t-mul_ui.c \
t-set.c \
t-set_q.c \
t-set_si.c \
t-set_ui.c \
t-sqrt.c \
t-sqrt_ui.c \
t-sub.c \
t-trunc.c \
t-ui_div.c)
TESTS_SRC += $(addprefix tests/mpn/, \
t-addadd_n.c \
t-addsub_n.c \
t-aors_1.c \
t-asmtype.c \
t-dc_bdiv_q.c \
t-dc_bdiv_qr.c \
t-dc_bdiv_qr_n.c \
t-dc_bdiv_q_n.c \
t-dc_divappr_q.c \
t-dc_div_q.c \
t-dc_div_qr.c \
t-dc_div_qr_n.c \
t-divebyff.c \
t-divebyfobm1.c \
t-divrem_1.c \
t-fat.c \
t-gcdext.c \
t-get_d.c \
t-hgcd.c \
t-invert.c \
t-inv_divappr_q.c \
t-inv_divappr_q_n.c \
t-inv_div_q.c \
t-inv_div_qr.c \
t-inv_div_qr_n.c \
t-iord_u.c \
t-logic.c \
t-lorrshift1.c \
t-matrix22.c \
t-mp_bases.c \
t-mullowhigh.c \
t-mullow_basecase.c \
t-mulmid.c \
t-mulmod_2expm1.c \
t-mulmod_2expp1.c \
t-neg.c \
t-perfsqr.c \
t-redc_1.c \
t-sb_bdiv_q.c \
t-sb_bdiv_qr.c \
t-sb_divappr_q.c \
t-sb_div_q.c \
t-sb_div_qr.c \
t-scan.c \
t-subadd_n.c \
t-tdiv_q.c \
t-tdiv_qr.c)
TESTS_SRC += $(addprefix tests/mpq/, \
t-aors.c \
t-cmp.c \
t-cmp_si.c \
t-cmp_ui.c \
t-equal.c \
t-get_d.c \
t-get_str.c \
t-inp_str.c \
t-md_2exp.c \
t-set_f.c \
t-set_str.c)
TESTS_SRC += $(addprefix tests/mpz/, \
t-addsub.c \
t-aorsmul.c \
t-bin.c \
t-cdiv_ui.c \
t-cmp.c \
t-cmp_d.c \
t-cmp_si.c \
t-cong.c \
t-cong_2exp.c \
t-divis.c \
t-divis_2exp.c \
t-div_2exp.c \
t-export.c \
t-fac_ui.c \
t-fdiv.c \
t-fdiv_ui.c \
t-fib_ui.c \
t-fits.c \
t-gcd.c \
t-gcd_ui.c \
t-get_d.c \
t-get_d_2exp.c \
t-get_si.c \
t-get_sx.c \
t-get_ux.c \
t-hamdist.c \
t-import.c \
t-inp_str.c \
t-io_raw.c \
t-jac.c \
t-lcm.c \
t-likely_prime_p.c \
t-lucnum_ui.c \
t-mul.c \
t-mul_i.c \
t-next_prime_candidate.c \
t-oddeven.c \
t-perfpow.c \
t-perfsqr.c \
t-popcount.c \
t-pow.c \
t-powm.c \
t-powm_ui.c \
t-pprime_p.c \
t-root.c \
t-scan.c \
t-set_d.c \
t-set_f.c \
t-set_si.c \
t-set_str.c \
t-set_sx.c \
t-set_ux.c \
t-sizeinbase.c \
t-sqrtrem.c \
t-tdiv.c \
t-tdiv_ui.c \
t-trial_division.c)
TESTS_SRC += $(addprefix tests/rand/, \
t-iset.c \
t-lc2exp.c \
t-mt.c \
t-rand.c \
t-urbui.c \
t-urmui.c \
t-urndmm.c)
TESTS_OBJ = $(call c_to_obj, $(TESTS_SRC))
TESTS_I = $(call c_to_i, $(TESTS_SRC))
.SECONDARY: $(TESTS_OBJ)
ifeq ($(CC),cl)
ifeq ($(USE_MAX_WARNINGS),0)
$(TESTS_OBJ) $(TESTS_I): EXTRA_CFLAGS += -wd4477 -wd4305
endif
endif
#
# Test programs for the C++ code in '$(MPIR_STAT_LIB)'.
#
# I failed to get them to link with '$(MPIR_IMP_LIB)'.
# Hence do not use '-DMSC_USE_DLL' for these.
#
TESTS_CXX_SRC = $(addprefix tests/cxx/, \
t-assign.cc \
t-binary.cc \
t-cast.cc \
t-constr.cc \
t-headers.cc \
t-istream.cc \
t-locale.cc \
t-misc.cc \
t-ops.cc \
t-ostream.cc \
t-prec.cc \
t-ternary.cc \
t-unary.cc \
t-rand.cc)
TESTS_CXX_OBJ = $(call cc_to_obj, $(TESTS_CXX_SRC), mpirxx/)
TESTS_CXX_I = $(call cc_to_i, $(TESTS_CXX_SRC))
#
# Cannot use 'mpir_$(CPU).dll' !
#
$(TESTS_CXX_OBJ) $(TESTS_CXX_I): EXTRA_CFLAGS = -UMSC_USE_DLL
OTHER_TESTS_SRC = $(addprefix tests/mpz/, \
bit.c \
convert.c \
dive.c \
dive_ui.c \
io.c \
logic.c \
reuse.c)
OTHER_TESTS_OBJ = $(call c_to_obj, $(OTHER_TESTS_SRC))
TEST_PROGRAMS = $(notdir $(TESTS_OBJ:.$(O)=.exe)) \
$(notdir $(TESTS_CXX_OBJ:.$(O)=.exe)) \
$(notdir $(OTHER_TESTS_OBJ:.$(O)=.exe)) \
speed.exe tune.exe stat.exe gen.exe
ifeq ($(USER),gv)
TEST_PROGRAMS += win_timing.exe
endif
TEST_PROGRAMS := $(sort $(TEST_PROGRAMS))
all: intro obj_dirs $(GENERATED) $(TARGETS) # tests
$(call green_msg, Welcome to the MPIR Library.\n)
intro:
$(call green_msg, Building MPIR version '$(VERSION)'.\nFeatures:)
$(call green_msg0, LIMB_BITS: $(LIMB_BITS).)
$(call green_msg0, NAIL_BITS: $(NAIL_BITS).)
$(call green_msg0, USE_ASM: $(USE_ASM).)
$(call green_msg0, CURDIR: $(CURDIR).)
$(call green_msg0, MAKE_HOST: $(MAKE_HOST).)
$(call green_msg0, SHELL: $(SHELL).)
obj_dirs:
- mkdir --parents $(OBJ_DIR)/mpirxx
help:
$(call green_msg, Usage: make -f $(THIS_FILE) <CPU=x86 | x64> CC=[gcc | cl] <targets>.)
$(call green_msg0, <targets>:$(BRIGHT_WHITE) all$(comma) clean$(comma) \
vclean$(comma) realclean$(comma) depend$(comma) \
tests$(comma) tune$(comma) run_tests$(comma) run_speed.)
ifeq ($(USE_ASM),1)
#
# Do not set VPATH for .asm-files. It confuses the hell out of GNU-make
# since there are multiple .asm-files. E.g. mod_1.asm are here:
# mpn/x86w/mod_1.asm
# mpn/x86w/p3/mod_1.asm
# mpn/x86w/p6/mod_1.asm
#
# Ref. the below "$(call Assemble)" below. They MUST be called in correct order.
#
$(OBJ_DIR)/asm_divrem_1.$(O): mpn/x86w/divrem_1.asm
$(OBJ_DIR)/asm_udiv_qrnnd.$(O): mpn/x86w/udiv_qrnnd.asm
$(OBJ_DIR)/asm_umul_ppmm.$(O): mpn/x86w/umul_ppmm.asm
$(OBJ_DIR)/asm_mod_1.$(O): mpn/x86w/mod_1.asm
$(OBJ_DIR)/asm_copyd.$(O): mpn/x86w/p4/copyd.asm
$(OBJ_DIR)/asm_copyi.$(O): mpn/x86w/p4/copyi.asm
$(OBJ_DIR)/asm_lshift.$(O): mpn/x86w/p4/lshift.asm
$(OBJ_DIR)/asm_rshift.$(O): mpn/x86w/p4/rshift.asm
$(OBJ_DIR)/asm_addmul_1.$(O): mpn/x86w/p4/sse2/addmul_1.asm
$(OBJ_DIR)/asm_add_n.$(O): mpn/x86w/p4/sse2/add_n.asm
$(OBJ_DIR)/asm_divexact_1.$(O): mpn/x86w/p4/sse2/divexact_1.asm
$(OBJ_DIR)/asm_divexact_by3c.$(O): mpn/x86w/p4/sse2/divexact_by3c.asm
$(OBJ_DIR)/asm_modexact_1c_odd.$(O): mpn/x86w/p4/sse2/modexact_1c_odd.asm
$(OBJ_DIR)/asm_mod_34lsub1.$(O): mpn/x86w/p4/sse2/mod_34lsub1.asm
$(OBJ_DIR)/asm_mul_1.$(O): mpn/x86w/p4/sse2/mul_1.asm
$(OBJ_DIR)/asm_mul_basecase.$(O): mpn/x86w/p4/sse2/mul_basecase.asm
$(OBJ_DIR)/asm_sqr_basecase.$(O): mpn/x86w/p4/sse2/sqr_basecase.asm
$(OBJ_DIR)/asm_submul_1.$(O): mpn/x86w/p4/sse2/submul_1.asm
$(OBJ_DIR)/asm_sub_n.$(O): mpn/x86w/p4/sse2/sub_n.asm
MPN_ASM_X86W = $(addprefix mpn/x86w/, \
divexact_1.asm \
divrem_1.asm \
mod_1.asm \
udiv_qrnnd.asm \
umul_ppmm.asm)
MPN_ASM_X86W_P4 = $(addprefix mpn/x86w/p4/, \
copyd.asm \
copyi.asm \
lshift.asm \
rshift.asm)
MPN_ASM_X86W_P4_SSE2 = $(addprefix mpn/x86w/p4/sse2/, \
addmul_1.asm \
add_n.asm \
divexact_1.asm \
divexact_by3c.asm \
modexact_1c_odd.asm \
mod_34lsub1.asm \
mul_1.asm \
mul_basecase.asm \
sqr_basecase.asm \
submul_1.asm \
sub_n.asm)
ASM_SRC = $(MPN_ASM_X86W) $(MPN_ASM_X86W_P4) $(MPN_ASM_X86W_P4_SSE2)
ASM_OBJ = $(call asm_to_obj, $(ASM_SRC), asm_)
endif
MPIRXX_SRC = $(addprefix cxx/, \
dummy.cc \
isfuns.cc \
ismpf.cc \
ismpq.cc \
ismpz.cc \
ismpznw.cc \
osdoprnti.cc \
osfuns.cc \
osmpf.cc \
osmpq.cc \
osmpz.cc)
#
# Add these to '$(MPIR_STAT_LIB)'.
#
MPIRXX_OBJ = $(call cc_to_obj, $(MPIRXX_SRC))
MPIRXX_I = $(call cc_to_i, $(MPIRXX_SRC))
#
# If 'USE_DEF_FILE == 1', simply add these to the '$(MPIR_IMP_LIB)'
# after linking 'mpir_$(CPU).dll'.
#
# If 'USE_DEF_FILE == 0', these dynamic .$(O)-files are linked
# together with '$(MPIR_OBJ)'.
#
MPIRXX_DLL_OBJ = $(call cc_to_obj, $(MPIRXX_SRC), mpirxx/)
MPIRXX_DLL_I = $(call cc_to_i, $(MPIRXX_SRC), mpirxx/)
$(MPIRXX_DLL_OBJ) $(MPIRXX_DLL_I): EXTRA_CFLAGS = $(MPIR_CFLAGS)
#
# E.g. $(call generate, config.h, //)
#
define generate
$(call green_msg, Generating $(1)...)
$(file > $(1),$(call Warning, $(1), $(2)))
endef
define Warning
$(2)
$(2) This file ($(strip $(1))) was generated at $(TODAY) from
$(2) $(realpath $(THIS_FILE)).
$(2) DO NOT EDIT!.
$(2)
endef
define CONFIG_H
#ifndef GMP_CONFIG_H
#define GMP_CONFIG_H
#include <stdio.h>
#define HAVE_NATIVE_mpn_add_n 1
#define HAVE_NATIVE_mpn_addmul_1 1
#define HAVE_NATIVE_mpn_addmul_1c 1
#define HAVE_NATIVE_mpn_copyd $(USE_ASM)
#define HAVE_NATIVE_mpn_copyi $(USE_ASM)
#define HAVE_NATIVE_mpn_divrem_1 $(USE_ASM)
#define HAVE_NATIVE_mpn_divexact_1 1
#define HAVE_NATIVE_mpn_divrem_1c 0
#define HAVE_NATIVE_mpn_lshiftc 0
#define HAVE_NATIVE_mpn_lshift1 0
#define HAVE_NATIVE_mpn_lshift2 0
#define HAVE_NATIVE_mpn_mod_1 1
#define HAVE_NATIVE_mpn_mod_1c 0
#define HAVE_NATIVE_mpn_modexact_1_odd 0
#define HAVE_NATIVE_mpn_mul_1 1
#define HAVE_NATIVE_mpn_rshift 1
#define HAVE_NATIVE_mpn_sqr_basecase 1
#define HAVE_NATIVE_mpn_sqr_diagonal 0
#define HAVE_NATIVE_mpn_sub_n 1
#define HAVE_NATIVE_mpn_submul_1 1
#define HAVE_NATIVE_mpn_submul_1c 1
#define HAVE_NATIVE_mpn_umul_ppmm 0
#define HAVE_NATIVE_mpn_udiv_qrnnd 0
#define HAVE_ALLOCA 1
#define HAVE_ATTRIBUTE_MODE 1
#define HAVE_UNISTD_H 1 /* For 'MSVC/clang-cl', this is 'msvc/getopt.h' */
#if defined(__GNUC__)
#define HAVE_ATTRIBUTE_CONST 1
#define HAVE_ATTRIBUTE_MALLOC 1
#define HAVE_ATTRIBUTE_NORETURN 1
#if defined(__MINGW32__)
#define HAVE_INTTYPES_H 1
#define HAVE_SYS_PARAM_H 1
#define HAVE_SYS_TIME_H 1
#define TIME_WITH_SYS_TIME 1
#define HAVE_DECL_OPTARG 1
#define VERSION "$(VERSION)"
#endif
#endif
#define __GMP_HAVE_CONST 1
#define __GMP_HAVE_PROTOTYPES 1
#define __GMP_HAVE_TOKEN_PASTE 1
#define HAVE_CALLING_CONVENTIONS 1
#define HAVE_CLOCK 1
#define HAVE_GETRUSAGE 1
#define HAVE_DECL_FGETC 1
#define HAVE_DECL_FSCANF 1
#define HAVE_DECL_UNGETC 1
#define HAVE_DECL_VFPRINTF 1
#define HAVE_DOUBLE_IEEE_LITTLE_ENDIAN 1
#define HAVE_FCNTL_H 1
#define HAVE_INTMAX_T 1
#define HAVE_LIMB_LITTLE_ENDIAN 1
#define HAVE_LOCALECONV 1
#define HAVE_LOCALE_H 1
#define HAVE_LONG_DOUBLE 1
#define HAVE_LONG_LONG 1
#define HAVE_MEMORY_H 1
#define HAVE_MEMSET 1
#define HAVE_POPEN 1
#define HAVE_PTRDIFF_T 1
#define HAVE_RAISE 1
/* Tune directory speed_cyclecounter, undef=none,1=32bits, 2=64bits)
*/
#define HAVE_SPEED_CYCLECOUNTER 2
#define HAVE_STDARG 1
#define HAVE_STDINT_H 1
#define HAVE_STDLIB_H 1
#define HAVE_STRCASECMP 1
#define HAVE_STRNCASECMP 1
#define HAVE_STRCHR 1
#define HAVE_STRINGIZE 1
#define HAVE_STRINGS_H 1
#define HAVE_STRING_H 1
#define HAVE_STRTOUL 1
#define HAVE_SYS_STAT_H 1
#define HAVE_SYS_TYPES_H 1
#define HAVE_VSNPRINTF 1
#define LSYM_PREFIX "L"
#define PACKAGE "mpir"
#define PROTOTYPES 1
#define RETSIGTYPE void
#define SIZEOF_UNSIGNED_SHORT 2
#define SIZEOF_UNSIGNED_LONG 4
#define SIZEOF_UNSIGNED 4
#define STDC_HEADERS 1
#define YYTEXT_POINTER 1
#define WANT_FAT_BINARY $(USE_FAT_BINARY)
/*
* Many of the ASSERT() calls in the code stems from the GMP days.
* The MPIR folks have made improvements in MPIR that remove some
* of the restrictions that a number of these ASSERT()s enforce. And
* since many (most?) of these folks seems to build w/o WANT_ASSERT,
* these ASSERT-calls are bogus. Same goes for code inside 'DEBUG'.
* Don't confuse '_DEBUG' with 'DEBUG'.
*/
#ifndef WANT_ASSERT
#define WANT_ASSERT $(USE_CRT_DEBUG)
#endif
/*
* Only one (1) of the below 'WANT_TMP_x' can be set. 'WANT_TMP_ALLOCA=1'
* seems to be fastest. alloca() should always be reentrant.
*/
#define WANT_TMP_DEBUG $(USE_CRT_DEBUG)
#define WANT_TMP_REENTRANT 0
#define WANT_TMP_NOTREENTRANT $(USE_CRT_DEBUG)
#define WANT_TMP_ALLOCA (1-$(USE_CRT_DEBUG))
#define WANT_FFT 1
#if defined(_MSC_VER)
#if defined(_DEBUG)
#define _CRTDBG_MAP_ALLOC
#undef _malloca /* Avoid MSVC-9 <malloc.h>/<crtdbg.h> name-clash */
#include <crtdbg.h>
#endif
#if !defined(__cplusplus)
#define inline __inline
#endif
#define restrict
/* For max speed with MSVC we use 'LDFLAGS=-nodefaultlib:oldnames.lib'. Hence
* define away those old names.
*/
#define access _access
#define alloca _alloca
#define popen _popen
#define getpid _getpid
#define strcasecmp _stricmp
#define strncasecmp _strnicmp
#define unlink _unlink
// #define printf _printf
#if (_MSC_VER < 1900)
#define snprintf _snprintf
#endif
#define HAVE_SYS_PARAM_H 0
#define HAVE_SYS_TIME_H 0
#define TIME_WITH_SYS_TIME 0
#define HAVE_DECL_OPTARG 0
#if 0
/* Special <crtdefs.h> defines:
*/
#define _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_DEPRECATE
#define _CRT_SECURE_NO_WARNINGS_GLOBALS
#define _CRT_NONSTDC_NO_WARNINGS
#define _CRT_OBSOLETE_NO_WARNINGS
#endif
#endif
#if defined(__GNUC__)
#define restrict __restrict__
#endif
#if defined(__cplusplus)
#define HAVE_SSTREAM 1
#endif
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <winsock2.h>
#ifndef SIZEOF_UINTMAX_T
#define SIZEOF_UINTMAX_T 8
#endif
#if defined(MSC_USE_DLL) && !defined(MSC_BUILD_DLL)
extern __declspec(dllimport) const unsigned char __gmpn_clz_tab[];
#endif
#if defined(__MINGW32__)
#include "msvc/getrusage.h"
#if defined(__x86_64__)
/*
* Ripped from:
* https://stackoverflow.com/questions/9887839/how-to-count-clock-cycles-with-rdtsc-in-gcc-x86
*/
static __inline__ void speed_cyclecounter (unsigned p[2])
{
unsigned hi, lo;
__asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
p[0] = lo;
p[1] = hi;
}
#endif
#endif
#endif /* GMP_CONFIG_H */
endef
define RC_COMMON
#include <winver.h>
#if !defined(RC_DLL_NAME)
#error "Define 'RC_DLL_NAME' first."
#endif
#if !defined(RC_DESCRIPTION)
#error "Define a 'RC_DESCRIPTION' first."
#endif
#if defined(__clang__)
#define RC_TARGET "clang-cl"
#elif defined(_MSC_VER)
#define RC_TARGET "MSVC"
#elif defined(__MINGW32__)
#define RC_TARGET "MinGW"
#else
#error "Who are you?"
#endif
VS_VERSION_INFO VERSIONINFO
FILEVERSION $(VER_MAJOR), $(VER_MINOR), $(VER_PATCH), 0
PRODUCTVERSION $(VER_MAJOR), $(VER_MINOR), $(VER_PATCH), 0
FILEFLAGSMASK 0x3fL
FILEOS 0x40004L
FILETYPE 0x2L
FILESUBTYPE 0x0L
#if defined(_DEBUG)
#define RC_VER_STR "$(VERSION).0 (debug)"
FILEFLAGS 0x1L
#else
#define RC_VER_STR "$(VERSION).0 (release)"
FILEFLAGS 0x0L
#endif
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", "https://github.com/BrianGladman/mpir.git"
VALUE "FileDescription", "MPIR library; " RC_DESCRIPTION
VALUE "FileVersion", RC_VER_STR
VALUE "InternalName", RC_DLL_NAME " (" RC_TARGET ", $(BITS)-bits)"
VALUE "LegalCopyright", ""
VALUE "LegalTrademarks", ""
VALUE "OriginalFilename", RC_DLL_NAME
VALUE "ProductName", "MPIR"
VALUE "ProductVersion", RC_VER_STR
VALUE "PrivateBuild", "The privat build of <[email protected]>."
VALUE "SpecialBuild", ""
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
endef
export CONFIG_H RC_COMMON
define generate_rc
$(call generate, $(1), //)
@echo ' #define RC_DLL_NAME $(2)' >> $(1)
@echo ' #define RC_DESCRIPTION $(3)' >> $(1)
@echo "$$RC_COMMON" >> $(1)
endef
$(OBJ_DIR)/%.res: $(OBJ_DIR)/%.rc
$(call create_res, $<, $@)
#####################################################################################
gcc.args: $(THIS_FILE)
$(call green_msg, Generating $@.)
$(call make_resp_file, $@, -c $(GCC_CFLAGS) $(CFLAGS))
cl.args: $(THIS_FILE)
$(call green_msg, Generating $@.)
$(call make_resp_file, $@, -c $(MSVC_CFLAGS) $(CFLAGS))
clang-cl.args: $(THIS_FILE)
$(call green_msg, Generating $@.)
$(call make_resp_file, $@, -c $(CLANG_CFLAGS) $(CFLAGS))
config.h: $(THIS_FILE)
$(call generate, $@, //)
@echo "$$CONFIG_H" >> $@
install: gmp.h mpir.h mpir_$(CPU).dll $(MPIR_STAT_LIB) $(MPIR_IMP_LIB)
cp --update gmp.h mpir.h $(INSTALL_ROOT)/include
cp --update mpir_$(CPU).dll $(INSTALL_ROOT)/bin
cp --update $(MPIR_STAT_LIB) $(INSTALL_ROOT)/lib
cp --update $(MPIR_IMP_LIB) $(INSTALL_ROOT)/lib
ifeq ($(CC),cl)
SED_CFLAGS = $(MSVC_CFLAGS)
else ifeq ($(CC),clang-cl)
SED_CFLAGS = $(CLANG_CFLAGS)
else
SED_CFLAGS = $(GCC_CFLAGS)
endif
SED_CFLAGS += $(CFLAGS)
gmp.h: gmp-h.in $(MDEPEND)
$(call generate, $@, //)
@sed -e 's|@GMP_LIMB_BITS@|$(LIMB_BITS)|' \
-e 's|@BITS_PER_MP_LIMB@|$(LIMB_BITS)|' \
-e 's|@GMP_NAIL_BITS@|$(NAIL_BITS)|' \
-e 's|@DEFN_LONG_LONG_LIMB@||' \
-e 's|__WIN64|_WIN64|' \
-e 's|@CC@|$(CC)|' \
-e 's|@CFLAGS@|$(strip $(SED_CFLAGS))|' \
-e 's|@GMP_CC@|#define GMP_CC __MPIR_CC|' \
-e 's|@GMP_CFLAGS@|#define GMP_CFLAGS __MPIR_CFLAGS|' \
-e 's|\#define __GMP_LIBGMP_DLL.*@LIBGMP_DLL@||' < $< >> $@
@echo -e '\n#define SIZEOF_MP_LIMB_T (GMP_LIMB_BITS >> 3)' >> $@
mpir.h: gmp.h
$(call generate, $@, //)
@echo '#include <gmp.h>' >> $@
longlong.h: longlong_pre.h mpn/x86/i386/longlong_inc.h longlong_post.h
$(call generate, $@, //)
@echo "/* inserting 'longlong_pre.h' inline */" >> $@
cat longlong_pre.h >> $@
@echo "/* inserting 'mpn/x86/i386/longlong_inc.h' inline */" >> $@
cat mpn/x86/i386/longlong_inc.h >> $@
@echo "/* inserting 'longlong_post.h' inline */" >> $@
cat longlong_post.h >> $@
#
# Extract code-symbols from object files in 'nm.args' that starts
# with prefixes in '$(1)'. Only x86 symbols starts with a '_'.
#
ifeq ($(BITS),32)
uscore := _
endif
extract_code_syms = nm @nm.args 2> NUL | grep -o $(foreach s, $(1), -e " T $(uscore)$(s).*") | \
sed "s/^.* $(uscore)/ /" >> $(2)
define extra_exports
mpir_sqrt
mpir_is_likely_prime_BPSW
__fermat_to_mpz
__gmp_default_fp_limb_precision DATA
__gmp_allocate_func DATA
__gmp_free_func DATA
__gmp_reallocate_func DATA
__gmp_modlimb_invert_table DATA
__gmp_bits_per_limb DATA
__gmp_fib_table DATA
__gmp_rands_initialized DATA
__gmp_rands DATA
__gmpn_bases DATA
__gmp_fac2cnt_table DATA
__gmp_oddfac_table DATA
__gmp_odd2fac_table DATA
__gmp_limbroots_table DATA
endef
define extra_exports_cl
;
; Needed by MSVC/clang-cl only!
;
__gmpn_clz_tab DATA
;
; Needed by e.g. 't-istream.cc' when using '-DMSC_USE_DLL' (which does not work):
;
; ??5@YAAAV?$basic_istream@DU?$char_traits@D@std@@@std@@AAV01@PAU__mpz_struct@@@Z
; ??5@YAAAV?$basic_istream@DU?$char_traits@D@std@@@std@@AAV01@PAU__mpq_struct@@@Z
; ??5@YAAAV?$basic_istream@DU?$char_traits@D@std@@@std@@AAV01@PAU__mpf_struct@@@Z
endef
export extra_exports extra_exports_cl
#
# Generate a .def-file using 'nm ...'.
#
$(OBJ_DIR)/mpir.def: $(THIS_FILE)
$(call generate, $@, ; )
@echo -en 'LIBRARY mpir_$(CPU).dll\nEXPORTS\n' >> $@
$(call make_resp_file, nm.args, $(MPIR_OBJ))
$(call extract_code_syms, __gmp __mpir mpf_, $@)
@echo "$$extra_exports" >> $@
ifneq ($(CC),gcc)
@echo "$$extra_exports_cl" >> $@
endif
$(MPIR_IMP_LIB): mpir_$(CPU).dll
ifeq ($(USE_DEF_FILE),1)
mpir_$(CPU).dll: $(MPIR_OBJ) $(MPIRXX_DLL_OBJ) $(OBJ_DIR)/mpir.def $(OBJ_DIR)/mpir.res
$(call link_DLL, $@, $(MPIR_IMP_LIB), $(MPIR_OBJ) $(OBJ_DIR)/mpir.res $(call DEF, $(OBJ_DIR)/mpir.def))
$(call add_lib, $(MPIR_IMP_LIB), $(MPIRXX_DLL_OBJ))
else
ifneq ($(CC),gcc)
EXTRA_EXPORT = # -export:__gmpn_clz_tab
endif
mpir_$(CPU).dll: $(MPIR_OBJ) $(MPIRXX_DLL_OBJ) $(OBJ_DIR)/mpir.res
$(call link_DLL, $@, $(MPIR_IMP_LIB), $^ $(EXTRA_EXPORT))
endif
$(MPIR_STAT_LIB): $(MPIR_OBJ) $(MPIRXX_OBJ)
$(call create_lib, $@, $^)
$(OBJ_DIR)/mpir.rc: $(THIS_FILE)
$(call generate_rc, $@, "mpir_$(CPU).dll", "Core API")
bench: $(MPIR_STAT_LIB)
$(MAKE) -f Makefile.Windows -C MPIR-benchmarks CC=$(CC) clean all
tests: $(TEST_LIBS) $(TEST_PROGRAMS)
$(call green_msg, TEST_PROGRAMS done.)
$(MPIR_TEST_LIB): $(TEST_LIB_OBJ)
$(call create_lib, $@, $^)
### Compile rules for .c-files: #####################################################
ifeq ($(USE_MP_COMPILE),1)
$(FFT_OBJ): $(FFT_SRC) | $(CC).args
$(call C_MP_Compile, $(FFT_SRC), fft, FFT_SRC)
$(BASE_OBJ): $(BASE_SRC) | $(CC).args
$(call C_MP_Compile, $(BASE_SRC), ., BASE_SRC)
$(MPF_OBJ): $(MPF_SRC) | $(CC).args
$(call C_MP_Compile, $(MPF_SRC), mpf, MPF_SRC)
$(MPN_OBJ): $(MPN_SRC) | $(CC).args
$(call C_MP_Compile, $(MPN_SRC), mpn/generic, MPN_SRC)
$(MPQ_OBJ): $(MPQ_SRC) | $(CC).args
$(call C_MP_Compile, $(MPQ_SRC), mpq, MPQ_SRC)
$(MPZ_OBJ): $(MPZ_SRC) | $(CC).args
$(call C_MP_Compile, $(MPZ_SRC), mpz, MPZ_SRC)
$(PRINTF_OBJ): $(PRINTF_SRC) | $(CC).args
$(call C_MP_Compile, $(PRINTF_SRC), printf, PRINTF_SRC)
$(SCANF_OBJ): $(SCANF_SRC) | $(CC).args
$(call C_MP_Compile, $(SCANF_SRC), scanf, SCANF_SRC)
$(TEST_LIB_OBJ): $(TEST_LIB_SRC) | $(CC).args
$(call C_MP_Compile, $(TEST_LIB_SRC), $(OBJ_DIR), TEST_LIB_SRC)
$(MPIRXX_OBJ): $(MPIRXX_SRC) | $(CC).args
$(call C_MP_Compile, $(MPIRXX_SRC), $(OBJ_DIR), MPIRXX_SRC)
#
# Must be compiled twice since the 'mpir.def' does not add C++ symbols.
# (tricky to generate a .def-file for C++ symbols).
#
$(MPIRXX_DLL_OBJ): $(MPIRXX_SRC) | $(CC).args
$(call C_MP_Compile, $(MPIRXX_SRC), $(OBJ_DIR)/mpirxx, MPIRXX_SRC)
else
fft/%.$(O): fft/%.c | $(CC).args
$(call C_Compile, $<, $@)
mpf/%.$(O): mpf/%.c | $(CC).args
$(call C_Compile, $<, $@)
mpq/%.$(O): mpq/%.c | $(CC).args
$(call C_Compile, $<, $@)
mpz/%.$(O): mpz/%.c | $(CC).args
$(call C_Compile, $<, $@)
mpn/generic/%.$(O): mpn/generic/%.c | $(CC).args
$(call C_Compile, $<, $@)
printf/%.$(O): printf/%.c | $(CC).args
$(call C_Compile, $<, $@)
scanf/%.$(O): scanf/%.c | $(CC).args
$(call C_Compile, $<, $@)
$(OBJ_DIR)/%.$(O): tests/%.c | $(CC).args
$(call C_Compile, $<, $@)
$(OBJ_DIR)/%.$(O): tune/%.c | $(CC).args
$(call C_Compile, $<, $@)
endif
$(OBJ_DIR)/msvc_%.$(O): %.c | $(CC).args
$(call C_Compile, $<, $@)
$(OBJ_DIR)/%.$(O): cxx/%.c | $(CC).args
$(call trace, Using cxx rule for .c-files)
$(call C_Compile, $<, $@)
### Compile rules for .cc-files: ####################################################
$(OBJ_DIR)/%.$(O): cxx/%.cc | $(CC).args
$(call trace, Using mpirxx for .cc-files)
$(call CC_Compile, $<, $@)
$(OBJ_DIR)/mpirxx/%.$(O): cxx/%.cc | $(CC).args
$(call trace, Using mpirxx for .cc-files)
$(call CC_Compile, $<, $@)
$(OBJ_DIR)/mpirxx/%.$(O): tests/cxx/%.cc | $(CC).args
$(call trace, Using mpirxx for tests .cc-files)
$(call CC_Compile, $<, $@)
#
# The 2 final rules for .c-files in VPATH:
#
%.$(O): %.c | $(CC).args
$(call trace, Using default rule 1.)
$(call C_Compile, $<, $@)
$(OBJ_DIR)/%.$(O): %.c | $(CC).args
$(call trace, Using default rule 2.)
$(call C_Compile, $<, $@)
### Compile rules for .asm-files: ###################################################
#
# The order of these rules is important:
#
$(OBJ_DIR)/asm_%.$(O): mpn/x86w/p4/sse2/%.asm
$(call Assemble, $<, $@)
$(OBJ_DIR)/asm_%.$(O): mpn/x86w/p4/%.asm
$(call Assemble, $<, $@)
$(OBJ_DIR)/asm_%.$(O): mpn/x86w/%.asm
$(call Assemble, $<, $@)
.PHONY: asm_test
asm_test: $(OBJ_DIR)/asm_copyd.$(O) $(OBJ_DIR)/asm_divrem_1.$(O)
### Link rules for C tests: #########################################################
t-%.exe: $(OBJ_DIR)/t-%.$(O) $(TEST_LIBS)
$(call link_EXE, $@, $^)
### Link rules for C++ tests: #######################################################
t-%.exe: $(OBJ_DIR)/mpirxx/t-%.$(O) $(TEST_LIBS)
$(call link_EXE_cc, $@, $^)
### Link rules for other programs ###################################################
ifeq ($(CC),gcc)
stat.exe: $(addprefix $(OBJ_DIR)/, stat.o statlib.o zdiv_round.o)
$(call C_Compile, $^, $(OBJ_DIR)\\ )
$(call link_EXE, $@, $^ $(TEST_LIBS))
else
stat.exe: $(addprefix tests/rand/, stat.c statlib.c zdiv_round.c) | $(CC).args
$(call C_Compile, -D_USE_MATH_DEFINES $^, $(OBJ_DIR)\\ )
$(call link_EXE, $@, -stack:5000000 $(call c_to_obj, $^) $(TEST_LIBS))
endif
gen.exe: tests/rand/gen.c | $(CC).args
$(call C_Compile, $<, $(OBJ_DIR)/gen.$(O))
$(call link_EXE, $@, $(OBJ_DIR)/gen.$(O) $(TEST_LIBS))
%.exe: tests/mpz/%.c | $(CC).args
$(call C_Compile, $<, $(OBJ_DIR)/$*.$(O))
$(call link_EXE, $@, $(OBJ_DIR)/$*.$(O) $(TEST_LIBS))
tune: speed.exe tune.exe
TUNE_LIBS = $(MPIR_TEST_LIB) $(MPIR_STAT_LIB)
ifeq ($(CC),gcc)
TUNE_EX_LIBS = -lpsapi -ladvapi32 -lversion
else
TUNE_EX_LIBS = psapi.lib advapi32.lib version.lib
endif
speed.exe: $(OBJ_DIR)/speed.$(O) $(TEST_LIBS)
$(call link_EXE, $@, $^ $(TUNE_EX_LIBS))
TUNE_SRC = tune/set_strp.c \
tune/tuneup.c
TUNE_SRC += $(addprefix $(MSVC_DIR)/mpir-tune/tune/, \
mod_1.c \
divrem_1.c \
fac_ui.c)
TUNE_OBJ = $(TUNE_SRC:.c=.$(O))
#
# Cannot use 'mpir_$(CPU).dll' !
#
$(TUNE_OBJ): EXTRA_CFLAGS = -UMSC_USE_DLL
tune_clean:
rm -f $(TUNE_OBJ)
$(MSVC_DIR)/mpir-tune/tune/%.obj: $(MSVC_DIR)/mpir-tune/tune/%.c | $(CC).args
$(call C_Compile, $<, $@)
tune.exe: $(TUNE_SRC:.c=.$(O)) $(MPIR_TEST_LIB) $(MPIR_STAT_LIB)
$(call link_EXE, $@, $^ $(TUNE_EX_LIBS))
win_timing.exe: $(OBJ_DIR)/test_win_timing.$(O) | $(CC).args
$(call link_EXE, $@, $< $(TUNE_EX_LIBS))
$(OBJ_DIR)/test_win_timing.$(O): MPIR-benchmarks/win_timing.c
$(call C_Compile, -DTEST_WIN_TIMING $<, $@)
#####################################################################################
clean_test:
rm -f $(MPIR_TEST_LIB): $(TEST_LIB_OBJ)
clean_doc:
$(MAKE) -f $(THIS_FILE) -C doc clean
clean: clean_doc
$(call green_msg, Deleting all objects.)
$(call make_resp_file, clean_files.args, \
$(MPIR_OBJ) $(MPIRXX_OBJ) $(MPIRXX_DLL_OBJ) \
$(OBJ_DIR)/*.$(O) $(OBJ_DIR)/mpirxx/*.$(O) $(OBJ_DIR)/*.lst \
$(OBJ_DIR)/mpir.rc $(OBJ_DIR)/mpir.res $(OBJ_DIR)/mpir.def \
tune/*.$(O) mpn/generic/*.$(O) \
$(CC).args $(TEST_PROGRAMS:.exe=.map) link.args link.tmp \
lib.args nm.args depend_files.args run-all-tests.py)
rm -f @clean_files.args
- rmdir --parents $(OBJ_DIR)/mpirxx
vclean realclean: clean clean_$(CC)
$(call green_msg, Deleting all generated files.)
$(call make_resp_file, vclean_files.args, \
$(GENERATED) .depend.Windows mpir_$(CPU).dll mpir_$(CPU).map \
$(MPIR_STAT_LIB) $(MPIR_IMP_LIB) $(MPIR_TEST_LIB) \
cpp_filter.py $(TEST_PROGRAMS) $(TEST_PROGRAMS:.exe=.$(O)))
rm -f @vclean_files.args vclean_files.args clean_files.args clean-cl_files.args
clean_cl clean_clang-cl:
$(call green_msg, Deleting MSVC/clang-cl specific files.)
$(call make_resp_file, clean-cl_files.args, \
vc1*.pdb mpir.pdb mpir*.pdb $(TEST_PROGRAMS:.exe=.pdb) \
$(TEST_PROGRAMS:.exe=.lib) $(TEST_PROGRAMS:.exe=.exp) \
$(MSVC_DIR)/mpir-tune/tune/*.obj)
rm -f @clean-cl_files.args
clean_gcc:
$(call green_msg, No gcc specific files to delete.)
ifeq ($(USE_CLANG_FORMATER),1)
C_FORMATER = | clang-format -style=Mozilla -assume-filename=c
CC_FORMATER = | clang-format -style=Mozilla -assume-filename=cpp
endif
%.i: %.c cpp_filter.py FORCE | $(CC).args
$(CC) -E @$(CC).args $(EXTRA_CFLAGS) $< | $(PYTHON) cpp_filter.py $(C_FORMATER) > $@
%.i: %.cc cpp_filter.py FORCE | $(CC).args
$(CC) -E @$(CC).args $(EXTRA_CFLAGS) $< | $(PYTHON) cpp_filter.py $(CC_FORMATER) > $@
#####################################################################################
run_tests: $(TEST_PROGRAMS) run-all-tests.py
GMP_CHECK_RANDOMIZE=0 \
$(PYTHON) run-all-tests.py
run_speed: speed.exe
MPIR_TRACE=1 \
$(PYTHON) $(MSVC_DIR)/run-speed.py
run-all-tests.py: $(THIS_FILE)
$(call generate, $@, #)
$(file >> $@,#!/usr/env/python)
$(file >> $@,from __future__ import print_function)
$(file >> $@,if 1:)
$(file >> $@,$(run_all_tests_py))
#
# The test-script.
#
define run_all_tests_py
import os, sys, argparse, fnmatch, subprocess
try:
import colorama
colorama.init()
_GREEN = colorama.Fore.GREEN + colorama.Style.BRIGHT
_WHITE = colorama.Fore.WHITE + colorama.Style.BRIGHT
_RED = colorama.Fore.RED + colorama.Style.BRIGHT
_RESET = colorama.Style.RESET_ALL
except ImportError as e:
print ("Failed to 'import colorama'.")
_GREEN = _WHITE = _RED = _RESET = ''
passed = failed = 0
failed_progs = []
t_spec = "*"
parser = argparse.ArgumentParser()
parser.add_argument ("-l", dest="list", action="store_true", help="list the tests")
parser.add_argument ("-p", dest="use_Popen", action="store_true", help="use Popen() and not 'os.system()'")
# parser.add_argument ("-s", action="store_const", help="the test-spec to use")
opt = parser.parse_args()
# t_spec = opt.spec
not_these = [ "gen.exe", "speed.exe", "stat.exe", "tune.exe", "win_timing.exe" ]
test_programs = [ \
$(foreach t, $(TEST_PROGRAMS), "$(t)",
) ]
#
# Find the longest test-program name.
#
t_len = 0
for t in test_programs:
if t_len < len(t):
t_len = len(t)
for t in sorted(test_programs):
args = ''
if t == 'gen.exe':
args = '100' # generate 100 random numbers is enough
print (" %s%s:%s%s" % (_WHITE, t, _RESET, " "*(1+t_len-len(t))), end="")
if opt.list:
if t in not_these:
print (" <skip>")
else:
print ("")
continue
if t in not_these or not fnmatch.fnmatch(t, t_spec):
print ("<skip>")
continue
if not opt.use_Popen:
ret = os.system (t + ' ' + args + '> %s' % os.devnull)
if ret:
print ("%sFAIL%s: 0x%08lX" % (_RED, _RESET, ret))
failed += 1
failed_progs.append (t)
else:
print ("%sPASS%s" % (_GREEN, _RESET))
passed += 1
else:
try:
prc = subprocess.Popen ([ t, args ], stdout = subprocess.PIPE,
stderr = subprocess.STDOUT, creationflags = 0x08000000)
except Exception as str:
print ("%sFAIL%s: %s" % (_RED, _RESET, str))
failed += 1
failed_progs.append (t)
continue
output = prc.communicate()[0]
if prc.returncode:
print ("%sFAIL%s: 0x%08lX" % (_RED, _RESET, prc.returncode))
failed += 1
failed_progs.append (t)
else:
print ("%sPASS%s" % (_GREEN, _RESET))
passed += 1
if output:
print (' ', output.decode())
if opt.list:
print ("Number of tests: %d" % len(test_programs))
else:
print ("Number of passed: %d" % passed)
print ("Number of failed: %d: %s" % (failed, ", ".join(failed_progs)))
endef
#
# GNU-Make macros:
#
# 'C_Compile' and 'CC_Compile'; macros for .c/.cc compiling.
# $(1): source file
# $(2): name of object-file
#
# 'C_MP_Compile' and 'CC_MP_Compile'; compile multiple .c/.cc files in one go.
# For MSVC only.
# $(1): source files
# $(2): directory to put the .obj-files into.
#
ifeq ($(CC),gcc)
C_Compile = $(CC) @gcc.args $(EXTRA_CFLAGS) -o $(2) $(1)
CC_Compile = $(CC) @gcc.args $(EXTRA_CFLAGS) -x c++ $(CC_WARN) -o $(2) $(1)
else ifeq ($(CC),clang-cl)
C_Compile = $(CLANG_ROOT_$(BITS)_BIT)/bin/clang-cl @clang-cl.args $(EXTRA_CFLAGS) -Fo./$(strip $(2)) $(1)
CC_Compile = $(CLANG_ROOT_$(BITS)_BIT)/bin/clang-cl @clang-cl.args $(EXTRA_CFLAGS) -Fo./$(strip $(2)) $(1)
else
C_Compile = $(VC_ROOT)/bin/HostX86/$(CPU)/cl.exe @cl.args $(EXTRA_CFLAGS) -Fo./$(strip $(2)) $(1)
CC_Compile = $(VC_ROOT)/bin/HostX86/$(CPU)/cl.exe @cl.args $(EXTRA_CFLAGS) -Fo./$(strip $(2)) $(1)
define C_MP_Compile
$(call green_msg, Compiling $(3): $(words $(1)) .c-files.)
$(VC_ROOT)/bin/HostX86/$(CPU)/cl.exe @cl.args $(EXTRA_CFLAGS) -MP -Fo./$(strip $(2))\\ $(1)
endef
define CC_MP_Compile
$(call green_msg, Compiling $(3): $(words $(1)) .cc-files.)
$(VC_ROOT)/bin/HostX86/$(CPU)/cl.exe @cl.args $(EXTRA_CFLAGS) -MP -Fo./$(strip $(2))\\ $(1)
endef
endif
define Assemble
$(AS) $(ASFLAGS) -l $(2:.$(O)=.lst) -o $(2) $(1)
endef
#
# .$(O) -> .exe macro:
# $(1): The .exe file.
# $(2): The .$(O) file(s), extra args and libs.
#
define link_EXE
$(call green_msg, Linking $(1)...)
$(call link_EXE_$(CC), $(1), $(2))
@echo
endef
define link_EXE_gcc
$(call make_resp_file, link.args, $(LDFLAGS) $(2))
$(CC) -o $(1) @link.args > $(1:.exe=.map)
endef
define link_EXE_cl
$(call make_resp_file, link.args, $(LDFLAGS) $(2))
$(VC_ROOT)/bin/HostX86/$(CPU)/link.exe -out:$(strip $(1)) @link.args > link.tmp
@cat link.tmp >> $(1:.exe=.map)
@rm -f $(1:.exe=.lib) $(1:.exe=.exp) link.tmp
endef
define link_EXE_clang-cl
$(call make_resp_file, link.args, $(LDFLAGS) $(2))
$(CLANG_ROOT_$(BITS)_BIT)/bin/lld-link.exe -out:$(strip $(1)) @link.args
endef
#
# The same for C++ programs. Only 'gcc' needs special handling.
#
define link_EXE_cc
$(call green_msg, Linking $(1)...)
$(call link_EXE_cc_$(CC), $(1), $(2))
@echo
endef
define link_EXE_cc_gcc
$(call make_resp_file, link.args, $(LDFLAGS) $(2))
g++ -o $(1) @link.args > $(1:.exe=.map)
endef
link_EXE_cc_cl = $(call link_EXE_cl, $(1), $(2))
link_EXE_cc_clang-cl = $(call link_EXE_clang-cl, $(1), $(2))
#
# Macro to create a DLL + import-lib from objects $(O).
# $(1): The .dll file.
# $(2): The import-lib.
# $(3): The .$(O) file(s), extra args and libs.
#
define link_DLL
$(call green_msg, Linking $(1)...)
$(call link_DLL_$(CC), $(1), $(2), $(3))
@echo
endef
define link_DLL_gcc
$(call make_resp_file, link.args, $(LDFLAGS) -Wl$(comma)--out-implib$(comma)$(strip $(2)) $(3))
$(CC) -shared -o $(1) @link.args > $(1:.dll=.map)
endef
define link_DLL_cl
$(call make_resp_file, link.args, $(LDFLAGS) -implib:$(strip $(2)) $(3))
$(VC_ROOT)/bin/HostX86/$(CPU)/link.exe -dll -out:$(strip $(1)) @link.args > link.tmp
@cat link.tmp >> $(1:.dll=.map)
@rm -f $(2:.lib=.exp) link.tmp
endef
define link_DLL_clang-cl
$(call make_resp_file, link.args, $(LDFLAGS) -implib:$(strip $(2)) $(3))
$(CLANG_ROOT_$(BITS)_BIT)/bin/lld-link.exe -dll -out:$(strip $(1)) @link.args
@rm -f $(2:.lib=.exp)
endef
#
# A lib creation macro:
# $(1) the name of the static library.
# $(2) the objects to add.
#
define create_lib
$(call make_resp_file, lib.args, $(2))
$(call green_msg, Adding $(words $(2)) objects to $(1).)
$(call create_lib_$(CC), $(1) @lib.args)
@echo
endef
create_lib_gcc = ar rs $(1)
create_lib_cl = lib -nologo -out:$(strip $(1))
create_lib_clang-cl = $(call create_lib_cl, $(1))
#
# As above, but add to an existing .a/.lib:
# $(1) the name of the static library.
# $(2) the objects to add.
#
define add_lib
$(call green_msg, Adding $(words $(2)) objects to $(1).)
$(call add_lib_$(CC), $(1) $(2))
@echo
endef
add_lib_gcc = ar rs $(1) $(2)
add_lib_cl = lib -nologo $(1) $(2)
add_lib_clang-cl = $(call create_lib_cl, $(1), $(2))
#
# A .res creation macro:
# $(1) the name of the .rc-file.
# $(2) the name of the .res-file.
#
define create_res
$(call create_res_$(CC), $(1), $(2))
@echo
endef
ifeq ($(BITS),32)
RC_TARGET = pe-i386
else
RC_TARGET = pe-x86-64
endif
create_res_gcc = windres $(RCFLAGS) --target=$(RC_TARGET) -o $(2) $(1)
create_res_cl = rc -nologo $(RCFLAGS) -fo $(2) $(1)
create_res_clang-cl = $(call create_res_cl, $(1), $(2))
#
# Make a response file instead of relying on various 'echo' programs.
# Depending on Cygwin or Msys version, the cmdline limit can be very
# low. Besides this macro avoids spawning 'sh'.
#
# $(1): The name of the response file
# $(2): The content for the response file. Each word is written on a separate line.
#
define make_resp_file
$(file > $(1))
$(foreach f, $(2), $(file >> $(1),$(strip $(f))) )
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
# print ("orig: \"%s\"" % line)
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
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
export CPP_FILTER_PY
FORCE:
cpp_filter.py: $(MDEPEND)
$(call generate, $@, #)
@echo "if 1:" >> $@
@echo "$$CPP_FILTER_PY" >> $@
#
# The sed expression replaces 'xx.o' with '$(2)/xx.$$(O)'.
#
define make_depend
$(call green_msg, Generating dependencies for $(words $(1)) files in $(firstword $(dir $(abspath $(1)))) ...)
$(call make_resp_file, depend_files.args, $(1))
gcc -MM @gcc.args @depend_files.args | sed -e 's@\(.*\)\.o: @\n$(strip $(2))\/\1.$$(O): @' >> .depend.Windows
@echo
endef
depend: gcc.args $(GENERATED)
$(call generate, .depend.Windows, #)
$(call make_depend, $(BASE_SRC), .)
$(call make_depend, $(FFT_SRC), fft)
$(call make_depend, $(MPF_SRC), mpf)
$(call make_depend, $(MPQ_SRC), mpq)
$(call make_depend, $(MPZ_SRC), mpz)
$(call make_depend, $(MPN_SRC), mpn/generic)
$(call make_depend, $(PRINTF_SRC), printf)
$(call make_depend, $(SCANF_SRC), scanf)
$(call make_depend, $(MPIRXX_SRC), $$(OBJ_DIR))
$(call make_depend, $(MPIRXX_SRC), $$(OBJ_DIR)\/mpirxx)
$(call make_depend, $(TEST_LIB_SRC), $$(OBJ_DIR))
$(call make_depend, $(TESTS_SRC), $$(OBJ_DIR))
$(call make_depend, $(TESTS_CXX_SRC), $$(OBJ_DIR))
-include .depend.Windows
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment