11
11
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
12
# See the License for the specific language governing permissions and
13
13
# limitations under the License.
14
+ import copy
14
15
import glob
16
+ import json
15
17
import os
16
18
import pathlib
17
19
import re
18
20
import shutil
19
21
import subprocess
20
22
import sys
21
23
from distutils .cmd import Command
24
+ from distutils .dir_util import copy_tree
22
25
from pathlib import Path
23
26
from subprocess import CalledProcessError
24
27
25
- from setuptools import find_packages
28
+ from setuptools import find_packages , Extension
26
29
27
30
try :
28
31
from setuptools import setup
29
32
from setuptools .command .build_py import build_py
33
+ from setuptools .command .build_ext import build_ext as _build_ext
30
34
from setuptools .command .develop import develop
31
35
from setuptools .command .install import install
32
- from setuptools . dist import Distribution
36
+
33
37
except ImportError :
34
38
from distutils .command .build_py import build_py
39
+ from distutils .command .build_ext import build_ext as _build_ext
35
40
from distutils .core import setup
36
- from distutils .dist import Distribution
37
41
38
42
NAME = "feast"
39
43
DESCRIPTION = "Python SDK for Feast"
@@ -189,7 +193,7 @@ class BuildPythonProtosCommand(Command):
189
193
190
194
def initialize_options (self ):
191
195
self .python_protoc = [
192
- "python" ,
196
+ sys . executable ,
193
197
"-m" ,
194
198
"grpc_tools.protoc" ,
195
199
] # find_executable("protoc")
@@ -292,7 +296,7 @@ class BuildGoProtosCommand(Command):
292
296
293
297
def initialize_options (self ):
294
298
self .go_protoc = [
295
- "python" ,
299
+ sys . executable ,
296
300
"-m" ,
297
301
"grpc_tools.protoc" ,
298
302
] # find_executable("protoc")
@@ -331,45 +335,6 @@ def run(self):
331
335
self ._generate_go_protos (f"feast/{ sub_folder } /*.proto" )
332
336
333
337
334
- class BuildGoEmbeddedCommand (Command ):
335
- description = "Builds Go embedded library"
336
- user_options = []
337
-
338
- def initialize_options (self ) -> None :
339
- self .path_val = _generate_path_with_gopath ()
340
-
341
- self .go_env = {}
342
- for var in ("GOCACHE" , "GOPATH" ):
343
- self .go_env [var ] = subprocess \
344
- .check_output (["go" , "env" , var ]) \
345
- .decode ("utf-8" ) \
346
- .strip ()
347
-
348
- def finalize_options (self ) -> None :
349
- pass
350
-
351
- def _compile_embedded_lib (self ):
352
- print ("Compile embedded go" )
353
- subprocess .check_call ([
354
- "gopy" ,
355
- "build" ,
356
- "-output" ,
357
- "feast/embedded_go/lib" ,
358
- "-vm" ,
359
- # Path of current python executable
360
- sys .executable ,
361
- "-no-make" ,
362
- "github.com/feast-dev/feast/go/embedded"
363
- ], env = {
364
- "PATH" : self .path_val ,
365
- "CGO_LDFLAGS_ALLOW" : ".*" ,
366
- ** self .go_env ,
367
- })
368
-
369
- def run (self ):
370
- self ._compile_embedded_lib ()
371
-
372
-
373
338
class BuildCommand (build_py ):
374
339
"""Custom build command."""
375
340
@@ -378,7 +343,7 @@ def run(self):
378
343
if os .getenv ("COMPILE_GO" , "false" ).lower () == "true" :
379
344
_ensure_go_and_proto_toolchain ()
380
345
self .run_command ("build_go_protos" )
381
- self . run_command ( "build_go_lib" )
346
+
382
347
build_py .run (self )
383
348
384
349
@@ -390,15 +355,61 @@ def run(self):
390
355
if os .getenv ("COMPILE_GO" , "false" ).lower () == "true" :
391
356
_ensure_go_and_proto_toolchain ()
392
357
self .run_command ("build_go_protos" )
393
- self . run_command ( "build_go_lib" )
358
+
394
359
develop .run (self )
395
360
396
361
397
- class BinaryDistribution (Distribution ):
398
- """Distribution which forces a binary package with platform name
399
- when go compilation is enabled"""
400
- def has_ext_modules (self ):
401
- return os .getenv ("COMPILE_GO" , "false" ).lower () == "true"
362
+ class build_ext (_build_ext ):
363
+ def finalize_options (self ) -> None :
364
+ super ().finalize_options ()
365
+ if os .getenv ("COMPILE_GO" , "false" ).lower () == "false" :
366
+ self .extensions = [e for e in self .extensions if not self ._is_go_ext (e )]
367
+
368
+ def _is_go_ext (self , ext : Extension ):
369
+ return any (source .endswith ('.go' ) or source .startswith ('github' ) for source in ext .sources )
370
+
371
+ def build_extension (self , ext : Extension ):
372
+ if not self ._is_go_ext (ext ):
373
+ # the base class may mutate `self.compiler`
374
+ compiler = copy .deepcopy (self .compiler )
375
+ self .compiler , compiler = compiler , self .compiler
376
+ try :
377
+ return _build_ext .build_extension (self , ext )
378
+ finally :
379
+ self .compiler , compiler = compiler , self .compiler
380
+
381
+ bin_path = _generate_path_with_gopath ()
382
+ go_env = json .loads (
383
+ subprocess .check_output (["go" , "env" , "-json" ]).decode ("utf-8" ).strip ()
384
+ )
385
+
386
+ destination = os .path .dirname (os .path .abspath (self .get_ext_fullpath (ext .name )))
387
+ subprocess .check_call ([
388
+ "gopy" ,
389
+ "build" ,
390
+ "-output" ,
391
+ destination ,
392
+ "-vm" ,
393
+ sys .executable ,
394
+ "-no-make" ,
395
+ * ext .sources
396
+ ], env = {
397
+ "PATH" : bin_path ,
398
+ "CGO_LDFLAGS_ALLOW" : ".*" ,
399
+ ** go_env ,
400
+ })
401
+
402
+ def copy_extensions_to_source (self ):
403
+ build_py = self .get_finalized_command ('build_py' )
404
+ for ext in self .extensions :
405
+ fullname = self .get_ext_fullname (ext .name )
406
+ modpath = fullname .split ('.' )
407
+ package = '.' .join (modpath [:- 1 ])
408
+ package_dir = build_py .get_package_dir (package )
409
+ src = os .path .join (self .build_lib , package_dir )
410
+
411
+ # copy whole directory
412
+ copy_tree (src , package_dir )
402
413
403
414
404
415
setup (
@@ -453,9 +464,10 @@ def has_ext_modules(self):
453
464
cmdclass = {
454
465
"build_python_protos" : BuildPythonProtosCommand ,
455
466
"build_go_protos" : BuildGoProtosCommand ,
456
- "build_go_lib" : BuildGoEmbeddedCommand ,
457
467
"build_py" : BuildCommand ,
458
468
"develop" : DevelopCommand ,
469
+ "build_ext" : build_ext ,
459
470
},
460
- distclass = BinaryDistribution , # generate wheel with platform-specific name
471
+ ext_modules = [Extension ('feast.embedded_go.lib._embedded' ,
472
+ ["github.com/feast-dev/feast/go/embedded" ])],
461
473
)
0 commit comments