WL#3201: Configure support for server plugins

Affects: Server-5.1   —   Status: Complete

Configure (autotools) should be aware of plugins available for the server and
appropriately configure makefiles for building plugins as either dynamic
libraries or statically built into mysqld.

All storage engines are plugins.

Some plugins are mandatory and are always built statically, such as MyISAM and 
HEAP.

Note:
Current implementation does not work on Windows. The Windows part is now part 
of WL#3653.
Configure should support the following arguments: 
 
  --with-plugins=CONFIG 
  --with-plugins=PLUGIN[,PLUGIN...] 
  --without-plugin-PLUGIN 
  --with-plugin-PLUGIN 
 
 where CONFIG is a preconfigured selection (such as "none", "max", "all") 
 
For all plugins specified using "--with-plugins=...", they are to be 
configured for static build. If not enumerated, they are to be built 
dynamically except where specified using "--without-plugin-..." or if a 
dynamic build is not supported by the module. Plugins which do not support a 
static build are always built dynamically. 
 
Plugins which are mandatory always behave as if they are specified using 
"--with-plugin-...". An attempt to disable a mandatory module will result in a 
configure error. 
 
Disabled plugins are never built and cause a configure error if they are 
selected. 
 
It is possible to mix the arguments to a limited degree - for example: 
"--with-plugins=all --without-plugin-ndbcluster" or 
"--with-plugins=berkeley,example --with-plugin-innobase" 
Support for legacy configure arguments are also supported, such as 
"--with-innodb --without-csv-storage-engine" 
 
A plugin will be compiled for static linking when the following conditions are 
met: 
1. The plugin supports static build 
2. The plugin is a member of the config group or is on the modules list or has 
been explicitly enabled via "--with-plugin-XXX" 
3. The plugin has not been explicitly disabled via "--without-plugin-XXX". If 
both --without and --with are given, then the behaviour is undefined (autoconf 
decides) 
 
A plugin is defined as supporting static build when a static target name is 
declared or if neither static target name nor plugin directory is declared in 
configure.in - as some plugin sources are still within sql subdir and are a 
part of the build there. A compiler preprocessor define should be used to 
include/exclude code from the build. 
 
A plugin will be compiled as dynamic when the following conditions are met: 
1. The plugin supports dynamic build 
2. The plugin is not configured to be statically linked against mysqld 
3. The plugin has not been explicitly disabled via "--without-plugin-XXX" 
 
A plugin is defined as supporting dynamic build when a dynamic target name is 
declared in configure.in. 
 
For all plugins selected for inclusion into the static build, their plugin 
struct name is added to a list which is used to initialize the plugin system 
with these plugins already included. The current plugin framework has support 
for multiple named plugins per plugin binary and so all named plugins will be 
installed. 
 
All available plugins are listed in the help text (configure --help), for 
example: 
 
  --with-plugins=PLUGIN[,PLUGIN..] 
                          Plugins to include in mysqld. (default is: none) 
                          Must be a configuration name or a comma separated 
                          list of plugins. 
                          Available configurations are: none max max-no-ndb 
                          all. 
                          Available plugins are: archive berkeley blackhole 
                          csv example federated ftexample heap innobase myisam 
                          myisammrg ndbcluster partition. 
  --without-plugin-PLUGIN Disable the named plugin from being built. 
                          Otherwise, for plugins which are not selected for 
                          inclusion in mysqld will be built dynamically (if 
                          supported) 
  --with-plugin-PLUGIN    Forces the named plugin to be linked into mysqld 
                          statically. 
 
At the end of the help text, descriptions of the plugins are listed, for 
example: 
 
   === Archive Storage Engine === 
  Plugin Name:      archive 
  Description:      Archive Storage Engine 
  Supports build:   static and dynamic 
  Configurations:   max, max-no-ndb 
 
   === BerkeleyDB Storage Engine === 
  Plugin Name:      berkeley 
  Description:      Transactional Tables using BerkeleyDB 
  Supports build:   static 
  Configurations:   max, max-no-ndb 
 
   === CSV Storage Engine === 
  Plugin Name:      csv 
  Description:      Stores tables in text CSV format 
  Supports build:   static 
  Status:           mandatory 
 
   === Simple Parser === 
  Plugin Name:      ftexample 
  Description:      Simple full-text parser plugin 
  Supports build:   dynamic 
 
   === Cluster Storage Engine === 
  Plugin Name:      ndbcluster 
  Description:      High Availability Clustered tables 
  Supports build:   static 
  Configurations:   max 
 
--------------------------------------------------------  
Declaring plug-ins:  
  
  MYSQL_PLUGIN(name, long-name, description [,configlist])  
  
All plug-ins are required to have MYSQL_PLUGIN() declared first. The  
configlist is an optional argument which is a comma seperated list of  
configurations which the module is a member.  

Example:  
  MYSQL_PLUGIN(ftexample, [Simple Parser], [Simple full-text parser plugin])  
  
  
--------------------------------------------------------  
Declaring storage engine plug-ins:  
  
  MYSQL_STORAGE_ENGINE(name, legacy-opt, long-name, description [,configlist])  
  
This is a simple utility macro which calls MYSQL_PLUGIN. It performs the bare  
basics required to declare a storage engine plugin and provides support for  
handling the legacy configure command line options. If the legacy-opt is not  
specified, it will default to "--with-NAME-storage-engine". Set the legacy-opt  
to "no" if you do not want to handle any legacy option.  
  
This macro is roughly equivalent to:  
    MYSQL_PLUGIN(name, long-name, description)  
    MYSQL_PLUGIN_DEFINE(name, WITH_name_STORAGE_ENGINE)  
  
