Skip to content

Commit 7caeccc

Browse files
authored
Add mergeback for -D and -W cflags to match pkgconf behavior (#43)
When multiple packages have the same -D or -W flags, pkgconf removes previous occurrences and keeps only the last one (merge back). This prevents flag duplication like "-DNOMINMAX" appearing many times. ```console $ pkgconf --cflags re2 -pthread -DNOMINMAX $ ruby -r pkg-config -e 'puts PKGConfig.cflags("re2")' -pthread -DNOMINMAX -DNOMINMAX -DNOMINMAX ... ``` Flags excluded from merge back (kept as duplicates): - -Wa, (assembler options) - -Wl, (linker options) - -Wp, (preprocessor options) This PR only supports merge back for -D and -W flags. Other flags that pkgconf also merges back are not yet supported.
1 parent ca9ad8a commit 7caeccc

File tree

2 files changed

+57
-0
lines changed

2 files changed

+57
-0
lines changed

lib/pkg-config.rb

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,7 @@ def collect_cflags
545545
flag.gsub(/\A-I/, "/I")
546546
end
547547
end
548+
other_flags = merge_back_cflags(other_flags)
548549
[path_flags, other_flags]
549550
end
550551

@@ -579,6 +580,32 @@ def normalize_cflags(cflags)
579580
normalized_cflags
580581
end
581582

583+
# Implementing behavior compatible with pkgconf's pkgconf_fragment_copy().
584+
# This is not a complete reproduction yet, but the goal is to stay compatible.
585+
# https://github.com/pkgconf/pkgconf/blob/pkgconf-2.5.1/libpkgconf/fragment.c#L381-L416
586+
def merge_back_cflags(cflags)
587+
merge_backed_cflags = []
588+
cflags.each do |cflag|
589+
if mergeable_flag?(cflag)
590+
# NOTE: This may be slow because this checks merge_back_cflags N times
591+
# (where N is the number of mergeable flags).
592+
merge_backed_cflags.delete(cflag)
593+
end
594+
merge_backed_cflags << cflag
595+
end
596+
merge_backed_cflags
597+
end
598+
599+
def mergeable_flag?(flag)
600+
return false unless flag.start_with?("-")
601+
return true if flag.start_with?("-D")
602+
if flag.start_with?("-W")
603+
return false if flag.start_with?("-Wa,", "-Wl,", "-Wp,")
604+
return true
605+
end
606+
false
607+
end
608+
582609
def collect_libs
583610
target_packages = [*required_packages, self]
584611
libs_set = []

test/test-pkg-config.rb

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,4 +314,34 @@ def test_equals_to
314314
parse_requires("fribidi = 1.0"))
315315
end
316316
end
317+
318+
sub_test_case("#merge_back_cflags") do
319+
def merge_back_cflags(cflags)
320+
@glib.__send__(:merge_back_cflags, cflags)
321+
end
322+
323+
def test_d
324+
assert_equal(["-DFOO"],
325+
merge_back_cflags(["-DFOO", "-DFOO"]))
326+
end
327+
328+
def test_w
329+
assert_equal(["-Wno-unknown-warning-option"],
330+
merge_back_cflags(["-Wno-unknown-warning-option",
331+
"-Wno-unknown-warning-option"]))
332+
end
333+
334+
def test_wa_wl_wp
335+
assert_equal(["-Wa,--noexecstack", "-Wl,--as-needed", "-Wp,-DFOO",
336+
"-Wa,--noexecstack", "-Wl,--as-needed", "-Wp,-DFOO"],
337+
merge_back_cflags(["-Wa,--noexecstack", "-Wl,--as-needed", "-Wp,-DFOO",
338+
"-Wa,--noexecstack", "-Wl,--as-needed", "-Wp,-DFOO"]))
339+
end
340+
341+
def test_mixed
342+
assert_equal(["-Wl,--as-needed", "-DFOO", "-Wall", "-Wl,--as-needed"],
343+
merge_back_cflags(["-DFOO", "-Wall", "-Wl,--as-needed",
344+
"-DFOO", "-Wall", "-Wl,--as-needed"]))
345+
end
346+
end
317347
end

0 commit comments

Comments
 (0)