diff --git a/lib/pkg-config.rb b/lib/pkg-config.rb index 197af8b..d46994e 100644 --- a/lib/pkg-config.rb +++ b/lib/pkg-config.rb @@ -545,6 +545,7 @@ def collect_cflags flag.gsub(/\A-I/, "/I") end end + other_flags = merge_back_cflags(other_flags) [path_flags, other_flags] end @@ -579,6 +580,32 @@ def normalize_cflags(cflags) normalized_cflags end + # Implementing behavior compatible with pkgconf's pkgconf_fragment_copy(). + # This is not a complete reproduction yet, but the goal is to stay compatible. + # https://github.com/pkgconf/pkgconf/blob/pkgconf-2.5.1/libpkgconf/fragment.c#L381-L416 + def merge_back_cflags(cflags) + merge_backed_cflags = [] + cflags.each do |cflag| + if mergeable_flag?(cflag) + # NOTE: This may be slow because this checks merge_back_cflags N times + # (where N is the number of mergeable flags). + merge_backed_cflags.delete(cflag) + end + merge_backed_cflags << cflag + end + merge_backed_cflags + end + + def mergeable_flag?(flag) + return false unless flag.start_with?("-") + return true if flag.start_with?("-D") + if flag.start_with?("-W") + return false if flag.start_with?("-Wa,", "-Wl,", "-Wp,") + return true + end + false + end + def collect_libs target_packages = [*required_packages, self] libs_set = [] diff --git a/test/test-pkg-config.rb b/test/test-pkg-config.rb index eace04b..67893b3 100644 --- a/test/test-pkg-config.rb +++ b/test/test-pkg-config.rb @@ -314,4 +314,34 @@ def test_equals_to parse_requires("fribidi = 1.0")) end end + + sub_test_case("#merge_back_cflags") do + def merge_back_cflags(cflags) + @glib.__send__(:merge_back_cflags, cflags) + end + + def test_d + assert_equal(["-DFOO"], + merge_back_cflags(["-DFOO", "-DFOO"])) + end + + def test_w + assert_equal(["-Wno-unknown-warning-option"], + merge_back_cflags(["-Wno-unknown-warning-option", + "-Wno-unknown-warning-option"])) + end + + def test_wa_wl_wp + assert_equal(["-Wa,--noexecstack", "-Wl,--as-needed", "-Wp,-DFOO", + "-Wa,--noexecstack", "-Wl,--as-needed", "-Wp,-DFOO"], + merge_back_cflags(["-Wa,--noexecstack", "-Wl,--as-needed", "-Wp,-DFOO", + "-Wa,--noexecstack", "-Wl,--as-needed", "-Wp,-DFOO"])) + end + + def test_mixed + assert_equal(["-Wl,--as-needed", "-DFOO", "-Wall", "-Wl,--as-needed"], + merge_back_cflags(["-DFOO", "-Wall", "-Wl,--as-needed", + "-DFOO", "-Wall", "-Wl,--as-needed"])) + end + end end