mirror of https://github.com/Icinga/icinga2.git
Implemented the 'Script' type.
This commit is contained in:
parent
7fac5b454e
commit
74b122d430
|
@ -78,6 +78,12 @@ if test "$ax_cv___attribute__" = "yes"; then
|
|||
CXXFLAGS="$CXXFLAGS -fvisibility=hidden"
|
||||
fi
|
||||
|
||||
AX_PYTHON_DEFAULT
|
||||
AX_PYTHON_ENABLE
|
||||
AX_PYTHON_VERSION_ENSURE([2.5])
|
||||
AX_PYTHON_CSPEC
|
||||
AX_PYTHON_LSPEC
|
||||
|
||||
AC_MSG_CHECKING(whether to enable debugging)
|
||||
AC_ARG_ENABLE(debug, [ --enable-debug=[no/yes] turn on debugging (default=no)],, enable_debug=no)
|
||||
if test "x$enable_debug" = "xyes"; then
|
||||
|
@ -121,6 +127,7 @@ lib/Makefile
|
|||
lib/base/Makefile
|
||||
lib/config/Makefile
|
||||
lib/icinga/Makefile
|
||||
lib/python/Makefile
|
||||
lib/remoting/Makefile
|
||||
test/Makefile
|
||||
third-party/Makefile
|
||||
|
|
|
@ -28,8 +28,8 @@ icinga2_LDADD = \
|
|||
$(BOOST_PROGRAM_OPTIONS_LIB) \
|
||||
${top_builddir}/lib/base/libbase.la \
|
||||
${top_builddir}/lib/config/libconfig.la \
|
||||
${top_builddir}/lib/remoting/libremoting.la \
|
||||
-dlopen ${top_builddir}/lib/icinga/libicinga.la \
|
||||
-dlopen ${top_builddir}/lib/python/libpython.la \
|
||||
-dlopen ${top_builddir}/components/checker/checker.la \
|
||||
-dlopen ${top_builddir}/components/replication/replication.la \
|
||||
-dlopen ${top_builddir}/components/compat/compat.la \
|
||||
|
|
|
@ -5,4 +5,5 @@ SUBDIRS = \
|
|||
base \
|
||||
config \
|
||||
remoting \
|
||||
icinga
|
||||
icinga \
|
||||
python
|
||||
|
|
|
@ -26,6 +26,7 @@ libbase_la_SOURCES = \
|
|||
exception.h \
|
||||
fifo.cpp \
|
||||
fifo.h \
|
||||
i2-base.cpp \
|
||||
i2-base.h \
|
||||
logger.cpp \
|
||||
logger.h \
|
||||
|
|
|
@ -481,6 +481,9 @@ void DynamicObject::FlushTx(void)
|
|||
BeginTx();
|
||||
}
|
||||
|
||||
void DynamicObject::OnInitCompleted(void)
|
||||
{ }
|
||||
|
||||
void DynamicObject::OnAttributeChanged(const String&, const Value&)
|
||||
{ }
|
||||
|
||||
|
|
|
@ -132,6 +132,7 @@ public:
|
|||
static void FlushTx(void);
|
||||
|
||||
protected:
|
||||
virtual void OnInitCompleted(void);
|
||||
virtual void OnAttributeChanged(const String& name, const Value& oldValue);
|
||||
|
||||
private:
|
||||
|
@ -148,6 +149,8 @@ private:
|
|||
/* This has to be a set of raw pointers because the DynamicObject
|
||||
* constructor has to be able to insert objects into this list. */
|
||||
static set<DynamicObject *> m_ModifiedObjects;
|
||||
|
||||
friend class DynamicType; /* for OnInitCompleted. */
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -93,6 +93,9 @@ DynamicObject::Ptr DynamicType::CreateObject(const Dictionary::Ptr& serializedUp
|
|||
/* apply the object's non-config attributes */
|
||||
obj->ApplyUpdate(serializedUpdate, Attribute_All & ~Attribute_Config);
|
||||
|
||||
/* notify the object that it's been fully initialized */
|
||||
obj->OnInitCompleted();
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,11 @@ Script::Script(const Dictionary::Ptr& properties)
|
|||
: DynamicObject(properties)
|
||||
{ }
|
||||
|
||||
void Script::OnInitCompleted(void)
|
||||
{
|
||||
SpawnInterpreter();
|
||||
}
|
||||
|
||||
String Script::GetLanguage(void) const
|
||||
{
|
||||
return Get("language");
|
||||
|
@ -44,17 +49,14 @@ String Script::GetCode(void) const
|
|||
|
||||
void Script::OnAttributeUpdate(const String& name, const Value& oldValue)
|
||||
{
|
||||
if (name == "code")
|
||||
Reload();
|
||||
if (name == "language" || name == "code")
|
||||
SpawnInterpreter();
|
||||
}
|
||||
|
||||
void Script::Reload(void)
|
||||
void Script::SpawnInterpreter(void)
|
||||
{
|
||||
if (!m_Interpreter) {
|
||||
ScriptLanguage::Ptr language = ScriptLanguage::GetByName(GetLanguage());
|
||||
Logger::Write(LogInformation, "base", "Reloading script '" + GetName() + "'");
|
||||
|
||||
m_Interpreter = language->CreateInterpreter(GetSelf());
|
||||
} else {
|
||||
m_Interpreter->Reload();
|
||||
}
|
||||
ScriptLanguage::Ptr language = ScriptLanguage::GetByName(GetLanguage());
|
||||
m_Interpreter = language->CreateInterpreter(GetSelf());
|
||||
}
|
||||
|
|
|
@ -42,12 +42,13 @@ public:
|
|||
String GetCode(void) const;
|
||||
|
||||
protected:
|
||||
virtual void OnInitCompleted(void);
|
||||
virtual void OnAttributeUpdate(const String& name, const Value& oldValue);
|
||||
|
||||
private:
|
||||
shared_ptr<ScriptInterpreter> m_Interpreter;
|
||||
|
||||
void Reload(void);
|
||||
void SpawnInterpreter(void);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -22,12 +22,12 @@
|
|||
using namespace icinga;
|
||||
|
||||
ScriptInterpreter::ScriptInterpreter(const Script::Ptr& script)
|
||||
: m_Thread(&ScriptInterpreter::ThreadWorkerProc, this, script)
|
||||
: m_Thread(&ScriptInterpreter::ThreadWorkerProc, this)
|
||||
{
|
||||
m_Thread.detach();
|
||||
}
|
||||
|
||||
void ScriptInterpreter::ThreadWorkerProc(const Script::Ptr& script)
|
||||
void ScriptInterpreter::ThreadWorkerProc(void)
|
||||
{
|
||||
ScriptCall call;
|
||||
|
||||
|
@ -55,3 +55,7 @@ bool ScriptInterpreter::WaitForCall(ScriptCall *call)
|
|||
return true;
|
||||
}
|
||||
|
||||
void ScriptInterpreter::RegisterMethod(const String& name)
|
||||
{
|
||||
// TODO: implement
|
||||
}
|
||||
|
|
|
@ -41,8 +41,6 @@ public:
|
|||
typedef shared_ptr<ScriptInterpreter> Ptr;
|
||||
typedef weak_ptr<ScriptInterpreter> WeakPtr;
|
||||
|
||||
virtual void Reload(void) = 0;
|
||||
|
||||
void EnqueueCall(const ScriptCall& call);
|
||||
|
||||
protected:
|
||||
|
@ -52,6 +50,8 @@ protected:
|
|||
|
||||
bool WaitForCall(ScriptCall *call);
|
||||
|
||||
void RegisterMethod(const String& name);
|
||||
|
||||
private:
|
||||
boost::mutex m_Mutex;
|
||||
deque<ScriptCall> m_Calls;
|
||||
|
@ -59,7 +59,7 @@ private:
|
|||
|
||||
boost::thread m_Thread;
|
||||
|
||||
void ThreadWorkerProc(const Script::Ptr& script);
|
||||
void ThreadWorkerProc(void);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -21,6 +21,9 @@
|
|||
|
||||
using namespace icinga;
|
||||
|
||||
ScriptLanguage::ScriptLanguage(void)
|
||||
{ }
|
||||
|
||||
void ScriptLanguage::Register(const String& name, const ScriptLanguage::Ptr& language)
|
||||
{
|
||||
GetLanguages()[name] = language;
|
||||
|
|
|
@ -47,6 +47,24 @@ private:
|
|||
static map<String, ScriptLanguage::Ptr>& GetLanguages(void);
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper class for registering ScriptLanguage implementation classes.
|
||||
*
|
||||
* @ingroup base
|
||||
*/
|
||||
class RegisterLanguageHelper
|
||||
{
|
||||
public:
|
||||
RegisterLanguageHelper(const String& name, const ScriptLanguage::Ptr& language)
|
||||
{
|
||||
if (!ScriptLanguage::GetByName(name))
|
||||
ScriptLanguage::Register(name, language);
|
||||
}
|
||||
};
|
||||
|
||||
#define REGISTER_SCRIPTLANGUAGE(name, klass) \
|
||||
static RegisterLanguageHelper g_RegisterSL_ ## type(name, boost::make_shared<klass>())
|
||||
|
||||
}
|
||||
|
||||
#endif /* SCRIPTLANGUAGE_H */
|
||||
|
|
|
@ -15,6 +15,7 @@ libconfig_la_SOURCES = \
|
|||
configcompilercontext.h \
|
||||
config_lexer.ll \
|
||||
config_parser.yy \
|
||||
i2-config.cpp \
|
||||
i2-config.h \
|
||||
configitem.cpp \
|
||||
configitem.h \
|
||||
|
|
|
@ -15,6 +15,7 @@ libicinga_la_SOURCES = \
|
|||
hostgroup.cpp \
|
||||
hostgroup.h \
|
||||
host.h \
|
||||
i2-icinga.cpp \
|
||||
i2-icinga.h \
|
||||
icingaapplication.cpp \
|
||||
icingaapplication.h \
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
if PYTHON_USE
|
||||
pkglib_LTLIBRARIES = \
|
||||
libpython.la
|
||||
|
||||
libpython_la_SOURCES = \
|
||||
i2-python.h \
|
||||
pythoninterpreter.cpp \
|
||||
pythoninterpreter.h \
|
||||
pythonlanguage.cpp \
|
||||
pythonlanguage.h
|
||||
|
||||
libpython_la_CPPFLAGS = \
|
||||
-DI2_PYTHON_BUILD \
|
||||
$(BOOST_CPPFLAGS) \
|
||||
@PYTHON_CSPEC@ \
|
||||
-I${top_srcdir}/lib/base \
|
||||
-I${top_srcdir}/lib/config \
|
||||
-I${top_srcdir}/lib/remoting \
|
||||
-I${top_srcdir}
|
||||
|
||||
libpython_la_LDFLAGS = \
|
||||
$(BOOST_LDFLAGS) \
|
||||
@PYTHON_LSPEC@
|
||||
-no-undefined \
|
||||
@RELEASE_INFO@ \
|
||||
@VERSION_INFO@
|
||||
|
||||
libpython_la_LIBADD = \
|
||||
$(BOOST_THREAD_LIB) \
|
||||
${top_builddir}/lib/base/libbase.la \
|
||||
${top_builddir}/lib/config/libconfig.la \
|
||||
${top_builddir}/lib/remoting/libremoting.la
|
||||
endif
|
|
@ -0,0 +1,22 @@
|
|||
/******************************************************************************
|
||||
* Icinga 2 *
|
||||
* Copyright (C) 2012 Icinga Development Team (http://www.icinga.org/) *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software Foundation *
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
******************************************************************************/
|
||||
|
||||
/* This file is used by MSVC to generate the pre-compiled hedader. */
|
||||
|
||||
#include "i2-python.h"
|
|
@ -0,0 +1,44 @@
|
|||
/******************************************************************************
|
||||
* Icinga 2 *
|
||||
* Copyright (C) 2012 Icinga Development Team (http://www.icinga.org/) *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software Foundation *
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef I2PYTHON_H
|
||||
#define I2PYTHON_H
|
||||
|
||||
/**
|
||||
* @defgroup python Icinga python support
|
||||
*
|
||||
* Lets you integrate Python scripts into Icinga.
|
||||
*/
|
||||
|
||||
#include <Python.h>
|
||||
|
||||
#include <i2-base.h>
|
||||
#include <i2-config.h>
|
||||
#include <i2-remoting.h>
|
||||
|
||||
#ifdef I2_PYTHON_BUILD
|
||||
# define I2_PYTHON_API I2_EXPORT
|
||||
#else /* I2_PYTHON_BUILD */
|
||||
# define I2_PYTHON_API I2_IMPORT
|
||||
#endif /* I2_PYTHON_BUILD */
|
||||
|
||||
#include "pythonlanguage.h"
|
||||
#include "pythoninterpreter.h"
|
||||
|
||||
#endif /* I2PYTHON_H */
|
|
@ -0,0 +1,56 @@
|
|||
/******************************************************************************
|
||||
* Icinga 2 *
|
||||
* Copyright (C) 2012 Icinga Development Team (http://www.icinga.org/) *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software Foundation *
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
******************************************************************************/
|
||||
|
||||
#include "i2-python.h"
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
PythonInterpreter::PythonInterpreter(const PythonLanguage::Ptr& language, const Script::Ptr& script)
|
||||
: ScriptInterpreter(script), m_Language(language), m_ThreadState(NULL)
|
||||
{
|
||||
PyEval_AcquireLock();
|
||||
|
||||
PyInterpreterState *interp = m_Language->GetMainThreadState()->interp;
|
||||
m_ThreadState = PyThreadState_New(interp);
|
||||
|
||||
PyEval_ReleaseLock();
|
||||
|
||||
PyEval_AcquireThread(m_ThreadState);
|
||||
PyRun_SimpleString(script->GetCode().CStr());
|
||||
PyEval_ReleaseThread(m_ThreadState);
|
||||
}
|
||||
|
||||
PythonInterpreter::~PythonInterpreter(void)
|
||||
{
|
||||
PyEval_AcquireLock();
|
||||
|
||||
PyThreadState_Clear(m_ThreadState);
|
||||
PyThreadState_Delete(m_ThreadState);
|
||||
|
||||
PyEval_ReleaseLock();
|
||||
}
|
||||
|
||||
void PythonInterpreter::ProcessCall(const ScriptCall& call)
|
||||
{
|
||||
PyEval_AcquireThread(m_ThreadState);
|
||||
PyRun_SimpleString("import antigravity");
|
||||
PyEval_ReleaseThread(m_ThreadState);
|
||||
|
||||
call.Task->FinishResult(0);
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
/******************************************************************************
|
||||
* Icinga 2 *
|
||||
* Copyright (C) 2012 Icinga Development Team (http://www.icinga.org/) *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software Foundation *
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef PYTHONINTERPRETER_H
|
||||
#define PYTHONINTERPRETER_H
|
||||
|
||||
namespace icinga
|
||||
{
|
||||
|
||||
/**
|
||||
* A Python script interpreter.
|
||||
*
|
||||
* @ingroup base
|
||||
*/
|
||||
class I2_PYTHON_API PythonInterpreter : public ScriptInterpreter
|
||||
{
|
||||
public:
|
||||
typedef shared_ptr<PythonInterpreter> Ptr;
|
||||
typedef weak_ptr<PythonInterpreter> WeakPtr;
|
||||
|
||||
PythonInterpreter(const PythonLanguage::Ptr& language, const Script::Ptr& script);
|
||||
~PythonInterpreter(void);
|
||||
|
||||
protected:
|
||||
PythonLanguage::Ptr m_Language;
|
||||
PyThreadState *m_ThreadState;
|
||||
|
||||
virtual void ProcessCall(const ScriptCall& call);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* PYTHONINTERPRETER_H */
|
|
@ -0,0 +1,54 @@
|
|||
/******************************************************************************
|
||||
* Icinga 2 *
|
||||
* Copyright (C) 2012 Icinga Development Team (http://www.icinga.org/) *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software Foundation *
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
******************************************************************************/
|
||||
|
||||
#include "i2-python.h"
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
REGISTER_SCRIPTLANGUAGE("Python", PythonLanguage);
|
||||
|
||||
PythonLanguage::PythonLanguage(void)
|
||||
: ScriptLanguage()
|
||||
{
|
||||
Py_Initialize();
|
||||
PyEval_InitThreads();
|
||||
|
||||
//PySys_SetArgv(argc, argv);
|
||||
|
||||
m_MainThreadState = PyThreadState_Get();
|
||||
|
||||
PyThreadState_Swap(NULL);
|
||||
|
||||
PyEval_ReleaseLock();
|
||||
}
|
||||
|
||||
PythonLanguage::~PythonLanguage(void)
|
||||
{
|
||||
Py_Finalize();
|
||||
}
|
||||
|
||||
ScriptInterpreter::Ptr PythonLanguage::CreateInterpreter(const Script::Ptr& script)
|
||||
{
|
||||
return boost::make_shared<PythonInterpreter>(GetSelf(), script);
|
||||
}
|
||||
|
||||
PyThreadState *PythonLanguage::GetMainThreadState(void) const
|
||||
{
|
||||
return m_MainThreadState;
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
/******************************************************************************
|
||||
* Icinga 2 *
|
||||
* Copyright (C) 2012 Icinga Development Team (http://www.icinga.org/) *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the Free Software Foundation *
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef PYTHONLANGUAGE_H
|
||||
#define PYTHONLANGUAGE_H
|
||||
|
||||
namespace icinga
|
||||
{
|
||||
|
||||
/**
|
||||
* The Python scripting language.
|
||||
*
|
||||
* @ingroup base
|
||||
*/
|
||||
class I2_PYTHON_API PythonLanguage : public ScriptLanguage
|
||||
{
|
||||
public:
|
||||
typedef shared_ptr<PythonLanguage> Ptr;
|
||||
typedef weak_ptr<PythonLanguage> WeakPtr;
|
||||
|
||||
PythonLanguage(void);
|
||||
~PythonLanguage(void);
|
||||
|
||||
virtual ScriptInterpreter::Ptr CreateInterpreter(const Script::Ptr& script);
|
||||
|
||||
PyThreadState *GetMainThreadState(void) const;
|
||||
private:
|
||||
PyThreadState *m_MainThreadState;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* PYTHONLANGUAGE_H */
|
|
@ -9,6 +9,7 @@ libremoting_la_SOURCES = \
|
|||
endpoint.h \
|
||||
endpointmanager.cpp \
|
||||
endpointmanager.h \
|
||||
i2-remoting.cpp \
|
||||
i2-remoting.h \
|
||||
jsonrpcconnection.cpp \
|
||||
jsonrpcconnection.h \
|
||||
|
|
|
@ -0,0 +1,515 @@
|
|||
# ===========================================================================
|
||||
# http://www.gnu.org/software/autoconf-archive/ax_python_embed.html
|
||||
# ===========================================================================
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# AX_PYTHON_DEFAULT
|
||||
# AX_PYTHON_ENABLE
|
||||
# AX_PYTHON_WITH
|
||||
# AX_PYTHON_PATH
|
||||
# AX_PYTHON_VERSION_ENSURE( [2.2] )
|
||||
# AX_PYTHON_CSPEC
|
||||
# AX_PYTHON_LSPEC
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# This file provides autoconf support for those applications that want to
|
||||
# embed python. It supports all pythons >= 2.2 which is the first official
|
||||
# release containing distutils. Version 2.2 of python was released
|
||||
# December 21, 2001. Since it actually executes the python, cross platform
|
||||
# configuration will probably not work. Also, most of the platforms
|
||||
# supported are consistent until you look into Mac OS X. The python
|
||||
# included with it is installed as a framework which is a very different
|
||||
# environment to set up the normal tools such as gcc and libtool to deal
|
||||
# with. Therefore, once we establish which python that we are going to
|
||||
# use, we use its distutils to actually compile and link our modules or
|
||||
# applications.
|
||||
#
|
||||
# At this time, it does NOT support linking with Python statically. It
|
||||
# does support dynamic linking.
|
||||
#
|
||||
# This set of macros help define $PYTHON, $PYTHON_USE, $PYTHON_CSPEC and
|
||||
# $PYTHON_LSPEC. $PYTHON defines the full executable path for the Python
|
||||
# being linked to and is used within these macros to determine if that has
|
||||
# been specified or found. These macros do execute this python version so
|
||||
# it must be present on the system at configure time.
|
||||
#
|
||||
# $PYTHON_USE is an automake variable that defines whether Python support
|
||||
# should be included or not in your application. $PYTHON_CSPEC is a
|
||||
# variable that supplies additional CFLAGS for the compilation of the
|
||||
# application/shared library. $PYTHON_LSPEC is a variable that supplies
|
||||
# additional LDFLAGS for linking the application/shared library.
|
||||
#
|
||||
# The following is an example of how to set up for python usage within
|
||||
# your application in your configure.in:
|
||||
#
|
||||
# AX_PYTHON_DEFAULT( )
|
||||
# AX_PYTHON_ENABLE( ) # Optional
|
||||
# AX_PYTHON_WITH( ) # Optional
|
||||
# AX_PYTHON_PATH( ) # or AX_PYTHON_INSIST( )
|
||||
# # if $PYTHON is not defined, then the following do nothing.
|
||||
# AX_PYTHON_VERSION_ENSURE( [2.2] )
|
||||
# AX_PYTHON_CSPEC
|
||||
# AX_PYTHON_LSPEC
|
||||
#
|
||||
# The AX_PYTHON_DEFAULT sets the $PYTHON_USE to false. Thereby, excluding
|
||||
# it if it was optional.
|
||||
#
|
||||
# The AX_PYTHON_ENABLE looks for the optional configure parameters of
|
||||
# --enable-python/--disable-python and establishes the $PYTHON and
|
||||
# $PYTHON_USE variables accordingly.
|
||||
#
|
||||
# The AX_PYTHON_WITH looks for the optional configure parameters of
|
||||
# --with-python/--without-python and establishes the $PYTHON and
|
||||
# $PYTHON_USE variables accordingly.
|
||||
#
|
||||
# The AX_PYTHON_PATH looks for python assuming that none has been
|
||||
# previously found or defined and issues an error if it does not find it.
|
||||
# If it does find it, it establishes the $PYTHON and $PYTHON_USE variables
|
||||
# accordingly. AX_PYTHON_INSIST could be used here instead if you want to
|
||||
# insist that Python support be included using the --enable-python or
|
||||
# --with-python checks previously done.
|
||||
#
|
||||
# The AX_PYTHON_VERSION_ENSURE issues an error if the Python previously
|
||||
# found is not of version 2.2 or greater.
|
||||
#
|
||||
# Once that these macros have be run, we can use PYTHON_USE within the
|
||||
# makefile.am file to conditionally add the Python support such as:
|
||||
#
|
||||
# Makefile.am example showing optional inclusion of directories:
|
||||
#
|
||||
# if PYTHON_USE
|
||||
# plugins = plugins
|
||||
# src = src
|
||||
# else
|
||||
# plugins =
|
||||
# src =
|
||||
# endif
|
||||
#
|
||||
# SUBDIRS = . $(plugins) $(src)
|
||||
#
|
||||
# Makefile.am example showing optional shared library build:
|
||||
#
|
||||
# if PYTHON_USE
|
||||
# lib_LTLIBRARIES = libElemList.la
|
||||
# libElemList_la_SOURCES = libElemList.c
|
||||
# libElemList_la_CFLAGS = @PYTHON_CSPEC@
|
||||
# libElemList_la_LDFLAGS = @PYTHON_LSPEC@
|
||||
# endif
|
||||
#
|
||||
# Makefile.am example showing optional program build:
|
||||
#
|
||||
# if PYTHON_USE
|
||||
# bin_PROGRAMS = runFunc
|
||||
# runFunc_SOURCES = runFunc.c
|
||||
# runFunc_CFLAGS = @PYTHON_CSPEC@
|
||||
# runFunc_LDFLAGS = @PYTHON_LSPEC@
|
||||
# endif
|
||||
#
|
||||
# The above compiles the modules only if PYTHON_USE was specified as true.
|
||||
# Also, the else portion of the if was optional.
|
||||
#
|
||||
# LICENSE
|
||||
#
|
||||
# Copyright (c) 2008 Robert White <kranki@mac.com>
|
||||
# Copyright (c) 2008 Dustin J. Mitchell <dustin@cs.uchicago.edu>
|
||||
#
|
||||
# Copying and distribution of this file, with or without modification, are
|
||||
# permitted in any medium without royalty provided the copyright notice
|
||||
# and this notice are preserved. This file is offered as-is, without any
|
||||
# warranty.
|
||||
|
||||
#serial 8
|
||||
|
||||
# AX_PYTHON_DEFAULT( )
|
||||
# -----------------
|
||||
# Sets the default to not include Python support.
|
||||
|
||||
AC_DEFUN([AX_PYTHON_DEFAULT],
|
||||
[
|
||||
ax_python_use=false
|
||||
AM_CONDITIONAL(PYTHON_USE, test x"$ax_python_use" = x"true")
|
||||
])
|
||||
|
||||
|
||||
|
||||
# AX_PYTHON_ENABLE( [path] )
|
||||
# -----------------------------------------------------------------
|
||||
# Handles the various --enable-python commands.
|
||||
# Input:
|
||||
# $1 is the optional search path for the python executable if needed
|
||||
# Ouput:
|
||||
# PYTHON_USE (AM_CONDITIONAL) is true if python executable found
|
||||
# and --enable-python was requested; otherwise false.
|
||||
# $PYTHON contains the full executable path to python if PYTHON_ENABLE_USE
|
||||
# is true.
|
||||
#
|
||||
# Example:
|
||||
# AX_PYTHON_ENABLE( )
|
||||
# or
|
||||
# AX_PYTHON_ENABLE( "/usr/bin" )
|
||||
|
||||
AC_DEFUN([AX_PYTHON_ENABLE],
|
||||
[
|
||||
AC_ARG_VAR([PYTHON],[Python Executable Path])
|
||||
|
||||
# unless PYTHON was supplied to us (as a precious variable),
|
||||
# see if --enable-python[=PythonExecutablePath], --enable-python,
|
||||
# --disable-python or --enable-python=no was given.
|
||||
if test -z "$PYTHON"
|
||||
then
|
||||
AC_MSG_CHECKING(for --enable-python)
|
||||
AC_ARG_ENABLE(
|
||||
python,
|
||||
AS_HELP_STRING([--enable-python@<:@=PYTHON@:>@],
|
||||
[absolute path name of Python executable]
|
||||
),
|
||||
[
|
||||
if test "$enableval" = "yes"
|
||||
then
|
||||
# "yes" was specified, but we don't have a path
|
||||
# for the executable.
|
||||
# So, let's searth the PATH Environment Variable.
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_PATH_PROG(
|
||||
[PYTHON],
|
||||
python,
|
||||
[],
|
||||
$1
|
||||
)
|
||||
if test -z "$PYTHON"
|
||||
then
|
||||
AC_MSG_ERROR(no path to python found)
|
||||
fi
|
||||
ax_python_use=true
|
||||
AM_CONDITIONAL(PYTHON_USE, test x"$ax_python_use" = x"true")
|
||||
AX_PYTHON_PREFIX( )
|
||||
elif test "$enableval" = "no"
|
||||
then
|
||||
AC_MSG_RESULT(no)
|
||||
ax_python_use=false
|
||||
AM_CONDITIONAL(PYTHON_USE, test x"$ax_python_use" = x"true")
|
||||
else
|
||||
# $enableval must be the executable path then.
|
||||
AC_SUBST([PYTHON], ["${enableval}"])
|
||||
AC_MSG_RESULT($withval)
|
||||
ax_python_use=true
|
||||
AM_CONDITIONAL(PYTHON_USE, test x"$ax_python_use" = x"true")
|
||||
AX_PYTHON_PREFIX( )
|
||||
fi
|
||||
],
|
||||
[
|
||||
# --with-python was not specified.
|
||||
AC_MSG_RESULT(no)
|
||||
ax_python_use=false
|
||||
AM_CONDITIONAL(PYTHON_USE, test x"$ax_python_use" = x"true")
|
||||
]
|
||||
)
|
||||
fi
|
||||
|
||||
])
|
||||
|
||||
|
||||
|
||||
# AX_PYTHON_CSPEC( )
|
||||
# -----------------
|
||||
# Set up the c compiler options to compile Python
|
||||
# embedded programs/libraries in $PYTHON_CSPEC if
|
||||
# $PYTHON has been defined.
|
||||
|
||||
AC_DEFUN([AX_PYTHON_CSPEC],
|
||||
[
|
||||
AC_ARG_VAR( [PYTHON], [Python Executable Path] )
|
||||
if test -n "$PYTHON"
|
||||
then
|
||||
ax_python_prefix=`${PYTHON} -c "import sys; print sys.prefix"`
|
||||
if test -z "$ax_python_prefix"
|
||||
then
|
||||
AC_MSG_ERROR([Python Prefix is not known])
|
||||
fi
|
||||
ax_python_execprefix=`${PYTHON} -c "import sys; print sys.exec_prefix"`
|
||||
ax_python_version=`$PYTHON -c "import sys; print sys.version[[:3]]"`
|
||||
ax_python_includespec="-I${ax_python_prefix}/include/python${ax_python_version}"
|
||||
if test x"$python_prefix" != x"$python_execprefix"; then
|
||||
ax_python_execspec="-I${ax_python_execprefix}/include/python${ax_python_version}"
|
||||
ax_python_includespec="${ax_python_includespec} $ax_python_execspec"
|
||||
fi
|
||||
ax_python_ccshared=`${PYTHON} -c "import distutils.sysconfig; print distutils.sysconfig.get_config_var('CFLAGSFORSHARED')"`
|
||||
ax_python_cspec="${ax_python_ccshared} ${ax_python_includespec}"
|
||||
AC_SUBST([PYTHON_CSPEC], [${ax_python_cspec}])
|
||||
AC_MSG_NOTICE([PYTHON_CSPEC=${ax_python_cspec}])
|
||||
fi
|
||||
])
|
||||
|
||||
|
||||
|
||||
# AX_PYTHON_INSIST( )
|
||||
# -----------------
|
||||
# Look for Python and set the output variable 'PYTHON'
|
||||
# to 'python' if found, empty otherwise.
|
||||
|
||||
AC_DEFUN([AX_PYTHON_INSIST],
|
||||
[
|
||||
AC_ARG_VAR( [PYTHON], [Python Executable Path] )
|
||||
if test -z "$PYTHON"
|
||||
then
|
||||
AC_MSG_ERROR([Python Executable not found])
|
||||
fi
|
||||
])
|
||||
|
||||
|
||||
|
||||
# AX_PYTHON_LSPEC( )
|
||||
# -----------------
|
||||
# Set up the linker options to link Python embedded
|
||||
# programs/libraries in $PYTHON_LSPEC if $PYTHON
|
||||
# has been defined.
|
||||
|
||||
AC_DEFUN([AX_PYTHON_LSPEC],
|
||||
[
|
||||
AC_ARG_VAR( [PYTHON], [Python Executable Path] )
|
||||
if test -n "$PYTHON"
|
||||
then
|
||||
AX_PYTHON_RUN([
|
||||
import sys
|
||||
import distutils.sysconfig
|
||||
strUseFrameWork = "--enable-framework"
|
||||
dictConfig = distutils.sysconfig.get_config_vars( )
|
||||
strConfigArgs = dictConfig.get("CONFIG_ARGS")
|
||||
strLinkSpec = dictConfig.get('LDFLAGS')
|
||||
if -1 == strConfigArgs.find(strUseFrameWork):
|
||||
strLibPL = dictConfig.get("LIBPL")
|
||||
if strLibPL and (strLibPL != ""):
|
||||
strLinkSpec += " -L%s" % (strLibPL)
|
||||
strSys = dictConfig.get("SYSLIBS")
|
||||
if strSys and (strSys != ""):
|
||||
strLinkSpec += " %s" % (strSys)
|
||||
strSHL = dictConfig.get("SHLIBS")
|
||||
if strSHL and (strSHL != ""):
|
||||
strLinkSpec += " %s" % (strSHL)
|
||||
# Construct the Python Library Name.
|
||||
strTmplte = " -lpython%d.%d"
|
||||
if (sys.platform == "win32") or (sys.platform == "os2emx"):
|
||||
strTmplte = " -lpython%d%d"
|
||||
strWrk = strTmplte % ( (sys.hexversion >> 24),
|
||||
((sys.hexversion >> 16) & 0xff))
|
||||
strLinkSpec += strWrk
|
||||
else:
|
||||
# This is not ideal since it changes the search path
|
||||
# for Frameworks which could have side-effects on
|
||||
# other included Frameworks. However, it is necessary
|
||||
# where someone has installed more than one frameworked
|
||||
# Python. Frameworks are really only used in MacOSX.
|
||||
strLibFW = dictConfig.get("PYTHONFRAMEWORKPREFIX")
|
||||
if strLibFW and (strLibFW != ""):
|
||||
strLinkSpec += " -F%s" % (strLibFW)
|
||||
strLinkSpec += " %s" % (dictConfig.get('LINKFORSHARED'))
|
||||
print strLinkSpec
|
||||
])
|
||||
AC_SUBST([PYTHON_LSPEC], [${ax_python_output}])
|
||||
AC_MSG_NOTICE([PYTHON_LSPEC=${ax_python_output}])
|
||||
fi
|
||||
])
|
||||
|
||||
|
||||
|
||||
# AX_PYTHON_PATH( )
|
||||
# -----------------
|
||||
# Look for Python and set the output variable 'PYTHON'
|
||||
# to 'python' if found, empty otherwise.
|
||||
|
||||
AC_DEFUN([AX_PYTHON_PATH],
|
||||
[
|
||||
AC_ARG_VAR( [PYTHON], [Python Executable Path] )
|
||||
AC_PATH_PROG( PYTHON, python, [], $1 )
|
||||
if test -z "$PYTHON"
|
||||
then
|
||||
AC_MSG_ERROR([Python Executable not found])
|
||||
else
|
||||
ax_python_use=true
|
||||
fi
|
||||
AM_CONDITIONAL(PYTHON_USE, test "$ax_python_use" = "true")
|
||||
])
|
||||
|
||||
|
||||
|
||||
# AX_PYTHON_PREFIX( )
|
||||
# -------------------
|
||||
# Use the values of $prefix and $exec_prefix for the corresponding
|
||||
# values of PYTHON_PREFIX and PYTHON_EXEC_PREFIX.
|
||||
|
||||
AC_DEFUN([AX_PYTHON_PREFIX],
|
||||
[
|
||||
if test -z "$PYTHON"
|
||||
then
|
||||
AC_MSG_ERROR([Python Executable Path is not known])
|
||||
fi
|
||||
ax_python_prefix=`${PYTHON} -c "import sys; print sys.prefix"`
|
||||
ax_python_execprefix=`${PYTHON} -c "import sys; print sys.exec_prefix"`
|
||||
AC_SUBST([PYTHON_PREFIX], ["${ax_python_prefix}"])
|
||||
AC_SUBST([PYTHON_EXECPREFIX], ["${ax_python_execprefix}"])
|
||||
])
|
||||
|
||||
|
||||
|
||||
# AX_PYTHON_RUN( PYTHON_PROGRAM )
|
||||
# -----------------
|
||||
# Run a Python Test Program saving its output
|
||||
# in ax_python_output and its condition code
|
||||
# in ax_python_cc.
|
||||
|
||||
AC_DEFUN([AX_PYTHON_RUN],
|
||||
[
|
||||
AC_ARG_VAR( [PYTHON], [Python Executable Path] )
|
||||
if test -z "$PYTHON"
|
||||
then
|
||||
AC_MSG_ERROR([Python Executable not found])
|
||||
else
|
||||
cat >conftest.py <<_ACEOF
|
||||
$1
|
||||
_ACEOF
|
||||
ax_python_output=`$PYTHON conftest.py`
|
||||
ax_python_cc=$?
|
||||
rm conftest.py
|
||||
if test -f "conftest.pyc"
|
||||
then
|
||||
rm conftest.pyc
|
||||
fi
|
||||
fi
|
||||
])
|
||||
|
||||
|
||||
|
||||
# AX_PYTHON_VERSION_CHECK( VERSION, [ACTION-IF-TRUE], [ACTION-IF-FALSE] )
|
||||
# -----------------------------------------------------------------------------
|
||||
# Run ACTION-IF-TRUE if the Python interpreter has version >= VERSION.
|
||||
# Run ACTION-IF-FALSE otherwise.
|
||||
# This test uses sys.hexversion instead of the string equivalant (first
|
||||
# word of sys.version), in order to cope with versions such as 2.2c1.
|
||||
# hexversion has been introduced in Python 1.5.2; it's probably not
|
||||
# worth to support older versions (1.5.1 was released on October 31, 1998).
|
||||
|
||||
AC_DEFUN([AX_PYTHON_VERSION_CHECK],
|
||||
[
|
||||
AC_ARG_VAR( [PYTHON], [Python Executable Path] )
|
||||
if test -n "$PYTHON"
|
||||
then
|
||||
AC_MSG_CHECKING([whether $PYTHON version >= $1])
|
||||
AX_PYTHON_RUN([
|
||||
import sys, string
|
||||
# split strings by '.' and convert to numeric. Append some zeros
|
||||
# because we need at least 4 digits for the hex conversion.
|
||||
minver = map(int, string.split('$1', '.')) + [[0, 0, 0]]
|
||||
minverhex = 0
|
||||
for i in xrange(0, 4): minverhex = (minverhex << 8) + minver[[i]]
|
||||
if sys.hexversion >= minverhex:
|
||||
sys.exit( 0 )
|
||||
else:
|
||||
sys.exit( 1 )
|
||||
])
|
||||
if test $ax_python_cc -eq 0
|
||||
then
|
||||
$2
|
||||
m4_ifvaln(
|
||||
[$3],
|
||||
[else $3]
|
||||
)
|
||||
fi
|
||||
fi
|
||||
])
|
||||
|
||||
|
||||
|
||||
# AX_PYTHON_VERSION_ENSURE( VERSION )
|
||||
# -----------------
|
||||
# Insure that the Python Interpreter Version
|
||||
# is greater than or equal to the VERSION
|
||||
# parameter.
|
||||
|
||||
AC_DEFUN([AX_PYTHON_VERSION_ENSURE],
|
||||
[
|
||||
AX_PYTHON_VERSION_CHECK(
|
||||
[$1],
|
||||
[AC_MSG_RESULT(yes)],
|
||||
[AC_MSG_ERROR(too old)]
|
||||
)
|
||||
])
|
||||
|
||||
|
||||
|
||||
# AX_PYTHON_WITH( [path] )
|
||||
# -----------------------------------------------------------------
|
||||
# Handles the various --with-python commands.
|
||||
# Input:
|
||||
# $1 is the optional search path for the python executable if needed
|
||||
# Ouput:
|
||||
# PYTHON_USE (AM_CONDITIONAL) is true if python executable found
|
||||
# and --with-python was requested; otherwise false.
|
||||
# $PYTHON contains the full executable path to python if PYTHON_USE
|
||||
# is true.
|
||||
#
|
||||
# Example:
|
||||
# AX_PYTHON_WITH( )
|
||||
# or
|
||||
# AX_PYTHON_WITH("/usr/bin")
|
||||
|
||||
AC_DEFUN([AX_PYTHON_WITH],
|
||||
[
|
||||
AC_ARG_VAR([PYTHON],[Python Executable Path])
|
||||
|
||||
# unless PYTHON was supplied to us (as a precious variable),
|
||||
# see if --with-python[=PythonExecutablePath], --with-python,
|
||||
# --without-python or --with-python=no was given.
|
||||
if test -z "$PYTHON"
|
||||
then
|
||||
AC_MSG_CHECKING(for --with-python)
|
||||
AC_ARG_WITH(
|
||||
python,
|
||||
AS_HELP_STRING([--with-python@<:@=PYTHON@:>@],
|
||||
[absolute path name of Python executable]
|
||||
),
|
||||
[
|
||||
if test "$withval" = "yes"
|
||||
then
|
||||
# "yes" was specified, but we don't have a path
|
||||
# for the executable.
|
||||
# So, let's searth the PATH Environment Variable.
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_PATH_PROG(
|
||||
[PYTHON],
|
||||
python,
|
||||
[],
|
||||
$1
|
||||
)
|
||||
if test -z "$PYTHON"
|
||||
then
|
||||
AC_MSG_ERROR(no path to python found)
|
||||
fi
|
||||
ax_python_use=true
|
||||
AM_CONDITIONAL(PYTHON_USE, test x"$ax_python_use" = x"true")
|
||||
AX_PYTHON_PREFIX( )
|
||||
elif test "$withval" = "no"
|
||||
then
|
||||
AC_MSG_RESULT(no)
|
||||
ax_python_use=false
|
||||
AM_CONDITIONAL(PYTHON_USE, test x"$ax_python_use" = x"true")
|
||||
else
|
||||
# $withval must be the executable path then.
|
||||
AC_SUBST([PYTHON], ["${withval}"])
|
||||
AC_MSG_RESULT($withval)
|
||||
ax_python_use=true
|
||||
AM_CONDITIONAL(PYTHON_USE, test x"$ax_python_use" = x"true")
|
||||
AX_PYTHON_PREFIX( )
|
||||
fi
|
||||
],
|
||||
[
|
||||
# --with-python was not specified.
|
||||
AC_MSG_RESULT(no)
|
||||
ax_python_use=false
|
||||
AM_CONDITIONAL(PYTHON_USE, test x"$ax_python_use" = x"true")
|
||||
]
|
||||
)
|
||||
fi
|
||||
|
||||
])
|
Loading…
Reference in New Issue