1#!/usr/bin/env python 2 3top = '.' 4out = 'bin' 5 6APPNAME='samba' 7VERSION=None 8 9import sys, os, tempfile 10sys.path.insert(0, top+"/buildtools/wafsamba") 11import shutil 12import wafsamba, samba_dist, samba_git, samba_version, samba_utils 13from waflib import Options, Scripting, Logs, Context, Errors 14 15samba_dist.DIST_DIRS('.') 16samba_dist.DIST_BLACKLIST('.gitignore .bzrignore source4/selftest/provisions') 17 18# install in /usr/local/samba by default 19default_prefix = Options.default_prefix = '/usr/local/samba' 20 21# This callback optionally takes a list of paths as arguments: 22# --with-system_mitkrb5 /path/to/krb5 /another/path 23def system_mitkrb5_callback(option, opt, value, parser): 24 setattr(parser.values, option.dest, True) 25 value = [] 26 for arg in parser.rargs: 27 # stop on --foo like options 28 if arg[:2] == "--" and len(arg) > 2: 29 break 30 value.append(arg) 31 if len(value)>0: 32 del parser.rargs[:len(value)] 33 setattr(parser.values, option.dest, value) 34 35def options(opt): 36 opt.BUILTIN_DEFAULT('NONE') 37 opt.PRIVATE_EXTENSION_DEFAULT('samba4') 38 opt.RECURSE('lib/replace') 39 opt.RECURSE('dynconfig') 40 opt.RECURSE('packaging') 41 opt.RECURSE('lib/ldb') 42 opt.RECURSE('selftest') 43 opt.RECURSE('source4/dsdb/samdb/ldb_modules') 44 opt.RECURSE('pidl') 45 opt.RECURSE('source3') 46 opt.RECURSE('lib/util') 47 opt.RECURSE('lib/crypto') 48 opt.RECURSE('ctdb') 49 50 51 opt.samba_add_onoff_option('pthreadpool', with_name="enable", without_name="disable", default=True) 52 53 opt.add_option('--with-system-mitkrb5', 54 help='build Samba with system MIT Kerberos. ' + 55 'You may specify list of paths where Kerberos is installed (e.g. /usr/local /usr/kerberos) to search krb5-config', 56 action='callback', callback=system_mitkrb5_callback, dest='with_system_mitkrb5', default=False) 57 58 opt.add_option('--with-experimental-mit-ad-dc', 59 help='Enable the experimental MIT Kerberos-backed AD DC. ' + 60 'Note that security patches are not issued for this configuration', 61 action='store_true', 62 dest='with_experimental_mit_ad_dc', 63 default=False) 64 65 opt.add_option('--with-system-mitkdc', 66 help=('Specify the path to the krb5kdc binary from MIT Kerberos'), 67 type="string", 68 dest='with_system_mitkdc', 69 default=None) 70 71 opt.add_option('--with-system-heimdalkrb5', 72 help=('build Samba with system Heimdal Kerberos. ' + 73 'Requires --without-ad-dc' and 74 'conflicts with --with-system-mitkrb5'), 75 action='store_true', 76 dest='with_system_heimdalkrb5', 77 default=False) 78 79 opt.add_option('--without-ad-dc', 80 help='disable AD DC functionality (enables only Samba FS (File Server, Winbind, NMBD) and client utilities.', 81 action='store_true', dest='without_ad_dc', default=False) 82 83 opt.add_option('--with-ntvfs-fileserver', 84 help='enable the deprecated NTVFS file server from the original Samba4 branch (default if --enable-selftest specified). Conflicts with --with-system-mitkrb5 and --without-ad-dc', 85 action='store_true', dest='with_ntvfs_fileserver') 86 87 opt.add_option('--without-ntvfs-fileserver', 88 help='disable the deprecated NTVFS file server from the original Samba4 branch', 89 action='store_false', dest='with_ntvfs_fileserver') 90 91 opt.add_option('--with-pie', 92 help=("Build Position Independent Executables " + 93 "(default if supported by compiler)"), 94 action="store_true", dest='enable_pie') 95 opt.add_option('--without-pie', 96 help=("Disable Position Independent Executable builds"), 97 action="store_false", dest='enable_pie') 98 99 opt.add_option('--with-relro', 100 help=("Build with full RELocation Read-Only (RELRO)" + 101 "(default if supported by compiler)"), 102 action="store_true", dest='enable_relro') 103 opt.add_option('--without-relro', 104 help=("Disable RELRO builds"), 105 action="store_false", dest='enable_relro') 106 107 gr = opt.option_group('developer options') 108 109 opt.load('python') # options for disabling pyc or pyo compilation 110 # enable options related to building python extensions 111 112 opt.add_option('--with-json', 113 action='store_true', dest='with_json', 114 help=("Build with JSON support (default=True). This " 115 "requires the jansson development headers.")) 116 opt.add_option('--without-json', 117 action='store_false', dest='with_json', 118 help=("Build without JSON support.")) 119 120def configure(conf): 121 version = samba_version.load_version(env=conf.env) 122 123 conf.DEFINE('CONFIG_H_IS_FROM_SAMBA', 1) 124 conf.DEFINE('_SAMBA_BUILD_', version.MAJOR, add_to_cflags=True) 125 conf.DEFINE('HAVE_CONFIG_H', 1, add_to_cflags=True) 126 127 if Options.options.developer: 128 conf.ADD_CFLAGS('-DDEVELOPER -DDEBUG_PASSWORD') 129 conf.env.DEVELOPER = True 130 # if we are in a git tree without a pre-commit hook, install a 131 # simple default. 132 pre_commit_hook = os.path.join(Context.g_module.top, '.git/hooks/pre-commit') 133 if (os.path.isdir(os.path.dirname(pre_commit_hook)) and 134 not os.path.exists(pre_commit_hook)): 135 shutil.copy(os.path.join(Context.g_module.top, 'script/git-hooks/pre-commit-hook'), 136 pre_commit_hook) 137 138 conf.ADD_EXTRA_INCLUDES('#include/public #source4 #lib #source4/lib #source4/include #include #lib/replace') 139 140 conf.env.replace_add_global_pthread = True 141 conf.RECURSE('lib/replace') 142 143 conf.RECURSE('examples/fuse') 144 conf.RECURSE('examples/winexe') 145 146 conf.SAMBA_CHECK_PERL(mandatory=True) 147 conf.find_program('xsltproc', var='XSLTPROC') 148 149 if conf.env.disable_python: 150 if not (Options.options.without_ad_dc): 151 raise Errors.WafError('--disable-python requires --without-ad-dc') 152 153 conf.SAMBA_CHECK_PYTHON() 154 conf.SAMBA_CHECK_PYTHON_HEADERS() 155 156 if sys.platform == 'darwin' and not conf.env['HAVE_ENVIRON_DECL']: 157 # Mac OSX needs to have this and it's also needed that the python is compiled with this 158 # otherwise you face errors about common symbols 159 if not conf.CHECK_SHLIB_W_PYTHON("Checking if -fno-common is needed"): 160 conf.ADD_CFLAGS('-fno-common') 161 if not conf.CHECK_SHLIB_W_PYTHON("Checking if -undefined dynamic_lookup is not need"): 162 conf.env.append_value('cshlib_LINKFLAGS', ['-undefined', 'dynamic_lookup']) 163 164 if sys.platform == 'darwin': 165 conf.ADD_LDFLAGS('-framework CoreFoundation') 166 167 conf.RECURSE('dynconfig') 168 conf.RECURSE('selftest') 169 170 conf.CHECK_CFG(package='zlib', minversion='1.2.3', 171 args='--cflags --libs', 172 mandatory=True) 173 conf.CHECK_FUNCS_IN('inflateInit2', 'z') 174 175 if conf.CHECK_FOR_THIRD_PARTY(): 176 conf.RECURSE('third_party') 177 else: 178 179 if not conf.CHECK_POPT(): 180 raise Errors.WafError('popt development packages have not been found.\nIf third_party is installed, check that it is in the proper place.') 181 else: 182 conf.define('USING_SYSTEM_POPT', 1) 183 184 if not conf.CHECK_CMOCKA(): 185 raise Errors.WafError('cmocka development packages has not been found.\nIf third_party is installed, check that it is in the proper place.') 186 else: 187 conf.define('USING_SYSTEM_CMOCKA', 1) 188 189 if conf.CONFIG_GET('ENABLE_SELFTEST'): 190 if not conf.CHECK_SOCKET_WRAPPER(): 191 raise Errors.WafError('socket_wrapper package has not been found.\nIf third_party is installed, check that it is in the proper place.') 192 else: 193 conf.define('USING_SYSTEM_SOCKET_WRAPPER', 1) 194 195 if not conf.CHECK_NSS_WRAPPER(): 196 raise Errors.WafError('nss_wrapper package has not been found.\nIf third_party is installed, check that it is in the proper place.') 197 else: 198 conf.define('USING_SYSTEM_NSS_WRAPPER', 1) 199 200 if not conf.CHECK_RESOLV_WRAPPER(): 201 raise Errors.WafError('resolv_wrapper package has not been found.\nIf third_party is installed, check that it is in the proper place.') 202 else: 203 conf.define('USING_SYSTEM_RESOLV_WRAPPER', 1) 204 205 if not conf.CHECK_UID_WRAPPER(): 206 raise Errors.WafError('uid_wrapper package has not been found.\nIf third_party is installed, check that it is in the proper place.') 207 else: 208 conf.define('USING_SYSTEM_UID_WRAPPER', 1) 209 210 if not conf.CHECK_PAM_WRAPPER(): 211 raise Errors.WafError('pam_wrapper package has not been found.\nIf third_party is installed, check that it is in the proper place.') 212 else: 213 conf.define('USING_SYSTEM_PAM_WRAPPER', 1) 214 215 conf.RECURSE('lib/ldb') 216 217 if conf.CHECK_LDFLAGS(['-Wl,--wrap=test']): 218 conf.env['HAVE_LDWRAP'] = True 219 conf.define('HAVE_LDWRAP', 1) 220 221 if not (Options.options.without_ad_dc): 222 conf.DEFINE('AD_DC_BUILD_IS_ENABLED', 1) 223 224 if Options.options.with_system_mitkrb5: 225 if not Options.options.with_experimental_mit_ad_dc and \ 226 not Options.options.without_ad_dc: 227 raise Errors.WafError('The MIT Kerberos build of Samba as an AD DC ' + 228 'is experimental. Therefore ' 229 '--with-system-mitkrb5 requires either ' + 230 '--with-experimental-mit-ad-dc or ' + 231 '--without-ad-dc') 232 233 conf.PROCESS_SEPARATE_RULE('system_mitkrb5') 234 235 if not (Options.options.without_ad_dc or Options.options.with_system_mitkrb5): 236 conf.DEFINE('AD_DC_BUILD_IS_ENABLED', 1) 237 238 if Options.options.with_system_heimdalkrb5: 239 if Options.options.with_system_mitkrb5: 240 raise Errors.WafError('--with-system-heimdalkrb5 conflicts with ' + 241 '--with-system-mitkrb5') 242 if not Options.options.without_ad_dc: 243 raise Errors.WafError('--with-system-heimdalkrb5 requires ' + 244 '--without-ad-dc') 245 conf.env.SYSTEM_LIBS += ('heimdal', 'asn1', 'com_err', 'roken', 246 'hx509', 'wind', 'gssapi', 'hcrypto', 247 'krb5', 'heimbase', 'asn1_compile', 248 'compile_et', 'kdc', 'hdb', 'heimntlm') 249 conf.PROCESS_SEPARATE_RULE('system_heimdal') 250 251 if not conf.CONFIG_GET('KRB5_VENDOR'): 252 conf.PROCESS_SEPARATE_RULE('embedded_heimdal') 253 254 conf.PROCESS_SEPARATE_RULE('system_gnutls') 255 256 conf.RECURSE('source4/dsdb/samdb/ldb_modules') 257 conf.RECURSE('source4/ntvfs/sysdep') 258 conf.RECURSE('lib/util') 259 conf.RECURSE('lib/util/charset') 260 conf.RECURSE('source4/auth') 261 conf.RECURSE('nsswitch') 262 conf.RECURSE('libcli/smbreadline') 263 conf.RECURSE('lib/crypto') 264 conf.RECURSE('pidl') 265 if conf.CONFIG_GET('ENABLE_SELFTEST'): 266 if Options.options.with_ntvfs_fileserver != False: 267 if not (Options.options.without_ad_dc): 268 conf.DEFINE('WITH_NTVFS_FILESERVER', 1) 269 if Options.options.with_ntvfs_fileserver == False: 270 if not (Options.options.without_ad_dc): 271 raise Errors.WafError('--without-ntvfs-fileserver conflicts with --enable-selftest while building the AD DC') 272 conf.RECURSE('testsuite/unittests') 273 274 if Options.options.with_ntvfs_fileserver == True: 275 if Options.options.without_ad_dc: 276 raise Errors.WafError('--with-ntvfs-fileserver conflicts with --without-ad-dc') 277 conf.DEFINE('WITH_NTVFS_FILESERVER', 1) 278 279 if Options.options.with_pthreadpool: 280 if conf.CONFIG_SET('HAVE_PTHREAD'): 281 conf.DEFINE('WITH_PTHREADPOOL', '1') 282 else: 283 Logs.warn("pthreadpool support cannot be enabled when pthread support was not found") 284 conf.undefine('WITH_PTHREADPOOL') 285 286 conf.SET_TARGET_TYPE('jansson', 'EMPTY') 287 288 if Options.options.with_json != False: 289 if conf.CHECK_CFG(package='jansson', args='--cflags --libs', 290 msg='Checking for jansson'): 291 conf.CHECK_FUNCS_IN('json_object', 'jansson') 292 293 if not conf.CONFIG_GET('HAVE_JSON_OBJECT'): 294 if Options.options.with_json != False: 295 conf.fatal("Jansson JSON support not found. " 296 "Try installing libjansson-dev or jansson-devel. " 297 "Otherwise, use --without-json to build without " 298 "JSON support. " 299 "JSON support is required for the JSON " 300 "formatted audit log feature, the AD DC, and " 301 "the JSON printers of the net utility") 302 if not Options.options.without_ad_dc: 303 raise Errors.WafError('--without-json requires --without-ad-dc. ' 304 'Jansson JSON library is required for ' 305 'building the AD DC') 306 Logs.info("Building without Jansson JSON log support") 307 308 conf.RECURSE('source3') 309 conf.RECURSE('lib/texpect') 310 conf.RECURSE('python') 311 if conf.env.with_ctdb: 312 conf.RECURSE('ctdb') 313 conf.RECURSE('lib/socket') 314 conf.RECURSE('lib/mscat') 315 conf.RECURSE('packaging') 316 317 conf.SAMBA_CHECK_UNDEFINED_SYMBOL_FLAGS() 318 319 # gentoo always adds this. We want our normal build to be as 320 # strict as the strictest OS we support, so adding this here 321 # allows us to find problems on our development hosts faster. 322 # It also results in faster load time. 323 324 conf.add_as_needed() 325 326 if not conf.CHECK_NEED_LC("-lc not needed"): 327 conf.ADD_LDFLAGS('-lc', testflags=False) 328 329 if not conf.CHECK_CODE('#include "tests/summary.c"', 330 define='SUMMARY_PASSES', 331 addmain=False, 332 msg='Checking configure summary'): 333 raise Errors.WafError('configure summary failed') 334 335 if Options.options.enable_pie != False: 336 if Options.options.enable_pie == True: 337 need_pie = True 338 else: 339 # not specified, only build PIEs if supported by compiler 340 need_pie = False 341 if conf.check_cc(cflags='-fPIE', ldflags='-pie', mandatory=need_pie, 342 msg="Checking compiler for PIE support"): 343 conf.env['ENABLE_PIE'] = True 344 345 if Options.options.enable_relro != False: 346 if Options.options.enable_relro == True: 347 need_relro = True 348 else: 349 # not specified, only build RELROs if supported by compiler 350 need_relro = False 351 if conf.check_cc(cflags='', ldflags='-Wl,-z,relro,-z,now', mandatory=need_relro, 352 msg="Checking compiler for full RELRO support"): 353 conf.env['ENABLE_RELRO'] = True 354 355 conf.SAMBA_CONFIG_H('include/config.h') 356 357def etags(ctx): 358 '''build TAGS file using etags''' 359 from waflib import Utils 360 source_root = os.path.dirname(Context.g_module.root_path) 361 cmd = 'rm -f %s/TAGS && (find %s -name "*.[ch]" | egrep -v \.inst\. | xargs -n 100 etags -a)' % (source_root, source_root) 362 print("Running: %s" % cmd) 363 status = os.system(cmd) 364 if os.WEXITSTATUS(status): 365 raise Errors.WafError('etags failed') 366 367def ctags(ctx): 368 "build 'tags' file using ctags" 369 from waflib import Utils 370 source_root = os.path.dirname(Context.g_module.root_path) 371 cmd = 'ctags --python-kinds=-i $(find %s -name "*.[ch]" | grep -v "*_proto\.h" | egrep -v \.inst\.) $(find %s -name "*.py")' % (source_root, source_root) 372 print("Running: %s" % cmd) 373 status = os.system(cmd) 374 if os.WEXITSTATUS(status): 375 raise Errors.WafError('ctags failed') 376 377 378# putting this here enabled build in the list 379# of commands in --help 380def build(bld): 381 '''build all targets''' 382 samba_version.load_version(env=bld.env, is_install=bld.is_install) 383 384 385def pydoctor(ctx): 386 '''build python apidocs''' 387 bp = os.path.abspath('bin/python') 388 mpaths = {} 389 modules = ['talloc', 'tdb', 'ldb'] 390 for m in modules: 391 f = os.popen("PYTHONPATH=%s python -c 'import %s; print %s.__file__'" % (bp, m, m), 'r') 392 try: 393 mpaths[m] = f.read().strip() 394 finally: 395 f.close() 396 mpaths['main'] = bp 397 cmd = ('PYTHONPATH=%(main)s pydoctor --introspect-c-modules --project-name=Samba ' 398 '--project-url=http://www.samba.org --make-html --docformat=restructuredtext ' 399 '--add-package bin/python/samba ' + ''.join('--add-module %s ' % n for n in modules)) 400 cmd = cmd % mpaths 401 print("Running: %s" % cmd) 402 status = os.system(cmd) 403 if os.WEXITSTATUS(status): 404 raise Errors.WafError('pydoctor failed') 405 406 407def pep8(ctx): 408 '''run pep8 validator''' 409 cmd='PYTHONPATH=bin/python pep8 -r bin/python/samba' 410 print("Running: %s" % cmd) 411 status = os.system(cmd) 412 if os.WEXITSTATUS(status): 413 raise Errors.WafError('pep8 failed') 414 415 416def wafdocs(ctx): 417 '''build wafsamba apidocs''' 418 from samba_utils import recursive_dirlist 419 os.system('pwd') 420 list = recursive_dirlist('../buildtools/wafsamba', '.', pattern='*.py') 421 422 print(list) 423 cmd='PYTHONPATH=bin/python pydoctor --project-name=wafsamba --project-url=http://www.samba.org --make-html --docformat=restructuredtext' +\ 424 "".join(' --add-module %s' % f for f in list) 425 print("Running: %s" % cmd) 426 status = os.system(cmd) 427 if os.WEXITSTATUS(status): 428 raise Errors.WafError('wafdocs failed') 429 430 431def dist(): 432 '''makes a tarball for distribution''' 433 sambaversion = samba_version.load_version(env=None) 434 435 os.system("make -C ctdb manpages") 436 samba_dist.DIST_FILES('ctdb/doc:ctdb/doc', extend=True) 437 438 os.system("DOC_VERSION='" + sambaversion.STRING + "' " + Context.g_module.top + "/release-scripts/build-manpages-nogit") 439 samba_dist.DIST_FILES('bin/docs:docs', extend=True) 440 441 if sambaversion.IS_SNAPSHOT: 442 # write .distversion file and add to tar 443 if not os.path.isdir(Context.g_module.out): 444 os.makedirs(Context.g_module.out) 445 distversionf = tempfile.NamedTemporaryFile(mode='w', prefix='.distversion',dir=Context.g_module.out) 446 for field in sambaversion.vcs_fields: 447 distveroption = field + '=' + str(sambaversion.vcs_fields[field]) 448 distversionf.write(distveroption + '\n') 449 distversionf.flush() 450 samba_dist.DIST_FILES('%s:.distversion' % distversionf.name, extend=True) 451 452 samba_dist.dist() 453 distversionf.close() 454 else: 455 samba_dist.dist() 456 457 458def distcheck(): 459 '''test that distribution tarball builds and installs''' 460 samba_version.load_version(env=None) 461 462def wildcard_cmd(cmd): 463 '''called on a unknown command''' 464 from samba_wildcard import run_named_build_task 465 run_named_build_task(cmd) 466 467def main(): 468 from samba_wildcard import wildcard_main 469 470 wildcard_main(wildcard_cmd) 471Scripting.main = main 472 473def reconfigure(ctx): 474 '''reconfigure if config scripts have changed''' 475 import samba_utils 476 samba_utils.reconfigure(ctx) 477 478 479if os.path.isdir(os.path.join(top, ".git")): 480 # Check if there are submodules that are checked out but out of date. 481 for submodule, status in samba_git.read_submodule_status(top): 482 if status == "out-of-date": 483 raise Errors.WafError("some submodules are out of date. Please run 'git submodule update'") 484