Skip to content

Commit

Permalink
Make it possible to build both python2 and python3 bindings
Browse files Browse the repository at this point in the history
  • Loading branch information
dmulder committed Jan 30, 2018
1 parent 4a896b8 commit 31bd543
Show file tree
Hide file tree
Showing 8 changed files with 116 additions and 21 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
@@ -1,4 +1,4 @@
FROM yastdevel/cpp
RUN zypper --gpg-auto-import-keys --non-interactive in --no-recommends \
python3-devel swig autoconf-archive
python-devel python3-devel swig autoconf-archive
COPY . /usr/src/app
14 changes: 10 additions & 4 deletions configure.in.in
Expand Up @@ -9,7 +9,13 @@
@YAST2-CHECKS-COMMON@
@YAST2-CHECKS-PROGRAM@

AM_PATH_PYTHON([3.4])
AC_ARG_ENABLE([python3], AS_HELP_STRING([--enable-python3], [Enable python3 build]))

if test "x$enable_python3" = "xyes"; then
AM_PATH_PYTHON([3.4])
else
AM_PATH_PYTHON([2.7])
fi
AX_PYTHON_DEVEL
AX_PKG_SWIG([], [], AC_MSG_ERROR([SWIG is required to build.]))
AX_SWIG_PYTHON
Expand All @@ -23,8 +29,8 @@ AC_SUBST([pkgpy2langdir], [\${yast_plugin_dir}])

## -pthread -fno-strict-aliasing -DNDEBUG -O2 -fmessage-length=0 -Wall -D_FORTIFY_SOURCE=2 -g -fPIC
## Find out what compiler/linker flags an embedded Python interpreter needs
PYTHON_CFLAGS=`python3-config --cflags`
PYTHON_LDFLAGS=`python3-config --libs`
PYTHON_CFLAGS=`${PYTHON}-config --cflags`
PYTHON_LDFLAGS=`${PYTHON}-config --libs`

AC_SUBST(PYTHON_CFLAGS)
AC_SUBST(PYTHON_LDFLAGS)
Expand All @@ -33,7 +39,7 @@ CFLAGS="${CFLAGS} ${PYTHON_CFLAGS}"
CXXFLAGS="${CXXFLAGS} ${PYTHON_CFLAGS}"

## Where to install modules
PYTHON_VENDORARCH=${libdir}/python`python3 -c 'import sys; print(sys.version@<:@:3@:>@)'`
PYTHON_VENDORARCH=${libdir}/python`$PYTHON -c 'import sys; print(sys.version@<:@:3@:>@)'`
AC_SUBST(PYTHON_VENDORARCH)

## make a literal of yast2dir so that it can be used in python instead
Expand Down
6 changes: 6 additions & 0 deletions package/yast2-python-bindings.changes
@@ -1,3 +1,9 @@
-------------------------------------------------------------------
Mon Jan 29 22:44:08 UTC 2018 - dmulder@suse.com

