@@ -58,9 +58,46 @@ def _build_contract_data(compilation_unit: "CompilationUnit") -> dict:
5858 return contracts
5959
6060
61+ def _export_link_info (compilation_unit : "CompilationUnit" , key : str , export_dir : str ) -> str :
62+ """Export linking information to a separate file.
63+
64+ Args:
65+ compilation_unit (CompilationUnit): Compilation unit to export
66+ key (str): Filename Id
67+ export_dir (str): Export directory
68+
69+ Returns:
70+ str: path to the generated file"""
71+
72+ autolink_path = os .path .join (export_dir , f"{ key } .link" )
73+
74+ # Get library addresses if they exist
75+ library_addresses = {}
76+ if compilation_unit .crytic_compile .libraries :
77+ library_addresses = {
78+ name : f"0x{ addr :040x} "
79+ for name , addr in compilation_unit .crytic_compile .libraries .items ()
80+ }
81+
82+ # Filter deployment order to only include libraries that have addresses
83+ full_deployment_order = compilation_unit .crytic_compile .deployment_order or []
84+ filtered_deployment_order = [lib for lib in full_deployment_order if lib in library_addresses ]
85+
86+ # Create autolink output with deployment order and library addresses
87+ autolink_output = {
88+ "deployment_order" : filtered_deployment_order ,
89+ "library_addresses" : library_addresses ,
90+ }
91+
92+ with open (autolink_path , "w" , encoding = "utf8" ) as file_desc :
93+ json .dump (autolink_output , file_desc , indent = 2 )
94+
95+ return autolink_path
96+
97+
6198def export_to_solc_from_compilation_unit (
6299 compilation_unit : "CompilationUnit" , key : str , export_dir : str
63- ) -> str | None :
100+ ) -> list [ str ] | None :
64101 """Export the compilation unit to the standard solc output format.
65102 The exported file will be $key.json
66103
@@ -70,7 +107,7 @@ def export_to_solc_from_compilation_unit(
70107 export_dir (str): Export directory
71108
72109 Returns:
73- Optional[str]: path to the file generated
110+ Optional[List[ str]] : path to the files generated
74111 """
75112 contracts = _build_contract_data (compilation_unit )
76113
@@ -89,7 +126,15 @@ def export_to_solc_from_compilation_unit(
89126
90127 with open (path , "w" , encoding = "utf8" ) as file_desc :
91128 json .dump (output , file_desc )
92- return path
129+
130+ paths = [path ]
131+
132+ # Export link info if compile_autolink or compile_libraries was used
133+ if compilation_unit .crytic_compile .libraries :
134+ link_path = _export_link_info (compilation_unit , key , export_dir )
135+ paths .append (link_path )
136+
137+ return paths
93138 return None
94139
95140
@@ -111,17 +156,18 @@ def export_to_solc(crytic_compile: "CryticCompile", **kwargs: str) -> list[str]:
111156
112157 if len (crytic_compile .compilation_units ) == 1 :
113158 compilation_unit = list (crytic_compile .compilation_units .values ())[0 ]
114- path = export_to_solc_from_compilation_unit (compilation_unit , "combined_solc" , export_dir )
115- if path :
116- return [ path ]
159+ paths = export_to_solc_from_compilation_unit (compilation_unit , "combined_solc" , export_dir )
160+ if paths :
161+ return paths
117162 return []
118163
119- paths = []
164+ all_paths = []
120165 for key , compilation_unit in crytic_compile .compilation_units .items ():
121- path = export_to_solc_from_compilation_unit (compilation_unit , key , export_dir )
122- if path :
123- paths .append (path )
124- return paths
166+ paths = export_to_solc_from_compilation_unit (compilation_unit , key , export_dir )
167+ if paths :
168+ all_paths .extend (paths )
169+
170+ return all_paths
125171
126172
127173class Solc (AbstractPlatform ):
0 commit comments