<pre style='margin:0'>
Ken (kencu) pushed a commit to branch master
in repository macports-ports.

</pre>
<p><a href="https://github.com/macports/macports-ports/commit/8b4dd794350f2dcf0e6b7be38c5fdcdb4aa2cef3">https://github.com/macports/macports-ports/commit/8b4dd794350f2dcf0e6b7be38c5fdcdb4aa2cef3</a></p>
<pre style="white-space: pre; background: #F8F8F8"><span style='display:block; white-space:pre;color:#808000;'>commit 8b4dd794350f2dcf0e6b7be38c5fdcdb4aa2cef3
</span>Author: Marcus Calhoun-Lopez <mcalhoun@macports.org>
AuthorDate: Sun Mar 27 11:54:30 2022 -0700

<span style='display:block; white-space:pre;color:#404040;'>    muniversal PG 1.1: new incompatible muniversal PG
</span>---
 _resources/port1.0/group/muniversal-1.1.tcl | 961 ++++++++++++++++++++++++++++
 1 file changed, 961 insertions(+)

<span style='display:block; white-space:pre;color:#808080;'>diff --git a/_resources/port1.0/group/muniversal-1.1.tcl b/_resources/port1.0/group/muniversal-1.1.tcl
</span>new file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 00000000000..74f87de04a9
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/_resources/port1.0/group/muniversal-1.1.tcl
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -0,0 +1,961 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# -*- coding: utf-8; mode: tcl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:ft=tcl:et:sw=4:ts=4:sts=4
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+##########################################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# change defaults from
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# https://github.com/macports/macports-base/blob/master/src/port1.0/portconfigure.tcl
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+##########################################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# disabling dependency tracking is only required when building for multiple architectures simultaneously
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+default configure.universal_args {}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# adding arch flags are handled elsewhere in the PortGroup
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+foreach tool {cc objc cxx objcxx fc f90 f77 ld} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    default configure.${tool}_archflags {}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+foreach lang {c objc cxx objcxx cpp ld} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    default configure.universal_${lang}flags {}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+unset lang tool
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+##########################################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# means of reducing possible architectures
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+##########################################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# if yes, build platform must be able to run binaries for supported architectures
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+options muniversal.run_binaries
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+default muniversal.run_binaries {no}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# if yes, merger will not work correctly if there are three supported architectures
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+options muniversal.no_3_archs
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+default muniversal.no_3_archs {no}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+##########################################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# for merging
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+##########################################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# list of file names for which diff will not work
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+options muniversal.dont_diff
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+default muniversal.dont_diff {}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+##########################################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# utilites
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+##########################################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# allow `foreach arch ${muniversal.architectures} { ... }` to be used regardless of whether +universal set or not
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+options muniversal.architectures
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+default muniversal.architectures {[expr {[option universal_possible] && [variant_isset universal] ? ${configure.universal_archs} : ${configure.build_arch}}]}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# procedures (pre-configure, configure, post-configure, etc.) will be run for each architecture
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# muniversal.build_arch will be set to the current architecture
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+options muniversal.build_arch
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+if {[option universal_possible] && [variant_isset universal]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    default muniversal.build_arch {}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+} else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    default muniversal.build_arch {${configure.build_arch}}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# if yes, system can run 64-bit binaries
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+options os.cpu64bit_capable
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+default os.cpu64bit_capable {[muniversal::cpu64bit_capable]}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+##########################################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# how to set architecture flag
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+##########################################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# if yes, set architecture in compiler flags
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+options muniversal.arch_flag
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+default muniversal.arch_flag {yes}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# if yes, append architecture flag to compiler name
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+options muniversal.arch_compiler
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+default muniversal.arch_compiler {no}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+##########################################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# MacPorts options for different architectures
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+##########################################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+foreach phase {configure build test destroot} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    foreach command {pre_args args post_args env} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        foreach arch {arm64 x86_64 i386 ppc ppc64} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            options ${phase}.${command}.${arch}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            if {"${phase}.${command}" eq "configure.pre_args"} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                default ${phase}.${command}.${arch} "\[muniversal::get_triplets ${arch}\]"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                default ${phase}.${command}.${arch} {}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+unset phase command arch
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+foreach arch {arm64 x86_64 i386 ppc ppc64} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    options patchfiles.${arch}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+unset arch
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+foreach arch {arm64 x86_64 i386 ppc ppc64} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    foreach flags {cppflags cflags cxxflags objcflags objcxxflags ldflags fflags f90flags fcflags} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        options configure.${flags}.${arch}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        default configure.${flags}.${arch} {}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+unset flags arch
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+foreach arch {arm64 x86_64 i386 ppc ppc64} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    foreach tool {cc objc cxx objcxx fc f90 f77 ld} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        options configure.${tool}_archflags.${arch}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        default configure.${tool}_archflags.${arch} "\[muniversal::get_archflag ${tool} ${arch}\]"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+unset tool arch
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+##########################################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# determine which architectures are different and which ones can be run via Rosetta
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+##########################################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+foreach arch {arm64 x86_64 i386 ppc ppc64} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    options muniversal.can_run.${arch}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    options muniversal.is_cross.${arch}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+unset arch
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+default muniversal.can_run.arm64    {[expr { ${os.arch} eq "arm"}]}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+default muniversal.can_run.x86_64   {[expr { (${os.arch} eq "i386" && ${os.cpu64bit_capable}) || (${os.arch} eq "arm" && ${os.major} < 2147483647) }]}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+default muniversal.can_run.i386     {[expr { ${os.arch} eq "i386" && ${os.major} < 19 }]}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+default muniversal.can_run.ppc      {[expr { ${os.arch} eq "powerpc" || (${os.arch} eq "i386" && ${os.major} < 11) }]}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+default muniversal.can_run.ppc64    {[expr { ${os.arch} eq "powerpc" && ${os.cpu64bit_capable} }]}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+default muniversal.is_cross.arm64   {[expr { ${os.arch} ne "arm" }]}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+default muniversal.is_cross.x86_64  {[expr { ${os.arch} ne "i386" || !${os.cpu64bit_capable} }]}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+default muniversal.is_cross.i386    {[expr { ${os.arch} ne "i386" || ${os.major} >= 19 }]}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+default muniversal.is_cross.ppc     {[expr { ${os.arch} ne "powerpc" }]}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+default muniversal.is_cross.ppc64   {[expr { ${os.arch} ne "powerpc" || !${os.cpu64bit_capable} }]}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+##########################################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# triplet information
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# see https://wiki.osdev.org/Target_Triplet
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+##########################################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+options triplet.vendor
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+default triplet.vendor      {apple}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+options triplet.os
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+default triplet.os          {${os.platform}${os.major}}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+options triplet.host_cmd
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+default triplet.host_cmd    {--host=}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+options triplet.build_cmd
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+default triplet.build_cmd   {--build=}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# possible values: none, all, cross, or a list of architectures
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+options triplet.add_host
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+default triplet.add_host    {cross}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# possible values: none, all, cross, or a list of architectures
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+options triplet.add_build
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+default triplet.add_build   {none}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+foreach arch {arm64 x86_64 i386 ppc ppc64} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    options triplet.cpu.${arch}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+unset arch
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+default triplet.cpu.arm64  {aarch64}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+default triplet.cpu.x86_64 {x86_64}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+default triplet.cpu.i386   {i686}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+default triplet.cpu.ppc    {powerpc}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+default triplet.cpu.ppc64  {powerpc64}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+foreach arch {arm64 x86_64 i386 ppc ppc64} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    options triplet.${arch}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    default triplet.${arch} "\${triplet.cpu.${arch}}-\${triplet.vendor}-\${triplet.os}"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+unset arch
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+namespace eval muniversal {}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+####################################################################################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# internal procedures
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+####################################################################################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# a version of `sysctl hw.cpu64bit_capable` that works on older systems
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# see https://trac.macports.org/ticket/25873
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+proc muniversal::cpu64bit_capable {} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if {[option os.major] >= 9} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return [sysctl hw.cpu64bit_capable]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } elseif {(![catch {sysctl hw.optional.x86_64} is_x86_64] && ${is_x86_64})
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+              || (![catch {sysctl hw.optional.64bitops} is_ppc64] && ${is_ppc64})} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return 1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return 0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# assemble `--build=...` and `--host=...` list based on triplet.* options
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+proc muniversal::get_triplets {arch} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    global triplet.add_host triplet.add_build os.arch os.cpu64bit_capable
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if { [file tail [option configure.cmd]] eq "cmake" }  { return "" }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set ret ""
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if { ${triplet.add_host} eq "all"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         || ${arch} in ${triplet.add_host}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         || ("cross" in ${triplet.add_host} && [option muniversal.is_cross.${arch}])
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     } {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        lappend ret "[option triplet.host_cmd][option triplet.${arch}]"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if { ${triplet.add_build} eq "all"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         || ${arch} in ${triplet.add_build}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         || ("cross" in ${triplet.add_build} && [option muniversal.is_cross.${arch}])
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+     } {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if { [option muniversal.is_cross.${arch}] } {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            set cpu_arch [option configure.build_arch]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            set cpu_arch ${arch}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        lappend ret "[option triplet.build_cmd][option triplet.${cpu_arch}]"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return ${ret}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# get current architecture in a way that tries to detect invalid states
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+proc muniversal::get_build_arch {} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    global muniversal.build_arch
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if { ${muniversal.build_arch} eq "" } {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        ui_error "universal: merge: architecture is not set"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return -code error "unknown architecture (empty)"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return ${muniversal.build_arch}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# map directory to name to architecture-dependent version
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+proc muniversal::get_arch_dir {dir arch} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    global worksrcpath configure.dir
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if { [string match "${worksrcpath}/*" ${dir}] } {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # the directory is inside the source directory, so put in the new source directory name
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return [string map "${worksrcpath} ${worksrcpath}-${arch}" ${dir}]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } elseif { [string match "${configure.dir}/*" ${dir}] } {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # the directory is outside the source directory but is a subdirectory of ${configure.dir}, so
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        #    append ${arch} to the ${configure.dir} part
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return [string map "${configure.dir} ${configure.dir}-${arch}" ${dir}]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # the directory is outside the source directory and ${configure.dir}, so
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        #    give it a new name by appending ${arch}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return ${dir}-${arch}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# map `${worksrcpath}` to architecture-dependent version in phase command
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# for example, `configure.cmd ${worksrcpath}/configure` --> `configure.cmd ${worksrcpath}-${arch}/configure`
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+proc muniversal::map_phase {dir_save dir phase_cmd} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return [string map "${dir_save} ${dir}" ${phase_cmd}]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# get architecture flag for a given tool
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# prefer `-arch ${arch}` for C-type languages and linker (if possible)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# prefer `-m32` or `-m64` for Fortran language
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# see `portconfigure::configure_get_archflags` and `portconfigure::configure_get_ld_archflags` in
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#     https://github.com/macports/macports-base/blob/master/src/port1.0/portconfigure.tcl
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+proc muniversal::get_archflag {tool arch} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    global configure.compiler
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if { [portconfigure::arch_flag_supported ${configure.compiler}] && ${tool} in {cc cxx objc objcxx ld } } {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return "-arch ${arch}"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } elseif { ${arch} in {arm64 ppc64 x86_64} } {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return "-m64"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } elseif {${configure.compiler} ne "gcc-3.3"} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return "-m32"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return ""
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# [muniversal::file_or_symlink_exists ${f}] tells you if ${f} exists
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# uunlike [file exists ${f}], if used on a symlink, [muniversal::file_or_symlink_exists ${f}]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# tells you about the symlink, not what it points to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+proc muniversal::file_or_symlink_exists {f} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # if [file type ${f}] throws an error, ${f} doesn't existx
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if {[catch {file type ${f}}]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return no
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # otherwise, it does
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return yes
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# merge two files (${dir1}/${fl} and ${dir2}/${fl}) to ${dir}/${fl}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# by stripping out -arch XXXX, -m32, and -m64
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+proc muniversal::strip_arch_flags {dir1 dir2 dir fl} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set tempdir [mkdtemp "/tmp/muniversal.XXXXXXXX"]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set tempfile1 "${tempdir}/1-${fl}"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set tempfile2 "${tempdir}/2-${fl}"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    copy ${dir1}/${fl} ${tempfile1}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    copy ${dir2}/${fl} ${tempfile2}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    reinplace -q -E {s:-arch +[0-9a-zA-Z_]+::g} ${tempfile1} ${tempfile2}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    reinplace -q {s:-m32::g} ${tempfile1} ${tempfile2}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    reinplace -q {s:-m64::g} ${tempfile1} ${tempfile2}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if { ! [catch {system "/usr/bin/cmp -s \"${tempfile1}\" \"${tempfile2}\""}] } {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # modified files are identical
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        ui_debug "universal: merge: ${fl} differs in ${dir1} and ${dir2} but are the same when stripping out -m32, -m64, and -arch XXX"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        copy ${tempfile1} ${dir}/${fl}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        delete ${tempfile1} ${tempfile2} ${tempdir}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        delete ${tempfile1} ${tempfile2} ${tempdir}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return -code error "${fl} differs in ${dir1} and ${dir2} and cannot be merged"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# merge ${base1}/${prefixDir} and ${base2}/${prefixDir} into dir ${base}/${prefixDir}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#        arch1, arch2: names to prepend to files if a diff merge of two files is forbidden by merger_dont_diff
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#    merger_dont_diff: list of files for which /usr/bin/diff ${diffFormat} will not merge correctly
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#          diffFormat: format used by diff to merge two text files
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+proc muniversal::merge {base1 base2 base prefixDir arch1 arch2 merger_dont_diff diffFormat} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set dir1  ${base1}/${prefixDir}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set dir2  ${base2}/${prefixDir}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set dir   ${base}/${prefixDir}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    xinstall -d -m 0755 ${dir}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    foreach fl [glob -directory ${dir2} -tails -nocomplain * .*] {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if {${fl} in [list . ..]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            continue
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if { ![muniversal::file_or_symlink_exists ${dir1}/${fl}] } {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            # File only exists in ${dir1}.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            ui_debug "universal: merge: ${prefixDir}/${fl} only exists in ${base2}"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            copy ${dir2}/${fl} ${dir}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    foreach fl [glob -directory ${dir1} -tails -nocomplain * .*] {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if {${fl} in [list . ..]} { continue }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if { ![muniversal::file_or_symlink_exists ${dir2}/${fl}] } {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            # file only exists in ${dir2}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            ui_debug "universal: merge: ${prefixDir}/${fl} only exists in ${base1}"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            copy ${dir1}/${fl} ${dir}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            # file exists in ${dir1} and ${dir2}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            ui_debug "universal: merge: merging ${prefixDir}/${fl} from ${base1} and ${base2}"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            # ensure files are of same type
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            if {[file type ${dir1}/${fl}] ne [file type ${dir2}/${fl}]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                error "${dir1}/${fl} and ${dir2}/${fl} are of different types"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            if {[file type ${dir1}/${fl}] eq "link"} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                # files are links
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                ui_debug "universal: merge: ${prefixDir}/${fl} is a link"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                # ensure links don't point to different things
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                if {[file readlink ${dir1}/${fl}] eq [file readlink ${dir2}/${fl}]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    copy ${dir1}/${fl} ${dir}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    error "${dir1}/${fl} and ${dir2}/${fl} point to different targets (can't merge them)"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            } elseif { [file isdirectory ${dir1}/${fl}] } {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                # files are directories (but not links), so recursively call function
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                muniversal::merge ${base1} ${base2} ${base} ${prefixDir}/${fl} ${arch1} ${arch2} ${merger_dont_diff} ${diffFormat}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                # files are neither directories nor links
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                if { ! [catch {system "/usr/bin/cmp -s \"${dir1}/${fl}\" \"${dir2}/${fl}\" && /bin/cp -v \"${dir1}/${fl}\" \"${dir}\""}] } {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    # files are byte by byte the same
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    ui_debug "universal: merge: ${prefixDir}/${fl} is identical in ${base1} and ${base2}"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    # actually try to merge the files
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    # first try lipo, then libtool
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    if { ! [catch {system "/usr/bin/lipo -create \"${dir1}/${fl}\" \"${dir2}/${fl}\" -output \"${dir}/${fl}\""}] } {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        # lipo worked
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        ui_debug "universal: merge: lipo created ${prefixDir}/${fl}"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    } elseif { ! [catch {system "/usr/bin/libtool \"${dir1}/${fl}\" \"${dir2}/${fl}\" -o \"${dir}/${fl}\""}] } {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        # libtool worked
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        ui_debug "universal: merge: libtool created ${prefixDir}/${fl}"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        # lipo and libtool have failed, so assume they are text files to be merged
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        if {"${prefixDir}/${fl}" in ${merger_dont_diff}} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                            # user has specified that diff does not work
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                            # attempt to give each file a unique name and create a new file which includes one of the original depending on the arch
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                            set fh [open ${dir}/${arch1}-${fl} w 0644]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                            puts ${fh} "#include \"${arch1}-${fl}\""
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                            close ${fh}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                            set fh [open ${dir}/${arch2}-${fl} w 0644]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                            puts ${fh} "#include \"${arch2}-${fl}\""
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                            close ${fh}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                            ui_debug "universal: merge: created ${prefixDir}/${fl} to include ${prefixDir}/${arch1}-${fl} ${prefixDir}/${arch1}-${fl}"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                            system "/usr/bin/diff -d ${diffFormat} \"${dir}/${arch1}-${fl}\" \"${dir}/${arch2}-${fl}\" > \"${dir}/${fl}\"; test \$? -le 1"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                            copy -force ${dir1}/${fl} ${dir}/${arch1}-${fl}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                            copy -force ${dir2}/${fl} ${dir}/${arch2}-${fl}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                            # files could not be merged into a fat binary
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                            # handle known file types
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                            switch -glob ${fl} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                *.mod {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                    # .mod files from Fortran modules
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                    # create a sepcial module directory for each architecture
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                    # to find these modules, GFortran might require -M or -J
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                    file mkdir ${dir}/mods32
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                    file mkdir ${dir}/mods64
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                    if {${arch1} in [list i386 ppc]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                        copy ${dir1}/${fl} ${dir}/mods32
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                        copy ${dir2}/${fl} ${dir}/mods64
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                    } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                        copy ${dir2}/${fl} ${dir}/mods32
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                        copy ${dir1}/${fl} ${dir}/mods64
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                *.pc -
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                *-config {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                    mergeStripArchFlags ${dir1} ${dir2} ${dir} ${fl}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                *.la {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                    if {[option destroot.delete_la_files]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                        ui_debug "universal: merge: ${prefixDir}/${fl} differs in ${base1} and ${base2}; ignoring due to delete_la_files"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                    } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                        return -code error "${prefixDir}/${fl} differs in ${base1} and ${base2} and cannot be merged"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                *.typelib {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                    # sometimes garbage ends up in ignored trailing bytes
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                    # https://trac.macports.org/ticket/39629
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                    # TODO: compare the g-ir-generate output
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                    ui_debug "universal: merge: ${prefixDir}/${fl} differs in ${base1} and ${base2}; assume trivial difference"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                    copy ${dir1}/${fl} ${dir}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                *.pyc {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                    # pyc files should be same across architectures
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                    # the timestamp is recorded, however
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                    ui_debug "universal: merge: ${prefixDir}/${fl} differs in ${base1} and ${base2}; assume trivial difference"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                    copy ${dir1}/${fl} ${dir}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                *.elc {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                    # elc files can be different because they record when and where they were built.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                    ui_debug "universal: merge: ${prefixDir}/${fl} differs in ${base1} and ${base2}; assume trivial difference"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                    copy ${dir1}/${fl} ${dir}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                *.el.gz -
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                *.el.bz2 {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                    # Emacs lisp files should be same across architectures
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                    # the emacs package (and perhaps others) records the date of automatically generated el files
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                    ui_debug "universal: merge: ${prefixDir}/${fl} differs in ${base1} and ${base2}; assume trivial difference"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                    copy ${dir1}/${fl} ${dir}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                *.lzma -
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                *.xz -
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                *.gz -
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                *.zip -
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                *.jar -
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                *.bz2 {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                    # compressed files can differ due to entropy
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                    switch -glob ${fl} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                        *.lzma {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                            set cat ${prefix}/bin/lzcat
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                        *.xz {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                            set cat ${prefix}/bin/xzcat
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                        *.gz {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                            set cat /usr/bin/gzcat
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                        *.zip {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                            set cat "/usr/bin/unzip -p"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                        *.jar {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                            set cat "/usr/bin/unzip -p"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                        *.bz2 {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                            set cat /usr/bin/bzcat
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                    set tempdir [mkdtemp "/tmp/muniversal.XXXXXXXX"]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                    set tempfile1 "${tempdir}/${arch1}-[file rootname ${fl}]"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                    set tempfile2 "${tempdir}/${arch2}-[file rootname ${fl}]"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                    system "${cat} \"${dir1}/${fl}\" > \"${tempfile1}\""
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                    system "${cat} \"${dir2}/${fl}\" > \"${tempfile2}\""
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                    if { ! [catch {system "/usr/bin/cmp -s \"${tempfile1}\" \"${tempfile2}\""}] } {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                        # files are identical
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                        ui_debug "universal: merge: ${prefixDir}/${fl} differs in ${base1} and ${base2} but the contents are the same"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                        copy ${dir1}/${fl} ${dir}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                        delete ${tempfile1} ${tempfile2} ${tempdir}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                    } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                        delete ${tempfile1} ${tempfile2} ${tempdir}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                        return -code error "${prefixDir}/${fl} differs in ${base1} and ${base2} and cannot be merged"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                default {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                    if { ! [catch {system "test \"`head -c2 ${dir1}/${fl}`\" = '#!'"}] } {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                        # shell script, hopefully striping out arch flags works...
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                        mergeStripArchFlags ${dir1} ${dir2} ${dir} ${fl}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                    } elseif { ! [catch {system "/usr/bin/diff -dw ${diffFormat} \"${dir1}/${fl}\" \"${dir2}/${fl}\" > \"${dir}/${fl}\"; test \$? -le 1"}] } {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                        # diff worked
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                        ui_debug "universal: merge: used diff to create ${prefixDir}/${fl}"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                    } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                        # File created by diff is invalid
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                        delete ${dir}/${fl}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                        return -code error "${prefixDir}/${fl} differs in ${base1} and ${base2} and cannot be merged"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+##########################################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# change base behavior
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+##########################################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# get default supported architectures then further restrict them depending on muniversal options
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+rename portconfigure::choose_supported_archs portconfigure::choose_supported_archs_real
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+proc portconfigure::choose_supported_archs {archs} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    global  os.arch
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set universal_archs_supported [portconfigure::choose_supported_archs_real ${archs}]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # user has specified that build platform must be able to run binaries for supported architectures
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if {[option muniversal.run_binaries]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        foreach arch {arm64 x86_64 i386 ppc ppc64} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            if { ![option muniversal.can_run.${arch}] } {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                set universal_archs_supported [ldelete ${universal_archs_supported} ${arch}]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # if muniversal.no_3_archs is yes, prune universal_archs_supported until it only has two elements
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if {[option muniversal.no_3_archs]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if { [llength ${universal_archs_supported}] >= 3 } {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            # first, try to remove ppc64 unless we're powerpc
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            if {${os.arch} ne "powerpc"} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                set universal_archs_supported [ldelete ${universal_archs_supported} "ppc64"]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if { [llength ${universal_archs_supported}] >= 3 } {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            # next, delete archs that are not evolutionarilary adjacent
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            if {${os.arch} eq "powerpc"} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                set universal_archs_supported [ldelete ${universal_archs_supported} "arm64"]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            } elseif {${os.arch} eq "arm"} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                set universal_archs_supported [ldelete ${universal_archs_supported} "ppc"]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if { [llength ${universal_archs_supported}] >= 3 } {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            # next continue to prune architectures that are not evolutionarilary adjacent
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            if {${os.arch} eq "arm"} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                set universal_archs_supported [ldelete ${universal_archs_supported} "i386"]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            } elseif {${os.arch} eq "powerpc"} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                set universal_archs_supported [ldelete ${universal_archs_supported} "x86_64"]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # arm64 hosts should be down to arm64 + x86_64 at this point
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # i386 hosts should be down to ppc + i386 + x86_64 at this point
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # powerpc hosts should be down to ppc + ppc64 + i386 at this point
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if { [llength ${universal_archs_supported}] >= 3 } {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            # lastly, remove remaining cross-compiled arch
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            if {${os.arch} eq "powerpc"} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                set universal_archs_supported [ldelete ${universal_archs_supported} "i386"]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            } elseif {${os.arch} eq "i386"} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                set universal_archs_supported [ldelete ${universal_archs_supported} "ppc"]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if { [llength ${universal_archs_supported}] >= 3 } {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            # at least one arch should have been removed from universal_archs_supported
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            error "Should Not Happen"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return ${universal_archs_supported}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# make use of architecture dependent variations of pre_args, args, and post_args
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# N.B.: this is a candidate for inclusion in the base code
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+rename command_string command_string_real
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+proc command_string {command} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if { ${command} in "extract archive" } { return [command_string_real ${command}] }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set arch [muniversal::get_build_arch]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    global ${command}.dir \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        ${command}.cmd \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        ${command}.pre_args \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        ${command}.pre_args.${arch} \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        ${command}.args \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        ${command}.args.${arch} \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        ${command}.post_args \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        ${command}.post_args.${arch}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if { [info exists ${command}.dir] } {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        append cmdstring "cd \"[set ${command}.dir]\" &&"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if { [info exists ${command}.cmd] } {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        foreach string [set ${command}.cmd] {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            append cmdstring " $string"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        append cmdstring " ${command}"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    foreach var "${command}.pre_args ${command}.pre_args.${arch} ${command}.args ${command}.args.${arch} ${command}.post_args ${command}.post_args.${arch}" {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if {[info exists $var]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            foreach string [set ${var}] {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                append cmdstring " ${string}"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return $cmdstring
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# make use of architecture dependent variations of env
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# N.B.: this is a candidate for inclusion in the base code
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+rename parse_environment parse_environment_real
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+proc parse_environment {command} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    parse_environment_real ${command}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if { ${command} in "extract archive" } { return }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set arch [muniversal::get_build_arch]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    global ${command}.env.${arch} \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           ${command}.env_array
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if { ${command} eq "configure" && [option muniversal.arch_compiler] && [option muniversal.is_cross.${arch}] } {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set ${command}.env_array(CPP_FOR_BUILD)     "[portconfigure::configure_get_compiler cpp]"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set ${command}.env_array(CXXCPP_FOR_BUILD)  "[portconfigure::configure_get_compiler cpp]"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set ${command}.env_array(CC_FOR_BUILD)      "[portconfigure::configure_get_compiler cc]  [portconfigure::configure_get_archflags cc]"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set ${command}.env_array(CXX_FOR_BUILD)     "[portconfigure::configure_get_compiler cxx] [portconfigure::configure_get_archflags cxx]"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if { [info exists ${command}.env.${arch}] } {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        foreach assignment [set ${command}.env.${arch}] {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            set equals_pos [string first = $assignment]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            if {$equals_pos == -1} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                ui_debug "parse_environment: skipping invalid entry: '$assignment'"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                continue
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            set key [string range $assignment 0 $equals_pos-1]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            set ${command}.env_array(${key}) [string range $assignment $equals_pos+1 end]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# make use of architecture dependent variations of configure.xflags
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# N.B.: this is a candidate for inclusion in the base code
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+rename get_canonical_archflags get_canonical_archflags_real
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+proc get_canonical_archflags {{tool cc}} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set ret     [get_canonical_archflags_real]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set arch    [muniversal::get_build_arch]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    switch -- ${tool} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        cc      { set c "c" }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        f77     { set c "f" }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        default { set c ${tool} }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    lappend ret {*}[option configure.${c}flags.${arch}]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if { ${tool} ne "cpp" && [option muniversal.arch_flag] } {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        lappend ret {*}[option configure.${tool}_archflags.${arch}]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return ${ret}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# make use of architecture dependent variations of patch files
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# N.B.: this is a candidate for inclusion in the base code
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+rename portpatch::patch_main portpatch::patch_main_real
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+proc portpatch::patch_main {args} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    global UI_PREFIX
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set patches ""
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if {[exists patchfiles]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        lappend patches {*}[option patchfiles]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set arch [muniversal::get_build_arch]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if {[exists patchfiles.${arch}]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        lappend patches {*}[option patchfiles.${arch}]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if { ${patches} eq "" } {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return 0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    ui_notice "$UI_PREFIX [format [msgcat::mc "Applying patches to %s"] [option subport]]"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    foreach patch ${patches} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set patch_file [getdistname $patch]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if {[file exists [option filespath]/$patch_file]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            lappend patchlist [option filespath]/$patch_file
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        } elseif {[file exists [option distpath]/$patch_file]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            lappend patchlist [option distpath]/$patch_file
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            return -code error [format [msgcat::mc "Patch file %s is missing"] $patch]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if {![info exists patchlist]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return -code error [msgcat::mc "Patch files missing"]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set gzcat "[findBinary gzip $portutil::autoconf::gzip_path] -dc"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set bzcat "[findBinary bzip2 $portutil::autoconf::bzip2_path] -dc"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    catch {set xzcat "[findBinary xz $portutil::autoconf::xz_path] -dc"}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    foreach patch $patchlist {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        ui_info "$UI_PREFIX [format [msgcat::mc "Applying %s"] [file tail $patch]]"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        switch -- [file extension $patch] {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            .Z -
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            .gz {command_exec patch "$gzcat \"$patch\" | (" ")"}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            .bz2 {command_exec patch "$bzcat \"$patch\" | (" ")"}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            .xz {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                if {[info exists xzcat]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    command_exec patch "$xzcat \"$patch\" | (" ")"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    return -code error [msgcat::mc "xz binary not found; port needs to add 'depends_patch bin:xz:xz'"]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                }}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            default {command_exec patch "" "< '$patch'"}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return 0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# add the universal variant if appropriate
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+rename universal_setup universal_setup_real
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+proc universal_setup {args} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if { ![exists os.universal_supported] || ![option os.universal_supported] } {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        ui_debug "OS doesn't support universal builds, so not adding the universal variant"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if { [llength [option configure.universal_archs]] < 2 } {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        ui_debug "muniversal: < 2 archs supported, not adding universal variant"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if { [exists universal_variant] && ![option universal_variant] } {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        ui_debug "muniversal: universal_variant is false, so not adding universal variant"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        return
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ui_debug "muniversal: adding universal variant"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+variant universal {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+##########################################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# changes if universal variant is set
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+##########################################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+foreach phase {patch configure build destroot test} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    foreach part {pre procedure post} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # wrap procedures (either user defined or MacPorts) with architecture specific code
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        foreach p [ditem_key [set org.macports.${phase}] ${part}] {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            if {[info procs user${p}] ne ""} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                set proc_name user${p}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                set proc_name ${p}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            rename ${proc_name} ${proc_name}_orig
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            proc ${proc_name} {{args ""}} "
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                global worksrcpath UI_PREFIX subport
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                foreach arch \"\[option configure.universal_archs\]\" {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    if { \"${phase}\" eq \"test\" && !\[option muniversal.can_run.\${arch}\] } { continue }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    ui_info \"\$UI_PREFIX \[format \[msgcat::mc \"Running ${part} ${phase} %1\\\$s for architecture %2\\\$s\"\] \${subport} \${arch}\]\"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    muniversal.build_arch \${arch}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    foreach dir {test.dir destroot.dir destroot build.dir autoreconf.dir autoconf.dir configure.dir} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        set     save-\${dir}    \[option \${dir}\]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        option  \${dir}         \[muniversal::get_arch_dir \[option \${dir}\] \${arch}\]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    set     save-worksrcpath    \${worksrcpath}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    option  worksrcpath         \${worksrcpath}-\${arch}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    if {\[option muniversal.arch_compiler\]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        # configure.cpp is intentionally left out
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        foreach tool {cxx objcxx cc objc fc f90 f77} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                            configure.\${tool}-append   {*}\[option configure.\${tool}_archflags.\${arch}\]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    foreach phase_map {configure build destroot test} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        set     save-\${phase_map}.cmd \[option \${phase_map}.cmd\]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        option  \${phase_map}.cmd \[muniversal::map_phase \${save-worksrcpath} \[option worksrcpath\] \[option \${phase_map}.cmd\]\]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    ${proc_name}_orig
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    if {\[option muniversal.arch_compiler\]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        foreach tool {f77 f90 fc objc cc objcxx cxx} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                            configure.\${tool}-delete   {*}\[option configure.\${tool}_archflags.\${arch}\]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    option  worksrcpath         \${save-worksrcpath}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    foreach dir {configure.dir autoconf.dir autoreconf.dir build.dir destroot destroot.dir test.dir} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        option  \${dir}         \[set save-\${dir}\]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    foreach phase_map {configure build destroot test} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        option  \${phase_map}.cmd   \[set save-\${phase_map}.cmd\]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                muniversal.build_arch
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            "
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+unset phase part p
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# copy `worksrcpath` to architecture-dependent version
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# rename portextract::extract_finish portextract::extract_finish_real
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+target_postrun ${org.macports.extract} portextract::extract_finish
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+proc portextract::extract_finish {args} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    global worksrcpath
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    foreach arch [option configure.universal_archs] {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        muniversal.build_arch ${arch}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if {![file exists ${worksrcpath}-${arch}]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            switch [file type ${worksrcpath}] {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                directory {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    copy ${worksrcpath} ${worksrcpath}-${arch}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                link {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    # we have to copy the actual directory tree instead of the verbatim symlink
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    set worksrcpath_work ${worksrcpath}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    set link_depth 0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    while {[file type ${worksrcpath_work}] eq "link"} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        set target [file readlink ${worksrcpath_work}]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        # canonicalize path
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        if {[string index ${target} 0] ne "/"} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                            set target [file dirname ${worksrcpath_work}]/${target}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        if {![file exists ${target}]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                            return -code error "worksrcpath symlink traversal encountered non-existent target path ${target} (dangling symlink)"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        incr link_depth
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        if {${link_depth} >= 50} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                            return -code error "worksrcpath symlink too deeply nested, giving up (loop?)"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        set worksrcpath_work ${target}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    copy ${worksrcpath_work} ${worksrcpath}-${arch}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                default {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    return -code error "worksrcpath not a symlink or directory, this is unexpected"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    muniversal.build_arch
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# copy `destroot` to architecture-dependent version
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+rename portdestroot::destroot_start portdestroot::destroot_start_real
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+proc portdestroot::destroot_start {args} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    portdestroot::destroot_start_real ${args}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    foreach arch [option configure.universal_archs] {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        copy [option destroot] [option workpath]/destroot-${arch}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    delete [option destroot]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# merge architecture-dependent versions of `destroot`
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+rename portdestroot::destroot_finish portdestroot::destroot_finish_real
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+proc portdestroot::destroot_finish {args} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    global  workpath \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            muniversal.dont_diff
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # /usr/bin/diff can merge two C/C++ files
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # See https://www.gnu.org/software/diffutils/manual/html_mono/diff.html#If-then-else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    # See https://www.gnu.org/software/diffutils/manual/html_mono/diff.html#Detailed%20If-then-else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set diffFormatProc {--old-group-format='#if (defined(__ppc__) || defined(__ppc64__))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ %<#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+' \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--new-group-format='#if defined (__i386__) || defined(__x86_64__)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+%>#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+' \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--unchanged-group-format='%=' \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--changed-group-format='#if (defined(__ppc__) || defined(__ppc64__))
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+%<#else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+%>#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+'}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set diffFormatM {--old-group-format='#ifndef __LP64__
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+%<#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+' \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--new-group-format='#ifdef __LP64__
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+%>#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+' \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--unchanged-group-format='%=' \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--changed-group-format='#ifndef __LP64__
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+%<#else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+%>#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+'}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set diffFormatArmElse {--old-group-format='#ifdef __arm64__
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+%<#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+' \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--new-group-format='#ifndef __arm64__
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+%>#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+' \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--unchanged-group-format='%=' \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+--changed-group-format='#ifdef __arm64__
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+%<#else
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+%>#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+'}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    muniversal::merge  ${workpath}/destroot-ppc      ${workpath}/destroot-ppc64     ${workpath}/destroot-powerpc   ""  ppc ppc64      ${muniversal.dont_diff}  ${diffFormatM}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    muniversal::merge  ${workpath}/destroot-i386     ${workpath}/destroot-x86_64    ${workpath}/destroot-intel     ""  i386 x86_64    ${muniversal.dont_diff}  ${diffFormatM}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    muniversal::merge  ${workpath}/destroot-powerpc  ${workpath}/destroot-intel     ${workpath}/destroot-ppc-intel ""  powerpc x86    ${muniversal.dont_diff}  ${diffFormatProc}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    muniversal::merge  ${workpath}/destroot-arm64    ${workpath}/destroot-ppc-intel ${workpath}/destroot           ""  arm64 ppcintel ${muniversal.dont_diff}  ${diffFormatArmElse}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    portdestroot::destroot_finish_real ${args}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+##########################################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# register callbacks
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+##########################################################################################
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# if base code not modified (i.e. not a universal build), append architecture flag to compiler name if requested
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+proc muniversal::add_compiler_flags {} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if { (![option universal_possible] || ![variant_isset universal]) && [option muniversal.arch_compiler]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        # configure.cpp is intentionally left out
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        foreach tool {cxx objcxx cc objc fc f90 f77} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            configure.${tool}-append   {*}[option configure.${tool}_archflags.[option configure.build_arch]]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+port::register_callback muniversal::add_compiler_flags
</span></pre><pre style='margin:0'>

</pre>