summaryrefslogtreecommitdiffstats
path: root/buildtools/wafsamba/samba_install.py
blob: a43d10398d3f7e07b7788a9ffb3be6158eef2222 (plain)
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
###########################
# this handles the magic we need to do for installing
# with all the configure options that affect rpath and shared
# library use

import os
from waflib import Utils, Errors
from waflib.TaskGen import feature, before, after
from samba_utils import LIB_PATH, MODE_755, install_rpath, build_rpath

@feature('install_bin')
@after('apply_core')
@before('apply_link', 'apply_obj_vars')
def install_binary(self):
    '''install a binary, taking account of the different rpath variants'''
    bld = self.bld

    # get the ldflags we will use for install and build
    install_ldflags = install_rpath(self)
    build_ldflags   = build_rpath(bld)

    if not self.bld.is_install:
        # just need to set rpath if we are not installing
        self.env.RPATH = build_ldflags
        return

    # work out the install path, expanding variables
    install_path = getattr(self, 'samba_inst_path', None) or '${BINDIR}'
    install_path = bld.EXPAND_VARIABLES(install_path)

    orig_target = os.path.basename(self.target)

    if install_ldflags != build_ldflags:
        # we will be creating a new target name, and using that for the
        # install link. That stops us from overwriting the existing build
        # target, which has different ldflags
        self.target += '.inst'

    # setup the right rpath link flags for the install
    self.env.RPATH = install_ldflags

    if not self.samba_install:
        # this binary is marked not to be installed
        return

    # tell waf to install the right binary
    bld.install_as(os.path.join(install_path, orig_target),
                   self.path.find_or_declare(self.target),
                   chmod=MODE_755)



@feature('install_lib')
@after('apply_core')
@before('apply_link', 'apply_obj_vars')
def install_library(self):
    '''install a library, taking account of the different rpath variants'''
    if getattr(self, 'done_install_library', False):
        return

    bld = self.bld

    default_env = bld.all_envs['default']
    try:
        install_ldflags = install_rpath(self)
        build_ldflags   = build_rpath(bld)

        if not self.bld.is_install or not getattr(self, 'samba_install', True):
            # just need to set the build rpath if we are not installing
            self.env.RPATH = build_ldflags
            return

        # setup the install path, expanding variables
        install_path = getattr(self, 'samba_inst_path', None)
        if install_path is None:
            if getattr(self, 'private_library', False):
                install_path = '${PRIVATELIBDIR}'
            else:
                install_path = '${LIBDIR}'
        install_path = bld.EXPAND_VARIABLES(install_path)

        target_name = self.target

        if install_ldflags != build_ldflags:
            # we will be creating a new target name, and using that for the
            # install link. That stops us from overwriting the existing build
            # target, which has different ldflags
            self.done_install_library = True
            t = self.clone(self.env)
            t.posted = False
            t.target += '.inst'
            t.name = self.name + '.inst'
            self.env.RPATH = build_ldflags
        else:
            t = self

        t.env.RPATH = install_ldflags

        dev_link     = None

        # in the following the names are:
        # - inst_name is the name with .inst. in it, in the build
        #   directory
        # - install_name is the name in the install directory
        # - install_link is a symlink in the install directory, to install_name

        if getattr(self, 'samba_realname', None):
            install_name = self.samba_realname
            install_link = None
            if getattr(self, 'soname', ''):
                install_link = self.soname
            if getattr(self, 'samba_type', None) == 'PYTHON':
                inst_name    = bld.make_libname(t.target, nolibprefix=True, python=True)
            else:
                inst_name    = bld.make_libname(t.target)
        elif self.vnum:
            vnum_base    = self.vnum.split('.')[0]
            install_name = bld.make_libname(target_name, version=self.vnum)
            install_link = bld.make_libname(target_name, version=vnum_base)
            inst_name    = bld.make_libname(t.target)
            if not self.private_library or not t.env.SONAME_ST:
                # only generate the dev link for non-bundled libs
                dev_link     = bld.make_libname(target_name)
        elif getattr(self, 'soname', ''):
            install_name = bld.make_libname(target_name)
            install_link = self.soname
            inst_name    = bld.make_libname(t.target)
        else:
            install_name = bld.make_libname(target_name)
            install_link = None
            inst_name    = bld.make_libname(t.target)

        if t.env.SONAME_ST:
            # ensure we get the right names in the library
            if install_link:
                t.env.append_value('LINKFLAGS', t.env.SONAME_ST % install_link)
            else:
                t.env.append_value('LINKFLAGS', t.env.SONAME_ST % install_name)
            t.env.SONAME_ST = ''

        # tell waf to install the library
        bld.install_as(os.path.join(install_path, install_name),
                       self.path.find_or_declare(inst_name),
                       chmod=MODE_755)

        if install_link and install_link != install_name:
            # and the symlink if needed
            bld.symlink_as(os.path.join(install_path, install_link), os.path.basename(install_name))
        if dev_link:
            bld.symlink_as(os.path.join(install_path, dev_link), os.path.basename(install_name))
    finally:
        bld.all_envs['default'] = default_env


