From 421739c3eb63d41c53a4e54bf98ce9db7c07a34a Mon Sep 17 00:00:00 2001 From: Cyan Ogilvie Date: Tue, 25 Nov 2025 18:37:26 -0300 Subject: [PATCH] Add libtommath 1.3.0 --- ci_config.json | 7 + releases.json | 8 + subprojects/libtommath.wrap | 9 + .../libtommath/doc/build-manual.py | 110 +++++ .../packagefiles/libtommath/libtommath.def | 219 +++++++++ .../packagefiles/libtommath/meson.build | 416 ++++++++++++++++++ .../packagefiles/libtommath/meson_options.txt | 20 + .../packagefiles/libtommath/run_mtest.py | 23 + tools/sanity_checks.py | 5 + 9 files changed, 817 insertions(+) create mode 100644 subprojects/libtommath.wrap create mode 100644 subprojects/packagefiles/libtommath/doc/build-manual.py create mode 100644 subprojects/packagefiles/libtommath/libtommath.def create mode 100644 subprojects/packagefiles/libtommath/meson.build create mode 100644 subprojects/packagefiles/libtommath/meson_options.txt create mode 100644 subprojects/packagefiles/libtommath/run_mtest.py diff --git a/ci_config.json b/ci_config.json index df90ddc27..5d1ebdf8f 100644 --- a/ci_config.json +++ b/ci_config.json @@ -778,6 +778,13 @@ "windows": false } }, + "libtommath": { + "build_options": [ + "libtommath:tests=true", + "libtommath:buildtype=release", + "libtommath:default_library=both" + ] + }, "libupnp": { "_comment": "Requires some special pthread library", "build_on": { diff --git a/releases.json b/releases.json index 27fb4f2e0..a8c454e22 100644 --- a/releases.json +++ b/releases.json @@ -2459,6 +2459,14 @@ "1.17-1" ] }, + "libtommath": { + "dependency_names": [ + "libtommath" + ], + "versions": [ + "1.3.0-1" + ] + }, "libunibreak": { "dependency_names": [ "libunibreak" diff --git a/subprojects/libtommath.wrap b/subprojects/libtommath.wrap new file mode 100644 index 000000000..6ed7babd9 --- /dev/null +++ b/subprojects/libtommath.wrap @@ -0,0 +1,9 @@ +[wrap-file] +directory = libtommath-1.3.0 +source_url = https://github.com/libtom/libtommath/releases/download/v1.3.0/ltm-1.3.0.tar.xz +source_filename = ltm-1.3.0.tar.xz +source_hash = 296272d93435991308eb73607600c034b558807a07e829e751142e65ccfa9d08 +patch_directory = libtommath + +[provide] +dependency_names = libtommath diff --git a/subprojects/packagefiles/libtommath/doc/build-manual.py b/subprojects/packagefiles/libtommath/doc/build-manual.py new file mode 100644 index 000000000..fb7f6cf4c --- /dev/null +++ b/subprojects/packagefiles/libtommath/doc/build-manual.py @@ -0,0 +1,110 @@ +#!/usr/bin/env python3 +"""Build the libtommath PDF manual from LaTeX sources + +This script is called by meson with the following environment variables set: +LATEX, PDFLATEX, MAKEINDEX + +Only requires standard Python library - no external tools beyond LaTeX itself. +""" + +import os +import sys +import shutil +import subprocess +import re +from datetime import datetime, timezone + + +def main(): + if len(sys.argv) != 4: + print("Usage: build-manual.py INPUT OUTDIR OUTPUT", file=sys.stderr) + sys.exit(1) + + input_file = sys.argv[1] + outdir = sys.argv[2] + output_file = sys.argv[3] + + # Get tools from environment + latex = os.environ.get('LATEX', 'latex') + pdflatex = os.environ.get('PDFLATEX', 'pdflatex') + makeindex = os.environ.get('MAKEINDEX', 'makeindex') + + # Convert paths to absolute before changing directories + input_file = os.path.abspath(input_file) + output_file = os.path.abspath(output_file) + + # Change to output directory + os.chdir(outdir) + + # Copy input to bn.tex + shutil.copy2(input_file, 'bn.tex') + + # Create backup with same timestamp + shutil.copy2('bn.tex', 'bn.bak') + + # Get modification time of bn.tex and format for PDF + mtime = os.stat('bn.tex').st_mtime + dt = datetime.fromtimestamp(mtime, tz=timezone.utc) + + # Format as PDF date string: D:YYYYMMDDHHmmSS+HH'mm' + # For UTC, timezone offset is +00'00' + date_str = dt.strftime("D:%Y%m%d%H%M%S+00'00'") + + # Write deterministic PDF header + with open('bn-deterministic.tex', 'w') as f: + f.write(f"\\def\\fixedpdfdate{{{date_str}}}\n") + f.write("\\pdfinfo{\n") + f.write(" /CreationDate (\\fixedpdfdate)\n") + f.write(" /ModDate (\\fixedpdfdate)\n") + f.write("}\n") + + # Append original content + with open('bn.tex', 'r') as orig: + f.write(orig.read()) + + # Replace bn.tex with deterministic version + shutil.move('bn-deterministic.tex', 'bn.tex') + + # Restore original timestamp + shutil.copystat('bn.bak', 'bn.tex') + + # Build the manual + with open('bn.ind', 'w') as f: + f.write('hello\n') + + subprocess.run([latex, 'bn'], stdout=subprocess.DEVNULL, check=True) + subprocess.run([latex, 'bn'], stdout=subprocess.DEVNULL, check=True) + subprocess.run([makeindex, 'bn'], check=True) + subprocess.run([latex, 'bn'], stdout=subprocess.DEVNULL, check=True) + subprocess.run([pdflatex, 'bn'], stdout=subprocess.DEVNULL, check=True) + + # Make PDF ID deterministic using Python + with open('bn.pdf', 'rb') as f: + pdf_data = f.read() + + # Replace /ID [<...> <...>] with /ID [<0> <0>] + pdf_data = re.sub(rb'^/ID \[.*\]$', rb'/ID [<0> <0>]', pdf_data, flags=re.MULTILINE) + + with open('bn.pdf', 'wb') as f: + f.write(pdf_data) + + # Rename to desired output name + shutil.move('bn.pdf', output_file) + + # Cleanup + shutil.move('bn.bak', 'bn.tex') + + cleanup_files = [ + 'bn.aux', 'bn.dvi', 'bn.log', 'bn.idx', + 'bn.lof', 'bn.out', 'bn.toc', 'bn.ilg', + 'bn.ind', 'bn.tex' + ] + for f in cleanup_files: + try: + os.remove(f) + except FileNotFoundError: + pass + + +if __name__ == '__main__': + main() diff --git a/subprojects/packagefiles/libtommath/libtommath.def b/subprojects/packagefiles/libtommath/libtommath.def new file mode 100644 index 000000000..32bcfbad0 --- /dev/null +++ b/subprojects/packagefiles/libtommath/libtommath.def @@ -0,0 +1,219 @@ +LIBRARY tommath-1 +EXPORTS + fast_mp_invmod + fast_mp_montgomery_reduce + fast_s_mp_mul_digs + fast_s_mp_mul_high_digs + fast_s_mp_sqr + mp_2expt + mp_abs + mp_add + mp_add_d + mp_addmod + mp_and + mp_balance_mul + mp_clamp + mp_clear + mp_clear_multi + mp_cmp + mp_cmp_d + mp_cmp_mag + mp_cnt_lsb + mp_complement + mp_copy + mp_count_bits + mp_decr + mp_div + mp_div_2 + mp_div_2d + mp_div_3 + mp_div_d + mp_dr_is_modulus + mp_dr_reduce + mp_dr_setup + mp_error_to_string + mp_exch + mp_export + mp_expt_d + mp_expt_d_ex + mp_exptmod + mp_exptmod_fast + mp_expt_n + mp_expt_u32 + mp_exteuclid + mp_fread + mp_from_sbin + mp_from_ubin + mp_fwrite + mp_gcd + mp_get_bit + mp_get_double + mp_get_i32 + mp_get_i64 + mp_get_int + mp_get_l + mp_get_ll + mp_get_long + mp_get_long_long + mp_get_mag_u32 + mp_get_mag_u64 + mp_get_mag_ul + mp_get_mag_ull + mp_grow + mp_import + mp_incr + mp_init + mp_init_copy + mp_init_i32 + mp_init_i64 + mp_init_l + mp_init_ll + mp_init_multi + mp_init_set + mp_init_set_int + mp_init_size + mp_init_u32 + mp_init_u64 + mp_init_ul + mp_init_ull + mp_invmod + mp_invmod_slow + mp_iseven + mp_isodd + mp_is_square + mp_jacobi + mp_karatsuba_mul + mp_karatsuba_sqr + mp_kronecker + mp_lcm + mp_log_n + mp_log_u32 + mp_lshd + mp_mod + mp_mod_2d + mp_mod_d + mp_montgomery_calc_normalization + mp_montgomery_reduce + mp_montgomery_setup + mp_mul + mp_mul_2 + mp_mul_2d + mp_mul_d + mp_mulmod + mp_neg + mp_n_root + mp_n_root_ex + mp_or + mp_pack + mp_pack_count + mp_prime_fermat + mp_prime_frobenius_underwood + mp_prime_is_divisible + mp_prime_is_prime + mp_prime_miller_rabin + mp_prime_next_prime + mp_prime_rabin_miller_trials + mp_prime_rand + mp_prime_random_ex + mp_prime_strong_lucas_selfridge + mp_radix_size + mp_rand + mp_rand_digit + mp_rand_source + mp_read_radix + mp_read_signed_bin + mp_read_unsigned_bin + mp_reduce + mp_reduce_2k + mp_reduce_2k_l + mp_reduce_2k_setup + mp_reduce_2k_setup_l + mp_reduce_is_2k + mp_reduce_is_2k_l + mp_reduce_setup + mp_root_n + mp_root_u32 + mp_rshd + mp_sbin_size + mp_set + mp_set_double + mp_set_i32 + mp_set_i64 + mp_set_int + mp_set_l + mp_set_ll + mp_set_long + mp_set_long_long + mp_set_u32 + mp_set_u64 + mp_set_ul + mp_set_ull + mp_shrink + mp_signed_bin_size + mp_signed_rsh + mp_sqr + mp_sqrmod + mp_sqrt + mp_sqrtmod_prime + mp_sub + mp_sub_d + mp_submod + mp_tc_and + mp_tc_div_2d + mp_tc_or + mp_tc_xor + mp_toom_mul + mp_toom_sqr + mp_to_radix + mp_toradix + mp_toradix_n + mp_to_sbin + mp_to_signed_bin + mp_to_signed_bin_n + mp_to_ubin + mp_to_unsigned_bin + mp_to_unsigned_bin_n + mp_ubin_size + mp_unpack + mp_unsigned_bin_size + mp_xor + mp_zero + s_mp_add + s_mp_balance_mul + s_mp_div_3 + s_mp_exptmod + s_mp_exptmod_fast + s_mp_get_bit + s_mp_invmod_fast + s_mp_invmod_slow + s_mp_karatsuba_mul + s_mp_karatsuba_sqr + s_mp_log + s_mp_log_2expt + s_mp_log_d + s_mp_montgomery_reduce_fast + s_mp_mul_digs + s_mp_mul_digs_fast + s_mp_mul_high_digs + s_mp_mul_high_digs_fast + s_mp_prime_is_divisible + s_mp_prime_random_ex + s_mp_rand_jenkins + s_mp_rand_jenkins_init + s_mp_rand_platform + s_mp_reverse + s_mp_sqr + s_mp_sqr_fast + s_mp_sub + s_mp_toom_mul + s_mp_toom_sqr + KARATSUBA_MUL_CUTOFF DATA + KARATSUBA_SQR_CUTOFF DATA + TOOM_MUL_CUTOFF DATA + TOOM_SQR_CUTOFF DATA + ltm_prime_tab DATA + mp_s_rmap DATA + mp_s_rmap_reverse DATA + mp_s_rmap_reverse_sz DATA + s_mp_prime_tab DATA + s_mp_rand_source DATA diff --git a/subprojects/packagefiles/libtommath/meson.build b/subprojects/packagefiles/libtommath/meson.build new file mode 100644 index 000000000..f037bd85d --- /dev/null +++ b/subprojects/packagefiles/libtommath/meson.build @@ -0,0 +1,416 @@ +project( + 'libtommath', + 'c', + version: '1.3.0', + license: 'Unlicense', + default_options: [ + 'c_std=c99', + ], + meson_version: '>=0.63.0', +) + +cc = meson.get_compiler('c') + +# Override optimization for debug builds to use -Og instead of -O0 to work +# around an issue with clang not optimizing away references to some +# conditionally defined functions with forward references +if get_option('debug') and get_option('optimization') == '0' and cc.get_id() in [ + 'clang', + 'clang-cl', +] + add_project_arguments( + '-Og', + language: 'c', + ) +endif + +if cc.get_id() in ['msvc', 'clang-cl'] + add_project_arguments( + '/wd4146', + '/wd4127', + '/wd4668', + '/wd4710', + '/wd4711', + '/wd4820', + '/wd5045', + '/wd4305', + '/Ox', + language: 'c', + ) +endif + +if host_machine.system() == 'windows' + add_project_arguments( + '-D_CRT_SECURE_NO_WARNINGS', + '-D_CRT_NONSTDC_NO_DEPRECATE', + '-D__STDC_WANT_SECURE_LIB__=1', + '-D_CRT_HAS_CXX17=0', + language: 'c', + ) +endif + +add_project_arguments( + cc.get_supported_arguments('-Wno-unused-but-set-variable'), + language: 'c', +) + +# Library sources +sources = files( + 'bn_cutoffs.c', + 'bn_deprecated.c', + 'bn_mp_2expt.c', + 'bn_mp_abs.c', + 'bn_mp_add.c', + 'bn_mp_add_d.c', + 'bn_mp_addmod.c', + 'bn_mp_and.c', + 'bn_mp_clamp.c', + 'bn_mp_clear.c', + 'bn_mp_clear_multi.c', + 'bn_mp_cmp.c', + 'bn_mp_cmp_d.c', + 'bn_mp_cmp_mag.c', + 'bn_mp_cnt_lsb.c', + 'bn_mp_complement.c', + 'bn_mp_copy.c', + 'bn_mp_count_bits.c', + 'bn_mp_decr.c', + 'bn_mp_div.c', + 'bn_mp_div_2.c', + 'bn_mp_div_2d.c', + 'bn_mp_div_d.c', + 'bn_mp_dr_is_modulus.c', + 'bn_mp_dr_reduce.c', + 'bn_mp_dr_setup.c', + 'bn_mp_error_to_string.c', + 'bn_mp_exch.c', + 'bn_mp_expt_n.c', + 'bn_mp_exptmod.c', + 'bn_mp_exteuclid.c', + 'bn_mp_fread.c', + 'bn_mp_from_sbin.c', + 'bn_mp_from_ubin.c', + 'bn_mp_fwrite.c', + 'bn_mp_gcd.c', + 'bn_mp_get_double.c', + 'bn_mp_get_i32.c', + 'bn_mp_get_i64.c', + 'bn_mp_get_l.c', + 'bn_mp_get_mag_u32.c', + 'bn_mp_get_mag_u64.c', + 'bn_mp_get_mag_ul.c', + 'bn_mp_grow.c', + 'bn_mp_incr.c', + 'bn_mp_init.c', + 'bn_mp_init_copy.c', + 'bn_mp_init_i32.c', + 'bn_mp_init_i64.c', + 'bn_mp_init_l.c', + 'bn_mp_init_multi.c', + 'bn_mp_init_set.c', + 'bn_mp_init_size.c', + 'bn_mp_init_u32.c', + 'bn_mp_init_u64.c', + 'bn_mp_init_ul.c', + 'bn_mp_invmod.c', + 'bn_mp_is_square.c', + 'bn_mp_iseven.c', + 'bn_mp_isodd.c', + 'bn_mp_kronecker.c', + 'bn_mp_lcm.c', + 'bn_mp_log_n.c', + 'bn_mp_lshd.c', + 'bn_mp_mod.c', + 'bn_mp_mod_2d.c', + 'bn_mp_mod_d.c', + 'bn_mp_montgomery_calc_normalization.c', + 'bn_mp_montgomery_reduce.c', + 'bn_mp_montgomery_setup.c', + 'bn_mp_mul.c', + 'bn_mp_mul_2.c', + 'bn_mp_mul_2d.c', + 'bn_mp_mul_d.c', + 'bn_mp_mulmod.c', + 'bn_mp_neg.c', + 'bn_mp_or.c', + 'bn_mp_pack.c', + 'bn_mp_pack_count.c', + 'bn_mp_prime_fermat.c', + 'bn_mp_prime_frobenius_underwood.c', + 'bn_mp_prime_is_prime.c', + 'bn_mp_prime_miller_rabin.c', + 'bn_mp_prime_next_prime.c', + 'bn_mp_prime_rabin_miller_trials.c', + 'bn_mp_prime_rand.c', + 'bn_mp_prime_strong_lucas_selfridge.c', + 'bn_mp_radix_size.c', + 'bn_mp_radix_smap.c', + 'bn_mp_rand.c', + 'bn_mp_read_radix.c', + 'bn_mp_reduce.c', + 'bn_mp_reduce_2k.c', + 'bn_mp_reduce_2k_l.c', + 'bn_mp_reduce_2k_setup.c', + 'bn_mp_reduce_2k_setup_l.c', + 'bn_mp_reduce_is_2k.c', + 'bn_mp_reduce_is_2k_l.c', + 'bn_mp_reduce_setup.c', + 'bn_mp_root_n.c', + 'bn_mp_rshd.c', + 'bn_mp_sbin_size.c', + 'bn_mp_set.c', + 'bn_mp_set_double.c', + 'bn_mp_set_i32.c', + 'bn_mp_set_i64.c', + 'bn_mp_set_l.c', + 'bn_mp_set_u32.c', + 'bn_mp_set_u64.c', + 'bn_mp_set_ul.c', + 'bn_mp_shrink.c', + 'bn_mp_signed_rsh.c', + 'bn_mp_sqr.c', + 'bn_mp_sqrmod.c', + 'bn_mp_sqrt.c', + 'bn_mp_sqrtmod_prime.c', + 'bn_mp_sub.c', + 'bn_mp_sub_d.c', + 'bn_mp_submod.c', + 'bn_mp_to_radix.c', + 'bn_mp_to_sbin.c', + 'bn_mp_to_ubin.c', + 'bn_mp_ubin_size.c', + 'bn_mp_unpack.c', + 'bn_mp_xor.c', + 'bn_mp_zero.c', + 'bn_prime_tab.c', + 'bn_s_mp_add.c', + 'bn_s_mp_balance_mul.c', + 'bn_s_mp_div_3.c', + 'bn_s_mp_exptmod.c', + 'bn_s_mp_exptmod_fast.c', + 'bn_s_mp_get_bit.c', + 'bn_s_mp_invmod_fast.c', + 'bn_s_mp_invmod_slow.c', + 'bn_s_mp_karatsuba_mul.c', + 'bn_s_mp_karatsuba_sqr.c', + 'bn_s_mp_log.c', + 'bn_s_mp_log_2expt.c', + 'bn_s_mp_log_d.c', + 'bn_s_mp_montgomery_reduce_fast.c', + 'bn_s_mp_mul_digs.c', + 'bn_s_mp_mul_digs_fast.c', + 'bn_s_mp_mul_high_digs.c', + 'bn_s_mp_mul_high_digs_fast.c', + 'bn_s_mp_prime_is_divisible.c', + 'bn_s_mp_rand_jenkins.c', + 'bn_s_mp_rand_platform.c', + 'bn_s_mp_reverse.c', + 'bn_s_mp_sqr.c', + 'bn_s_mp_sqr_fast.c', + 'bn_s_mp_sub.c', + 'bn_s_mp_toom_mul.c', + 'bn_s_mp_toom_sqr.c', +) + +inc = include_directories('.') + +# Add extra optimization flags to match Makefile and CMake builds +# Note: Meson already adds -O3 when optimization=3 (from buildtype=release) +# We only need to add the flags Meson doesn't add by default +if not get_option('debug') + add_project_arguments( + cc.get_supported_arguments('-funroll-loops', '-fomit-frame-pointer'), + language: 'c', + ) +endif + +# Build both static and shared libraries by default +# Users can override with -Ddefault_library=static or -Ddefault_library=shared +libtommath = library( + 'tommath', + sources, + install: true, + include_directories: inc, + version: meson.project_version(), + link_args: cc.get_id() in ['msvc', 'clang-cl'] ? [ + # MSVC by default exports no symbols, leading to no .LIB file being generated + '/DEF:@0@'.format(meson.current_source_dir() / 'libtommath.def'), + ] : [], + c_args: cc.get_id() in ['msvc', 'clang-cl'] ? [ + # MSVC defaults to IEEE754 since VS 2010, but doesn't set the macro. + # Can't use add_project_arguments here because that enables tests that contain + # literal division by zero, which breaks compilation. + '/fp:precise', + '-D__STDC_IEC_559__', + ] : [], +) + +# Install headers +install_headers(files('tommath.h')) + +# Generate pkg-config file +pkg = import('pkgconfig') +pkg.generate( + libtommath, + name: meson.project_name(), + description: 'public domain library for manipulating large integer numbers', + url: 'https://www.libtom.net/LibTomMath/', +) + +# Create a dependency object for use by other projects +# This makes the library usable as a Meson subproject +libtommath_dep = declare_dependency( + link_with: libtommath, + include_directories: inc, +) + +# Make the dependency available to parent projects +meson.override_dependency('libtommath', libtommath_dep) + +# Build and run unit tests if requested +if get_option('tests') + if not meson.can_run_host_binaries() + error( + 'Cannot run tests: cross-compilating and no host binary helper available', + ) + endif + + libtommath_for_tests = libtommath + if cc.get_id() in ['msvc', 'clang-cl'] + if get_option('default_library') == 'shared' + error('Static library build is required to run tests with MSVC/clang-cl') + endif + libtommath_for_tests = libtommath.get_static_lib() + endif + + tommath_test_exe = executable( + 'tommath_test', + ['demo/test.c', 'demo/shared.c'], + link_with: libtommath_for_tests, + include_directories: inc, + build_by_default: false, + ) + + mtest_opponent_exe = executable( + 'mtest_opponent', + ['demo/mtest_opponent.c', 'demo/shared.c'], + link_with: libtommath_for_tests, + include_directories: inc, + build_by_default: false, + ) + + # Build mtest - reference implementation for differential testing + # Note: mtest.c includes mpi.c directly, so we only compile mtest.c + # Have to disable optimization when building mpi.c or the test fails + # due to bugs in mpi.c + mtest_exe = executable( + 'mtest', + 'mtest/mtest.c', + include_directories: include_directories('mtest'), + override_options: ['optimization=0'], + c_args: cc.get_id() == 'clang-cl' ? [ + # For some reason the optimization=0 override doesn't work properly with clang-cl + '/Od', + ] : [], + build_by_default: false, + ) + + test('tommath_test', tommath_test_exe) + + # Differential test: mtest generates test cases, mtest_opponent validates them + # Usage: mtest | mtest_opponent + test( + 'mtest_opponent', + find_program( + 'run_mtest.py', + native: true, + ), + args: [ + mtest_exe.full_path(), + mtest_opponent_exe.full_path(), + # Iteration count can be added using --test-args, default is 1000 + ], + depends: [mtest_exe, mtest_opponent_exe], + timeout: 30, + suite: 'differential', + ) +endif + +if get_option('benchmarks') + if not meson.can_run_host_binaries() + error( + 'Cannot run benchmarks: cross-compilating and no host binary helper available', + ) + endif + + timing_exe = executable( + 'timing', + 'demo/timing.c', + link_with: libtommath, + c_args: ['-DTIMER'], + include_directories: inc, + build_by_default: false, + ) + + # Create logs directory in build root for benchmark output (timings binary segfaults without it) + python_mkdir = [ + find_program( + 'python3', + native: true, + ), + '-c', + 'import os, sys; os.makedirs(sys.argv[1]) if not os.path.exists(sys.argv[1]) else None', + ] + run_command( + python_mkdir, + meson.project_build_root() / 'logs', + check: true, + ) + benchmark( + 'benchmarks', + timing_exe, + timeout: 30, + ) +endif + +# Documentation target - build PDF manual from LaTeX sources +if get_option('docs') + # Find LaTeX tools (these may not be installed) + latex = find_program( + 'latex', + required: true, + ) + pdflatex = find_program( + 'pdflatex', + required: true, + ) + makeindex = find_program( + 'makeindex', + required: true, + ) + + custom_target( + 'docs', + input: 'doc/bn.tex', + output: '@0@-@1@.pdf'.format(meson.project_name(), meson.project_version()), + command: [ + find_program( + 'doc/build-manual.py', + native: true, + ), + '@INPUT@', + '@OUTDIR@', + '@OUTPUT@', + ], + env: environment( + { + 'LATEX': latex.full_path(), + 'PDFLATEX': pdflatex.full_path(), + 'MAKEINDEX': makeindex.full_path(), + }, + ), + console: true, + install: true, + install_dir: get_option('datadir') / 'doc' / 'libtommath', + ) +endif diff --git a/subprojects/packagefiles/libtommath/meson_options.txt b/subprojects/packagefiles/libtommath/meson_options.txt new file mode 100644 index 000000000..bee5d93fb --- /dev/null +++ b/subprojects/packagefiles/libtommath/meson_options.txt @@ -0,0 +1,20 @@ +option( + 'tests', + type: 'boolean', + value: false, + description: 'Build and run unit tests', +) + +option( + 'benchmarks', + type: 'boolean', + value: false, + description: 'Build and run benchmarks', +) + +option( + 'docs', + type: 'boolean', + value: false, + description: 'Build PDF documentation from LaTeX sources', +) diff --git a/subprojects/packagefiles/libtommath/run_mtest.py b/subprojects/packagefiles/libtommath/run_mtest.py new file mode 100644 index 000000000..ea8e08a87 --- /dev/null +++ b/subprojects/packagefiles/libtommath/run_mtest.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python3 +import sys +import subprocess + +# Get executables from arguments +mtest, mtest_opponent = sys.argv[1:3] + +# Get iteration count from command line (default 1000) +iterations = sys.argv[3] if len(sys.argv) > 3 else '1000' + +# Run mtest and pipe its output to mtest_opponent +mtest_proc = subprocess.Popen([mtest, iterations], stdout=subprocess.PIPE) +mtest_opponent_proc = subprocess.Popen([mtest_opponent], stdin=mtest_proc.stdout) + +# Close mtest stdout in parent to allow proper SIGPIPE handling +mtest_proc.stdout.close() + +# Wait for both processes to complete +mtest_opponent_proc.wait() +mtest_proc.wait() + +# Exit with mtest_opponent's exit code (standard pipe behavior) +sys.exit(mtest_opponent_proc.returncode) diff --git a/tools/sanity_checks.py b/tools/sanity_checks.py index 42ae20079..de9ed89fe 100755 --- a/tools/sanity_checks.py +++ b/tools/sanity_checks.py @@ -97,6 +97,10 @@ 'libtiff': { 'cmakedefine.py', }, + 'libtommath': { + 'build-manual.py', + 'run_mtest.py', + }, 'libuv': { 'link_file_in_build_dir.py', }, @@ -168,6 +172,7 @@ SOURCE_FILENAME_PREFIXES = { 'icu': 'icu4c', 'libtomcrypt': 'crypt', + 'libtommath': 'ltm', } MIT_LICENSE_BLOCKS = {'expat', 'freeglut', 'glew', 'google-brotli'} FORMAT_CHECK_FILES = {'meson.build', 'meson_options.txt', 'meson.options'}