3
# Copyright (C) 2009 Sun Microsystems, Inc.
4
# Copyright (C) 2010, 2011 Monty Taylor
6
# This program is free software; you can redistribute it and/or modify
7
# it under the terms of the GNU General Public License as published by
8
# the Free Software Foundation; version 2 of the License.
10
# This program is distributed in the hope that it will be useful,
11
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
# GNU General Public License for more details.
15
# You should have received a copy of the GNU General Public License
16
# along with this program; if not, write to the Free Software
17
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19
pandora_plugin_file = 'config/pandora-plugin.ini'
21
# Find plugins in the tree and add them to the build system
23
import ConfigParser, os, sys
31
class ChangeProtectedFile(object):
33
def __init__(self, fname):
34
self.bogus_file= False
35
self.real_fname= fname
36
self.new_fname= "%s.new" % fname
38
self.new_file= open(self.new_fname,'w+')
42
def write(self, text):
43
if not self.bogus_file:
44
self.new_file.write(text)
46
# We've written all of this out into .new files, now we only copy them
47
# over the old ones if they are different, so that we don't cause
48
# unnecessary recompiles
50
"""Return True if the file had changed."""
54
new_content = self.new_file.read()
57
old_file = file(self.real_fname, 'r')
58
old_content = old_file.read()
62
if new_content != old_content:
63
if old_content != None:
64
os.unlink(self.real_fname)
65
os.rename(self.new_fname, self.real_fname)
69
os.unlink(self.new_fname)
74
def write_external_configure(plugin, plugin_file):
75
"""Write the initial bits of the configure.ac file"""
76
if not os.path.exists('m4'):
79
AC_PREREQ(2.59)dnl Minimum Autoconf version required.
80
AC_INIT([%(name)s],[%(version)s],[%(url)s])
81
AC_CONFIG_SRCDIR([%(main_source)s])
82
AC_CONFIG_AUX_DIR(config)
84
PANDORA_CANONICAL_TARGET(less-warnings, warnings-always-on, require-cxx, force-gcc42,skip-visibility)
86
PANDORA_REQUIRE_LIBPROTOBUF
87
PANDORA_PROTOBUF_REQUIRE_VERSION([2.1.0])
88
PANDORA_REQUIRE_PROTOC
91
PANDORA_REQUIRE_PTHREAD
95
PANDORA_USE_BETTER_MALLOC
100
write_plugin_ac(plugin, plugin_file)
102
plugin_file.write("""
103
AC_CONFIG_FILES(Makefile)
108
echo "Configuration summary for $PACKAGE_NAME version $VERSION $PANDORA_RELEASE_COMMENT"
110
echo " * Installation prefix: $prefix"
111
echo " * System type: $host_vendor-$host_os"
112
echo " * Host CPU: $host_cpu"
113
echo " * C Compiler: $CC_VERSION"
114
echo " * C++ Compiler: $CXX_VERSION"
115
echo " * Debug enabled: $with_debug"
116
echo " * Warnings as failure: $ac_cv_warnings_as_errors"
117
echo " * C++ cstdint location: $ac_cv_cxx_cstdint"
118
echo " * C++ hash_map location: $ac_cv_cxx_hash_map"
119
echo " * C++ hash namespace: $ac_cv_cxx_hash_namespace"
120
echo " * C++ shared_ptr namespace: $ac_cv_shared_ptr_namespace"
126
def write_external_makefile(plugin, plugin_file):
128
plugin_file.write("""
129
ACLOCAL_AMFLAGS = -I m4 --force
130
VERSION=$(PANDORA_RELEASE_VERSION)
132
pkgplugindir=%(pkgplugindir)s
133
EXTRA_DIST = plugin.ini
136
nobase_include_HEADERS=
137
nobase_pkginclude_HEADERS=
144
if plugin['headers'] != "":
145
plugin_file.write("noinst_HEADERS += %(headers)s\n" % plugin)
146
if plugin['install_headers'] != "":
147
plugin_file.write("nobase_pkginclude_HEADERS += %(install_headers)s\n" % plugin)
148
if plugin['testsuite']:
149
if plugin.has_key('testsuitedir') and plugin['testsuitedir'] != "":
150
plugin_file.write("EXTRA_DIST += %(testsuitedir)s\n" % plugin)
151
plugin_file.write("""
152
pkgplugin_LTLIBRARIES=%(libname)s.la
153
%(libname)s_la_LDFLAGS=-avoid-version -rpath $(pkgplugindir) $(AM_LDFLAGS) %(ldflags)s $(GCOV_LIBS)
154
%(libname)s_la_LIBADD=%(libs)s
155
%(libname)s_la_DEPENDENCIES=%(libs)s
156
%(libname)s_la_CPPFLAGS=$(AM_CPPFLAGS) -DPANDORA_DYNAMIC_PLUGIN -DPANDORA_MODULE_NAME=%(module_name)s -DPANDORA_MODULE_AUTHOR='%(author)s' -DPANDORA_MODULE_TITLE='%(title)s' -DPANDORA_MODULE_VERSION='%(version)s' -DPANDORA_MODULE_LICENSE=%(license)s %(cppflags)s
157
%(libname)s_la_CXXFLAGS=$(AM_CXXFLAGS) %(cxxflags)s
158
%(libname)s_la_CFLAGS=$(AM_CFLAGS) %(cflags)s
159
%(libname)s_la_SOURCES=%(sources)s
160
check_PROGRAMS += %(tests)s
162
plugin_am_file=os.path.join(plugin['rel_path'],'plugin.am')
163
if os.path.exists(plugin_am_file):
164
plugin_file.write('include %s\n' % plugin_am_file)
166
def write_external_plugin():
167
"""Return True if the plugin had changed."""
168
plugin = read_plugin_ini('.')
169
expand_plugin_ini(plugin)
170
plugin_file = ChangeProtectedFile('configure.ac')
171
write_external_configure(plugin, plugin_file)
172
result = plugin_file.close()
173
plugin_file = ChangeProtectedFile('Makefile.am')
174
write_external_makefile(plugin, plugin_file)
175
# Write some stub configure.ac and Makefile.am files that include the above
176
result = plugin_file.close() or result
179
def write_plugin(plugin, plugin_ini_list):
180
# Since this function is recursive, make sure we're not already in it.
181
if plugin.has_key('writing_status'):
182
if plugin['writing_status'] == 'done':
185
print "Dependency loop detected with %s" % plugin['name']
188
plugin['writing_status'] = 'dependencies'
190
# Write all dependencies first to get around annoying automake bug
191
for dependency in plugin['dependency_list']:
193
for find_plugin in plugin_ini_list:
194
if find_plugin['module_name'] == dependency:
196
write_plugin(find_plugin, plugin_ini_list)
199
print "Could not find dependency %s: %s" % (plugin['name'], dependency)
202
write_plugin_ac(plugin, plugin_ac_file)
203
write_plugin_am(plugin, plugin_am_file)
204
write_plugin_docs(plugin, plugin_doc_index)
205
plugin['writing_status'] = 'done'
207
def write_plugin_docs(plugin, doc_index):
208
if plugin['docs'] is not None and os.path.isdir("docs/plugins"):
209
if not os.path.exists(os.path.join("docs/plugins",plugin["name"])):
210
os.symlink(os.path.abspath(plugin["docs"]), os.path.join("docs/plugins",plugin["name"]))
212
%(name)s/index""" % plugin)
214
def write_plugin_ac(plugin, plugin_ac):
216
# Write plugin config instructions into plugin.ac file.
218
plugin_ac_file=os.path.join(plugin['rel_path'],'plugin.ac')
219
plugin_m4_dir=os.path.join(plugin['rel_path'],'m4')
221
if os.path.exists(plugin_m4_dir) and os.path.isdir(plugin_m4_dir):
222
for m4_file in os.listdir(plugin_m4_dir):
223
if os.path.splitext(m4_file)[-1] == '.m4':
224
plugin_m4_files.append(os.path.join(plugin['rel_path'], m4_file))
226
dnl Config for %(title)s
228
for m4_file in plugin_m4_files:
229
plugin_ac.write('m4_sinclude([%s])\n' % m4_file)
230
plugin['plugin_dep_libs']=" ".join(["\${top_builddir}/%s" % f for f in plugin['libs'].split()])
233
AC_ARG_WITH([%(name_with_dashes)s-plugin],[
234
dnl indented wierd to make the help output correct
235
AS_HELP_STRING([--with-%(name_with_dashes)s-plugin],[Build %(title)s. @<:@default=%(enabled)s@:>@])
236
AS_HELP_STRING([--without-%(name_with_dashes)s-plugin],[Disable building %(title)s])
238
with_%(name)s_plugin="$withval"
239
AS_IF([test "x$with_%(name)s_plugin" = "xyes"],[
240
requested_%(name)s_plugin="yes"
242
requested_%(name)s_plugin="no"
245
with_%(name)s_plugin="%(enabled)s"
246
requested_%(name)s_plugin="no"
248
AC_ARG_WITH([static-%(name_with_dashes)s-plugin],[
249
AS_HELP_STRING([--with-static-%(name_with_dashes)s-plugin],[Build Archive Storage Engine. @<:@default=%(static_yesno)s@:>@])
250
AS_HELP_STRING([--without-static-%(name_with_dashes)s-plugin],[Disable building Archive Storage Engine])
252
with_static_%(name)s_plugin=${withval}
254
with_static_%(name)s_plugin=%(static_yesno)s
256
AS_IF([test "x${with_static_%(name)s_plugin}" = "xyes" -o "x${with_all_static}" = "xyes"],[
257
shared_%(name)s_plugin=no
259
shared_%(name)s_plugin=yes
261
AC_ARG_ENABLE([%(name_with_dashes)s-plugin],[
262
dnl indented wierd to make the help output correct
263
AS_HELP_STRING([--enable-%(name_with_dashes)s-plugin],[Enable loading %(title)s by default. @<:@default=%(default_yesno)s@:>@])
264
AS_HELP_STRING([--disable-%(name_with_dashes)s-plugin],[Disable loading %(title)s by default.])
266
[enable_%(name)s_plugin="$enableval"],
267
[enable_%(name)s_plugin=%(default_yesno)s])
270
if os.path.exists(plugin_ac_file):
271
plugin_ac.write('m4_sinclude([%s])\n' % plugin_ac_file)
272
# The plugin author has specified some check to make to determine
273
# if the plugin can be built. If the plugin is turned on and this
274
# check fails, then configure should error out. If the plugin is not
275
# turned on, then the normal conditional build stuff should just let
276
# it silently not build
277
if plugin['has_build_conditional']:
279
AS_IF([test %(build_conditional)s],
280
[], dnl build_conditional can only negate
282
AS_IF([test "x${requested_%(name)s_plugin}" = "xyes"],
283
[AC_MSG_ERROR([Plugin %(name)s was explicitly requested, yet failed build dependency checks. Aborting!])])
284
with_%(name)s_plugin=no
288
if not plugin['unconditional']:
290
AM_CONDITIONAL([%(static_build_conditional_tag)s],
291
[test %(build_conditional)s -a ! %(shared_build)s])
292
AM_CONDITIONAL([%(shared_build_conditional_tag)s],
293
[test %(build_conditional)s -a %(shared_build)s])
294
AM_CONDITIONAL([%(build_conditional_tag)s],
295
[test %(build_conditional)s])
299
AS_IF([test "x$with_%(name)s_plugin" = "xyes"],[
301
if plugin['testsuite']:
303
pandora_plugin_test_list="%(name)s,${pandora_plugin_test_list}"
306
AS_IF([test "x${with_static_%(name)s_plugin}" = "xyes" -o "x${with_all_static}" = "xyes"],[
308
AS_IF([test "x$enable_%(name)s_plugin" = "xyes"],[
309
pandora_builtin_load_list="%(module_name)s,${pandora_builtin_load_list}"
310
pandora_builtin_load_symbols_list="_drizzled_%(module_name)s_plugin_,${pandora_builtin_load_symbols_list}"
311
PANDORA_PLUGIN_DEP_LIBS="${PANDORA_PLUGIN_DEP_LIBS} %(plugin_dep_libs)s"
313
pandora_builtin_list="%(module_name)s,${pandora_builtin_list}"
314
pandora_builtin_symbols_list="_drizzled_%(module_name)s_plugin_,${pandora_builtin_symbols_list}"
315
pandora_plugin_libs="${pandora_plugin_libs} \${top_builddir}/%(root_plugin_dir)s/%(libname)s.la"
317
AS_IF([test "x$enable_%(name)s_plugin" = "xyes"],[
318
pandora_default_plugin_list="%(name)s,${pandora_default_plugin_list}"
322
plugin_ac.write("])\n")
324
def fix_file_paths(plugin, files):
325
# TODO: determine path to plugin dir relative to top_srcdir... append it to
326
# source files if they don't already have it
328
if plugin['plugin_dir'] != ".":
329
for file in files.split():
330
if not file.startswith(plugin['rel_path']):
331
file= os.path.join(plugin['rel_path'], file)
332
new_files= "%s %s" % (new_files, file)
334
new_files= " ".join(plugin['sources'].split())
339
def expand_plugin_ini(plugin):
340
if plugin['name'] == "**OUT-OF-TREE**":
341
print "Out of tree plugins require the name field to be specified in plugin.ini"
344
if plugin['plugin_dir'] == ".":
345
plugin['rel_path']= plugin['plugin_dir']
346
plugin['unconditional']=True
348
plugin['rel_path']= plugin['plugin_dir'][len(config['top_srcdir'])+len(os.path.sep):]
349
plugin['unconditional']=False
351
plugin['sources']= fix_file_paths(plugin, plugin['sources'])
352
plugin['main_source']= plugin['sources'].split()[0]
353
plugin['headers']= fix_file_paths(plugin, plugin['headers'])
354
plugin['install_headers']= fix_file_paths(plugin, plugin['install_headers'])
355
plugin['tests']= fix_file_paths(plugin, plugin['tests'])
357
# Make a yes/no version for autoconf help messages
358
if plugin['load_by_default']:
359
plugin['default_yesno']="yes"
361
plugin['default_yesno']="no"
363
if plugin.has_key('extra_dist'):
364
plugin['extra_dist']=" ".join([os.path.join(plugin['rel_path'],f) for f in plugin['extra_dist'].split()])
368
plugin['static_yesno']="yes"
370
plugin['static_yesno']="no"
371
plugin['build_conditional_tag']= "BUILD_%s_PLUGIN" % plugin['name'].upper()
372
plugin['shared_build_conditional_tag']= "BUILD_%s_PLUGIN_SHARED" % plugin['name'].upper()
373
plugin['static_build_conditional_tag']= "BUILD_%s_PLUGIN_STATIC" % plugin['name'].upper()
374
plugin['name_with_dashes']= plugin['name'].replace('_','-')
375
if plugin.has_key('build_conditional'):
376
plugin['has_build_conditional']=True
377
plugin['build_conditional']='"x${with_%(name)s_plugin}" = "xyes" -a %(build_conditional)s' % plugin
379
plugin['has_build_conditional']=False
380
plugin['build_conditional']='"x${with_%(name)s_plugin}" = "xyes"' %plugin
381
plugin['shared_build']='"x${shared_%(name)s_plugin}" = "xyes"' %plugin
383
if plugin['install']:
384
plugin['library_type']= 'pkgplugin'
386
plugin['library_type']= 'noinst'
388
def find_testsuite(plugin_dir):
389
for testdir in ['drizzle-tests','tests']:
390
if os.path.isdir(os.path.join(plugin_dir,testdir)):
392
if os.path.isdir(os.path.join('tests','suite',os.path.basename(plugin_dir))):
396
def find_docs(plugin_dir):
397
if os.path.isfile(os.path.join(plugin_dir, "docs", "index.rst")):
398
return os.path.join(plugin_dir, "docs")
400
def read_plugin_ini(plugin_dir):
402
if plugin_dir == ".":
403
plugin_name="**OUT-OF-TREE**"
404
module_name="**OUT-OF-TREE**"
406
sources_default="%s.cc" % os.path.basename(plugin_dir)
407
plugin_name = plugin_dir[plugin_dir.index(config['root_plugin_dir']) + len(config['root_plugin_dir']) + 1:]
408
module_name = plugin_name.replace("/", config['module_name_separator']).replace("\\", config['module_name_separator'])
409
plugin_name = plugin_name.replace("/", config['plugin_name_separator']).replace("\\", config['plugin_name_separator'])
412
plugin_file= os.path.join(plugin_dir,config['plugin_ini_fname'])
413
plugin_defaults= dict(sources=sources_default,
424
license="PLUGIN_LICENSE_GPL",
426
module_name=module_name,
427
load_by_default=config['default_load_by_default'],
431
dependency_aliases="",
433
install=config['default_install'])
434
parser=ConfigParser.ConfigParser(defaults= plugin_defaults)
435
parser.read(plugin_file)
436
plugin=dict(parser.items('plugin'))
437
plugin['plugin_dir'] = plugin_dir
438
if plugin_dir == '.':
439
if not plugin.has_key('url'):
440
print "External Plugins are required to specifiy a url"
441
plugin['url']= 'http://launchpad.net/%(name)s' % plugin
443
if plugin_dir == '.' and not plugin.has_key('version'):
444
print "External Plugins are required to specifiy a version"
446
if not plugin.has_key('version'):
447
plugin['version'] = config['default_plugin_version']
448
if plugin.has_key('load_by_default'):
449
plugin['load_by_default']=parser.getboolean('plugin','load_by_default')
450
if plugin.has_key('disabled'):
451
plugin['disabled']=parser.getboolean('plugin','disabled')
452
if plugin['disabled']:
453
plugin['enabled']="no"
455
plugin['enabled']="yes"
456
if plugin.has_key('static'):
458
plugin['static']= parser.getboolean('plugin','static')
460
if plugin['static'][:5] == os.sys.platform[:5]:
461
plugin['static']= True
463
plugin['static']= False
464
if plugin.has_key('install'):
465
plugin['install']= parser.getboolean('plugin','install')
466
if plugin.has_key('testsuite'):
467
if plugin['testsuite'] == 'disable':
468
plugin['testsuite']= False
469
plugin['dist_testsuite']= find_testsuite(plugin_dir)
471
plugin_testsuite= find_testsuite(plugin_dir)
472
plugin['testsuitedir']=plugin_testsuite
473
if plugin_testsuite is not None:
474
plugin['testsuite']=True
476
plugin['testsuite']=False
477
plugin['docs']= find_docs(plugin_dir)
479
plugin['cflags']+= ' ' + config['extra_cflags']
480
plugin['cppflags']+= ' ' + config['extra_cppflags']
481
plugin['cxxflags']+= ' ' + config['extra_cxxflags']
483
plugin['libname']= "lib%s%s%s" % (config['plugin_prefix'],
485
config['plugin_suffix'])
486
if config['force_lowercase_libname']:
487
plugin['libname']= plugin['libname'].lower()
489
plugin['root_plugin_dir']= config['root_plugin_dir']
490
plugin['plugin_prefix']= config['plugin_prefix']
491
plugin['plugin_suffix']= config['plugin_suffix']
492
plugin['pkgplugindir']= config['pkgplugindir']
494
# Dependencies must have a module but dependency aliases are simply added
495
# to the variable passed during compile.
496
plugin['dependency_list'] = plugin['dependencies'].split()
497
dependency_aliases = plugin['dependency_aliases'].split()
498
plugin['dependencies'] = ','.join(plugin['dependency_list'] +
499
plugin['dependency_aliases'].split())
500
dependency_libs = ["%s/lib%s%s.la" % (config['root_plugin_dir'],
501
dependency.lower().replace('::', '_'),
502
config['plugin_suffix'])
503
for dependency in plugin['dependency_list']]
504
plugin['libs'] = " ".join(plugin['libs'].split() + dependency_libs);
506
# Libtool is going to expand:
507
# -DPANDORA_MODULE_AUTHOR='"Padraig O'"'"'Sullivan"'
509
# "-DPANDORA_MODULE_AUTHOR=\"Padraig O'Sullivan\""
510
# So we have to replace internal ''s to '"'"'
511
for key in ('author','title','description','version'):
512
plugin[key]=plugin[key].replace('"','\\"')
513
plugin[key]=plugin[key].replace("'","'\"'\"'")
517
def write_plugin_am(plugin, plugin_am):
518
"""Write an automake fragment for this plugin.
520
:param plugin: The plugin dict.
521
:param plugin_am: The file to write to.
523
# The .plugin.ini.stamp avoids changing the datestamp on plugin.ini which can
524
# confuse VCS systems.
526
EXTRA_DIST += %(rel_path)s/plugin.ini
528
# Prevent errors when a plugin dir is removed
529
%(rel_path)s/plugin.ini:
532
if plugin.has_key('extra_dist') and plugin['extra_dist'] != "":
533
plugin_am.write("EXTRA_DIST += %(extra_dist)s\n" % plugin)
534
if plugin['headers'] != "":
535
plugin_am.write("noinst_HEADERS += %(headers)s\n" % plugin)
536
if plugin['install_headers'] != "":
537
plugin_am.write("nobase_pkginclude_HEADERS += %(install_headers)s\n" % plugin)
538
if plugin['testsuite']:
539
if plugin.has_key('testsuitedir') and plugin['testsuitedir'] != "":
540
plugin_am.write("EXTRA_DIST += %(rel_path)s/%(testsuitedir)s\n" % plugin)
541
if plugin.has_key('dist_testsuite') and plugin['dist_testsuite'] != "":
542
plugin_am.write("EXTRA_DIST += %(rel_path)s/%(dist_testsuite)s\n" % plugin)
543
if plugin['docs'] is not None:
544
plugin_am.write("EXTRA_DIST += ${top_srcdir}/%(rel_path)s/docs/*.rst\n" % plugin)
546
%(root_plugin_dir)s_%(plugin_prefix)s%(name)s_dir=${top_srcdir}/%(rel_path)s
547
# Include sources in EXTRA_DIST because we might not build this, but we
548
# still want the sources to wind up in a tarball
549
EXTRA_DIST += %(rel_path)s/plugin.ini %(sources)s
550
if %(static_build_conditional_tag)s
551
noinst_LTLIBRARIES+=%(root_plugin_dir)s/%(libname)s.la
552
%(root_plugin_dir)s_%(libname)s_la_LIBADD=%(libs)s
553
%(root_plugin_dir)s_%(libname)s_la_DEPENDENCIES=%(libs)s
554
%(root_plugin_dir)s_%(libname)s_la_LDFLAGS=$(AM_LDFLAGS) %(ldflags)s $(GCOV_LIBS)
555
%(root_plugin_dir)s_%(libname)s_la_CPPFLAGS=$(AM_CPPFLAGS) -DPANDORA_MODULE_NAME=%(module_name)s -DPANDORA_MODULE_AUTHOR='%(author)s' -DPANDORA_MODULE_TITLE='%(title)s' -DPANDORA_MODULE_VERSION='%(version)s' -DPANDORA_MODULE_LICENSE=%(license)s -DPANDORA_MODULE_DEPENDENCIES='%(dependencies)s' %(cppflags)s
556
%(root_plugin_dir)s_%(libname)s_la_CXXFLAGS=$(AM_CXXFLAGS) %(cxxflags)s
557
%(root_plugin_dir)s_%(libname)s_la_CFLAGS=$(AM_CFLAGS) %(cflags)s
558
%(root_plugin_dir)s_%(libname)s_la_SOURCES=%(sources)s
559
check_PROGRAMS += %(tests)s
560
PANDORA_DYNAMIC_LDADDS+=${top_builddir}/%(root_plugin_dir)s/%(libname)s.la
562
EXTRA_DIST += %(rel_path)s/plugin.ini
563
if %(shared_build_conditional_tag)s
564
%(library_type)s_LTLIBRARIES+=%(root_plugin_dir)s/%(libname)s.la
565
%(root_plugin_dir)s_%(libname)s_la_LDFLAGS=-avoid-version -rpath $(pkgplugindir) $(AM_LDFLAGS) %(ldflags)s $(GCOV_LIBS)
566
%(root_plugin_dir)s_%(libname)s_la_LIBADD=%(libs)s
567
%(root_plugin_dir)s_%(libname)s_la_DEPENDENCIES=%(libs)s
568
%(root_plugin_dir)s_%(libname)s_la_CPPFLAGS=$(AM_CPPFLAGS) -DPANDORA_DYNAMIC_PLUGIN -DPANDORA_MODULE_NAME=%(module_name)s -DPANDORA_MODULE_AUTHOR='%(author)s' -DPANDORA_MODULE_TITLE='%(title)s' -DPANDORA_MODULE_VERSION='%(version)s' -DPANDORA_MODULE_LICENSE=%(license)s -DPANDORA_MODULE_DEPENDENCIES='%(dependencies)s' %(cppflags)s
569
%(root_plugin_dir)s_%(libname)s_la_CXXFLAGS=$(AM_CXXFLAGS) %(cxxflags)s
570
%(root_plugin_dir)s_%(libname)s_la_CFLAGS=$(AM_CFLAGS) %(cflags)s
571
%(root_plugin_dir)s_%(libname)s_la_SOURCES=%(sources)s
572
check_PROGRAMS += %(tests)s
575
plugin_am_file=os.path.join(plugin['rel_path'],'plugin.am')
576
if os.path.exists(plugin_am_file):
577
plugin_am.write('include %s\n' % plugin_am_file)
583
# Parse the pandora-plugin config file
585
config_defaults= dict(
588
plugin_ini_fname='plugin.ini',
596
default_install='True',
597
default_plugin_version='',
598
default_load_by_default='False',
599
force_lowercase_libname='True',
600
plugin_name_separator='_',
601
module_name_separator='::'
604
config_parser = ConfigParser.ConfigParser(defaults=config_defaults)
605
config_parser.read(pandora_plugin_file)
606
config = dict(config_parser.items('pandora-plugin'))
607
config['force_lowercase_libname']=config_parser.getboolean('pandora-plugin','force_lowercase_libname')
609
# I'm 3 seconds away from writing a comprehensive build solution
610
if not os.path.exists('config/pandora_vc_revinfo'):
611
if os.path.exists('.bzr'):
612
bzr_revno= subprocess.Popen(["bzr", "revno"], stdout=subprocess.PIPE).communicate()[0].strip()
613
rev_date= datetime.date.fromtimestamp(time.time())
614
config['default_plugin_version'] = "%d.%02d.%s" % (rev_date.year, rev_date.month, bzr_revno)
616
config['default_plugin_version']=datetime.date.fromtimestamp(time.time()).isoformat()
618
# need to read config/pandora_vc_revno
619
pandora_vc_revno=open('config/pandora_vc_revinfo','r').read().split()
622
for revno_line in pandora_vc_revno:
623
(revno_key,revno_val)= revno_line.split("=")
624
if revno_key == 'PANDORA_VC_REVNO':
625
bzr_revno=revno_val.strip()
626
elif revno_key == 'PANDORA_RELEASE_DATE':
627
rev_date=revno_val.strip()
629
config['default_plugin_version'] = "%s.%s" % (rev_date, bzr_revno)
633
if arg.startswith('--top_srcdir='):
634
config['top_srcdir']=arg[12:]
635
elif arg.startswith('--top_builddir='):
636
config['top_builddir']=arg[14:]
637
elif arg == "--force-all":
638
actions=['plugin-list','pandora-plugin.am','write']
642
if len(actions) == 0:
643
actions.append('write')
647
def accumulate_plugins(arg, dirname, fnames):
648
# plugin_ini_fname is a name in dirname indicating dirname is a plugin.
649
if config['plugin_ini_fname'] in fnames:
652
os.path.walk(os.path.join(config['top_srcdir'],
653
config['root_plugin_dir']),
657
if not os.path.exists("config/pandora-plugin.am") or "write" in actions:
658
plugin_am_file = ChangeProtectedFile(os.path.join('config', 'pandora-plugin.am'))
659
plugin_am_file.write("""
660
# always the current list, generated every build so keep this lean.
661
# pandora-plugin.list: datestamp preserved list
662
${srcdir}/config/pandora-plugin.list: .plugin.scan
664
@cd ${top_srcdir} && python config/pandora-plugin plugin-list
666
# Plugins affect configure; so to prevent configure running twice in a tarball
667
# build (once up front, once with the right list of plugins, we ship the
668
# generated list of plugins and the housekeeping material for that list so it
669
# is likewise not updated.
671
config/pandora-plugin.am \
672
config/pandora-plugin.ac \
673
config/pandora-plugin \
674
config/pandora-plugin.ini
677
# Seed the list of plugin LDADDS which plugins may extend.
678
PANDORA_DYNAMIC_LDADDS=
680
# plugin.stamp: graph dominator for creating all per pandora-plugin.ac/am
681
# files. This is invoked when the code to generate such files has altered.""")
683
if not os.path.exists("config/pandora-plugin.ac") or "write" in actions:
684
plugin_ac_file = ChangeProtectedFile(os.path.join('config', 'pandora-plugin.ac'))
685
plugin_ac_file.write("dnl Generated file, run make to rebuild\n")
686
plugin_ac_file.write("""
687
AC_ARG_WITH([all-static],[
688
AS_HELP_STRING([--with-all-static],[Link all plugins staticly into the server @<:@default=no@:>@])
690
with_all_static="$withval"
696
if os.path.exists("docs/plugins"):
697
if not os.path.exists("docs/plugins/list.rst") or "write" in actions:
698
plugin_doc_index = ChangeProtectedFile("docs/plugins/list.rst")
699
plugin_doc_index.write("""
708
if os.path.exists('plugin.ini'):
709
# Are we in a plugin dir which wants to have a self-sufficient build system?
712
write_external_plugin()
714
plugin_list_file = ChangeProtectedFile(os.path.join('config', 'pandora-plugin.list'))
715
for p in plugin_list:
716
plugin_list_file.write(p)
717
plugin_list_file.write("\n")
719
plugin_list_file.close()
721
if not os.path.exists("config/pandora-plugin.am") or 'write' in actions:
722
plugin_am_file.write("\n${top_srcdir}/config/pandora-plugin.am: ${top_srcdir}/config/pandora-plugin.list ${top_srcdir}/config/pandora-plugin ")
723
for plugin_dir in plugin_list:
724
plugin_am_file.write("\\\n\t%s/plugin.ini " % plugin_dir)
725
plugin_am_file.write("\n\tcd ${top_srcdir} && python config/pandora-plugin write\n")
728
# Load all plugin.ini files first so we can do dependency tracking.
729
for plugin_dir in plugin_list:
730
plugin = read_plugin_ini(plugin_dir)
731
expand_plugin_ini(plugin)
732
plugin_ini_list.append(plugin)
734
# Check for duplicates
735
plugin_name_list = [plugin['libname'] for plugin in plugin_ini_list]
736
for plugin in plugin_ini_list:
737
if plugin_name_list.count(plugin['libname']) != 1:
738
print "Duplicate module name %s" % plugin['libname']
741
for plugin in plugin_ini_list:
742
write_plugin(plugin, plugin_ini_list)
744
if plugin_am_file is not None:
745
plugin_am_file.close()
746
if plugin_ac_file is not None:
747
plugin_ac_file.close()
748
if plugin_doc_index is not None:
749
plugin_doc_index.close()