@feature('cshlib')
@after('apply_implib')
@before('apply_vnum')
def apply_soname(self):
    '''install a library, taking account of the different rpath variants'''

    if self.env.SONAME_ST and getattr(self, 'soname', ''):
        self.env.append_value('LINKFLAGS', self.env.SONAME_ST % self.soname)
        self.env.SONAME_ST = ''

@feature('cshlib')
@after('apply_implib')
@before('apply_vnum')
def apply_vscript(self):
    '''add version-script arguments to library build'''

    if self.env.HAVE_LD_VERSION_SCRIPT and getattr(self, 'version_script', ''):
        self.env.append_value('LINKFLAGS', "-Wl,--version-script=%s" %
            self.version_script)
        self.version_script = None


##############################
# handle the creation of links for libraries and binaries in the build tree

@feature('symlink_lib')
@after('apply_link')
def symlink_lib(self):
    '''symlink a shared lib'''

    if self.target.endswith('.inst'):
        return

    blddir = os.path.dirname(self.bld.srcnode.abspath(self.bld.env))
    libpath = self.link_task.outputs[0].abspath(self.env)

    # calculate the link target and put it in the environment
    soext=""
    vnum = getattr(self, 'vnum', None)
    if vnum is not None:
        soext = '.' + vnum.split('.')[0]

    link_target = getattr(self, 'link_name', '')
    if link_target == '':
        basename = os.path.basename(self.bld.make_libname(self.target, version=soext))
        if getattr(self, "private_library", False):
            link_target = '%s/private/%s' % (LIB_PATH, basename)
        else:
            link_target = '%s/%s' % (LIB_PATH, basename)

    link_target = os.path.join(blddir, link_target)

    if os.path.lexists(link_target):
        if os.path.islink(link_target) and os.readlink(link_target) == libpath:
            return
        os.unlink(link_target)

    link_container = os.path.dirname(link_target)
    if not os.path.isdir(link_container):
        os.makedirs(link_container)

    os.symlink(libpath, link_target)


@feature('symlink_bin')
@after('apply_link')
def symlink_bin(self):
    '''symlink a binary into the build directory'''

    if self.target.endswith('.inst'):
        return

    if not self.link_task.outputs or not self.link_task.outputs[0]:
        raise Errors.WafError('no outputs found for %s in symlink_bin' % self.name)
    binpath = self.link_task.outputs[0].abspath(self.env)
    bldpath = os.path.join(self.bld.env.BUILD_DIRECTORY, self.link_task.outputs[0].name)

    if os.path.lexists(bldpath):
        if os.path.islink(bldpath) and os.readlink(bldpath) == binpath:
            return
        os.unlink(bldpath)
    os.symlink(binpath, bldpath)