2020
2121import io
2222import os
23+ import sys
2324import ssl
2425import glob
2526import shutil
@@ -126,8 +127,7 @@ def extract(self, overwrite=True):
126127 if os .path .exists (zipfold ):
127128 if not overwrite :
128129 raise OSError ("folder '{0}' already exists" .format (zipfold ))
129- else :
130- shutil .rmtree (zipfold )
130+ shutil .rmtree (zipfold )
131131
132132 # Decompress zip file.
133133 with contextlib .closing (ZipFile (zippath , "r" )) as fd :
@@ -137,16 +137,6 @@ def extract(self, overwrite=True):
137137 for path in sorted (glob .glob (os .path .join (zipfold , "tools" , "*.sh" ))):
138138 os .chmod (path , 0o755 )
139139
140- # Patch CMakeLists so that libgeos_c.so does not depend on libgeos.so.
141- cmakefile = os .path .join (zipfold , "capi" , "CMakeLists.txt" )
142- with io .open (cmakefile , "r" , encoding = "utf-8" ) as fd :
143- lines = fd .readlines ()
144- with io .open (cmakefile , "wb" ) as fd :
145- oldtext = "target_link_libraries(geos_c geos)"
146- newtext = "target_link_libraries(geos_c geos-static)"
147- for line in lines :
148- fd .write (line .replace (oldtext , newtext ).encode ())
149-
150140 # Apply specific patches for GEOS < 3.6.0.
151141 if self .version_tuple < (3 , 6 , 0 ):
152142 # The SVN revision file is not created on the fly before 3.6.0.
@@ -166,66 +156,121 @@ def extract(self, overwrite=True):
166156 for line in lines :
167157 fd .write (line .replace (oldtext , newtext ).encode ())
168158
159+ # Apply specific patches for 3.6.0 <= GEOS < 3.7.0 on Windows.
160+ if (3 , 6 , 0 ) <= self .version_tuple < (3 , 7 , 0 ) and os .name == "nt" :
161+ autogen_file = os .path .join (zipfold , "autogen.bat" )
162+ subprocess .call ([autogen_file ], cwd = zipfold )
163+ cppfile = os .path .join (zipfold , "src" , "geomgraph" , "DirectedEdgeStar.cpp" )
164+ with io .open (cppfile , "r" , encoding = "utf-8" ) as fd :
165+ lines = fd .readlines ()
166+ with io .open (cppfile , "wb" ) as fd :
167+ oldtext = "DirectedEdgeStar::print() const"
168+ newtext = oldtext .replace (" const" , "" )
169+ for line in lines :
170+ fd .write (line .replace (oldtext , newtext ).encode ())
171+ hfile = os .path .join (zipfold , "include" , "geos" , "geomgraph" , "DirectedEdgeStar.h" )
172+ with io .open (hfile , "r" , encoding = "utf-8" ) as fd :
173+ lines = fd .readlines ()
174+ with io .open (hfile , "wb" ) as fd :
175+ oldtext = "virtual std::string print() const;"
176+ newtext = oldtext .replace (" const" , "" )
177+ for line in lines :
178+ fd .write (line .replace (oldtext , newtext ).encode ())
179+
180+ # Patch CMakeLists to link shared geos_c with static geos.
181+ if self .version_tuple < (3 , 8 , 0 ):
182+ cmakefile = os .path .join (zipfold , "capi" , "CMakeLists.txt" )
183+ oldtext = "target_link_libraries(geos_c geos)"
184+ newtext = "target_link_libraries(geos_c geos-static)"
185+ else :
186+ cmakefile = os .path .join (zipfold , "CMakeLists.txt" )
187+ oldtext = 'add_library(geos "")'
188+ newtext = 'add_library(geos STATIC "")'
189+ with io .open (cmakefile , "r" , encoding = "utf-8" ) as fd :
190+ lines = fd .readlines ()
191+ with io .open (cmakefile , "wb" ) as fd :
192+ found_sharedline = False
193+ shared_oldtext = "if(BUILD_SHARED_LIBS)"
194+ shared_newtext = "if(FALSE)"
195+ for line in lines :
196+ if not found_sharedline and shared_oldtext in line :
197+ line = line .replace (shared_oldtext , shared_newtext )
198+ found_sharedline = True
199+ fd .write (line .replace (oldtext , newtext ).encode ())
200+
201+ # Patch doc CMakeLists in GEOS 3.8.x series.
202+ if (3 , 8 , 0 ) <= self .version_tuple < (3 , 9 , 0 ):
203+ cmakefile = os .path .join (zipfold , "doc" , "CMakeLists.txt" )
204+ oldtext1 = "target_include_directories(test_geos_unit\n "
205+ newtext1 = "if(BUILD_TESTING)\n {0}" .format (oldtext1 )
206+ oldtext2 = "$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}>)\n "
207+ newtext2 = "{0}endif()\n " .format (oldtext2 )
208+ with io .open (cmakefile , "r" , encoding = "utf-8" ) as fd :
209+ lines = fd .readlines ()
210+ with io .open (cmakefile , "wb" ) as fd :
211+ for line in lines :
212+ line = line .replace (oldtext1 , newtext1 )
213+ line = line .replace (oldtext2 , newtext2 )
214+ fd .write (line .encode ())
215+
169216 def build (self , installdir = None , njobs = 1 ):
170217 """Build and install GEOS from source."""
171218
172219 # Download and extract zip file if not present.
173220 zipfold = os .path .join (self .root , "geos-{0}" .format (self .version ))
174221 self .extract (overwrite = True )
222+ version = self .version_tuple
175223
176- # Define build directory.
224+ # Define build and install directory.
177225 builddir = os .path .join (zipfold , "build" )
178-
179- # Define installation directory.
180226 if installdir is None :
181227 installdir = os .path .expanduser ("~/.local/share/libgeos" )
182228 installdir = os .path .abspath (installdir )
183229
184- # Define configure options.
230+ # Define generic configure and build options.
185231 config_opts = [
186- "-DCMAKE_INSTALL_PREFIX={0}" .format (installdir ),
187- "-DGEOS_ENABLE_TESTS=OFF" ,
188232 "-DCMAKE_BUILD_TYPE=Release" ,
233+ "-DCMAKE_INSTALL_PREFIX={0}" .format (installdir ),
234+ "-D{0}=OFF" .format ("GEOS_ENABLE_TESTS" if version < (3 , 8 , 0 )
235+ else "BUILD_TESTING" )
189236 ]
190- if os .name == "nt" and self .version_tuple < (3 , 6 , 0 ):
191- config_opts = ["-G" , "NMake Makefiles" ] + config_opts
192-
193- # Define build options.
194- build_env = os .environ .copy ()
195237 build_opts = [
196238 "--config" , "Release" ,
197239 "--target" , "install" ,
198240 ]
199- if os .name != "nt" :
200- build_env ["MAKEFLAGS" ] = "-j {0:d}" .format (njobs )
201- elif self .version_tuple < (3 , 6 , 0 ):
202- win64 = (8 * struct .calcsize ("P" ) == 64 )
203- build_opts .extend ([
204- "--" ,
205- "WIN64={0}" .format ("YES" if win64 else "NO" ),
206- "BUILD_BATCH={0}" .format ("YES" if njobs > 1 else "NO" ),
207- ])
241+ build_env = os .environ .copy ()
242+
243+ # Define custom configure and build options.
244+ if os .name == "nt" :
245+ config_opts += ["-DCMAKE_CXX_FLAGS='/wd4251 /wd4458 /wd4530'" ]
246+ if version >= (3 , 6 , 0 ) and sys .version_info [:2 ] >= (3 , 3 ):
247+ build_opts = ["-j" , "{0:d}" .format (njobs )] + build_opts
248+ else :
249+ win64 = (8 * struct .calcsize ("P" ) == 64 )
250+ config_opts = ["-G" , "NMake Makefiles" ] + config_opts
251+ build_opts .extend ([
252+ "--" ,
253+ "WIN64={0}" .format ("YES" if win64 else "NO" ),
254+ "BUILD_BATCH={0}" .format ("YES" if njobs > 1 else "NO" ),
255+ ])
256+ if sys .version_info [:2 ] < (3 , 3 ):
257+ build_opts += ["MSVC_VER=1500" ]
208258 else :
209- build_opts = ["-j" , "{0:d}" .format (njobs )] + build_opts
259+ build_env ["MAKEFLAGS" ] = "-j {0:d}" .format (njobs )
260+ if version >= (3 , 7 , 0 ):
261+ config_opts += ["-DCMAKE_CXX_FLAGS='-fPIC'" ]
210262
211- # Now move to the GEOS source code folder and build with CMake.
212- cwd = os .getcwd ()
263+ # Call cmake configure after ensuring that the build directory exists.
213264 try :
214- # Ensure that the build directory exists.
215- try :
216- os .makedirs (builddir )
217- except OSError :
218- pass
219- os .chdir (builddir )
220- # Call cmake configure.
221- subprocess .call (["cmake" , ".." ] + config_opts )
222- # Ensure that the install directory exists.
223- try :
224- os .makedirs (installdir )
225- except OSError :
226- pass
227- # Call cmake build and install.
228- subprocess .call (["cmake" , "--build" , "." ] + build_opts ,
229- env = build_env )
230- finally :
231- os .chdir (cwd )
265+ os .makedirs (builddir )
266+ except OSError :
267+ pass
268+ subprocess .call (["cmake" , ".." ] + config_opts , cwd = builddir )
269+
270+ # Call cmake build after ensuring that the install directory exists.
271+ try :
272+ os .makedirs (installdir )
273+ except OSError :
274+ pass
275+ subprocess .call (["cmake" , "--build" , "." ] + build_opts ,
276+ cwd = builddir , env = build_env )
0 commit comments