-
Notifications
You must be signed in to change notification settings - Fork 8
/
devport-1.0.tcl
268 lines (254 loc) · 12.4 KB
/
devport-1.0.tcl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
# -*- 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
# Copyright (c) 2015 The MacPorts Project
# Copyright (c) 2017-2019 RJVB
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. Neither the name of Apple Computer, Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
#
# Usage:
# PortGroup devport 1.0
options mainport_name devport_name devport_content devport_description devport_long_description
default mainport_name {${name}}
default devport_name {${mainport_name}-dev}
default devport_content ""
default devport_description {"Development headers and libraries for ${mainport_name}"}
default devport_long_description {"${long_description}\nThis installs the development headers and libraries."}
# namespace eval dev {
# it shouldn't be necessary to record variants in the archive name
options dev::archname dev::archdir
default dev::archname {${mainport_name}@${version}-dev.tar.bz2}
# this could go into the software images directory
default dev::archdir {${prefix}/var/devcontent}
set dev::mainport_installed no
# }
# create the online devport content archive
proc create_devport_content_archive {} {
global destroot prefix mainport_name devport_name dev::archdir dev::archname
set rawargs [option devport_content]
set args ""
# convert the arguments to local-relative:
foreach a ${rawargs} {
set args "${args} .${a}"
}
xinstall -m 755 -d ${destroot}${dev::archdir}
ui_debug "Creating devport archive ${destroot}${dev::archdir}/${dev::archname} from \"${args}\""
if {[catch {system -W ${destroot} "bsdtar -cjvf ${destroot}${dev::archdir}/${dev::archname} ${args}"} err]} {
ui_error "Failure creating ${destroot}${dev::archdir}/${dev::archname} for ${args}: ${err}"
file delete -force ${destroot}${dev::archdir}/${dev::archname}
} else {
ui_debug "Deleting archived \"${args}\""
foreach a ${args} {
file delete -force ${destroot}/${a}
}
}
}
# registers content that standard devports will contain
proc register_devport_standard_content {} {
global subport destroot prefix mainport_name devport_name
if {${subport} eq "${mainport_name}"} {
ui_msg "----> Transferring developer content to ${devport_name}"
ui_debug "Finding and registering standard content for the devport"
foreach h [glob -nocomplain ${destroot}${prefix}/include/*] {
ui_debug "\theader: ${h}"
devport_content-append [string map [list ${destroot} ""] ${h}]
}
foreach h [glob -nocomplain ${destroot}${prefix}/lib/lib*.a] {
ui_debug "\tstatic library: ${h}"
devport_content-append [string map [list ${destroot} ""] ${h}]
}
foreach h [glob -nocomplain ${destroot}${prefix}/lib/lib*.la] {
ui_debug "\t.la library: ${h}"
devport_content-append [string map [list ${destroot} ""] ${h}]
}
foreach h [glob -nocomplain ${destroot}${prefix}/lib/lib*.dylib] {
if {![string match -nocase {lib*.[0-9.]*.dylib} [file tail ${h}]] && [file type ${h}] eq "link"} {
ui_debug "\tMac shared linker library: ${h}"
devport_content-append [string map [list ${destroot} ""] ${h}]
}
}
foreach h [glob -nocomplain ${destroot}${prefix}/lib/lib*.so] {
if {[file type ${h}] eq "link"} {
ui_debug "\tstandard Unix shared linker library: ${h}"
devport_content-append [string map [list ${destroot} ""] ${h}]
}
}
foreach h [glob -nocomplain ${destroot}${prefix}/lib/pkgconfig/*] {
ui_debug "\tpkg-config file: ${h}"
devport_content-append [string map [list ${destroot} ""] ${h}]
}
}
}
proc append_to_devport_standard_content {args} {
global subport destroot prefix mainport_name devport_name
if {${subport} eq "${mainport_name}"} {
foreach pattern ${args} {
ui_debug "Finding and registering additional content for the devport: \"${pattern}\""
foreach h [glob ${destroot}${pattern}] {
ui_debug "\tmatching: ${h}"
devport_content-append [string map [list ${destroot} ""] ${h}]
}
}
}
}
# check for the presence and basic validity of the -dev port tarball,
# restoring the file from the main port install image if required.
# Main purpose: allow reinstalling the -dev port after uninstalling it,
# without having to reinstall/re-activate the main port.
# Warnings but no errors are raised if this fails.
proc restore_devport_tarball {baseport} {
global dev::archdir dev::archname
if {[file exists ${dev::archdir}/${dev::archname}]
&& [file size ${dev::archdir}/${dev::archname}] > 0} {
return
}
if {![catch {set installed [lindex [registry_active ${baseport}] 0]}]} {
set cVersion [lindex $installed 1]
set cRevision [lindex $installed 2]
set cVariants [lindex $installed 3]
global name subport portdbpath os.platform os.major build_arch portarchivetype prefix
set portimage "${portdbpath}/software/${baseport}/${baseport}-${cVersion}_${cRevision}${cVariants}.${os.platform}_${os.major}.${build_arch}.${portarchivetype}"
if {[file exists ${portimage}]} {
if {[catch {system -W ${dev::archdir} "bsdtar -xOf ${portimage} .${dev::archdir}/${dev::archname} > ${dev::archname}"} err]} {
ui_warn "Failure restoring ${dev::archdir}/${dev::archname}: ${err}"
} elseif {![file exists ${dev::archdir}/${dev::archname}]
|| [file size ${dev::archdir}/${dev::archname}] == 0} {
ui_warn "Failure restoring ${dev::archdir}/${dev::archname} - did you use sudo?"
system "ls -l ${dev::archdir}/${dev::archname}*"
}
} else {
ui_warn "Calculated port image \"${portimage}\" doesn't exist"
if {[file exists ${portdbpath}/software/${baseport}]} {
ui_warn "Image directory content:"
system "ls -1 ${portdbpath}/software/${baseport}"
}
}
} else {
ui_warn "Cannot determine installed image name for ${baseport}"
}
return 0
}
proc unpack_devport_content {} {
global destroot prefix mainport_name devport_name subport dev::archdir dev::archname
if {[file exists ${dev::archdir}/${dev::archname}]
&& [file size ${dev::archdir}/${dev::archname}] > 0} {
ui_debug "Unpacking \"${dev::archdir}/${dev::archname}\" for ${subport}"
if {[catch {system -W ${destroot} "bsdtar -xvf ${dev::archdir}/${dev::archname}"} err]} {
ui_error "Failure unpacking ${dev::archdir}/${dev::archname}: ${err}"
}
} else {
ui_error "The port's content archive doesn't exists or is empty (${dev::archdir}/${dev::archname})!"
return -code error "Missing or invalid content archive; try re-activating or reinstalling port:${mainport_name}"
}
}
# Define (more so than create!) the devport
# and (231021) add post-installation logic to install/upgrade it after installing/upgrading
# the main port. See comments in the post-activate procedure for when we do and when we don't.
proc create_devport {dependency} {
global subport mainport_name devport_name devport_description devport_long_description baseport \
dev::archdir dev::archname \
dev::mainport_installed
# just so we're clear that what port we're talking about (the main port):
set baseport ${mainport_name}
subport ${devport_name} {
description [join ${devport_description}]
long_description [join ${devport_long_description}]
depends_fetch
depends_build
depends_run
depends_lib ${dependency}
depends_extract bin:bsdtar:libarchive
installs_libs yes
supported_archs noarch
distfiles
fetch {}
checksum {}
extract {}
use_configure no
patchfiles
build {}
destroot {
restore_devport_tarball ${baseport}
unpack_devport_content
}
pre-activate {
if {[file exists ${dev::archdir}/${dev::archname}]} {
ui_info "${subport} is now installed, removing installed content archive ${dev::archdir}/${dev::archname}"
file delete -force ${dev::archdir}/${dev::archname}
# make sure the file exists to keep rev-upgrade happy
# NB: this c/should be a symlink to the port's image tarball!
system "touch ${dev::archdir}/${dev::archname}"
}
}
}
if {${subport} eq ${baseport}} {
post-install {
# register that we just have installed the main port
set dev::mainport_installed yes
}
post-activate {
# we activated a version/variant of the mainport; try to auto-install the corresponding
# version/variant of the devport if the activation followed an install. We just remind
# the user to do this manually if we only activated an already installed version/variant
# (because the user might have deactivated the devport on purpose).
if {![catch {set installed [lindex [registry_active ${baseport}] 0]}]} {
set cVersion [lindex $installed 1]
set cRevision [lindex $installed 2]
set cVariants [lindex $installed 3]
if {${dev::mainport_installed} eq yes} {
ui_msg "----> Programming the installation of the dev port \"${devport_name} ${cVariants}\""
catch {
system "port -v clean ${devport_name}"
# we need to spawn/fork the actual install or else we'll be waiting
# indefinitely to obtain a lock on the registry!
exec port -n install ${devport_name} ${cVariants} &
}
} else {
ui_msg "${baseport}@${cVersion}_${cRevision}${cVariants} activated, please activate the corresponding port:${devport_name}!"
}
} else {
if {${dev::mainport_installed} eq yes} {
set action "install"
} else {
set action "activate"
}
ui_warning "----> Couldn't obtain the required information to auto-${action} the devport!"
ui_msg " Please ${action} port:${devport_name} with the same variants as the active port:${baseport}!"
}
}
}
}
proc is_devport {} {
global subport mainport_name
return [eval {${subport} eq "${devport_name}"}]
}
proc is_mainport {} {
global subport mainport_name
return [expr {${subport} eq "${mainport_name}"}]
}
# if {[is_mainport] && [file exists ${destroot}${dev::archdir}/${dev::archname}]} {
# notes-append "Don't forget to upgrade port:${devport_name} after upgrading port:${mainport_name}"
# }