-
Notifications
You must be signed in to change notification settings - Fork 263
Add libtommath 1.3.0 #2528
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Add libtommath 1.3.0 #2528
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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') | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What's happening here?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have no idea. It dates back to a commit in 2003 with the message |
||
|
|
||
| subprocess.run([latex, 'bn'], stdout=subprocess.DEVNULL, check=True) | ||
| subprocess.run([latex, 'bn'], stdout=subprocess.DEVNULL, check=True) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this intentionally doubled?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Only insofar as it replicates what upstream's makefile does. My best guess is that there is some build stability hysteresis issue that produces different results if the output artifacts exist already |
||
| 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: | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These are all written to the build directory. Is it important to clean them up?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would certainly leave that to the normal build dir handling, but since upstream's rules explicitly cleaned up these files separately from its |
||
| try: | ||
| os.remove(f) | ||
| except FileNotFoundError: | ||
| pass | ||
|
|
||
|
|
||
| if __name__ == '__main__': | ||
| main() | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like there's a lot of unnecessary code to move files around. Why not just write the deterministic header directly into
bn.tex(or intotempfile.NamedTemporaryFile()), copyinput_fileinto it afterward, and set its timestamp frominput_file?Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Re this and the other review comments on this script: this is a python port of upstream's doc build rules:
Which seem to contain a lot of voodoo in pursuit of deterministic builds, but I honestly don't understand the intent of each bit well enough to reason about which side effects are being relied upon (and the commit history didn't shed any light on it), so I instead aimed to replicate the process and side-effects as exactly as possible.
My python is pretty rusty (I last did any substantial work in python over 5 years ago, and even then not much), so I used AI for the initial port and then checked it as best I can, which probably hasn't helped matters.
For my use case I don't care about deterministic builds (especially for an optional documentation target). That seems like a core focus of other build systems like bazel, and I've seen it mentioned for meson but I don't know what the official stance is towards deterministic builds here. It's curious that libtommath seemed to work so hard on making this output deterministic 23 years go, long before I'd heard anything about deterministic builds.