source: branches/gsoc13-tests/src/package1.0/portrpm.tcl @ 139170

Last change on this file since 139170 was 111323, checked in by marius@…, 7 years ago

Merge from trunk.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 8.9 KB
Line 
1# et:ts=4
2# portrpm.tcl
3# $Id: portrpm.tcl 111323 2013-09-18 23:11:02Z marius@macports.org $
4#
5# Copyright (c) 2005 - 2007, 2009 - 2011, 2013 The MacPorts Project
6# Copyright (c) 2002 - 2003 Apple Inc.
7# All rights reserved.
8#
9# Redistribution and use in source and binary forms, with or without
10# modification, are permitted provided that the following conditions
11# are met:
12# 1. Redistributions of source code must retain the above copyright
13#    notice, this list of conditions and the following disclaimer.
14# 2. Redistributions in binary form must reproduce the above copyright
15#    notice, this list of conditions and the following disclaimer in the
16#    documentation and/or other materials provided with the distribution.
17# 3. Neither the name of Apple Inc. nor the names of its contributors
18#    may be used to endorse or promote products derived from this software
19#    without specific prior written permission.
20#
21# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31# POSSIBILITY OF SUCH DAMAGE.
32#
33
34package provide portrpm 1.0
35package require portutil 1.0
36
37set org.macports.rpm [target_new org.macports.rpm portrpm::rpm_main]
38target_runtype ${org.macports.rpm} always
39target_provides ${org.macports.rpm} rpm
40target_requires ${org.macports.rpm} archivefetch unarchive destroot
41
42namespace eval portrpm {
43}
44
45# Options
46options rpm.asroot \
47        package.destpath
48
49# Set up defaults
50default rpm.asroot yes
51
52default rpm.srcdir {${prefix}/src/macports}
53default rpm.tmpdir {${prefix}/var/tmp}
54
55set_ui_prefix
56
57proc portrpm::rpm_main {args} {
58    global subport version revision UI_PREFIX
59
60    ui_msg "$UI_PREFIX [format [msgcat::mc "Creating RPM package for %s-%s"] ${subport} ${version}]"
61
62    return [rpm_pkg $subport $version $revision]
63}
64
65proc portrpm::rpm_pkg {portname portversion portrevision} {
66    global UI_PREFIX rpm.asroot package.destpath portdbpath destpath workpath \
67           prefix categories maintainers description long_description \
68           homepage epoch portpath os.platform os.arch os.version os.major \
69           supported_archs configure.build_arch license
70
71    set rpmdestpath ""
72    if {![string equal ${package.destpath} ${workpath}] && ![string equal ${package.destpath} ""]} {
73        set rpm.asroot no
74        set pkgpath ${package.destpath}
75        file mkdir ${pkgpath}/BUILD \
76                   ${pkgpath}/RPMS \
77                   ${pkgpath}/SOURCES \
78                   ${pkgpath}/SPECS \
79                   ${pkgpath}/SRPMS
80        set rpmdestpath "--define '_topdir ${pkgpath}'"
81    }
82
83    set rpmbuildarch ""
84    if {$supported_archs == "noarch"} {
85        set rpmbuildarch "--target noarch"
86    } elseif {[variant_exists universal] && [variant_isset universal]} {
87        set rpmbuildarch "--target fat"
88    } elseif {${configure.build_arch} != ""} {
89        set rpmbuildarch "--target ${configure.build_arch}"
90    }
91
92    foreach dir [list "${prefix}/src/macports/RPMS" "${prefix}/src/apple/RPMS" "/usr/src/apple/RPMS" "/macports/rpms/RPMS"] {
93        foreach arch [list ${configure.build_arch} ${os.arch} "fat" "noarch"] {
94            set rpmpath "$dir/${arch}/${portname}-${portversion}-${portrevision}.${arch}.rpm"
95            if {[file readable $rpmpath] && ([file mtime ${rpmpath}] >= [file mtime ${portpath}/Portfile])} {
96                ui_debug "$rpmpath"
97                ui_msg "$UI_PREFIX [format [msgcat::mc "RPM package for %s version %s is up-to-date"] ${portname} ${portversion}]"
98                return 0
99            }
100        }
101    }
102
103    set specpath ${workpath}/${portname}.spec
104    # long_description, description, or homepage may not exist
105    foreach variable {long_description description homepage categories maintainers} {
106        if {![info exists $variable]} {
107            set pkg_$variable ""
108        } else {
109            set pkg_$variable [set $variable]
110        }
111    }
112    set category   [lindex [split $categories " "] 0]
113    set maintainer $maintainers
114
115    set dependencies {}
116    # get deplist
117    set deps [make_dependency_list $portname]
118    set deps [lsort -unique $deps]
119    foreach dep $deps {
120        set name [lindex [split $dep /] 0]
121        set vers [lindex [split $dep /] 1]
122        # don't re-package ourself
123        if {$name != $portname} {
124            lappend dependencies "${name} >= ${vers}"
125        }
126    }
127
128        # depend on system (virtual packages for apple stuff)
129        lappend dependencies "org.macports.${os.platform}${os.major}"
130
131    set listpath ${workpath}/${portname}.filelist
132    system "rm -f '${workpath}/${portname}.filelist' && touch '${workpath}/${portname}.filelist'"
133    #system "cd '${destpath}' && find . -type d | grep -v -E '^.$' | sed -e 's/\"/\\\"/g' -e 's/^./%dir \"/' -e 's/$/\"/' > '${workpath}/${portname}.filelist'"
134    system "cd '${destpath}' && find . ! -type d | grep -v /etc/ | sed -e 's/\"/\\\"/g' -e 's/^./\"/' -e 's/$/\"/' >> '${workpath}/${portname}.filelist'"
135    system "cd '${destpath}' && find . ! -type d | grep /etc/ | sed -e 's/\"/\\\"/g' -e 's/^./%config \"/' -e 's/$/\"/' >> '${workpath}/${portname}.filelist'"
136    write_spec ${specpath} ${destpath} ${listpath} $portname $portversion $portrevision $pkg_description $pkg_long_description $pkg_homepage $category $license $maintainer $dependencies $epoch
137    system "MP_USERECEIPTS='${portdbpath}/receipts' rpmbuild -bb -v ${rpmbuildarch} ${rpmdestpath} ${specpath}"
138
139    return 0
140}
141
142proc portrpm::make_dependency_list {portname} {
143    set result {}
144    if {[catch {set res [mport_lookup $portname]} error]} {
145                global errorInfo
146                ui_debug "$errorInfo"
147        ui_error "port lookup failed: $error"
148        return 1
149    }
150    foreach {name array} $res {
151        array set portinfo $array
152
153        if {[info exists portinfo(depends_run)] || [info exists portinfo(depends_lib)]} {
154            # get the union of depends_run and depends_lib
155            # xxx: only examines the portfile component of the depspec
156            set depends {}
157            if {[info exists portinfo(depends_run)]} { eval "lappend depends $portinfo(depends_run)" }
158            if {[info exists portinfo(depends_lib)]} { eval "lappend depends $portinfo(depends_lib)" }
159
160            foreach depspec $depends {
161                set dep [lindex [split $depspec :] end]
162
163                # xxx: nasty hack
164                if {$dep != "XFree86"} {
165                    eval "lappend result [make_dependency_list $dep]"
166                }
167            }
168        }
169        lappend result $portinfo(name)/$portinfo(version)
170        unset portinfo
171    }
172    ui_debug "dependencies for ${portname}: $result"
173    return $result
174}
175
176proc portrpm::word_wrap {orig Length} {
177    set pos 0
178    set line ""
179    set text ""
180
181    set words [split $orig]
182    set numWords [llength $words]
183    for {set cnt 0} {$cnt < $numWords} {incr cnt} {
184        set w [lindex $words $cnt]
185        set wLen [string length $w]
186
187        if {($pos+$wLen < $Length)} {
188            # append word to current line
189            if {$pos} {append line " "; incr pos}
190            append line $w
191            incr pos $wLen
192        } else {
193            # line full => write buffer and  begin a new line
194            if {[string length $text]} {append text "\n"}
195            append text $line
196            set line $w
197            set pos $wLen
198        }
199    }
200
201    if {[string length $text]} {append text "\n"}
202    if {[string length $line]} {append text $line}
203    return $text
204}
205
206proc portrpm::write_spec {specfile destroot filelist portname portversion portrevision description long_description homepage category license maintainer dependencies epoch} {
207    set specfd [open ${specfile} w+]
208    set origportname ${portname}
209    regsub -all -- "\-" $portversion "_" portversion
210    regsub -all -- "\-" $portname "_" portname
211    puts $specfd "\#Spec file generated by MacPorts
212%define distribution MacPorts
213%define vendor MacPorts
214%define packager ${maintainer}
215
216%define buildroot ${destroot}
217# Avoid cleaning BuildRoot in the pre-install:
218%define __spec_install_pre     %{___build_pre}
219%define __spec_clean_body      %{nil}
220
221Summary: ${description}
222Name: ${portname}
223Version: ${portversion}
224Release: ${portrevision}
225Group: ${category}
226License: ${license}
227URL: ${homepage}
228BuildRoot: ${destroot}
229AutoReq: no"
230    if {[expr ${epoch} != 0]} {
231            puts $specfd "Epoch: ${epoch}"
232    }
233    if {[llength ${dependencies}] != 0} {
234        foreach require ${dependencies} {
235            puts $specfd "Requires: [regsub -all -- "\-" $require "_"]"
236        }
237    }
238    set wrap_description [word_wrap ${long_description} 72]
239    puts $specfd "
240%description
241$wrap_description
242
243%prep
244%build
245%install
246%clean
247
248%files -f ${filelist}"
249    close $specfd
250}
Note: See TracBrowser for help on using the repository browser.