PSARC/2015/294 cx_Oracle for Solaris
authorjmcp <James.McPherson@oracle.com>
Fri, 18 Sep 2015 15:29:23 -0700
changeset 4886 5489d408f67a
parent 4880 7bf19af9de1b
child 4887 4db7e64f5de8
PSARC/2015/294 cx_Oracle for Solaris 15803329 SUNBT7183489 Include python module cx_Oracle in Solaris
components/python/cx_oracle/Makefile
components/python/cx_oracle/cx_Oracle-PYVER.p5m
components/python/cx_oracle/cx_Oracle.license
components/python/cx_oracle/patches/cx_Oracle-setup.patch
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/python/cx_oracle/Makefile	Fri Sep 18 15:29:23 2015 -0700
@@ -0,0 +1,63 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+
+#
+# Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+#
+
+include ../../../make-rules/shared-macros.mk
+
+COMPONENT_NAME=		cx_Oracle
+COMPONENT_VERSION=	5.2
+COMPONENT_SRC=		$(COMPONENT_NAME)-$(COMPONENT_VERSION)
+COMPONENT_ARCHIVE=	$(COMPONENT_SRC).tar.gz
+COMPONENT_ARCHIVE_HASH=		\
+	sha256:c580d5e7fa9748326dbae22f5832401f229ddda5354ec17120d9b28893925bbb
+COMPONENT_ARCHIVE_URL=	$(call pypi_url)
+COMPONENT_PROJECT_URL=  http://cx-oracle.sourceforge.net/
+COMPONENT_BUGDB=	python-mod/cx_oracle
+
+TPNO=			23247
+
+# Specifying PYTHON2_VERSIONS so that we don't get the 2.6
+# version built as well. It's an oversight in setup.py.mk
+# that isn't worth fixing since 2.6 is going away very soon.
+PYTHON2_VERSIONS=	2.7
+PYTHON_VERSIONS=	2.7 $(PYTHON3_VERSIONS)
+
+include $(WS_MAKE_RULES)/prep.mk
+include $(WS_MAKE_RULES)/ips.mk
+include $(WS_MAKE_RULES)/setup.py.mk
+
+# common targets
+
+build:		$(BUILD_32_and_64)
+
+install:	$(INSTALL_32_and_64)
+
+# We do not run automated tests of this package because doing
+# requires access to a captive Oracle database instance.
+test:		$(NO_TESTS)
+
+system-test:    $(NO_TESTS)
+
+REQUIRED_PACKAGES += database/oracle/instantclient
+REQUIRED_PACKAGES += developer/oracle/instantclient/sdk
+REQUIRED_PACKAGES += system/library
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/python/cx_oracle/cx_Oracle-PYVER.p5m	Fri Sep 18 15:29:23 2015 -0700
@@ -0,0 +1,49 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+#
+
+set name=pkg.fmri \
+    value=pkg:/library/python/cx_oracle-$(PYV)@$(IPS_COMPONENT_VERSION),$(BUILD_VERSION)
+set name=pkg.summary value="Python bindings for the Oracle Database"
+set name=pkg.description \
+    value="cx_Oracle is a Python extension module that enables access to Oracle databases and conforms to PEP 0249, the Python Database API Specification v2.0"
+set name=com.oracle.info.description value="the cx_Oracle Python module"
+set name=com.oracle.info.tpno value=$(TPNO)
+set name=info.classification \
+    value=org.opensolaris.category.2008:Development/Databases \
+    value=org.opensolaris.category.2008:Development/Python
+set name=info.source-url value=$(COMPONENT_ARCHIVE_URL)
+set name=info.upstream value="Anthony Tuininga <[email protected]>"
+set name=info.upstream-url value=$(COMPONENT_PROJECT_URL)
+set name=org.opensolaris.arc-caseid value=PSARC/2015/294
+set name=org.opensolaris.consolidation value=$(CONSOLIDATION)
+# python-3-soabi transforms this line for us
+file path=usr/lib/python$(PYVER)/vendor-packages/64/cx_Oracle.so
+file path=usr/lib/python$(PYVER)/vendor-packages/cx_Oracle-$(COMPONENT_VERSION)-py$(PYVER).egg-info/PKG-INFO
+file path=usr/lib/python$(PYVER)/vendor-packages/cx_Oracle-$(COMPONENT_VERSION)-py$(PYVER).egg-info/SOURCES.txt
+file path=usr/lib/python$(PYVER)/vendor-packages/cx_Oracle-$(COMPONENT_VERSION)-py$(PYVER).egg-info/dependency_links.txt
+file path=usr/lib/python$(PYVER)/vendor-packages/cx_Oracle-$(COMPONENT_VERSION)-py$(PYVER).egg-info/top_level.txt
+file path=usr/lib/python$(PYVER)/vendor-packages/cx_Oracle.so
+#
+license cx_Oracle.license license=BSD
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/python/cx_oracle/cx_Oracle.license	Fri Sep 18 15:29:23 2015 -0700
@@ -0,0 +1,28 @@
+Copyright © 2007-2015, Anthony Tuininga. All rights reserved.
+
+Copyright © 2001-2007, Computronix (Canada) Ltd., Edmonton, Alberta, Canada. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    Redistributions of source code must retain the above copyright notice, this
+    list of conditions, and the disclaimer that follows.
+    Redistributions in binary form must reproduce the above copyright notice,
+    this list of conditions, and the following disclaimer in the documentation
+    and/or other materials provided with the distribution.
+    Neither the names of the copyright holders nor the names of any contributors
+    may be used to endorse or promote products derived from this software without
+    specific prior written permission.
+
+DISCLAIMER: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+*AS IS* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Computronix ® is a registered trademark of Computronix (Canada) Ltd.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/python/cx_oracle/patches/cx_Oracle-setup.patch	Fri Sep 18 15:29:23 2015 -0700
@@ -0,0 +1,165 @@
+This patch provides support for finding the Oracle Instant Client
+libraries (and sdk) delivered via IPS. It also forces the specification
+of an RPATH so that the cx_Oracle module links against the IPS-
+delivered Instant Client packages.
+
+This patch has not yet been integrated with upstream.
+
+
+--- cx_Oracle-5.2/setup.py.orig	Fri Apr  3 21:10:29 2015
++++ cx_Oracle-5.2/setup.py	Fri Sep 11 17:23:39 2015
+@@ -61,9 +61,17 @@
+ # define the list of files to be included as documentation for bdist_rpm
+ docFiles = "README.txt BUILD.txt samples test"
+ 
++# Globalize some variables
++subDirs = []
++versions = []
++if struct.calcsize("P") == 4:
++    bitness = 32
++else:
++    bitness = 64
++
+ # method for checking a potential Oracle home
+ def CheckOracleHome(directoryToCheck):
+-    global oracleHome, oracleVersion, oracleLibDir
++    global oracleHome, oracleVersion, oracleLibDir, subDirs, versions
+     import os
+     import struct
+     import sys
+@@ -81,8 +89,19 @@
+                 ("11g", "libclntsh.dylib.11.1"),
+                 ("10g", "libclntsh.dylib.10.1")
+         ]
++    elif sys.platform == "sunos5":
++        if bitness == 32:
++            # 32bit
++            subDirs = ["lib"]
++        else:
++            subDirs = ["lib/64", "lib"]
++        filesToCheck = [
++                ("12c", "libclntsh.so.12.1"),
++                ("11g", "libclntsh.so.11.1"),
++                ("10g", "libclntsh.so.10.1")
++        ]
+     else:
+-        if struct.calcsize("P") == 4:
++        if bitness == 32:
+             subDirs = ["lib", "lib32"]
+         else:
+             subDirs = ["lib", "lib64"]
+@@ -124,7 +143,7 @@
+ # Older Instant Client dirs have the form:
+ #    /usr/lib/oracle/10.2.0.5/client[64]/lib
+ def FindInstantClientRPMLib():
+-    versions = []
++    global versions
+     for path in glob.glob(os.path.join(rpmBaseLibDir, "[0-9.]*")):
+         versions.append(os.path.basename(path))
+     versions.sort(key = lambda x: [int(s) for s in x.split(".")])
+@@ -147,26 +166,68 @@
+ # define Linux Instant Client RPM path components
+ # Assume 64 bit builds if the platform is 64 bit
+ rpmBaseLibDir = "/usr/lib/oracle"
+-if struct.calcsize("P") == 4:
++if bitness == 32:
+     rpmClientDir = "client"
+ else:
+     rpmClientDir = "client64"
+ instantClientRPMLib = None
+ 
++#
++# Solaris 11.x and later make use of the Image Packaging System, IPS,
++# and can install Instant Client 12.1 (and later versions) using that
++# format. IPS-delivered versions exist under
++#    /usr/oracle/instantclient/[version]
++# which allows us to bake an rpath into this module and remove the need
++# for setting LD_LIBRARY_PATH in a wrapper.
++def FindInstantClientIPSLib():
++    global versions
++    for path in glob.glob(os.path.join(ipsBaseLibDir, "[0-9.]*")):
++        versions.append(os.path.basename(path))
++    versions.sort(key = lambda x: [int(s) for s in x.split(".")])
++    versions.reverse()
++    for version in versions:
++        path = os.path.join(ipsBaseLibDir, version)
++        if os.path.exists(path) and CheckOracleHome(path):
++            return path
++
++# If the lib dir appears to be an Instant Client IPS dir, then look only
++# for matching SDK headers
++def FindInstantClientIPSInclude(libDir):
++    includeDir = os.path.join("/usr/include/oracle", versions[0])
++    if os.path.isfile(os.path.join(includeDir, "oci.h")):
++        return [includeDir]
++    raise DistutilsSetupError("cannot locate Oracle Instant Client " \
++            "SDK RPM header files")
++
++# Now we can define path components for the Solaris 11.x++ Instant Client
++# delivered via IPS.
++#
++# We build cx_Oracle as 32bit if we're running python2.7, and
++# 64bit if we're running python3.4 or later. That, however,
++# doesn't matter when finding the libraries since the IPS package
++# ships with both 32- and 64-bit libraries.
++ipsBaseLibDir = "/usr/oracle/instantclient"
++instantClientIPSLib = None
++
++
+ # try to determine the Oracle home
+ userOracleHome = os.environ.get("ORACLE_HOME")
+ if userOracleHome is not None:
+     if not CheckOracleHome(userOracleHome):
+         messageFormat = "Oracle home (%s) does not refer to an " \
+-                "10g, 11g or 12c installation."
++                "10g, 11g or 12c installation.\n"
+         raise DistutilsSetupError(messageFormat % userOracleHome)
+ else:
+     for path in os.environ["PATH"].split(os.pathsep):
+         if CheckOracleHome(path):
+             break
+-    if oracleHome is None and sys.platform.startswith("linux"):
+-        instantClientRPMLib = FindInstantClientRPMLib()
+     if oracleHome is None:
++        if sys.platform.startswith("linux"):
++            instantClientRPMLib = FindInstantClientRPMLib()
++        elif sys.platform.startswith("sunos5"):
++            instantClientIPSLib = FindInstantClientIPSLib()
++    else:
++        # oracleHome is None
+         raise DistutilsSetupError("cannot locate an Oracle software " \
+                 "installation")
+ 
+@@ -199,6 +260,8 @@
+     libs = ["clntsh"]
+     if instantClientRPMLib is not None:
+         includeDirs = FindInstantClientRPMInclude(instantClientRPMLib)
++    elif instantClientIPSLib is not None:
++        includeDirs = FindInstantClientIPSInclude(instantClientIPSLib)
+     else:
+         possibleIncludeDirs = ["rdbms/demo", "rdbms/public", "network/public",
+                 "sdk/include"]
+@@ -238,12 +301,19 @@
+ elif sys.platform == "darwin":
+     extraLinkArgs.append("-shared-libgcc")
+ 
+-# force the inclusion of an RPATH linker directive if desired; this will
+-# eliminate the need for setting LD_LIBRARY_PATH but it also means that this
+-# location will be the only location searched for the Oracle client library
+-if "FORCE_RPATH" in os.environ or instantClientRPMLib:
++# Eliminate the need for setting LD_LIBRARY_PATH in a wrapper script
++# by baking in a RUNPATH (aka RPATH)
++if sys.platform.startswith("sunos5"):
++    extraLinkArgs.append("-R%s" % oracleLibDir)
++else:
+     extraLinkArgs.append("-Wl,-rpath,%s" % oracleLibDir)
+ 
++# If we're running as a 64bit python interpreter, we need to ensure that
++# we get the compiler and linker to generate 64bit code too.
++if bitness == 64:
++    extraCompileArgs.append("-m64")
++    extraLinkArgs.append("-m64")
++
+ # tweak distribution full name to include the Oracle version
+ class Distribution(distutils.dist.Distribution):
+