Ticket #68364: rust-1.0.2.tcl

File rust-1.0.2.tcl, 41.3 KB (added by Schamschula (Marius Schamschula), 9 months ago)
Line 
1# -*- coding: utf-8; mode: tcl; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4; truncate-lines: t -*- vim:fenc=utf-8:et:sw=4:ts=4:sts=4
2#
3# This PortGroup supports the Rust language ecosystem
4#
5# Usage:
6#
7# PortGroup     rust 1.0
8#
9# cargo.crates \
10#     foo  1.0.1  abcdef123456... \
11#     bar  2.5.0  fedcba654321...
12#
13# The cargo.crates option expects a list with 3-tuples consisting of name,
14# version, and sha256 checksum. Only sha256 is supported at this time as
15# the checksum will be reused by cargo internally.
16#
17# The list of crates and their checksums can be found in the Cargo.lock file in
18# the upstream source code. The cargo2port generator can be used to automate
19# updates of this list for new releases.
20#
21# To get a list of these, run in worksrcdir:
22#     cargo update
23#     egrep -e '^(name|version|checksum) = ' Cargo.lock | perl -pe 's/^(?:name|version|checksum) = "(.+)"/$1/'
24#
25# https://github.com/macports/macports-contrib/tree/master/cargo2port/cargo2port.tcl
26#
27# If Cargo.lock references pre-release versions, or in general references
28# crates not published on crates.io, but available from GitHub, also use the
29# following:
30#
31# # download additional crates from github, not published on crates.io
32# cargo.crates_github \
33#    baz    author/baz  branch  abcdef12345678...commit...abcdef12345678  fedcba654321...
34#
35
36PortGroup   muniversal          1.1
37PortGroup   compiler_wrapper    1.0
38# ideally, we would like to add the openssl PG, however
39#     its use of `option_proc` makes changing the default value of `openssl.branch` difficult, and
40#     it interferes with our intended use of compiler_wrapper PG
41# for now, create an option `openssl.branch` in this PG
42# Cargo's interaction with OpenSSL is a bit delicate
43# see, e.g., https://trac.macports.org/ticket/65011
44#
45# similarly for legacysupport PG
46
47options     cargo.bin \
48            cargo.home \
49            cargo.crates \
50            cargo.offline_cmd \
51            cargo.crates_github \
52            cargo.update
53
54default     cargo.bin           {${prefix}/bin/cargo}
55default     cargo.home          {${workpath}/.home/.cargo}
56default     cargo.crates        {}
57default     cargo.crates_github {}
58
59# if a dependency has been patched, `--offline` might be a reasonable choice
60default     cargo.offline_cmd   {--frozen}
61
62# some packags do not provide Cargo.lock,
63# so offer the option of running cargo-update
64default     cargo.update        {no}
65
66# use `--remap-path-prefix` to prevent build information from bing included installed binaries
67options     rust.remap
68default     rust.remap          {${cargo.home} "" ${worksrcpath} ""}
69
70# flags to be passed to the rust compiler
71# --remap-path-prefix=... is eventually added unless rust.remap is empty
72options     rust.flags
73default     rust.flags          {}
74
75options     rust.upstream_deployment_target \
76            rust.upstream_archs \
77            rust.use_cctools \
78            rust.archiver \
79            rust.ranlib
80
81# default macosx_deployment_target value of Rust function macos_default_deployment_target
82# see https://github.com/rust-lang/rust/blob/master/compiler/rustc_target/src/spec/apple_base.rs
83default     rust.upstream_deployment_target {[expr {${os.arch} eq "arm" ? 11.0 : 10.7}]}
84
85# architectures for which an upstream bootstrap compiler is available
86default     rust.upstream_archs     {[expr {${os.platform} eq "darwin" && ${os.major} >= 13 ? {arm64 x86_64} : {}}]}
87
88# some tools provided by system are too old, so use MacPorts version instead
89default     rust.use_cctools        {[expr {${os.platform} eq "darwin" && ${os.major} < 11 ? "yes" : "no"}]}
90default     rust.archiver           {[expr {${rust.use_cctools} ? "${prefix}/bin/ar" : "/usr/bin/ar"}]}
91default     rust.ranlib             {[expr {${rust.use_cctools} ? "${prefix}/bin/ranlib" : "/usr/bin/ranlib"}]}
92
93# compiler runtime library
94#     N.B.: `configure.ldflags-append {*}${rust.rt_static_libs}` might be insufficient
95#     `rust.rt_static_libs` will not give the correct value until *after* the compiler is active
96#     the compiler might not be active immediately if added as a dependency
97options     rust.rt_static_libs
98default     rust.rt_static_libs     {[rust::get_static_rutime_libraries]}
99
100# force compiler runtime library to be included in link flags
101options     rust.add_compiler_runtime
102default     rust.add_compiler_runtime   {no}
103
104# the distfiles of the main port will also be stored in this directory,
105# but this is the only way to allow reusing the same crates across multiple ports.
106default     dist_subdir             {[expr {[llength ${cargo.crates}] > 0 || [llength ${cargo.crates_github}] > 0 ? "cargo-crates" : ${name}}]}
107default     extract.only            {[rust::disttagclean $distfiles]}
108
109# to wrap linker, compiler_wrapper PG required existence of configure.ld
110options     configure.ld
111default     configure.ld            {${configure.cc}}
112
113# Rust set its own compiler flags, so make empty by default
114default     configure.cflags        {}
115default     configure.cxxflags      {}
116default     configure.ldflags       {[expr {${rust.add_compiler_runtime} ? ${rust.rt_static_libs} : {}} ]}
117default     compiler.limit_flags    {yes}
118default     configure.pipe          {no}
119rename      portconfigure::should_add_stdlib  portconfigure::should_add_stdlib_real
120rename      portconfigure::should_add_cxx_abi portconfigure::should_add_cxx_abi_real
121proc        portconfigure::should_add_stdlib  {} {return no}
122proc        portconfigure::should_add_cxx_abi {} {return no}
123
124# enforce same compiler settings as used by rust
125default compiler.cxx_standard           2017
126default compiler.thread_local_storage   yes
127
128# do not include os.major in target triplet
129default     triplet.os              {${os.platform}}
130
131# Rust does not easily pass external flags to compilers, so add them to compiler wrappers
132default     compwrap.compilers_to_wrap          {cc cxx ld}
133default     compwrap.ccache_supported_compilers {}
134
135# possible OpenSSL versions: empty, 3, 1.1, and 1.0
136options     openssl.branch
137default     openssl.branch      {}
138
139# utility method to get bootstrap compilers
140# should only be needed by Rust/Cargo ports
141proc rust.add_bootstrap_components {architectures {components {rust-std rustc cargo}}} {
142    global extract.suffix os.major subport
143
144    set version_current         1.74.1
145    set version_m1              1.74.0
146    set version_m2              1.73.0
147
148    master_sites-append         https://static.rust-lang.org/dist:apple_vendor \
149                                https://github.com/MarcusCalhoun-Lopez/rust/releases/download/${version_current}:macports_vendor \
150                                file://[option prefix]/libexec/rust-bootstrap:transition_vendor
151
152    if { [join [lrange [split ${subport} -] 0 1] -] eq "rust-bootstrap" } {
153        set is_bootstrap        yes
154    } else {
155        set is_bootstrap        no
156    }
157
158    set rustc_version           ${version_m1}; # ensure value is always set (see https://trac.macports.org/ticket/65183)
159    foreach arch ${architectures} {
160        # rust-bootstrap requires `macosx_deployment_target` instead of `os.major`
161        if { ${arch} in [option rust.upstream_archs] && [vercmp [option macosx_deployment_target] >= [option rust.upstream_deployment_target]]} {
162            set build_vendor        apple
163            if { ${is_bootstrap} } {
164                set rustc_version   ${version_m2}
165            } else {
166                set rustc_version   ${version_m1}
167            }
168            set build_major         ""
169        } elseif { ${arch} in [option rust.upstream_archs] && ${is_bootstrap} && ${subport} ne "rust-bootstrap-transition" } {
170            set build_vendor        transition
171            set build_major         ""
172            set rustc_version       ${version_m1}
173        } else {
174            set build_vendor        macports
175            if { ${os.major} >= 11 || [option os.platform] ne "darwin" } {
176                set rustc_version   ${version_m1}+0
177                set build_major     ""
178            } elseif { ${os.major} >= 10 } {
179                set rustc_version   ${version_m1}+0
180                set build_major     10
181            } elseif { ${os.major} >= 9 } {
182                set rustc_version   ${version_m1}+0
183                set build_major     9
184            } elseif { ${os.major} >= 8 } {
185                set rustc_version   ${version_m1}+0
186                set build_major     8
187            }
188        }
189
190        if { ${build_vendor} ne "transition" } {
191            foreach component ${components} {
192                set binTag          ${rustc_version}-[option triplet.cpu.${arch}]-${build_vendor}-[option triplet.os]${build_major}
193                # bootstrap binaries not currently available for Tiger
194                # https://trac.macports.org/ticket/65184
195                if {$build_major != 8} {
196                    distfiles-append    ${component}-${binTag}${extract.suffix}:${build_vendor}_vendor
197                }
198                # mirroring workaround for Snow Leopard i386 files
199                if {[variant_exists mirror_i386] && [variant_isset mirror_i386]} {
200                    set extrabintag     ${version_m1}+0-[option triplet.cpu.i386]-macports-[option triplet.os]10
201                    distfiles-append    ${component}-${extrabintag}${extract.suffix}:macports_vendor
202                }
203            }
204        } else {
205            depends_extract-delete          port:rust-bootstrap-transition
206            depends_extract-append          port:rust-bootstrap-transition
207            depends_build-delete            port:rust-bootstrap-transition
208            depends_build-append            port:rust-bootstrap-transition
209            depends_skip_archcheck-delete   rust-bootstrap-transition
210            depends_skip_archcheck-append   rust-bootstrap-transition
211
212            if {[option muniversal.is_cross.[option configure.build_arch]]} {
213                # if os.arch is arm and subport is rust-bootstrap-10.6, avoid
214                #     Error: Cannot install rust-bootstrap-10.6 for the arch 'x86_64' because
215                #     Error: its dependency rust-bootstrap-transition does not build for the required arch by default
216                #     Error: and does not have a universal variant.
217                known_fail                  yes
218                pre-fetch {
219                    ui_error "${subport} does not support cross-compilation"
220                    return -code error "incompatible OS configuration"
221                }
222            }
223
224            foreach component ${components} {
225                set binTag          ${rustc_version}+0-[option triplet.cpu.${arch}]-${build_vendor}-[option triplet.os]${build_major}
226                set distfile        [option prefix]/libexec/rust-bootstrap/${component}-${binTag}${extract.suffix}
227                post-extract        "system -W \${workpath} \"\${extract.cmd} \${extract.pre_args} ${distfile} \${extract.post_args}\""
228            }
229        }
230    }
231
232    # upstream binaries
233    checksums-append        rust-std-${version_m1}-x86_64-apple-darwin${extract.suffix} \
234                            rmd160  d1620d5bcd9a5e86a4794848f547dd32484f52c1 \
235                            sha256  0bce6e0abf5b7375ae4e78ec59d3036100267c300cb999dc6e665356bce6e3b2 \
236                            size    44978754 \
237                            rustc-${version_m1}-x86_64-apple-darwin${extract.suffix} \
238                            rmd160  bfe1a33979dd6d33eae8569f52b6afbfa6cc4106 \
239                            sha256  b4b6fa6605dac66c38008020ea11b59a06bcc1cdbac66a17204ff38aa7115221 \
240                            size    91444261 \
241                            cargo-${version_m1}-x86_64-apple-darwin${extract.suffix} \
242                            rmd160  c15fad1fbf3d0da04a17d544c3e84923caab9bd5 \
243                            sha256  e8f67154ae8faefb81be06b8804658cdde39d96e8fbd6b5240a9ef9d95f49f57 \
244                            size    8607683 \
245                            rust-std-${version_m1}-aarch64-apple-darwin${extract.suffix} \
246                            rmd160  5efbab74af2376a619a84d00e6fa6bd2dc388f1b \
247                            sha256  7fa4b1390784ab83cdef0b1dcacba9710024bb47867b72d09d6b9a711bebceb6 \
248                            size    41922676 \
249                            rustc-${version_m1}-aarch64-apple-darwin${extract.suffix} \
250                            rmd160  ac2cb4cb93666d8d2e4470ae22c1fd964d285467 \
251                            sha256  efad5373622c83dc301c4c045bc3b0ad5cb271409f89c839864f4c3af1510cc8 \
252                            size    96608181 \
253                            cargo-${version_m1}-aarch64-apple-darwin${extract.suffix} \
254                            rmd160  0a99954fa31ac4527691c4d09bc2c03df0dd4138 \
255                            sha256  42eee022368b143c45cd86905d1c9b5ac28fe0608288a805b508a0435c1433e6 \
256                            size    8051884
257
258    # upstream binaries
259    checksums-append        rust-std-${version_m2}-x86_64-apple-darwin${extract.suffix} \
260                            rmd160  53e46f3e7e148cc4860f5e752f3e2590ad3abf9c \
261                            sha256  e44d71250dc5a238da0dc4784dad59d562862653adecd31ea52e0920b85c6a7c \
262                            size    44783473 \
263                            rustc-${version_m2}-x86_64-apple-darwin${extract.suffix} \
264                            rmd160  956a17845cf43a68091011eb722c923d7f823e28 \
265                            sha256  7b337037b7b7b2ec71cd369009cd94a32019466cdae56b6d6a8cfb74481a3de5 \
266                            size    88715010 \
267                            cargo-${version_m2}-x86_64-apple-darwin${extract.suffix} \
268                            rmd160  d6bc4e1e3fd2a4f279ee9a61bbcb20c71123ee16 \
269                            sha256  3ed0b5eaaf7e908f196b4882aad757cb2a623ca3c8e8e74471422df5e93ebfb0 \
270                            size    7379771 \
271                            rust-std-${version_m2}-aarch64-apple-darwin${extract.suffix} \
272                            rmd160  2aca579bc99ece76ffdfd4b110212fe4ca82e656 \
273                            sha256  651d9ccf5282c67b4f5bcf0eb194b0d29750667271144c3921016a018e33e3c5 \
274                            size    40836286 \
275                            rustc-${version_m2}-aarch64-apple-darwin${extract.suffix} \
276                            rmd160  bfdb11a317401146484dc5eba074ea41b99dade1 \
277                            sha256  f5c938b2aedaf3451e41b696875aab7f66c435d8245af3af1f61ec636b0e64ee \
278                            size    101863654 \
279                            cargo-${version_m2}-aarch64-apple-darwin${extract.suffix} \
280                            rmd160  b361e49a5d09da64a694f72fa0ca2cbd387883f7 \
281                            sha256  370496a66ccadb3d07800949eee01f0088b3efb220fa80973a7ff7e68b1097c8 \
282                            size    8946256
283
284    # MacPorts bootstrap binaries for older system
285    checksums-append        rust-std-${version_m1}+0-x86_64-macports-darwin${extract.suffix} \
286                            rmd160  457fee19b1250947a981f336498dafd5434070fd \
287                            sha256  eff776006cef19592e41ffbc5263443ce9e6a100383e47cd71b8b8e1b0afc593 \
288                            size    44835405 \
289                            rustc-${version_m1}+0-x86_64-macports-darwin${extract.suffix} \
290                            rmd160  13748051b3301bb41b4bc3e6f13f70d51d0f952b \
291                            sha256  6884fe0de7732d23b9dd48e5a3d4346548aed88a6aeebcfeadce7aa7f66698b6 \
292                            size    59051829 \
293                            cargo-${version_m1}+0-x86_64-macports-darwin${extract.suffix} \
294                            rmd160  6bc89b0e031cbf012a7cf9b12df5ac1d324e493f \
295                            sha256  a3a3f73b5272793125bc64f35f58ad7b6914eaca10d2642b3298f7b3792dbf3a \
296                            size    9932453 \
297                            rust-std-${version_m1}+0-i686-macports-darwin${extract.suffix} \
298                            rmd160  37155e045512352f810e8488d378dbca5933c42a \
299                            sha256  75dd7eff3c4d990a4279879a0611720a39dc3c900d184867f1e63c22892ec5a9 \
300                            size    44218170 \
301                            rustc-${version_m1}+0-i686-macports-darwin${extract.suffix} \
302                            rmd160  572d2975a03cc3f754473c0a1d2bda66b50274af \
303                            sha256  f5035f3dcc619a36cd7bff92cb6a1846ecfa7bb771632c647efb58f3bb09439e \
304                            size    74893342 \
305                            cargo-${version_m1}+0-i686-macports-darwin${extract.suffix} \
306                            rmd160  18ddfeee80b7686b9e495a735852764faf49a782 \
307                            sha256  e0abceb7f07edf55a912082693dd90688545de9aaf06677e0db15544691b669d \
308                            size    9798952 \
309                            rust-std-${version_m1}+0-x86_64-macports-darwin10${extract.suffix} \
310                            rmd160  27db2aa733e80209dbf698edc20067c68b48bf2b \
311                            sha256  e0bd630e3b2494dc796f5df92897a0f7ff50f1ee8c312446d656af104ba6c265 \
312                            size    44876779 \
313                            rustc-${version_m1}+0-x86_64-macports-darwin10${extract.suffix} \
314                            rmd160  d413bcc4ba9fabf584f7ba2ba8449b8878d9f67a \
315                            sha256  fffab98ee25df2433be4369f571a2b84d5bd0e29015a3fe094bd1da761655041 \
316                            size    59166376 \
317                            cargo-${version_m1}+0-x86_64-macports-darwin10${extract.suffix} \
318                            rmd160  8306676aee2799577fd385a43bb8fd2efff4ec7a \
319                            sha256  606d333fd5e7d380cbef6dba50329f45b0d9667f5a184c067d7493ea3bf51c8d \
320                            size    9956017 \
321                            rust-std-${version_m1}+0-i686-macports-darwin10${extract.suffix} \
322                            rmd160  2e0be41a349982ddbcb060345e28539810ac9489 \
323                            sha256  ae6d00c0caaba2e624bf6cdea9054a0ba45f7016accf4916b8ed3d9a70a3f490 \
324                            size    44270577 \
325                            rustc-${version_m1}+0-i686-macports-darwin10${extract.suffix} \
326                            rmd160  6e4443f4e02a25815f80371b210b82cb25697e5a \
327                            sha256  cfbd5004f0e9306d3ea794b0237c819d7b7cfae3080f60d0515762bb416215ad \
328                            size    75107810 \
329                            cargo-${version_m1}+0-i686-macports-darwin10${extract.suffix} \
330                            rmd160  30f0dbf3dfe74fcab3c0409f8e9a94a487a3e5a5 \
331                            sha256  bf59d3b356acf089ef65d191f97c8705e88190aa35712bfd503e2a7cce0a9510 \
332                            size    9829404 \
333                            rust-std-${version_m1}+0-x86_64-macports-darwin9${extract.suffix} \
334                            rmd160  161a128048a6c0005ecc2184dcfdb2e8375ac858 \
335                            sha256  706001daf9e137acda75dd33d20b246641dbf9f6d8aad5076a24599c8e850044 \
336                            size    44687581 \
337                            rustc-${version_m1}+0-x86_64-macports-darwin9${extract.suffix} \
338                            rmd160  312787e1b9b60deef69f7a6472acf75f049604d8 \
339                            sha256  1db6b423872d0c46b62e39c4f99d8100028b89d3f668c1fbcdf4827c953c6119 \
340                            size    58819501 \
341                            cargo-${version_m1}+0-x86_64-macports-darwin9${extract.suffix} \
342                            rmd160  e32ca8380099bab3d687ec9d6533878fad919135 \
343                            sha256  b0b5b3a5382e6274ab8e9a0dff0522212bfaec4e21cc5f37f344e78093993cc5 \
344                            size    9796058 \
345                            rust-std-${version_m1}+0-i686-macports-darwin9${extract.suffix} \
346                            rmd160  496a0012a3488e8cf59f59201ab7f1ad0eaf2fdf \
347                            sha256  25198cfe531f30dc7ac1ff63c7a2283734cf43e6db01b5c5ad2739d4ae7030b0 \
348                            size    44079023 \
349                            rustc-${version_m1}+0-i686-macports-darwin9${extract.suffix} \
350                            rmd160  998d6b5af4c9a913786898aca773d7acc5ad4888 \
351                            sha256  e8964088c4d859201e23df3206667f00a4e54dfdd07bfaaadcad502dab3a0fe6 \
352                            size    74812980 \
353                            cargo-${version_m1}+0-i686-macports-darwin9${extract.suffix} \
354                            rmd160  ca9b0fd9f2866e78d53ee35d00a5199abe51c7ca \
355                            sha256  f7b17341e7711a3f8679d92533ac5ffe0791ee23f2f4aeb565e26384b787b142 \
356                            size    9674221
357
358    return                  [lindex [split ${rustc_version} +] 0]
359}
360
361####################################################################################################################################
362# for building LLVM as part of building the Rust compiler
363####################################################################################################################################
364
365options     rust.llvm.legacy
366default     rust.llvm.legacy        {[expr {${os.major} < 11}]}
367
368options     rust.llvm.cflags
369default     rust.llvm.cflags        {[portconfigure::configure_get_cppflags] ${configure.optflags} [expr {${rust.llvm.legacy} ? "-isystem${prefix}/include/LegacySupport" : ""}]}
370
371options     rust.llvm.cxxflags
372default     rust.llvm.cxxflags      {[portconfigure::configure_get_cppflags] ${configure.optflags} [expr {${rust.llvm.legacy} ? "-isystem${prefix}/include/LegacySupport" : ""}]}
373
374options     rust.llvm.ldflags
375default     rust.llvm.ldflags       {[portconfigure::configure_get_ldflags] [expr {${rust.llvm.legacy} ? "${prefix}/lib/libMacportsLegacySupport.a" : ""}]}
376
377####################################################################################################################################
378# utility procedures
379####################################################################################################################################
380
381# MacPorts architecture name --> Rust architecture name
382proc rust.rust_arch {arch} {
383    switch ${arch} {
384        arm64       {return aarch64}
385        i386        {return i686}
386        ppc         {return powerpc}
387        ppc64       {return powerpc64}
388        default     {return ${arch}}
389    }
390}
391
392# Rust architecture name --> MacPorts architecture name
393proc rust.marcports_arch {rarch} {
394    switch ${rarch} {
395        aarch64     {return arm64}
396        i686        {return i386}
397        powerpc     {return ppc}
398        powerpc64   {return ppc64}
399        default     {return ${rarch}}
400    }
401}
402
403####################################################################################################################################
404# compatibility procedures
405####################################################################################################################################
406proc cargo.rust_platform {{arch ""}} {
407    if {${arch} eq ""} {
408        set arch [option muniversal.build_arch]
409        # muniversal.build_arch is empty if we are not doing a universal build
410        if {${arch} eq ""} {
411            set arch [option configure.build_arch]
412            if {${arch} eq ""} {
413                error "No build arch configured"
414            }
415        }
416    }
417    return [option triplet.${arch}]
418}
419
420####################################################################################################################################
421# internal procedures
422####################################################################################################################################
423
424namespace eval rust {}
425
426# for symbol ___emutls_get_address (used when thread-local-storage is emulated)
427#
428# for Clang, provides symbol ___muloti4
429# since https://github.com/rust-lang/rust/commit/8a6ff90a3a41e6ace18aeb089ea0a0eb3726dd08
430#
431proc rust::get_static_rutime_libraries {} {
432    set libs [list ]
433
434    if {[string match *clang* [option configure.compiler]]} {
435        set libName lib/[option os.platform]/libclang_rt.osx.a
436    } else {
437        set libName libgcc_eh.a
438    }
439
440    if {![catch [list exec [option configure.cc] --print-search-dirs] results]} {
441        foreach ln [split ${results} \n] {
442            set splt [split ${ln} =]
443            if {[lindex ${splt} 0] eq "libraries: "} {
444                foreach dir [split [lindex ${splt} 1] :] {
445                    set fl [string trimright ${dir} "/"]/${libName}
446                    if {[file exists ${fl}]} {
447                        lappend libs ${fl}
448                    }
449                }
450            }
451        }
452    }
453
454    return ${libs}
455}
456
457proc rust::configure_ldflags_proc {option action args} {
458    if {$action ne "read"} return
459    if {[option rust.add_compiler_runtime]} {
460        configure.ldflags-delete    {*}[option rust.rt_static_libs]
461        configure.ldflags-append    {*}[option rust.rt_static_libs]
462    }
463}
464option_proc configure.ldflags rust::configure_ldflags_proc
465
466# based on portextract::disttagclean from portextract.tcl
467proc rust::disttagclean {list} {
468    if {$list eq ""} {
469        return $list
470    }
471    foreach fname $list {
472        set name [getdistname ${fname}]
473
474        set is_crate no
475        foreach {cname cversion chksum} [option cargo.crates] {
476            set cratefile ${cname}-${cversion}.crate
477            if {${name} eq ${cratefile}} {
478                set is_crate yes
479            }
480        }
481        foreach {cname cgithub cbranch crevision chksum} [option cargo.crates_github] {
482            set cratefile ${cname}-${crevision}.tar.gz
483            if {${name} eq ${cratefile}} {
484                set is_crate yes
485            }
486        }
487        if {!${is_crate}} {
488            lappend val ${name}
489        }
490    }
491    return $val
492}
493
494proc rust::handle_crates {} {
495    foreach {cname cversion chksum} [option cargo.crates] {
496        # The same crate name can appear with multiple versions. Use
497        # a combination of crate name and checksum as unique identifier.
498        # As the :disttag cannot contain dots, the version number cannot be
499        # used.
500        #
501        # To download the crate file curl-0.4.11.crate, the URL is
502        #    https://crates.io/api/v1/crates/curl/0.4.11/download.
503        # Use ?dummy= to ignore ${distfile}
504        # see https://trac.macports.org/wiki/PortfileRecipes#fetchwithgetparams
505        set cratefile       ${cname}-${cversion}.crate
506        set cratetag        crate-${cname}-${chksum}
507        distfiles-append    ${cratefile}:${cratetag}
508        master_sites-append https://crates.io/api/v1/crates/${cname}/${cversion}/download?dummy=:${cratetag}
509        checksums-append    ${cratefile} sha256 ${chksum}
510    }
511
512    foreach {cname cgithub cbranch crevision chksum} [option cargo.crates_github] {
513        set cratefile       ${cname}-${crevision}.tar.gz
514        set cratetag        crate-${cname}-${chksum}
515        distfiles-append    ${cratefile}:${cratetag}
516        master_sites-append https://github.com/${cgithub}/archive/${crevision}.tar.gz?dummy=:${cratetag}
517        checksums-append    ${cratefile} sha256 ${chksum}
518    }
519}
520port::register_callback rust::handle_crates
521
522proc rust::extract_crate {cratefile} {
523    set tar [findBinary tar ${portutil::autoconf::tar_path}]
524    system -W "[option cargo.home]/macports" "$tar -xf [shellescape [option distpath]/${cratefile}]"
525}
526
527proc rust::write_cargo_checksum {cdirname chksum} {
528    # although cargo will never see the .crate, it expects to find the sha256 checksum here
529    set chkfile [open "[option cargo.home]/macports/${cdirname}/.cargo-checksum.json" "w"]
530    puts $chkfile "{"
531    puts $chkfile "    \"package\": ${chksum},"
532    puts $chkfile "    \"files\": {}"
533    puts $chkfile "}"
534    close $chkfile
535}
536
537proc rust::old_macos_compatibility {cname cversion} {
538    global cargo.home subport
539
540    switch ${cname} {
541        "kqueue" {
542            if { [vercmp ${cversion} < 1.0.5] && "i386" in [option muniversal.architectures] } {
543                # see https://gitlab.com/worr/rust-kqueue/-/merge_requests/10
544                reinplace {s|all(target_os = "freebsd", target_arch = "x86")|all(any(target_os = "freebsd", target_os = "macos"), any(target_arch = "x86", target_arch = "powerpc"))|g} \
545                    ${cargo.home}/macports/${cname}-${cversion}/src/time.rs
546                cargo.offline_cmd-replace --frozen --offline
547            }
548        }
549        "curl-sys" {
550            if { [vercmp ${cversion} < 0.4.56] } {
551                # on Mac OS X 10.6, clang exists, but `clang --print-search-dirs` returns an empty library directory
552                # see https://github.com/alexcrichton/curl-rust/commit/b3a3ce876921f2e82a145d9abd539cd8f9b7ab7b
553                # see https://trac.macports.org/ticket/64146#comment:16
554                #
555                # on other systems, we want the static library of the compiler we are using and not necessarily the system compiler
556                # see https://github.com/alexcrichton/curl-rust/commit/a6969c03b1e8f66bc4c801914327176ed38f44c5
557                # see https://github.com/alexcrichton/curl-rust/issues/279
558                #
559                # for upstream pull request, see https://github.com/alexcrichton/curl-rust/pull/451
560                #
561                reinplace "s|Command::new(\"clang\")|cc::Build::new().get_compiler().to_command()|g" \
562                    ${cargo.home}/macports/${cname}-${cversion}/build.rs
563            }
564        }
565    }
566
567    # rust-bootstrap requires `macosx_deployment_target` instead of `os.major`
568    if {[option os.platform] ne "darwin" || [vercmp [option macosx_deployment_target] >= 10.8]} {
569        return
570    }
571
572    switch ${cname} {
573        "crypto-hash" {
574            # switch crypto-hash to use openssl instead of commoncrypto
575            # See: https://github.com/malept/crypto-hash/issues/23
576            reinplace "s|target_os = \"macos\"|target_os = \"macos_disabled\"|g" \
577                ${cargo.home}/macports/${cname}-${cversion}/src/lib.rs
578            reinplace "s|macos|macos_disabled|g" \
579                ${cargo.home}/macports/${cname}-${cversion}/Cargo.toml
580        }
581        "curl-sys" {
582            # curl-sys requires CCDigestGetOutputSizeFromRef which is only available since macOS 10.8
583            # disable USE_SECTRANSP to avoid calling of CCDigestGetOutputSizeFromRef and use OpenSSL instead
584            # See: https://github.com/alexcrichton/curl-rust/issues/429
585            reinplace "s|else if target.contains(\"-apple-\")|else if target.contains(\"-apple_disabled-\")|g" \
586                ${cargo.home}/macports/${cname}-${cversion}/build.rs
587            reinplace "s|macos|macos_disabled|g" \
588                ${cargo.home}/macports/${cname}-${cversion}/Cargo.toml
589        }
590        "libgit2-sys" {
591            # libgit2-sys requires SSLCreateContext which is only available since macOS 10.8
592            # disable GIT_SECURE_TRANSPORT to avoid calling of SSLCreateContext and use OpenSSL instead
593            reinplace "s|else if target.contains(\"apple\")|else if target.contains(\"apple_disabled\")|g" \
594                ${cargo.home}/macports/${cname}-${cversion}/build.rs
595        }
596    }
597
598    if {[option os.platform] ne "darwin" || [vercmp [option macosx_deployment_target] >= 10.6]} {
599        return
600    }
601
602    switch ${cname} {
603        "notify" {
604            reinplace {s|default = \["macos_fsevent"\]|default = \["macos_kqueue"\]|g} \
605                ${cargo.home}/macports/${cname}-${cversion}/Cargo.toml
606        }
607        "cargo-util" {
608            reinplace {s|#\[cfg(not(target_os = "macos"))\]|#\[cfg(not(target_os = "macos_temp"))\]|g} \
609                ${cargo.home}/macports/${cname}-${cversion}/src/paths.rs
610            reinplace {s|#\[cfg(target_os = "macos")\]|#\[cfg(not(target_os = "macos"))\]|g} \
611                ${cargo.home}/macports/${cname}-${cversion}/src/paths.rs
612            reinplace {s|#\[cfg(not(target_os = "macos_temp"))\]|#\[cfg(target_os = "macos")\]|g} \
613                ${cargo.home}/macports/${cname}-${cversion}/src/paths.rs
614        }
615    }
616}
617
618proc rust::import_crate {cname cversion chksum cratefile} {
619    global cargo.home
620
621    ui_info "Adding ${cratefile} to cargo home"
622    rust::extract_crate ${cratefile}
623    rust::write_cargo_checksum "${cname}-${cversion}" "\"${chksum}\""
624    rust::old_macos_compatibility ${cname} ${cversion}
625}
626
627proc rust::import_crate_github {cname cgithub crevision chksum cratefile} {
628    global cargo.home
629
630    set crepo [lindex [split ${cgithub} "/"] 1]
631    set cdirname "${crepo}-${crevision}"
632
633    ui_info "Adding ${cratefile} from github to cargo home"
634    rust::extract_crate ${cratefile}
635    rust::write_cargo_checksum ${cdirname} "null"
636    rust::old_macos_compatibility ${cname} ${crevision}
637}
638
639post-extract {
640    if {[llength ${cargo.crates}] > 0 || [llength ${cargo.crates_github}]>0} {
641        file mkdir "${cargo.home}/macports"
642
643        # avoid downloading files from online repository during build phase
644        # use a replacement for crates.io
645        # https://doc.rust-lang.org/cargo/reference/source-replacement.html
646        set conf [open "${cargo.home}/config.toml" "w"]
647        puts $conf "\[source\]"
648        puts $conf "\[source.macports\]"
649        puts $conf "directory = \"${cargo.home}/macports\""
650        puts $conf "\[source.crates-io\]"
651        puts $conf "replace-with = \"macports\""
652        puts $conf "local-registry = \"/var/empty\""
653        foreach {cname cgithub cbranch crevision chksum} ${cargo.crates_github} {
654            puts $conf "\[source.\"https://github.com/${cgithub}\"\]"
655            puts $conf "git = \"https://github.com/${cgithub}\""
656            puts $conf "branch = \"${cbranch}\""
657            puts $conf "replace-with = \"macports\""
658        }
659        close $conf
660
661        # import all crates
662        foreach {cname cversion chksum} ${cargo.crates} {
663            set cratefile ${cname}-${cversion}.crate
664            rust::import_crate ${cname} ${cversion} ${chksum} ${cratefile}
665        }
666        foreach {cname cgithub cbranch crevision chksum} ${cargo.crates_github} {
667            set cratefile ${cname}-${crevision}.tar.gz
668            rust::import_crate_github ${cname} ${cgithub} ${crevision} ${chksum} ${cratefile}
669        }
670    }
671
672    if {${subport} ne "rust" && [join [lrange [split ${subport} -] 0 1] -] ne "rust-bootstrap"} {
673
674        # see comment below concerning RUSTC and RUSTFLAGS
675
676        file mkdir "${cargo.home}"
677        set conf [open "${cargo.home}/config.toml" "a"]
678
679        puts $conf "\[build\]"
680        puts $conf "rustc = \"${prefix}/bin/rustc\""
681        if {[option rust.flags] ne ""} {
682            puts $conf "rustflags = \[\"[join [option rust.flags] {", "}]\"\]"
683        }
684
685        # be sure to include all architectures in case, e.g., a 64-bit Cargo compiles a 32-bit port
686        foreach arch {arm64 x86_64 i386 ppc ppc64} {
687            puts $conf "\[target.[option triplet.${arch}]\]"
688            puts $conf "linker = \"[compwrap::wrap_compiler ld]\""
689        }
690        close $conf
691    }
692}
693
694proc rust::append_envs { var {phases {configure build destroot}} } {
695    foreach phase ${phases} {
696        ${phase}.env-delete ${var}
697        ${phase}.env-append ${var}
698    }
699}
700
701# Is build caching enabled ?
702# WIP for now ...
703#if {[tbool configure.ccache]} {
704#    # Enable sccache for rust caching
705#    depends_build-append port:sccache
706#    rust::append_envs    RUSTC_WRAPPER=${prefix}/bin/sccache
707#    rust::append_envs    SCCACHE_CACHE_SIZE=2G
708#    rust::append_envs    SCCACHE_DIR=${workpath}/.sccache
709#}
710
711proc rust::set_environment {} {
712    global prefix configure.pkg_config_path
713    global subport configure.build_arch configure.universal_archs
714
715    rust::append_envs     "RUST_BACKTRACE=1"
716
717    rust::append_envs     CC=[compwrap::wrap_compiler cc]   {build destroot}
718    rust::append_envs     CXX=[compwrap::wrap_compiler cxx] {build destroot}
719
720    if { [option openssl.branch] ne "" } {
721        set openssl_ver                     [string map {. {}} [option openssl.branch]]
722        rust::append_envs                   OPENSSL_DIR=${prefix}/libexec/openssl${openssl_ver}
723        compiler.cpath-prepend              ${prefix}/libexec/openssl${openssl_ver}/include
724        compiler.library_path-prepend       ${prefix}/libexec/openssl${openssl_ver}/lib
725        configure.pkg_config_path-prepend   ${prefix}/libexec/openssl${openssl_ver}/lib/pkgconfig
726    }
727
728    # Propagate pkgconfig path to build and destroot phases as well.
729    # Needed to work with openssl PG.
730    if { ${configure.pkg_config_path} ne "" } {
731        rust::append_envs "PKG_CONFIG_PATH=[join ${configure.pkg_config_path} :]" {build destroot}
732    }
733
734    if {${subport} ne "rust" && [join [lrange [split ${subport} -] 0 1] -] ne "rust-bootstrap"} {
735
736        # when CARGO_BUILD_TARGET is set or `--target` is used, RUSTFLAGS and RUSTC are ignored
737        #     rust::append_envs     "RUSTFLAGS=-C linker=[compwrap::wrap_compiler ld]"
738        #     rust::append_envs     "RUSTC=${prefix}/bin/rustc"
739        # see https://github.com/rust-lang/cargo/issues/4423
740
741        foreach stage {configure build destroot} {
742            foreach arch [option muniversal.architectures] {
743                ${stage}.env.${arch}-append "CARGO_BUILD_TARGET=[option triplet.${arch}]"
744            }
745        }
746    }
747}
748port::register_callback rust::set_environment
749
750proc rust::rust_pg_callback {} {
751    global  subport \
752            prefix
753
754    if { ${subport} ne "rust" && [join [lrange [split ${subport} -] 0 1] -] ne "rust-bootstrap" } {
755        # port is *not* building Rust
756
757        foreach {f s} [option rust.remap] {
758            rust.flags-prepend          --remap-path-prefix=${f}=${s}
759        }
760
761        depends_build-delete            port:rust
762        depends_build-append            port:rust
763
764        if { ${subport} ne "cargo" } {
765            # port is building neither Rust nor Cargo
766            depends_build-delete        port:cargo
767            depends_build-append        port:cargo
768            depends_skip_archcheck-delete   cargo
769            depends_skip_archcheck-append   cargo
770        }
771    } else {
772        # port is building Rust
773
774        if { [option rust.llvm.legacy] } {
775            depends_build-delete        path:lib/libMacportsLegacySupport.a:legacy-support
776            depends_build-append        path:lib/libMacportsLegacySupport.a:legacy-support
777        }
778
779        if { [option rust.use_cctools] } {
780            depends_build-delete        port:cctools
781            depends_build-append        port:cctools
782            depends_skip_archcheck-delete   cctools
783            depends_skip_archcheck-append   cctools
784        }
785    }
786
787    if { [option openssl.branch] ne "" } {
788        set openssl_ver                 [string map {. {}} [option openssl.branch]]
789        depends_lib-delete              port:openssl${openssl_ver}
790        depends_lib-append              port:openssl${openssl_ver}
791    }
792
793    if { [string match "macports-clang*" [option configure.compiler]] && [option os.major] < 11 } {
794        # by default, ld64 uses ld64-127 when 9 <= ${os.major} < 11
795        # Rust fails to build when architecture is x86_64 and ld64 uses ld64-127
796        depends_build-delete            port:ld64-274
797        depends_build-append            port:ld64-274
798        depends_skip_archcheck-delete   ld64-274
799        depends_skip_archcheck-append   ld64-274
800        configure.ldflags-delete        -fuse-ld=${prefix}/bin/ld-274
801        configure.ldflags-append        -fuse-ld=${prefix}/bin/ld-274
802    }
803
804    # rust-bootstrap requires `macosx_deployment_target` instead of `os.major`
805    if { [option os.platform] eq "darwin" && [vercmp [option macosx_deployment_target] < 10.6]} {
806        # __Unwind_RaiseException
807        depends_lib-delete              port:libunwind
808        depends_lib-append              port:libunwind
809        configure.ldflags-delete        -lunwind
810        configure.ldflags-append        -lunwind
811
812        if { [join [lrange [split ${subport} -] 0 1] -] eq "rust-bootstrap" } {
813            # Bootstrap compilers are building on newer machines to be run on older ones.
814            # Use libMacportsLegacySystem.B.dylib since it is able to use the `__asm("$ld$add$os10.5$...")` trick for symbols that are part of legacy-support *only* on older systems.
815            set legacyLib               libMacportsLegacySystem.B.dylib
816            set dep_type                lib
817
818            # code should mimic legacy-support
819            # see https://github.com/macports/macports-ports/blob/master/devel/legacy-support/Portfile
820            set max_darwin_reexport 19
821            if { [option configure.build_arch] eq "arm64" || [option os.major] > ${max_darwin_reexport} } {
822                # ${prefix}/lib/libMacportsLegacySystem.B.dylib does not exist
823                # see https://trac.macports.org/ticket/65255
824                known_fail              yes
825                pre-fetch {
826                    ui_error "${subport} requires libMacportsLegacySystem.B.dylib, which is provided by legacy-support"
827                    return -code error "incompatible system configuration"
828                }
829            }
830        } else {
831            # Use the static library since the Rust compiler looks up certain symbols at *runtime* (e.g. `openat`).
832            # Normally, we would want the additional functionality provided by MacPorts.
833            # However, for reasons yet unknown, the Rust file system (sys/unix/fs.rs) functions fail when they try to use MacPorts system calls.
834            set legacyLib               libMacportsLegacySupport.a
835            set dep_type                build
836        }
837
838        # LLVM: CFPropertyListCreateWithStream, uuid_string_t
839        # Rust: _posix_memalign, extended _realpath, _pthread_setname_np, _copyfile_state_get
840        depends_${dep_type}-delete      path:lib/${legacyLib}:legacy-support
841        depends_${dep_type}-append      path:lib/${legacyLib}:legacy-support
842        configure.ldflags-delete        -Wl,${prefix}/lib/${legacyLib}
843        configure.ldflags-append        -Wl,${prefix}/lib/${legacyLib}
844    }
845
846    # sometimes Cargo.lock does not exist
847    post-extract {
848        if { ${cargo.update} } {
849            system -W ${worksrcpath} "${cargo.bin} --offline update"
850        }
851    }
852}
853port::register_callback rust::rust_pg_callback