Example:  
  MYSQL_STORAGE_ENGINE(berkeley,  berkeley-db, [BerkeleyDB Storage Engine],  
        [Transactional Tables using BerkeleyDB], [max,max-no-ndb])  
  
  
--------------------------------------------------------  
Declaring a C preprocessor variable:  
  
  MYSQL_PLUGIN_DEFINE(name, define-name)  
  
When a plug-in will be included in a static build, this will set a  
preprocessor variable to 1. These preprocessor variables are defined in  
config.h  
  
Example:  
  MYSQL_PLUGIN_DEFINE(innobase, WITH_INNOBASE_STORAGE_ENGINE)  
  
  
--------------------------------------------------------  
Declaring a source directory for a plug-in:  
  
  MYSQL_PLUGIN_DIRECTORY(name, dir-name)  
  
Includes the specified directory into the build. If a file named "configure"  
is detected in the directory, it will be executed as part of the configure  
build otherwise it is assumed that there is a Makefile to be built in that  
directory.  
Currently, there is only support for plugin directories to be specified in the  
storage/ and plugin/ subdirectories.  
  
Example:  
  MYSQL_PLUGIN_DIRECTORY(archive, [storage/archive])  
  
  
--------------------------------------------------------  
Declaring a static library name for a plug-in:  
  
  MYSQL_PLUGIN_STATIC(name, lib-name)  
  
Sets the configure substitution @plugin_NAME_static_target@ to the supplied  
library name if the plugin is a static build. It also adds the library to the  
list of libraries to be linked into mysqld. It may either be just the name of  
the library where if there is a directory specified then the directory will be  
prepended for the link or if the supplied argument is another make variable or  
substitution, it will be passed through as is.  
  
Example:  
  MYSQL_PLUGIN_STATIC(archive, [libarchive.a])  
  MYSQL_PLUGIN_STATIC(berkeley, [[\$(bdb_libs_with_path)]])  
  
  
--------------------------------------------------------  
Declaring a dynamic library name for a plug-in:  
  
  MYSQL_PLUGIN_DYNAMIC(name, dso-name)  
  
Sets the configure substitution @plugin_NAME_shared_target@ to the supplied  
library name if the module is a dynamic build.  
  
Example:  
  MYSQL_PLUGIN_DYNAMIC(archive, [ha_archive.la])  
  
  
--------------------------------------------------------  
Declaring a plug-in as a mandatory module:  
  
  MYSQL_PLUGIN_MANDATORY(name)  
  
Mandatory plugins cannot be disabled.  
  
Example:  
  MYSQL_PLUGIN_MANDATORY(myisam)  
  
  
--------------------------------------------------------  
Declaring a plug-in as disabled:  
  
  MYSQL_PLUGIN_DISABLED(name)  
  
A disabled plugin will not be included in any build. If the plugin has been  
marked as MANDATORY, it will result in an autoconf error.  
  
--------------------------------------------------------  
Declaring additional plug-in configure actions:  
  
  MYSQL_PLUGIN_ACTIONS(name, configure-actions)  
  
Useful if there are additional configure actions required for a plugin. The  
configure-actions argument may either be the name of an autoconf macro or it  
may be more autoconf script.  
  
Example:  
  MYSQL_PLUGIN_ACTIONS(ndbcluster,[MYSQL_SETUP_NDBCLUSTER])  
  
  
--------------------------------------------------------  
Declaring plug-in dependency:  
  
  MYSQL_PLUGIN_DEPENDS(name, dependencies)  
  
Declares all plugins, in a comma-seperated list, which are required for the  
named plugin to be built. If the named plugin is selected, it will in turn  
enable all its depenencies.  
All plugins listed as a dependency must already have been declared with  
MYSQL_PLUGIN()  
  
Example:  
  MYSQL_PLUGIN_DEPENDS(ndbcluster, [partition])  
  
  
--------------------------------------------------------  
Performing the magic:  
  
  MYSQL_CONFIGURE_PLUGINS(default-names)  
  
Actually performs the task of generating the shell scripts for configure based  
upon the declarations made previously. It emits the shell code neccessary to  
check the options and sets the variables accordingly.  
  
Example:  
  MYSQL_CONFIGURE_PLUGINS([none])  
  
  
============================================================  
Configure errors:  
  
When any plugin macro is called before MYSQL_PLUGIN() is declared for that  
plugin, configure aborts with an error.  
  
When any of the plugin specified in the dependency list doesn't exist,  
configure aborts with an error.  
  
When a mandatory plug-in is specified in "--without-plugin-NAME", configure  
aborts with an error.  
  
When a disabled plug-in is specified in "--with-modules=..." or  
"--with-plugin=NAME", configure reports an error.  
  
When an optional plug-in which may only be built dynamically is specified in  
"--with-plugins=..." or "--with-plugin-NAME", configure emits a warning and  
continues to configure the plugin for dynamic build.  
  
When an optional plug-in which may only be built statically is not specified  
in "--with-plugins=..." nor "--without-plugin-NAME", configure emits a warning  
but should proceed anyway.  
  
============================================================
Avoiding configure.in changes

If a plugin source (which is located in a subdirectory of the storage/ or
plugin/ directory) contains plug.in file (e.g. storage/example/plug.in), this
file will be included as a part of configure.in. This way configure.in does not
need to be modified to add a new plugin to the build.

plug.in file may contain everything configure.in can, in particular all
MYSQL_PLUGIN_xxx macros as above. plug.in file does not need to specify
MYSQL_PLUGIN_DIRECTORY - it is set automatically to the directory of plug.in file.