1 ###########################
2 # this handles the magic we need to do for installing
3 # with all the configure options that affect rpath and shared
7 from waflib
import Utils
, Errors
8 from waflib
.TaskGen
import feature
, before
, after
9 from samba_utils
import LIB_PATH
, MODE_755
, install_rpath
, build_rpath
11 @feature('install_bin')
13 @before('apply_link', 'apply_obj_vars')
14 def install_binary(self
):
15 '''install a binary, taking account of the different rpath varients'''
18 # get the ldflags we will use for install and build
19 install_ldflags
= install_rpath(self
)
20 build_ldflags
= build_rpath(bld
)
22 if not self
.bld
.is_install
:
23 # just need to set rpath if we are not installing
24 self
.env
.RPATH
= build_ldflags
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
)
31 orig_target
= os
.path
.basename(self
.target
)
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'
39 # setup the right rpath link flags for the install
40 self
.env
.RPATH
= install_ldflags
42 if not self
.samba_install
:
43 # this binary is marked not to be installed
46 # tell waf to install the right binary
47 bld
.install_as(os
.path
.join(install_path
, orig_target
),
48 self
.path
.find_or_declare(self
.target
),
53 @feature('install_lib')
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):
63 default_env
= bld
.all_envs
['default']
65 if self
.env
['IS_EXTRA_PYTHON']:
66 bld
.all_envs
['default'] = bld
.all_envs
['extrapython']
68 install_ldflags
= install_rpath(self
)
69 build_ldflags
= build_rpath(bld
)
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
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}'
82 install_path
= '${LIBDIR}'
83 install_path
= bld
.EXPAND_VARIABLES(install_path
)
85 target_name
= self
.target
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
)
95 t
.name
= self
.name
+ '.inst'
96 self
.env
.RPATH
= build_ldflags
100 t
.env
.RPATH
= install_ldflags
104 # in the following the names are:
105 # - inst_name is the name with .inst. in it, in the build
107 # - install_name is the name in the install directory
108 # - install_link is a symlink in the install directory, to install_name
110 if getattr(self
, 'samba_realname', None):
111 install_name
= self
.samba_realname
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)
118 inst_name
= bld
.make_libname(t
.target
)
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
)
132 install_name
= bld
.make_libname(target_name
)
134 inst_name
= bld
.make_libname(t
.target
)
137 # ensure we get the right names in the library
139 t
.env
.append_value('LINKFLAGS', t
.env
.SONAME_ST
% install_link
)
141 t
.env
.append_value('LINKFLAGS', t
.env
.SONAME_ST
% install_name
)
144 # tell waf to install the library
145 bld
.install_as(os
.path
.join(install_path
, install_name
),
146 self
.path
.find_or_declare(inst_name
),
149 if install_link
and install_link
!= install_name
:
150 # and the symlink if needed
151 bld
.symlink_as(os
.path
.join(install_path
, install_link
), os
.path
.basename(install_name
))
153 bld
.symlink_as(os
.path
.join(install_path
, dev_link
), os
.path
.basename(install_name
))
155 bld
.all_envs
['default'] = default_env
159 @after('apply_implib')
160 @before('apply_vnum')
161 def apply_soname(self
):
162 '''install a library, taking account of the different rpath varients'''
164 if self
.env
.SONAME_ST
and getattr(self
, 'soname', ''):
165 self
.env
.append_value('LINKFLAGS', self
.env
.SONAME_ST
% self
.soname
)
166 self
.env
.SONAME_ST
= ''
169 @after('apply_implib')
170 @before('apply_vnum')
171 def apply_vscript(self
):
172 '''add version-script arguments to library build'''
174 if self
.env
.HAVE_LD_VERSION_SCRIPT
and getattr(self
, 'version_script', ''):
175 self
.env
.append_value('LINKFLAGS', "-Wl,--version-script=%s" %
177 self
.version_script
= None
180 ##############################
181 # handle the creation of links for libraries and binaries in the build tree
183 @feature('symlink_lib')
185 def symlink_lib(self
):
186 '''symlink a shared lib'''
188 if self
.target
.endswith('.inst'):
191 blddir
= os
.path
.dirname(self
.bld
.srcnode
.abspath(self
.bld
.env
))
192 libpath
= self
.link_task
.outputs
[0].abspath(self
.env
)
194 # calculat the link target and put it in the environment
196 vnum
= getattr(self
, 'vnum', None)
198 soext
= '.' + vnum
.split('.')[0]
200 link_target
= getattr(self
, 'link_name', '')
201 if link_target
== '':
202 basename
= os
.path
.basename(self
.bld
.make_libname(self
.target
, version
=soext
))
203 if getattr(self
, "private_library", False):
204 link_target
= '%s/private/%s' % (LIB_PATH
, basename
)
206 link_target
= '%s/%s' % (LIB_PATH
, basename
)
208 link_target
= os
.path
.join(blddir
, link_target
)
210 if os
.path
.lexists(link_target
):
211 if os
.path
.islink(link_target
) and os
.readlink(link_target
) == libpath
:
213 os
.unlink(link_target
)
215 link_container
= os
.path
.dirname(link_target
)
216 if not os
.path
.isdir(link_container
):
217 os
.makedirs(link_container
)
219 os
.symlink(libpath
, link_target
)
222 @feature('symlink_bin')
224 def symlink_bin(self
):
225 '''symlink a binary into the build directory'''
227 if self
.target
.endswith('.inst'):
230 if not self
.link_task
.outputs
or not self
.link_task
.outputs
[0]:
231 raise Errors
.WafError('no outputs found for %s in symlink_bin' % self
.name
)
232 binpath
= self
.link_task
.outputs
[0].abspath(self
.env
)
233 bldpath
= os
.path
.join(self
.bld
.env
.BUILD_DIRECTORY
, self
.link_task
.outputs
[0].name
)
235 if os
.path
.lexists(bldpath
):
236 if os
.path
.islink(bldpath
) and os
.readlink(bldpath
) == binpath
:
239 os
.symlink(binpath
, bldpath
)