@@ -59,6 +59,7 @@ def clean
59
59
observe_file_removal info_dir_file
60
60
end
61
61
62
+ rewrite_pkgconfig
62
63
rewrite_shebangs
63
64
clean_python_metadata
64
65
@@ -153,6 +154,48 @@ def clean_dir(directory)
153
154
end
154
155
end
155
156
157
+ sig { void }
158
+ def rewrite_pkgconfig
159
+ basepath = @formula . prefix . realpath
160
+ pc_files = %w[ lib share ] . flat_map do |subdir |
161
+ pc_dir = basepath /subdir /"pkgconfig"
162
+ next [ ] if !pc_dir . exist? || @formula . skip_clean? ( basepath /subdir ) || @formula . skip_clean? ( pc_dir )
163
+
164
+ pc_dir . glob ( "*.pc" ) . reject { |pc_file | @formula . skip_clean? ( pc_file ) }
165
+ end
166
+ return if pc_files . empty?
167
+
168
+ # TODO: Add support for `brew unlink`-ed formulae and check on recursive dependencies
169
+ deps_pc_files = @formula . deps
170
+ . filter_map { |dep | dep . to_formula if !dep . build? && !dep . test? }
171
+ . select ( &:keg_only? )
172
+ . flat_map { |f | f . opt_prefix . glob ( "{lib,share}/pkgconfig/*.pc" ) }
173
+ . to_h { |pc_file | [ pc_file . basename ( ".pc" ) . to_s . downcase , pc_file . to_s ] }
174
+ deps_pc_modules_pattern = deps_pc_files . keys . map { |mod | Regexp . escape ( mod ) } . join ( "|" )
175
+
176
+ pc_files . each do |pc_file |
177
+ modified_lines = pc_file . each_line . map do |line |
178
+ rewrote_prefix = line . gsub! ( @formula . prefix . realpath . to_s , @formula . opt_prefix . to_s ) . present?
179
+ next [ line , rewrote_prefix ] if deps_pc_files . empty? || !line . start_with? ( /Requires(?:\. private)?:/ )
180
+
181
+ # pkgconf's pc.5 man page defines dependency list ABNF syntax as:
182
+ #
183
+ # > package-list = *WSP *( package-spec *( package-sep ) )
184
+ # > package-sep = WSP / ","
185
+ # > package-spec = package-key [ ver-op package-version ]
186
+ # > ver-op = "<" / "<=" / "=" / "!=" / ">=" / ">"
187
+ #
188
+ # A simplified regular expression is used to lookahead/lookbehind for common
189
+ # separator characters to extract the modules used in Requires/Requires.private
190
+ rewrote_module = line . gsub! ( /(?<=[:,\s ])(#{ deps_pc_modules_pattern } )(?=[<=>!,\s ])/io , deps_pc_files ) . present?
191
+ [ line , rewrote_prefix || rewrote_module ]
192
+ end
193
+ next if modified_lines . none? ( &:second )
194
+
195
+ pc_file . atomic_write ( modified_lines . map ( &:first ) . join )
196
+ end
197
+ end
198
+
156
199
sig { void }
157
200
def rewrite_shebangs
158
201
require "language/node"
0 commit comments