- Build both python2 and python3 versions of the bindings;
(bsc#1074696).

-------------------------------------------------------------------
Thu Jan 4 15:45:46 UTC 2018 - dmulder@suse.com

Expand Down
88 changes: 75 additions & 13 deletions package/yast2-python-bindings.spec
Expand Up @@ -16,12 +16,23 @@
#


%define python_sitelib %(%{__python3} -c "from distutils.sysconfig import get_python_lib; import sys; sys.stdout.write(get_python_lib())")
%define python_sitearch %(%{__python3} -c "from distutils.sysconfig import get_python_lib; import sys; sys.stdout.write(get_python_lib(1))")
%if 0%{?suse_version} > 1310 || 0%{?fedora_version} > 20
%define with_python3 1
%else
%define with_python3 0
%endif

%define python_sitelib %(%{__python} -c "from distutils.sysconfig import get_python_lib; import sys; sys.stdout.write(get_python_lib())")
%define python_sitearch %(%{__python} -c "from distutils.sysconfig import get_python_lib; import sys; sys.stdout.write(get_python_lib(1))")
%define python3_sitelib %(%{__python3} -c "from distutils.sysconfig import get_python_lib; import sys; sys.stdout.write(get_python_lib())")
%define python3_sitearch %(%{__python3} -c "from distutils.sysconfig import get_python_lib; import sys; sys.stdout.write(get_python_lib(1))")

Name: yast2-python-bindings
Version: 4.0.1
Version: 4.0.2
Release: 0
Summary: Python3 bindings for the YaST platform
License: GPL-2.0
Group: System/YaST

BuildRoot: %{_tmppath}/%{name}-%{version}-build
Source0: %{name}-%{version}.tar.bz2
Expand All @@ -33,42 +44,93 @@ BuildRequires: gcc-c++
BuildRequires: libtool
BuildRequires: libyui-devel
BuildRequires: make
BuildRequires: python
BuildRequires: python-devel
%if %{with_python3}
BuildRequires: python3
BuildRequires: python3-devel
%endif
BuildRequires: swig
BuildRequires: yast2-core-devel
BuildRequires: yast2-ycp-ui-bindings
BuildRequires: yast2-ycp-ui-bindings-devel

Requires: python3
Requires: python
Requires: yast2-core
Requires: yast2-ycp-ui-bindings
Obsoletes: yast2-python-bindings < 4.0.1
Conflicts: yast2-python3-bindings

Summary: Python bindings for the YaST platform
License: GPL-2.0
%description -n yast2-python-bindings
The bindings allow YaST modules to be written using the Python language
and also Python scripts can use YaST agents, APIs and modules.

%if %{with_python3}
%package -n yast2-python3-bindings
Summary: Python3 bindings for the YaST platform
Group: System/YaST
Requires: python3
Requires: yast2-core
Requires: yast2-ycp-ui-bindings
Obsoletes: yast2-python-bindings == 4.0.1
Conflicts: yast2-python-bindings

%description
%description -n yast2-python3-bindings
The bindings allow YaST modules to be written using the Python language
and also Python scripts can use YaST agents, APIs and modules.
%endif

%define builddir %{_builddir}/%{name}-%{version}

%prep
%setup -n %{name}-%{version}

%build
%yast_build
make -f Makefile.cvs all

%if %{with_python3}
%configure --enable-python3
make
mkdir -p %{builddir}/python3
%__cp -d src/*.py %{builddir}/python3
%__cp -d src/.libs/*.so.0.0.0 %{builddir}/python3
%__cp -d src/*.la %{builddir}/python3
make clean
%endif

%configure
make

%install
%yast_install
rm %{buildroot}/%{python_sitelib}/*.pyc
rm %{buildroot}/%{python_sitelib}/*.pyo
rm %{buildroot}/%{python_sitearch}/*.la
rm %{buildroot}/%{yast_plugindir}/*.la
%if %{with_python3}
%__mkdir_p %{buildroot}/%{python3_sitelib}/
%__install -m 0644 %{builddir}/python3/*.py %{buildroot}/%{python3_sitelib}/
%__mkdir_p %{buildroot}/%{python3_sitearch}/
%__install -m 0755 %{builddir}/python3/_ycp.so* %{buildroot}/%{python3_sitearch}/
%__ln_s %{python3_sitearch}/_ycp.so.0.0.0 %{buildroot}/%{python3_sitearch}/_ycp.so.0
%__ln_s %{python3_sitearch}/_ycp.so.0.0.0 %{buildroot}/%{python3_sitearch}/_ycp.so
%__install -m 0755 %{builddir}/python3/libpy2lang_python.so* %{buildroot}/%{yast_plugindir}/
%endif

rm %{buildroot}/%{python_sitelib}/__pycache__/*.pyc
rm %{buildroot}/%{yast_plugindir}/libpy2lang_python.la
%if %{with_python3}
%files -n yast2-python3-bindings
%defattr (-, root, root)
%doc %{yast_docdir}
%{python3_sitelib}/*.py
%{python3_sitearch}/_ycp.so*
%{yast_plugindir}/libpy2lang_python.so.*
%{yast_plugindir}/libpy2lang_python.so
%endif

%files
%files -n yast2-python-bindings
%defattr (-, root, root)
%doc %{yast_docdir}
%{python_sitelib}/*.py
%{python_sitearch}/_ycp.*
%{python_sitearch}/_ycp.so*
%{yast_plugindir}/libpy2lang_python.so.*
%{yast_plugindir}/libpy2lang_python.so

Expand Down
6 changes: 3 additions & 3 deletions src/Makefile.am
@@ -1,6 +1,6 @@
BUILT_SOURCES = ycp.py
ycp.py yast-core_wrap.cxx: yast-core.i ytypes.i ycp.i $(libpy2UI) YCPMap.h y2log.i yast.h ytypes.h y2log.h PythonLogger.h Y2PythonClientComponent.h YPythonCode.h Y2CCPythonClient.h
$(SWIG) $(AX_SWIG_PYTHON_OPT) -py3 -c++ -I/usr/include/YaST2 -o $@ $<
$(SWIG) $(AX_SWIG_PYTHON_OPT) -c++ -I/usr/include/YaST2 -o $@ $<

# Remove non-standard syntax unrecognized by swig from YCPMap.h
YCPMap.h:
Expand All @@ -17,13 +17,13 @@ _ycp_la_LDFLAGS = -module ${PYTHON_LDFLAGS} -Wl,-rpath=$(py2langdir)

_ycp_la_LIBADD = -L$(py2langdir) -lpy2UI

_ycp_la_CPPFLAGS = -std=c++11 -I/usr/include/YaST2 ${PYTHON_CPPFLAGS} -Wno-terminate
_ycp_la_CPPFLAGS = -std=c++11 -I/usr/include/YaST2 ${PYTHON_CPPFLAGS} -Wno-terminate -Wno-format-security -Wno-format-nonliteral

py2lang_LTLIBRARIES = libpy2lang_python.la

libpy2lang_python_la_SOURCES = Y2PythonClientComponent.cc Y2CCPythonClient.cc

libpy2lang_python_la_LDFLAGS = -lpython3 ${PYTHON_LDFLAGS} -Wl,-rpath=$(pyexecdir)
libpy2lang_python_la_LDFLAGS = ${PYTHON_LDFLAGS} -Wl,-rpath=$(pyexecdir)

libpy2lang_python_la_CPPFLAGS = -std=c++11 -I/usr/include/YaST2 ${PYTHON_CPPFLAGS} -Wno-terminate

Expand Down
4 changes: 4 additions & 0 deletions src/Y2PythonClientComponent.cc
Expand Up @@ -54,8 +54,12 @@ YCPValue callClient(const string& client)
{
FILE *fp = fopen(client.c_str(), "r");
int res = 0;
#if PY_MAJOR_VERSION >= 3
wstring wclient = wstring(client.begin(), client.end());
wchar_t* arg1 = (wchar_t*)wclient.c_str();
#else
char *arg1 = (char*)client.c_str();
#endif
if (fp == NULL) {
return YCPBoolean(false);
}
Expand Down
11 changes: 11 additions & 0 deletions src/yast.cpp
Expand Up @@ -62,6 +62,7 @@ YCPValue GetYCPVariable(const string & namespace_name, const string & variable_n
/**
* This is needed for importing new module from ycp.
*/
#if PY_MAJOR_VERSION >= 3
static struct PyModuleDef moduledef = {
PyModuleDef_HEAD_INIT,
NULL, /* m_name */
Expand All @@ -73,6 +74,12 @@ static struct PyModuleDef moduledef = {
NULL, /* m_clear */
NULL, /* m_free */
};
#else
static PyMethodDef new_module_methods[] =
{
{NULL, NULL, 0, NULL}
};
#endif

YCPList * list_functions;
YCPList * list_variables;
Expand Down Expand Up @@ -106,8 +113,12 @@ PyObject* import_module(const string & ns_name)
if (!ns) return Py_None;

// Init new module with name NameSpace and method __run (see new_module_methods)
#if PY_MAJOR_VERSION >= 3
moduledef.m_name = ns_name.c_str();
PyObject *new_module = PyModule_Create(&moduledef);
#else
PyObject *new_module = Py_InitModule(ns_name.c_str(), new_module_methods);
#endif
if (new_module == NULL) return Py_None;

// Dictionary of new_module - there will be registered all functions
Expand Down
6 changes: 6 additions & 0 deletions src/ytypes.i
Expand Up @@ -7,7 +7,11 @@ YCPValue pyval_to_ycp(PyObject *input)
if (input == Py_None)
return YCPNull();
if (PyBool_Check(input)) {
#if PY_MAJOR_VERSION >= 3
if (PyObject_RichCompareBool(input, Py_True, Py_EQ) == 1)
#else
if (PyObject_Compare(input, Py_True) == 0)
#endif
return YCPBoolean(true);
else
return YCPBoolean(false);
Expand All @@ -18,8 +22,10 @@ YCPValue pyval_to_ycp(PyObject *input)
return YCPFloat(PyFloat_AsDouble(input));
if (PyString_Check(input))
return YCPString(PyString_AsString(input));
#if PY_MAJOR_VERSION >= 3
if (PyUnicode_Check(input))
return YCPString(_PyUnicode_AsString(input));
#endif
if (PyList_Check(input)) {
auto size = PyList_Size(input);
if (size > 0 && PyFunction_Check(PyList_GetItem(input, 0))) {
Expand Down

0 comments on commit 31bd543

Please sign in to comment.