diff --git a/config2.h.in b/config2.h.in index 63a5b588..d77877ce 100644 --- a/config2.h.in +++ b/config2.h.in @@ -196,6 +196,9 @@ /* Define if you want: Pod2HTML support */ #mesondefine CONFIG_POD2HTML +/* Define if you want: Reproducible build */ +#mesondefine CONFIG_REPRODUCIBLE + /* Define if you want: QuickJS support */ #mesondefine CONFIG_QUICKJS diff --git a/doc/meson.build b/doc/meson.build index 2a90eb94..79d76875 100644 --- a/doc/meson.build +++ b/doc/meson.build @@ -10,6 +10,12 @@ xmlto = find_program('xmlto', required: false) perl_html = [] perl_hooks_html = [] +if conf_data.get('CONFIG_REPRODUCIBLE') + asciidoc_env = ['LC_ALL=C', 'LANGUAGE=en', 'CONFIG_REPRODUCIBLE=1', 'SOURCE_DATE_EPOCH='+conf_data.get('SOURCE_DATE_EPOCH')] +else + asciidoc_env = [] +endif + if pod2html.found() perl_html = custom_target('perl.html', input: ['perl.pod'], @@ -68,6 +74,7 @@ elinks_1_html = custom_target('elinks.1.html', input: 'elinks.1.txt', output: 'elinks.1.html', depends: option_command_frag_xhtml, + env: asciidoc_env, command: [meson.current_source_dir() + '/tools/asciidoc/asciidoc.py', '--no-conf', '-f', meson.current_source_dir() + '/tools/asciidoc/asciidoc.conf', '-f', meson.current_source_dir() + '/tools/asciidoc/xhtml11.conf', @@ -81,6 +88,7 @@ elinks_conf_5_html = custom_target('elinks.conf.5.html', input: 'elinks.conf.5.txt', output: 'elinks.conf.5.html', depends: option_config_frag_xhtml, + env: asciidoc_env, command: [meson.current_source_dir() + '/tools/asciidoc/asciidoc.py', '--no-conf', '-f', meson.current_source_dir() + '/tools/asciidoc/asciidoc.conf', '-f', meson.current_source_dir() + '/tools/asciidoc/xhtml11.conf', @@ -94,6 +102,7 @@ elinkskeys_5_html = custom_target('elinkskeys.5.html', input: 'elinkskeys.5.txt', output: 'elinkskeys.5.html', depends: [keymap_actions_txt, keymap_defaults_txt], + env: asciidoc_env, command: [meson.current_source_dir() + '/tools/asciidoc/asciidoc.py', '--no-conf', '-f', meson.current_source_dir() + '/tools/asciidoc/asciidoc.conf', '-f', meson.current_source_dir() + '/tools/asciidoc/xhtml11.conf', @@ -106,6 +115,7 @@ elinkskeys_5_html = custom_target('elinkskeys.5.html', hacking_html = custom_target('hacking.html', input: 'hacking.txt', output: 'hacking.html', + env: asciidoc_env, command: [meson.current_source_dir() + '/tools/asciidoc/asciidoc.py', '--no-conf', '-f', meson.current_source_dir() + '/tools/asciidoc/asciidoc.conf', '-f', meson.current_source_dir() + '/tools/asciidoc/xhtml11.conf', @@ -119,6 +129,7 @@ manual_html = custom_target('manual.html', input: 'manual.txt', output: 'manual.html', depends: features_txt, + env: asciidoc_env, command: [meson.current_source_dir() + '/tools/asciidoc/asciidoc.py', '--no-conf', '-f', meson.current_source_dir() + '/tools/asciidoc/asciidoc.conf', '-f', meson.current_source_dir() + '/tools/asciidoc/xhtml11.conf', @@ -132,6 +143,7 @@ elinks_1_xml = custom_target('elinks.1.xml', input: 'elinks.1.txt', output: 'elinks.1.xml', depends: option_command_frag_xml, + env: asciidoc_env, command: [meson.current_source_dir() + '/tools/asciidoc/asciidoc.py', '--no-conf', '-f', meson.current_source_dir() + '/tools/asciidoc/asciidoc.conf', '-f', meson.current_source_dir() + '/tools/asciidoc/docbook.conf', @@ -146,6 +158,7 @@ elinks_conf_5_xml = custom_target('elinks.conf.5.xml', input: 'elinks.conf.5.txt', output: 'elinks.conf.5.xml', depends: option_config_frag_xml, + env: asciidoc_env, command: [meson.current_source_dir() + '/tools/asciidoc/asciidoc.py', '--no-conf', '-f', meson.current_source_dir() + '/tools/asciidoc/asciidoc.conf', '-f', meson.current_source_dir() + '/tools/asciidoc/docbook.conf', @@ -160,6 +173,7 @@ elinkskeys_5_xml = custom_target('elinkskeys.5.xml', input: 'elinkskeys.5.txt', output: 'elinkskeys.5.xml', depends: [keymap_actions_txt, keymap_defaults_txt], + env: asciidoc_env, command: [meson.current_source_dir() + '/tools/asciidoc/asciidoc.py', '--no-conf', '-f', meson.current_source_dir() + '/tools/asciidoc/asciidoc.conf', '-f', meson.current_source_dir() + '/tools/asciidoc/docbook.conf', @@ -173,6 +187,7 @@ elinkskeys_5_xml = custom_target('elinkskeys.5.xml', hacking_xml = custom_target('hacking.xml', input: 'hacking.txt', output: 'hacking.xml', + env: asciidoc_env, command: [meson.current_source_dir() + '/tools/asciidoc/asciidoc.py', '--no-conf', '-f', meson.current_source_dir() + '/tools/asciidoc/asciidoc.conf', '-f', meson.current_source_dir() + '/tools/asciidoc/docbook.conf', @@ -186,6 +201,7 @@ manual_xml = custom_target('manual.xml', input: 'manual.txt', output: 'manual.xml', depends: features_txt, + env: asciidoc_env, command: [meson.current_source_dir() + '/tools/asciidoc/asciidoc.py', '--no-conf', '-f', meson.current_source_dir() + '/tools/asciidoc/asciidoc.conf', '-f', meson.current_source_dir() + '/tools/asciidoc/docbook.conf', diff --git a/doc/tools/asciidoc/asciidoc.py b/doc/tools/asciidoc/asciidoc.py index dbfb66f0..a488df5e 100755 --- a/doc/tools/asciidoc/asciidoc.py +++ b/doc/tools/asciidoc/asciidoc.py @@ -1061,13 +1061,19 @@ class Document: self.safe = True # Default safe mode. def init_attrs(self): # Set implicit attributes. - d = time.localtime(time.time()) - self.attributes['localdate'] = time.strftime('%d-%b-%Y',d) - s = time.strftime('%H:%M:%S',d) - if time.daylight: - self.attributes['localtime'] = s + ' ' + time.tzname[1] + if os.environ.get('CONFIG_REPRODUCIBLE', ''): + d = time.gmtime(int(os.environ.get('SOURCE_DATE_EPOCH', time.time()))) + self.attributes['localdate'] = time.strftime('%d-%b-%Y',d) + s = time.strftime('%H:%M:%S %z',d) + self.attributes['localtime'] = s else: - self.attributes['localtime'] = s + ' ' + time.tzname[0] + d = time.localtime(time.time()) + self.attributes['localdate'] = time.strftime('%d-%b-%Y',d) + s = time.strftime('%H:%M:%S',d) + if time.daylight: + self.attributes['localtime'] = s + ' ' + time.tzname[1] + else: + self.attributes['localtime'] = s + ' ' + time.tzname[0] self.attributes['asciidoc-version'] = VERSION self.attributes['backend'] = document.backend self.attributes['doctype'] = document.doctype diff --git a/meson.build b/meson.build index 4d09941b..5941f217 100644 --- a/meson.build +++ b/meson.build @@ -74,6 +74,9 @@ conf_data.set('CONFIG_SCRIPTING_GUILE', get_option('guile')) conf_data.set('CONFIG_SCRIPTING_PERL', get_option('perl')) conf_data.set('CONFIG_SCRIPTING_PYTHON', get_option('python')) +conf_data.set('CONFIG_REPRODUCIBLE', get_option('reproducible')) +conf_data.set('SOURCE_DATE_EPOCH', get_option('source-date-epoch')) + luapkg = get_option('luapkg') if luapkg != '' conf_data.set('CONFIG_SCRIPTING_LUA', true) diff --git a/meson_options.txt b/meson_options.txt index 26c760d8..c6ee87ee 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -65,3 +65,6 @@ option('gemini', type: 'boolean', value: false, description: 'gemini protocol su option('gettext', type: 'boolean', value: false, description: 'use external gettext library') option('quickjs', type: 'boolean', value: false, description: 'use quickjs library') option('static', type: 'boolean', value: false, description: 'link static binary') + +option('reproducible', type: 'boolean', value: false, description: 'reproducible build') +option('source-date-epoch', type: 'string', value: '', description: 'source date epoch for reproducible builds') diff --git a/src/main/version.c b/src/main/version.c index 0d329c23..e52f5967 100644 --- a/src/main/version.c +++ b/src/main/version.c @@ -124,9 +124,10 @@ get_dyn_full_version(struct terminal *term, int more) } add_char_to_string(&string, '\n'); +#ifndef CONFIG_REPRODUCIBLE add_format_to_string(&string, _("Built on %s %s", term), build_date, build_time); - +#endif if (more) { add_to_string(&string, "\n\n"); add_to_string(&string, _("Text WWW browser", term)); diff --git a/src/vernum.c b/src/vernum.c index c72da35f..fcf38f7d 100644 --- a/src/vernum.c +++ b/src/vernum.c @@ -8,6 +8,8 @@ #include "vernum.h" +#ifndef CONFIG_REPRODUCIBLE const char *build_date = __DATE__; const char *build_time = __TIME__; +#endif const char *build_id = BUILD_ID;