build: allow specifying prerequisite flags when checking flags
[samba.git] / buildtools / wafsamba / samba_install.py
1 ###########################
2 # this handles the magic we need to do for installing
3 # with all the configure options that affect rpath and shared
4 # library use
5
6 import os
7 import Utils
8 from TaskGen import feature, before, after
9 from samba_utils import LIB_PATH, MODE_755, install_rpath, build_rpath
10
11 @feature('install_bin')
12 @after('apply_core')
13 @before('apply_link', 'apply_obj_vars')
14 def install_binary(self):
15     '''install a binary, taking account of the different rpath varients'''
16     bld = self.bld
17
18     # get the ldflags we will use for install and build
19     install_ldflags = install_rpath(self)
20     build_ldflags   = build_rpath(bld)
21
22     if not self.bld.is_install:
23         # just need to set rpath if we are not installing
24         self.env.RPATH = build_ldflags
25         return
26
27     # work out the install path, expanding variables
28     install_path = getattr(self, 'samba_inst_path', None) or '${BINDIR}'
29     install_path = bld.EXPAND_VARIABLES(install_path)
30
31     orig_target = os.path.basename(self.target)
32
33     if install_ldflags != build_ldflags:
34         # we will be creating a new target name, and using that for the
35         # install link. That stops us from overwriting the existing build
36         # target, which has different ldflags
37         self.target += '.inst'
38
39     # setup the right rpath link flags for the install
40     self.env.RPATH = install_ldflags
41
42     if not self.samba_install:
43         # this binary is marked not to be installed
44         return
45
46     # tell waf to install the right binary
47     bld.install_as(os.path.join(install_path, orig_target),
48                    os.path.join(self.path.abspath(bld.env), self.target),
49                    chmod=MODE_755)
50
51
52
53 @feature('install_lib')
54 @after('apply_core')
55 @before('apply_link', 'apply_obj_vars')
56 def install_library(self):
57     '''install a library, taking account of the different rpath varients'''
58     if getattr(self, 'done_install_library', False):
59         return
60
61     bld = self.bld
62
63     default_env = bld.all_envs['default']
64     try:
65         if self.env['IS_EXTRA_PYTHON']:
66             bld.all_envs['default'] = bld.all_envs['extrapython']
67
68         install_ldflags = install_rpath(self)
69         build_ldflags   = build_rpath(bld)
70
71         if not self.bld.is_install or not getattr(self, 'samba_install', True):
72             # just need to set the build rpath if we are not installing
73             self.env.RPATH = build_ldflags
74             return
75
76         # setup the install path, expanding variables
77         install_path = getattr(self, 'samba_inst_path', None)
78         if install_path is None:
79             if getattr(self, 'private_library', False):
80                 install_path = '${PRIVATELIBDIR}'
81             else:
82                 install_path = '${LIBDIR}'
83         install_path = bld.EXPAND_VARIABLES(install_path)
84
85         target_name = self.target
86
87         if install_ldflags != build_ldflags:
88             # we will be creating a new target name, and using that for the
89             # install link. That stops us from overwriting the existing build
90             # target, which has different ldflags
91             self.done_install_library = True
92             t = self.clone(self.env)
93             t.posted = False
94             t.target += '.inst'
95             t.name = self.name + '.inst'
96             self.env.RPATH = build_ldflags
97         else:
98             t = self
99
100         t.env.RPATH = install_ldflags
101
102         dev_link     = None
103
104         # in the following the names are:
105         # - inst_name is the name with .inst. in it, in the build
106         #   directory
107         # - install_name is the name in the install directory
108         # - install_link is a symlink in the install directory, to install_name
109
110         if getattr(self, 'samba_realname', None):
111             install_name = self.samba_realname
112             install_link = None
113             if getattr(self, 'soname', ''):
114                 install_link = self.soname
115             if getattr(self, 'samba_type', None) == 'PYTHON':
116                 inst_name    = bld.make_libname(t.target, nolibprefix=True, python=True)
117             else:
118                 inst_name    = bld.make_libname(t.target)
119         elif self.vnum:
120             vnum_base    = self.vnum.split('.')[0]
121             install_name = bld.make_libname(target_name, version=self.vnum)
122             install_link = bld.make_libname(target_name, version=vnum_base)
123             inst_name    = bld.make_libname(t.target)
124             if not self.private_library:
125                 # only generate the dev link for non-bundled libs
126                 dev_link     = bld.make_libname(target_name)
127         elif getattr(self, 'soname', ''):
128             install_name = bld.make_libname(target_name)
129             install_link = self.soname
130             inst_name    = bld.make_libname(t.target)
131         else:
132             install_name = bld.make_libname(target_name)
133             install_link = None
134             inst_name    = bld.make_libname(t.target)
135
136         if t.env.SONAME_ST:
137             # ensure we get the right names in the library
138             if install_link:
139                 t.env.append_value('LINKFLAGS', t.env.SONAME_ST % install_link)
140             else:
141                 t.env.append_value('LINKFLAGS', t.env.SONAME_ST % install_name)
142             t.env.SONAME_ST = ''
143
144         # tell waf to install the library
145         bld.install_as(os.path.join(install_path, install_name),
146                        os.path.join(self.path.abspath(bld.env), inst_name),
147                        chmod=MODE_755)
148         if install_link and install_link != install_name:
149             # and the symlink if needed
150             bld.symlink_as(os.path.join(install_path, install_link), os.path.basename(install_name))
151         if dev_link:
152             bld.symlink_as(os.path.join(install_path, dev_link), os.path.basename(install_name))
153     finally:
154         bld.all_envs['default'] = default_env
155
156
157 @feature('cshlib')
158 @after('apply_implib')
159 @before('apply_vnum')
160 def apply_soname(self):
161     '''install a library, taking account of the different rpath varients'''
162
163     if self.env.SONAME_ST and getattr(self, 'soname', ''):
164         self.env.append_value('LINKFLAGS', self.env.SONAME_ST % self.soname)
165         self.env.SONAME_ST = ''
166
167 @feature('cshlib')
168 @after('apply_implib')
169 @before('apply_vnum')
170 def apply_vscript(self):
171     '''add version-script arguments to library build'''
172
173     if self.env.HAVE_LD_VERSION_SCRIPT and getattr(self, 'version_script', ''):
174         self.env.append_value('LINKFLAGS', "-Wl,--version-script=%s" %
175             self.version_script)
176         self.version_script = None
177
178
179 ##############################
180 # handle the creation of links for libraries and binaries in the build tree
181
182 @feature('symlink_lib')
183 @after('apply_link')
184 def symlink_lib(self):
185     '''symlink a shared lib'''
186
187     if self.target.endswith('.inst'):
188         return
189
190     blddir = os.path.dirname(self.bld.srcnode.abspath(self.bld.env))
191     libpath = self.link_task.outputs[0].abspath(self.env)
192
193     # calculat the link target and put it in the environment
194     soext=""
195     vnum = getattr(self, 'vnum', None)
196     if vnum is not None:
197         soext = '.' + vnum.split('.')[0]
198
199     link_target = getattr(self, 'link_name', '')
200     if link_target == '':
201         basename = os.path.basename(self.bld.make_libname(self.target, version=soext))
202         if getattr(self, "private_library", False):
203             link_target = '%s/private/%s' % (LIB_PATH, basename)
204         else:
205             link_target = '%s/%s' % (LIB_PATH, basename)
206
207     link_target = os.path.join(blddir, link_target)
208
209     if os.path.lexists(link_target):
210         if os.path.islink(link_target) and os.readlink(link_target) == libpath:
211             return
212         os.unlink(link_target)
213
214     link_container = os.path.dirname(link_target)
215     if not os.path.isdir(link_container):
216         os.makedirs(link_container)
217
218     os.symlink(libpath, link_target)
219
220
221 @feature('symlink_bin')
222 @after('apply_link')
223 def symlink_bin(self):
224     '''symlink a binary into the build directory'''
225
226     if self.target.endswith('.inst'):
227         return
228
229     if not self.link_task.outputs or not self.link_task.outputs[0]:
230         raise Utils.WafError('no outputs found for %s in symlink_bin' % self.name)
231     binpath = self.link_task.outputs[0].abspath(self.env)
232     bldpath = os.path.join(self.bld.env.BUILD_DIRECTORY, self.link_task.outputs[0].name)
233
234     if os.path.lexists(bldpath):
235         if os.path.islink(bldpath) and os.readlink(bldpath) == binpath:
236             return
237         os.unlink(bldpath)
238     os.symlink(binpath, bldpath)