|
1 This patch provides support for finding the Oracle Instant Client |
|
2 libraries (and sdk) delivered via IPS. It also forces the specification |
|
3 of an RPATH so that the cx_Oracle module links against the IPS- |
|
4 delivered Instant Client packages. |
|
5 |
|
6 This patch has not yet been integrated with upstream. |
|
7 |
|
8 |
|
9 --- cx_Oracle-5.2/setup.py.orig Fri Apr 3 21:10:29 2015 |
|
10 +++ cx_Oracle-5.2/setup.py Fri Sep 11 17:23:39 2015 |
|
11 @@ -61,9 +61,17 @@ |
|
12 # define the list of files to be included as documentation for bdist_rpm |
|
13 docFiles = "README.txt BUILD.txt samples test" |
|
14 |
|
15 +# Globalize some variables |
|
16 +subDirs = [] |
|
17 +versions = [] |
|
18 +if struct.calcsize("P") == 4: |
|
19 + bitness = 32 |
|
20 +else: |
|
21 + bitness = 64 |
|
22 + |
|
23 # method for checking a potential Oracle home |
|
24 def CheckOracleHome(directoryToCheck): |
|
25 - global oracleHome, oracleVersion, oracleLibDir |
|
26 + global oracleHome, oracleVersion, oracleLibDir, subDirs, versions |
|
27 import os |
|
28 import struct |
|
29 import sys |
|
30 @@ -81,8 +89,19 @@ |
|
31 ("11g", "libclntsh.dylib.11.1"), |
|
32 ("10g", "libclntsh.dylib.10.1") |
|
33 ] |
|
34 + elif sys.platform == "sunos5": |
|
35 + if bitness == 32: |
|
36 + # 32bit |
|
37 + subDirs = ["lib"] |
|
38 + else: |
|
39 + subDirs = ["lib/64", "lib"] |
|
40 + filesToCheck = [ |
|
41 + ("12c", "libclntsh.so.12.1"), |
|
42 + ("11g", "libclntsh.so.11.1"), |
|
43 + ("10g", "libclntsh.so.10.1") |
|
44 + ] |
|
45 else: |
|
46 - if struct.calcsize("P") == 4: |
|
47 + if bitness == 32: |
|
48 subDirs = ["lib", "lib32"] |
|
49 else: |
|
50 subDirs = ["lib", "lib64"] |
|
51 @@ -124,7 +143,7 @@ |
|
52 # Older Instant Client dirs have the form: |
|
53 # /usr/lib/oracle/10.2.0.5/client[64]/lib |
|
54 def FindInstantClientRPMLib(): |
|
55 - versions = [] |
|
56 + global versions |
|
57 for path in glob.glob(os.path.join(rpmBaseLibDir, "[0-9.]*")): |
|
58 versions.append(os.path.basename(path)) |
|
59 versions.sort(key = lambda x: [int(s) for s in x.split(".")]) |
|
60 @@ -147,26 +166,68 @@ |
|
61 # define Linux Instant Client RPM path components |
|
62 # Assume 64 bit builds if the platform is 64 bit |
|
63 rpmBaseLibDir = "/usr/lib/oracle" |
|
64 -if struct.calcsize("P") == 4: |
|
65 +if bitness == 32: |
|
66 rpmClientDir = "client" |
|
67 else: |
|
68 rpmClientDir = "client64" |
|
69 instantClientRPMLib = None |
|
70 |
|
71 +# |
|
72 +# Solaris 11.x and later make use of the Image Packaging System, IPS, |
|
73 +# and can install Instant Client 12.1 (and later versions) using that |
|
74 +# format. IPS-delivered versions exist under |
|
75 +# /usr/oracle/instantclient/[version] |
|
76 +# which allows us to bake an rpath into this module and remove the need |
|
77 +# for setting LD_LIBRARY_PATH in a wrapper. |
|
78 +def FindInstantClientIPSLib(): |
|
79 + global versions |
|
80 + for path in glob.glob(os.path.join(ipsBaseLibDir, "[0-9.]*")): |
|
81 + versions.append(os.path.basename(path)) |
|
82 + versions.sort(key = lambda x: [int(s) for s in x.split(".")]) |
|
83 + versions.reverse() |
|
84 + for version in versions: |
|
85 + path = os.path.join(ipsBaseLibDir, version) |
|
86 + if os.path.exists(path) and CheckOracleHome(path): |
|
87 + return path |
|
88 + |
|
89 +# If the lib dir appears to be an Instant Client IPS dir, then look only |
|
90 +# for matching SDK headers |
|
91 +def FindInstantClientIPSInclude(libDir): |
|
92 + includeDir = os.path.join("/usr/include/oracle", versions[0]) |
|
93 + if os.path.isfile(os.path.join(includeDir, "oci.h")): |
|
94 + return [includeDir] |
|
95 + raise DistutilsSetupError("cannot locate Oracle Instant Client " \ |
|
96 + "SDK RPM header files") |
|
97 + |
|
98 +# Now we can define path components for the Solaris 11.x++ Instant Client |
|
99 +# delivered via IPS. |
|
100 +# |
|
101 +# We build cx_Oracle as 32bit if we're running python2.7, and |
|
102 +# 64bit if we're running python3.4 or later. That, however, |
|
103 +# doesn't matter when finding the libraries since the IPS package |
|
104 +# ships with both 32- and 64-bit libraries. |
|
105 +ipsBaseLibDir = "/usr/oracle/instantclient" |
|
106 +instantClientIPSLib = None |
|
107 + |
|
108 + |
|
109 # try to determine the Oracle home |
|
110 userOracleHome = os.environ.get("ORACLE_HOME") |
|
111 if userOracleHome is not None: |
|
112 if not CheckOracleHome(userOracleHome): |
|
113 messageFormat = "Oracle home (%s) does not refer to an " \ |
|
114 - "10g, 11g or 12c installation." |
|
115 + "10g, 11g or 12c installation.\n" |
|
116 raise DistutilsSetupError(messageFormat % userOracleHome) |
|
117 else: |
|
118 for path in os.environ["PATH"].split(os.pathsep): |
|
119 if CheckOracleHome(path): |
|
120 break |
|
121 - if oracleHome is None and sys.platform.startswith("linux"): |
|
122 - instantClientRPMLib = FindInstantClientRPMLib() |
|
123 if oracleHome is None: |
|
124 + if sys.platform.startswith("linux"): |
|
125 + instantClientRPMLib = FindInstantClientRPMLib() |
|
126 + elif sys.platform.startswith("sunos5"): |
|
127 + instantClientIPSLib = FindInstantClientIPSLib() |
|
128 + else: |
|
129 + # oracleHome is None |
|
130 raise DistutilsSetupError("cannot locate an Oracle software " \ |
|
131 "installation") |
|
132 |
|
133 @@ -199,6 +260,8 @@ |
|
134 libs = ["clntsh"] |
|
135 if instantClientRPMLib is not None: |
|
136 includeDirs = FindInstantClientRPMInclude(instantClientRPMLib) |
|
137 + elif instantClientIPSLib is not None: |
|
138 + includeDirs = FindInstantClientIPSInclude(instantClientIPSLib) |
|
139 else: |
|
140 possibleIncludeDirs = ["rdbms/demo", "rdbms/public", "network/public", |
|
141 "sdk/include"] |
|
142 @@ -238,12 +301,19 @@ |
|
143 elif sys.platform == "darwin": |
|
144 extraLinkArgs.append("-shared-libgcc") |
|
145 |
|
146 -# force the inclusion of an RPATH linker directive if desired; this will |
|
147 -# eliminate the need for setting LD_LIBRARY_PATH but it also means that this |
|
148 -# location will be the only location searched for the Oracle client library |
|
149 -if "FORCE_RPATH" in os.environ or instantClientRPMLib: |
|
150 +# Eliminate the need for setting LD_LIBRARY_PATH in a wrapper script |
|
151 +# by baking in a RUNPATH (aka RPATH) |
|
152 +if sys.platform.startswith("sunos5"): |
|
153 + extraLinkArgs.append("-R%s" % oracleLibDir) |
|
154 +else: |
|
155 extraLinkArgs.append("-Wl,-rpath,%s" % oracleLibDir) |
|
156 |
|
157 +# If we're running as a 64bit python interpreter, we need to ensure that |
|
158 +# we get the compiler and linker to generate 64bit code too. |
|
159 +if bitness == 64: |
|
160 + extraCompileArgs.append("-m64") |
|
161 + extraLinkArgs.append("-m64") |
|
162 + |
|
163 # tweak distribution full name to include the Oracle version |
|
164 class Distribution(distutils.dist.Distribution): |
|
165 |