15
15
# along with this program; if not, write to the Free Software
16
16
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
pandora_plugin_file = 'config/pandora-plugin.ini'
19
# Find plugins in the tree and add them to the build system
20
# Find plugins in the tree and add them to the build system
21
22
import ConfigParser, os, sys
22
23
import datetime, time
27
plugin_ini_fname='plugin.ini'
29
26
plugin_am_file=None
30
27
plugin_ac_file=None
32
plugin_suffix='_plugin'
36
root_plugin_dir='plugin'
37
pkgplugindir='$(libdir)/drizzle'
38
default_install='True'
39
default_plugin_version=''
41
29
class ChangeProtectedFile(object):
146
134
if plugin['headers'] != "":
147
135
plugin_file.write("noinst_HEADERS = %(headers)s\n" % plugin)
136
if plugin['install_headers'] != "":
137
plugin_file.write("nobase_include_HEADERS += %(install_headers)s\n" % plugin)
148
138
if plugin['testsuite']:
149
139
if plugin.has_key('testsuitedir') and plugin['testsuitedir'] != "":
150
140
plugin_file.write("EXTRA_DIST += %(testsuitedir)s\n" % plugin)
151
141
plugin_file.write("""
152
pkgplugin_LTLIBRARIES=%(pname)s.la
153
%(pname)s_la_LDFLAGS=-avoid-version -rpath $(pkgplugindir) $(AM_LDFLAGS) %(ldflags)s $(GCOV_LIBS)
154
%(pname)s_la_LIBADD=%(libs)s
155
%(pname)s_la_DEPENDENCIES=%(libs)s
156
%(pname)s_la_CPPFLAGS=$(AM_CPPFLAGS) -DPANDORA_DYNAMIC_PLUGIN -DPANDORA_MODULE_NAME=%(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
%(pname)s_la_CXXFLAGS=$(AM_CXXFLAGS) %(cxxflags)s
158
%(pname)s_la_CFLAGS=$(AM_CFLAGS) %(cflags)s
160
%(pname)s_la_SOURCES=%(sources)s
142
pkgplugin_LTLIBRARIES=%(libname)s.la
143
%(libname)s_la_LDFLAGS=-avoid-version -rpath $(pkgplugindir) $(AM_LDFLAGS) %(ldflags)s $(GCOV_LIBS)
144
%(libname)s_la_LIBADD=%(libs)s
145
%(libname)s_la_DEPENDENCIES=%(libs)s
146
%(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
147
%(libname)s_la_CXXFLAGS=$(AM_CXXFLAGS) %(cxxflags)s
148
%(libname)s_la_CFLAGS=$(AM_CFLAGS) %(cflags)s
149
%(libname)s_la_SOURCES=%(sources)s
150
check_PROGRAMS += %(tests)s
163
152
plugin_am_file=os.path.join(plugin['rel_path'],'plugin.am')
164
153
if os.path.exists(plugin_am_file):
177
166
result = plugin_file.close() or result
180
def write_plugin(plugin_dir):
181
"""Return True if the plugin had changed."""
182
plugin = read_plugin_ini(plugin_dir)
183
expand_plugin_ini(plugin, plugin_dir)
169
def write_plugin(plugin, plugin_ini_list):
170
# Since this function is recursive, make sure we're not already in it.
171
if plugin.has_key('writing_status'):
172
if plugin['writing_status'] == 'done':
175
print "Dependency loop detected with %s" % plugin['name']
178
plugin['writing_status'] = 'dependencies'
180
# Write all dependencies first to get around annoying automake bug
181
for dependency in plugin['dependency_list']:
183
for find_plugin in plugin_ini_list:
184
if find_plugin['module_name'] == dependency:
186
write_plugin(find_plugin, plugin_ini_list)
189
print "Could not find dependency %s: %s" % (plugin['name'], dependency)
184
192
write_plugin_ac(plugin, plugin_ac_file)
185
193
write_plugin_am(plugin, plugin_am_file)
194
plugin['writing_status'] = 'done'
187
196
def write_plugin_ac(plugin, plugin_ac):
202
211
plugin_ac.write('m4_sinclude([%s])\n' % m4_file)
203
212
plugin['plugin_dep_libs']=" ".join(["\${top_builddir}/%s" % f for f in plugin['libs'].split()])
207
dnl This plugin is staticly built, which means we cannot live without and it is not
208
dnl possible to disable it. Once it is disableable, we will make it non-static.
209
with_%(name)s_plugin=yes
210
pandora_builtin_list="_drizzled_%(name)s_plugin_,${pandora_builtin_list}"
211
pandora_plugin_libs="${pandora_plugin_libs} \${top_builddir}/%(root_plugin_dir)s/%(pname)s.la"
212
PANDORA_PLUGIN_DEP_LIBS="${PANDORA_PLUGIN_DEP_LIBS} %(plugin_dep_libs)s"
215
if plugin['testsuite']:
217
pandora_plugin_test_list="%(name)s,${pandora_plugin_test_list}"
221
215
AC_ARG_WITH([%(name_with_dashes)s-plugin],[
222
216
dnl indented wierd to make the help output correct
223
217
AS_HELP_STRING([--with-%(name_with_dashes)s-plugin],[Build %(title)s. @<:@default=%(enabled)s@:>@])
238
232
AS_HELP_STRING([--enable-%(name_with_dashes)s-plugin],[Build %(title)s. @<:@default=%(default_yesno)s@:>@])
239
233
AS_HELP_STRING([--disable-%(name_with_dashes)s-plugin],[Disable building %(title)s])
241
[enable_%(name)s_plugin="$withval"],
235
[enable_%(name)s_plugin="$enableval"],
242
236
[enable_%(name)s_plugin=%(default_yesno)s])
245
239
if os.path.exists(plugin_ac_file):
246
plugin_ac.write('m4_sinclude([%s])\n' % plugin_ac_file)
240
plugin_ac.write('m4_sinclude([%s])\n' % plugin_ac_file)
247
241
# The plugin author has specified some check to make to determine
248
# if the plugin can be built. If the plugin is turned on and this
242
# if the plugin can be built. If the plugin is turned on and this
249
243
# check fails, then configure should error out. If the plugin is not
250
244
# turned on, then the normal conditional build stuff should just let
251
245
# it silently not build
265
259
AM_CONDITIONAL([%(build_conditional_tag)s],
266
260
[test %(build_conditional)s])
268
if not plugin['static']:
270
264
AS_IF([test "x$with_%(name)s_plugin" = "xyes"],
273
if plugin['testsuite']:
275
pandora_plugin_test_list="%(name)s,${pandora_plugin_test_list}"
267
if plugin['testsuite']:
269
pandora_plugin_test_list="%(name)s,${pandora_plugin_test_list}"
273
AS_IF([test "x$enable_%(name)s_plugin" = "xyes"],[
274
pandora_builtin_list="%(module_name)s,${pandora_builtin_list}"
275
pandora_builtin_symbols_list="_drizzled_%(module_name)s_plugin_,${pandora_builtin_symbols_list}"
276
pandora_plugin_libs="${pandora_plugin_libs} \${top_builddir}/%(root_plugin_dir)s/%(libname)s.la"
277
PANDORA_PLUGIN_DEP_LIBS="${PANDORA_PLUGIN_DEP_LIBS} %(plugin_dep_libs)s"
278
282
plugin_ac.write("""
279
283
AS_IF([test "x$enable_%(name)s_plugin" = "xyes"],[
280
284
pandora_default_plugin_list="%(name)s,${pandora_default_plugin_list}"
283
plugin_ac.write(" ])\n")
286
def expand_plugin_ini(plugin, plugin_dir):
287
plugin_ac.write(" ])\n")
289
def fix_file_paths(plugin, files):
290
# TODO: determine path to plugin dir relative to top_srcdir... append it to
291
# source files if they don't already have it
293
if plugin['plugin_dir'] != ".":
294
for file in files.split():
295
if not file.startswith(plugin['rel_path']):
296
file= os.path.join(plugin['rel_path'], file)
297
new_files= "%s %s" % (new_files, file)
299
new_files= " ".join(plugin['sources'].split())
304
def expand_plugin_ini(plugin):
287
305
if plugin['name'] == "**OUT-OF-TREE**":
288
306
print "Out of tree plugins require the name field to be specified in plugin.ini"
291
if plugin_dir == ".":
292
plugin['rel_path']= plugin_dir
309
if plugin['plugin_dir'] == ".":
310
plugin['rel_path']= plugin['plugin_dir']
293
311
plugin['unconditional']=True
295
plugin['rel_path']= plugin_dir[len(top_srcdir)+len(os.path.sep):]
313
plugin['rel_path']= plugin['plugin_dir'][len(config['top_srcdir'])+len(os.path.sep):]
296
314
plugin['unconditional']=False
297
# TODO: determine path to plugin dir relative to top_srcdir... append it to
298
# source files if they don't already have it
299
if plugin['sources'] == "":
300
plugin['sources']="%s.cc" % plugin['name']
302
if plugin_dir != ".":
303
for src in plugin['sources'].split():
304
if not src.startswith(plugin['rel_path']):
305
src= os.path.join(plugin['rel_path'], src)
306
new_sources= "%s %s" % (new_sources, src)
308
new_sources= " ".join(plugin['sources'].split())
309
if new_sources != "":
310
plugin['sources']= new_sources
316
plugin['sources']= fix_file_paths(plugin, plugin['sources'])
311
317
plugin['main_source']= plugin['sources'].split()[0]
314
if plugin_dir != ".":
315
for header in plugin['headers'].split():
316
if not header.startswith(plugin['rel_path']):
317
header= os.path.join(plugin['rel_path'], header)
318
new_headers= "%s %s" % (new_headers, header)
320
new_headers= " ".join(plugin['headers'].split())
321
if new_headers != "":
322
plugin['headers']= new_headers
318
plugin['headers']= fix_file_paths(plugin, plugin['headers'])
319
plugin['install_headers']= fix_file_paths(plugin, plugin['install_headers'])
320
plugin['tests']= fix_file_paths(plugin, plugin['tests'])
324
322
# Make a yes/no version for autoconf help messages
325
if plugin['load_by_default']:
323
if plugin['load_by_default'] or plugin['static']:
326
324
plugin['default_yesno']="yes"
328
326
plugin['default_yesno']="no"
331
329
plugin['build_conditional_tag']= "BUILD_%s_PLUGIN" % plugin['name'].upper()
332
330
plugin['name_with_dashes']= plugin['name'].replace('_','-')
333
331
if plugin.has_key('build_conditional'):
354
352
if plugin_dir == ".":
355
353
plugin_name="**OUT-OF-TREE**"
357
plugin_name=os.path.basename(plugin_dir)
359
plugin_file= os.path.join(plugin_dir,plugin_ini_fname)
360
plugin_defaults= dict(sources="",
355
short_name=os.path.basename(plugin_dir)
356
plugin_name = plugin_dir[plugin_dir.index(config['root_plugin_dir']) + len(config['root_plugin_dir']) + 1:]
357
module_name = plugin_name.replace("/", config['module_name_separator']).replace("\\", config['module_name_separator'])
358
plugin_name = plugin_name.replace("/", config['plugin_name_separator']).replace("\\", config['plugin_name_separator'])
361
plugin_file= os.path.join(plugin_dir,config['plugin_ini_fname'])
362
plugin_defaults= dict(sources="%s.cc" % short_name,
411
419
plugin['testsuite']=False
413
plugin['cflags']+= extra_cflags
414
plugin['cppflags']+= extra_cppflags
415
plugin['cxxflags']+= extra_cxxflags
417
plugin['pname']= "lib%s%s%s" % (plugin_prefix, plugin['name'], plugin_suffix)
418
plugin['root_plugin_dir']= root_plugin_dir
419
plugin['plugin_prefix']= plugin_prefix
420
plugin['plugin_suffix']= plugin_suffix
421
plugin['pkgplugindir']= pkgplugindir
421
plugin['cflags']+= ' ' + config['extra_cflags']
422
plugin['cppflags']+= ' ' + config['extra_cppflags']
423
plugin['cxxflags']+= ' ' + config['extra_cxxflags']
425
plugin['libname']= "lib%s%s%s" % (config['plugin_prefix'],
427
config['plugin_suffix'])
428
if config['force_lowercase_libname']:
429
plugin['libname']= plugin['libname'].lower()
431
plugin['root_plugin_dir']= config['root_plugin_dir']
432
plugin['plugin_prefix']= config['plugin_prefix']
433
plugin['plugin_suffix']= config['plugin_suffix']
434
plugin['pkgplugindir']= config['pkgplugindir']
436
# Dependencies must have a module but dependency aliases are simply added
437
# to the variable passed during compile.
438
plugin['dependency_list'] = plugin['dependencies'].split()
439
dependency_aliases = plugin['dependency_aliases'].split()
440
plugin['dependencies'] = ','.join(plugin['dependency_list'] +
441
plugin['dependency_aliases'].split())
442
dependency_libs = ["%s/lib%s%s.la" % (config['root_plugin_dir'],
443
dependency.lower().replace('::', '_'),
444
config['plugin_suffix'])
445
for dependency in plugin['dependency_list']]
446
plugin['libs'] = " ".join(plugin['libs'].split() + dependency_libs);
448
# Libtool is going to expand:
449
# -DPANDORA_MODULE_AUTHOR='"Padraig O'"'"'Sullivan"'
451
# "-DPANDORA_MODULE_AUTHOR=\"Padraig O'Sullivan\""
452
# So we have to replace internal ''s to '"'"'
453
for key in ('author','title','description','version'):
454
plugin[key]=plugin[key].replace('"','\\"')
455
plugin[key]=plugin[key].replace("'","'\"'\"'")
426
459
def write_plugin_am(plugin, plugin_am):
427
460
"""Write an automake fragment for this plugin.
429
462
:param plugin: The plugin dict.
430
463
:param plugin_am: The file to write to.
448
483
%(root_plugin_dir)s_%(plugin_prefix)s%(name)s_dir=${top_srcdir}/%(rel_path)s
449
484
EXTRA_DIST += %(rel_path)s/plugin.ini
450
485
if %(build_conditional_tag)s
451
noinst_LTLIBRARIES+=%(root_plugin_dir)s/%(pname)s.la
452
%(root_plugin_dir)s_%(pname)s_la_LIBADD=%(libs)s
453
%(root_plugin_dir)s_%(pname)s_la_DEPENDENCIES=%(libs)s
454
%(root_plugin_dir)s_%(pname)s_la_LDFLAGS=$(AM_LDFLAGS) %(ldflags)s $(GCOV_LIBS)
455
%(root_plugin_dir)s_%(pname)s_la_CPPFLAGS=$(AM_CPPFLAGS) -DPANDORA_MODULE_NAME=%(name)s -DPANDORA_MODULE_AUTHOR="%(author)s" -DPANDORA_MODULE_TITLE="%(title)s" -DPANDORA_MODULE_VERSION="%(version)s" -DPANDORA_MODULE_LICENSE=%(license)s %(cppflags)s
456
%(root_plugin_dir)s_%(pname)s_la_CXXFLAGS=$(AM_CXXFLAGS) %(cxxflags)s
457
%(root_plugin_dir)s_%(pname)s_la_CFLAGS=$(AM_CFLAGS) %(cflags)s
459
%(root_plugin_dir)s_%(pname)s_la_SOURCES=%(sources)s
460
PANDORA_DYNAMIC_LDADDS+=${top_builddir}/%(root_plugin_dir)s/%(pname)s.la
486
noinst_LTLIBRARIES+=%(root_plugin_dir)s/%(libname)s.la
487
%(root_plugin_dir)s_%(libname)s_la_LIBADD=%(libs)s
488
%(root_plugin_dir)s_%(libname)s_la_DEPENDENCIES=%(libs)s
489
%(root_plugin_dir)s_%(libname)s_la_LDFLAGS=$(AM_LDFLAGS) %(ldflags)s $(GCOV_LIBS)
490
%(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
491
%(root_plugin_dir)s_%(libname)s_la_CXXFLAGS=$(AM_CXXFLAGS) %(cxxflags)s
492
%(root_plugin_dir)s_%(libname)s_la_CFLAGS=$(AM_CFLAGS) %(cflags)s
493
%(root_plugin_dir)s_%(libname)s_la_SOURCES=%(sources)s
494
check_PROGRAMS += %(tests)s
495
PANDORA_DYNAMIC_LDADDS+=${top_builddir}/%(root_plugin_dir)s/%(libname)s.la
465
500
%(root_plugin_dir)s_%(plugin_prefix)s%(name)s_dir=${top_srcdir}/%(rel_path)s
466
501
EXTRA_DIST += %(rel_path)s/plugin.ini
467
502
if %(build_conditional_tag)s
468
%(library_type)s_LTLIBRARIES+=%(root_plugin_dir)s/%(pname)s.la
469
%(root_plugin_dir)s_%(pname)s_la_LDFLAGS=-avoid-version -rpath $(pkgplugindir) $(AM_LDFLAGS) %(ldflags)s $(GCOV_LIBS)
470
%(root_plugin_dir)s_%(pname)s_la_LIBADD=%(libs)s
471
%(root_plugin_dir)s_%(pname)s_la_DEPENDENCIES=%(libs)s
472
%(root_plugin_dir)s_%(pname)s_la_CPPFLAGS=$(AM_CPPFLAGS) -DPANDORA_DYNAMIC_PLUGIN -DPANDORA_MODULE_NAME=%(name)s -DPANDORA_MODULE_AUTHOR="%(author)s" -DPANDORA_MODULE_TITLE="%(title)s" -DPANDORA_MODULE_VERSION="%(version)s" -DPANDORA_MODULE_LICENSE=%(license)s %(cppflags)s
473
%(root_plugin_dir)s_%(pname)s_la_CXXFLAGS=$(AM_CXXFLAGS) %(cxxflags)s
474
%(root_plugin_dir)s_%(pname)s_la_CFLAGS=$(AM_CFLAGS) %(cflags)s
476
%(root_plugin_dir)s_%(pname)s_la_SOURCES=%(sources)s
503
%(library_type)s_LTLIBRARIES+=%(root_plugin_dir)s/%(libname)s.la
504
%(root_plugin_dir)s_%(libname)s_la_LDFLAGS=-avoid-version -rpath $(pkgplugindir) $(AM_LDFLAGS) %(ldflags)s $(GCOV_LIBS)
505
%(root_plugin_dir)s_%(libname)s_la_LIBADD=%(libs)s
506
%(root_plugin_dir)s_%(libname)s_la_DEPENDENCIES=%(libs)s
507
%(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
508
%(root_plugin_dir)s_%(libname)s_la_CXXFLAGS=$(AM_CXXFLAGS) %(cxxflags)s
509
%(root_plugin_dir)s_%(libname)s_la_CFLAGS=$(AM_CFLAGS) %(cflags)s
510
%(root_plugin_dir)s_%(libname)s_la_SOURCES=%(sources)s
511
check_PROGRAMS += %(tests)s
479
514
plugin_am_file=os.path.join(plugin['rel_path'],'plugin.am')
480
515
if os.path.exists(plugin_am_file):
481
516
plugin_am.write('include %s\n' % plugin_am_file)
522
# Parse the pandora-plugin config file
524
config_defaults= dict(
527
plugin_ini_fname='plugin.ini',
535
default_install='True',
536
default_plugin_version='',
537
default_load_by_default='False',
538
force_lowercase_libname='True',
539
plugin_name_separator='_',
540
module_name_separator='::'
543
config_parser = ConfigParser.ConfigParser(defaults=config_defaults)
544
config_parser.read(pandora_plugin_file)
545
config = dict(config_parser.items('pandora-plugin'))
546
config['force_lowercase_libname']=config_parser.getboolean('pandora-plugin','force_lowercase_libname')
485
548
# I'm 3 seconds away from writing a comprehensive build solution
486
549
if not os.path.exists('config/pandora_vc_revinfo'):
487
550
if os.path.exists('.bzr'):
488
551
bzr_revno= subprocess.Popen(["bzr", "revno"], stdout=subprocess.PIPE).communicate()[0].strip()
489
552
rev_date= datetime.date.fromtimestamp(time.time())
490
default_plugin_version = "%d.%02d.%s" % (rev_date.year, rev_date.month, bzr_revno)
553
config['default_plugin_version'] = "%d.%02d.%s" % (rev_date.year, rev_date.month, bzr_revno)
492
default_plugin_version=datetime.date.fromtimestamp(time.time()).isoformat()
555
config['default_plugin_version']=datetime.date.fromtimestamp(time.time()).isoformat()
494
557
# need to read config/pandora_vc_revno
495
558
pandora_vc_revno=open('config/pandora_vc_revinfo','r').read().split()
502
565
elif revno_key == 'PANDORA_RELEASE_DATE':
503
566
rev_date=revno_val.strip()
505
default_plugin_version = "%s.%s" % (rev_date, bzr_revno)
568
config['default_plugin_version'] = "%s.%s" % (rev_date, bzr_revno)
508
571
for arg in sys.argv:
509
572
if arg.startswith('--top_srcdir='):
573
config['top_srcdir']=arg[12:]
511
574
elif arg.startswith('--top_builddir='):
512
top_builddir=arg[14:]
575
config['top_builddir']=arg[14:]
513
576
elif arg == "--force-all":
514
577
actions=['plugin-list','pandora-plugin.am','write']
518
581
if len(actions) == 0:
519
582
actions.append('write')
521
586
def accumulate_plugins(arg, dirname, fnames):
522
587
# plugin_ini_fname is a name in dirname indicating dirname is a plugin.
523
if plugin_ini_fname in fnames:
588
if config['plugin_ini_fname'] in fnames:
524
589
arg.append(dirname)
525
os.path.walk(os.path.join(top_srcdir,root_plugin_dir),accumulate_plugins,plugin_list)
591
os.path.walk(os.path.join(config['top_srcdir'],
592
config['root_plugin_dir']),
528
597
if not os.path.exists("config/pandora-plugin.am") or "write" in actions:
573
643
for plugin_dir in plugin_list:
574
644
plugin_am_file.write("\\\n\t%s/plugin.ini " % plugin_dir)
575
645
plugin_am_file.write("\n\tcd ${top_srcdir} && python config/pandora-plugin write\n")
648
# Load all plugin.ini files first so we can do dependency tracking.
576
649
for plugin_dir in plugin_list:
577
write_plugin(plugin_dir)
650
plugin = read_plugin_ini(plugin_dir)
651
expand_plugin_ini(plugin)
652
plugin_ini_list.append(plugin)
654
# Check for duplicates
655
plugin_name_list = [plugin['libname'] for plugin in plugin_ini_list]
656
for plugin in plugin_ini_list:
657
if plugin_name_list.count(plugin['libname']) != 1:
658
print "Duplicate module name %s" % plugin['libname']
661
for plugin in plugin_ini_list:
662
write_plugin(plugin, plugin_ini_list)
579
664
if plugin_am_file is not None:
580
665
plugin_am_file.close()