2929import sh
3030from sh import ErrorReturnCode
3131
32+ from s2e_env import CONSTANTS
3233from s2e_env .command import EnvCommand , CommandError
33-
34+ from s2e_env . utils . host import get_os_version
3435
3536logger = logging .getLogger ('build' )
3637
3738
39+ def _get_clang_version ():
40+ default = CONSTANTS ["clang_versions" ]["default" ]
41+ os_name , os_version = get_os_version ()
42+ version = CONSTANTS ["clang_versions" ].get (f"{ os_name } -{ os_version } " , None )
43+ if version :
44+ logger .info ('Using clang-%s to build S2E' , version )
45+ return version
46+
47+ logger .info ('Using clang-%s to build S2E' , default )
48+ return default
49+
50+
3851class Command (EnvCommand ):
3952 """
4053 Builds S2E.
@@ -60,20 +73,53 @@ def add_arguments(self, parser):
6073 help = 'List of S2E components to clean prior to '
6174 'the build process' )
6275
63- def handle (self , * args , ** options ):
76+ def _build_tools (self , build_dir ):
77+ makefile = self .env_path ('source' , 's2e' , 'Makefile.tools' )
78+ if not os .path .isfile (makefile ):
79+ raise CommandError (f'{ makefile } not found' )
80+
81+ try :
82+ logger .info ('Generating S2E build environment Docker image' )
83+ docker = sh .Command ('docker' )
84+
85+ docker (
86+ "build" ,
87+ "--target" , "s2e-build-env" ,
88+ "-t" , "s2e-build-env" ,
89+ "." ,
90+ _out = sys .stdout ,
91+ _err = sys .stderr ,
92+ _cwd = self .env_path ('source' , 's2e' )
93+ )
94+
95+ logger .info ('Building S2E tools in %s' , build_dir )
96+ docker (
97+ "run" , "-t" , "--rm" ,
98+ "-e" , "SYSTEM_CLANG_VERSION=15" ,
99+ "-e" , f"S2E_PREFIX={ self .install_path ()} " ,
100+ "-w" , build_dir ,
101+ "-v" , f"{ self .env_path ()} :{ self .env_path ()} " ,
102+ "s2e-build-env" ,
103+ "/run_as.sh" , os .getuid (), os .getgid (),
104+ "make" , "-f" , makefile , "install" ,
105+ _out = sys .stdout ,
106+ _err = sys .stderr
107+ )
108+ except ErrorReturnCode as e :
109+ raise CommandError (e ) from e
110+
111+ logger .success ('S2E tools built' )
112+
113+ def _build_s2e (self , build_dir , ** options ):
64114 # Exit if the makefile doesn't exist
65115 makefile = self .env_path ('source' , 'Makefile' )
66116 if not os .path .isfile (makefile ):
67- raise CommandError (f'No makefile found in { os .path .dirname (makefile )} ' )
68-
69- # If the build directory doesn't exist, create it
70- build_dir = self .env_path ('build' )
71- if not os .path .isdir (build_dir ):
72- os .mkdir (build_dir )
117+ raise CommandError (f'{ makefile } not found' )
73118
74119 # Set up some environment variables
75120 env_vars = os .environ .copy ()
76121 env_vars ['S2E_PREFIX' ] = self .install_path ()
122+ env_vars ['SYSTEM_CLANG_VERSION' ] = f"{ _get_clang_version ()} "
77123
78124 components = options ['components' ]
79125 self ._make = sh .Command ('make' ).bake (directory = build_dir , file = makefile , _env = env_vars )
@@ -96,6 +142,15 @@ def handle(self, *args, **options):
96142
97143 logger .success ('S2E built' )
98144
145+ def handle (self , * args , ** options ):
146+ # If the build directory doesn't exist, create it
147+ build_dir = self .env_path ('build' )
148+ if not os .path .isdir (build_dir ):
149+ os .mkdir (build_dir )
150+
151+ self ._build_tools (build_dir )
152+ self ._build_s2e (build_dir , ** options )
153+
99154 def _get_components (self , target ):
100155 lines = self ._make (target ).strip ().split ('\n ' )
101156 print (lines )
0 commit comments