summaryrefslogtreecommitdiff
path: root/rules/CC
diff options
context:
space:
mode:
authorOliver Reiche <oliver.reiche@huawei.com>2023-01-20 16:20:30 +0100
committerOliver Reiche <oliver.reiche@huawei.com>2023-01-20 16:20:30 +0100
commit89b76f2558da0c41280b9eb389384824babfbef6 (patch)
tree489057736f3fcc4f9e14bcb27e14eb0effbd815a /rules/CC
parent25981eeccf645ddc6338bed0b159014f210f4326 (diff)
parente75f101e8b988adb458e594ffaaaebc0c01f65df (diff)
downloadrules-cc-89b76f2558da0c41280b9eb389384824babfbef6.tar.gz
Merge commit 'e75f101e8b988adb458e594ffaaaebc0c01f65df' into rules-cc
Diffstat (limited to 'rules/CC')
-rw-r--r--rules/CC/EXPRESSIONS384
-rw-r--r--rules/CC/RULES28
-rw-r--r--rules/CC/prebuilt/EXPRESSIONS186
-rw-r--r--rules/CC/prebuilt/RULES31
-rwxr-xr-xrules/CC/prebuilt/read_pkgconfig.py75
-rw-r--r--rules/CC/test/RULES8
6 files changed, 614 insertions, 98 deletions
diff --git a/rules/CC/EXPRESSIONS b/rules/CC/EXPRESSIONS
index cfbce42..5a425c7 100644
--- a/rules/CC/EXPRESSIONS
+++ b/rules/CC/EXPRESSIONS
@@ -333,6 +333,151 @@
}
}
}
+, "pkg-map-provider-deps":
+ { "doc": ["Collect maps from provider \"package\" for given target_fields"]
+ , "vars": ["pkg-key", "deps-fieldnames", "deps-transition"]
+ , "vars_doc":
+ { "pkg-key": ["Key to lookup in provider \"package\"."]
+ , "deps-fieldnames": ["List of target_field names to collect maps from."]
+ , "deps-transition":
+ ["The optional configuration transition for the targets."]
+ }
+ , "imports": {"provider_list": ["./", "..", "field_provider_list"]}
+ , "expression":
+ { "type": "disjoint_map_union"
+ , "$1":
+ { "type": "++"
+ , "$1":
+ { "type": "foreach"
+ , "var": "fieldname"
+ , "range": {"type": "var", "name": "deps-fieldnames"}
+ , "body":
+ { "type": "let*"
+ , "bindings":
+ [ ["provider", "package"]
+ , ["default", {"type": "empty_map"}]
+ , ["transition", {"type": "var", "name": "deps-transition"}]
+ ]
+ , "body":
+ { "type": "foreach"
+ , "range": {"type": "CALL_EXPRESSION", "name": "provider_list"}
+ , "var": "map"
+ , "body":
+ { "type": "lookup"
+ , "key": {"type": "var", "name": "pkg-key"}
+ , "map": {"type": "var", "name": "map"}
+ , "default": {"type": "empty_map"}
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+, "cflags-files-deps":
+ { "doc": ["Collect cflags files from target_fields"]
+ , "vars": ["deps-fieldnames", "deps-transition"]
+ , "vars_doc":
+ { "deps-fieldnames": ["List of target_field names to collect files from."]
+ , "deps-transition":
+ ["The optional configuration transition for the targets."]
+ }
+ , "imports": {"pkg-provider": "pkg-map-provider-deps"}
+ , "expression":
+ { "type": "let*"
+ , "bindings": [["pkg-key", "cflags-files"]]
+ , "body": {"type": "CALL_EXPRESSION", "name": "pkg-provider"}
+ }
+ }
+, "ldflags-files-deps":
+ { "doc": ["Collect cflags files from target_fields"]
+ , "vars": ["deps-fieldnames", "deps-transition"]
+ , "vars_doc":
+ { "deps-fieldnames": ["List of target_field names to collect files from."]
+ , "deps-transition":
+ ["The optional configuration transition for the targets."]
+ }
+ , "imports": {"pkg-provider": "pkg-map-provider-deps"}
+ , "expression":
+ { "type": "let*"
+ , "bindings": [["pkg-key", "ldflags-files"]]
+ , "body": {"type": "CALL_EXPRESSION", "name": "pkg-provider"}
+ }
+ }
+, "pkg-prefix-lib-paths":
+ { "doc": ["Detect ldflags referring to local libs and prefix them."]
+ , "vars": ["pkg-ldflags", "pkg-libs", "flat-libs", "lib-prefix"]
+ , "imports": {"contains": ["", "contains"]}
+ , "expression":
+ { "type": "let*"
+ , "bindings":
+ [["list", {"type": "keys", "$1": {"type": "var", "name": "pkg-libs"}}]]
+ , "body":
+ { "type": "foreach"
+ , "var": "item"
+ , "range": {"type": "var", "name": "pkg-ldflags"}
+ , "body":
+ { "type": "if"
+ , "cond": {"type": "CALL_EXPRESSION", "name": "contains"}
+ , "then":
+ { "type": "join"
+ , "$1":
+ { "type": "if"
+ , "cond": {"type": "var", "name": "flat-libs"}
+ , "then":
+ [ "-l:"
+ , {"type": "basename", "$1": {"type": "var", "name": "item"}}
+ ]
+ , "else":
+ [ {"type": "var", "name": "lib-prefix"}
+ , "/"
+ , {"type": "var", "name": "item"}
+ ]
+ }
+ }
+ , "else": {"type": "var", "name": "item"}
+ }
+ }
+ }
+ }
+, "pkg-prefix-flag-paths":
+ { "doc": ["Detect flags referring to local flag files and prefix them."]
+ , "vars": ["flags", "pkg-flag-files", "flag-prefix"]
+ , "imports": {"contains": ["", "contains"]}
+ , "expression":
+ { "type": "let*"
+ , "bindings":
+ [ [ "list"
+ , {"type": "keys", "$1": {"type": "var", "name": "pkg-flag-files"}}
+ ]
+ , ["list_prefix", "@"]
+ ]
+ , "body":
+ { "type": "foreach"
+ , "var": "item"
+ , "range": {"type": "var", "name": "flags"}
+ , "body":
+ { "type": "let*"
+ , "bindings":
+ [["flag-file", {"type": "CALL_EXPRESSION", "name": "contains"}]]
+ , "body":
+ { "type": "if"
+ , "cond": {"type": "var", "name": "flag-file"}
+ , "then":
+ { "type": "join"
+ , "$1":
+ [ "@"
+ , {"type": "var", "name": "flag-prefix"}
+ , "/"
+ , {"type": "var", "name": "flag-file"}
+ ]
+ }
+ , "else": {"type": "var", "name": "item"}
+ }
+ }
+ }
+ }
+ }
, "pkg-config":
{ "vars":
[ "pkg-name"
@@ -340,103 +485,97 @@
, "pkg-version"
, "pkg-cflags"
, "pkg-ldflags"
+ , "pkg-flag-files"
, "pkg-libs"
, "flat-libs"
+ , "pc-install-dir"
]
- , "imports": {"contains": ["", "contains"]}
+ , "imports":
+ { "pkg-prefix-lib-paths": "pkg-prefix-lib-paths"
+ , "pkg-prefix-flag-paths": "pkg-prefix-flag-paths"
+ }
, "expression":
- { "type": "singleton_map"
- , "key":
- {"type": "join", "$1": [{"type": "var", "name": "pkg-name"}, ".pc"]}
- , "value":
- { "type": "BLOB"
- , "data":
- { "type": "join"
- , "separator": "\n"
- , "$1":
- [ { "type": "join"
- , "$1":
- [ "prefix="
- , {"type": "var", "name": "pkg-prefix", "default": "/"}
- ]
- }
- , "libdir=${prefix}/lib"
- , "includedir=${prefix}/include"
- , { "type": "join"
- , "$1": ["Name: ", {"type": "var", "name": "pkg-name"}]
- }
- , { "type": "join"
- , "$1":
- [ "Version: "
- , {"type": "var", "name": "pkg-version", "default": "unknown"}
- ]
- }
- , { "type": "join"
- , "$1":
- [ "Description: Pkg-config for "
- , {"type": "var", "name": "pkg-name"}
- , ", generated by JustBuild"
- ]
- }
- , "URL: unknown"
- , { "type": "join"
- , "separator": " "
- , "$1":
- { "type": "++"
+ { "type": "let*"
+ , "bindings":
+ [ ["lib-prefix", "${libdir}"]
+ , [ "pkg-ldflags"
+ , {"type": "CALL_EXPRESSION", "name": "pkg-prefix-lib-paths"}
+ ]
+ , [ "flag-prefix"
+ , { "type": "join"
+ , "$1": ["${prefix}/", {"type": "var", "name": "pc-install-dir"}]
+ }
+ ]
+ , ["flags", {"type": "var", "name": "pkg-cflags"}]
+ , [ "pkg-cflags"
+ , {"type": "CALL_EXPRESSION", "name": "pkg-prefix-flag-paths"}
+ ]
+ , ["flags", {"type": "var", "name": "pkg-ldflags"}]
+ , [ "pkg-ldflags"
+ , {"type": "CALL_EXPRESSION", "name": "pkg-prefix-flag-paths"}
+ ]
+ ]
+ , "body":
+ { "type": "singleton_map"
+ , "key":
+ {"type": "join", "$1": [{"type": "var", "name": "pkg-name"}, ".pc"]}
+ , "value":
+ { "type": "BLOB"
+ , "data":
+ { "type": "join"
+ , "separator": "\n"
+ , "$1":
+ [ { "type": "join"
, "$1":
- [ ["Cflags:", "-I${includedir}"]
- , {"type": "var", "name": "pkg-cflags"}
+ [ "prefix="
+ , {"type": "var", "name": "pkg-prefix", "default": "/"}
]
}
- }
- , { "type": "join"
- , "separator": " "
- , "$1":
- { "type": "++"
+ , "libdir=${prefix}/lib"
+ , "includedir=${prefix}/include"
+ , { "type": "join"
+ , "$1": ["Name: ", {"type": "var", "name": "pkg-name"}]
+ }
+ , { "type": "join"
, "$1":
- [ ["Libs:"]
- , { "type": "if"
- , "cond": {"type": "var", "name": "flat-libs"}
- , "then": ["-L${libdir}"]
- }
- , { "type": "let*"
- , "bindings":
- [ [ "list"
- , { "type": "keys"
- , "$1": {"type": "var", "name": "pkg-libs"}
- }
- ]
- ]
- , "body":
- { "type": "foreach"
- , "var": "item"
- , "range": {"type": "var", "name": "pkg-ldflags"}
- , "body":
- { "type": "if"
- , "cond": {"type": "CALL_EXPRESSION", "name": "contains"}
- , "then":
- { "type": "join"
- , "$1":
- { "type": "if"
- , "cond": {"type": "var", "name": "flat-libs"}
- , "then":
- [ "-l:"
- , { "type": "basename"
- , "$1": {"type": "var", "name": "item"}
- }
- ]
- , "else":
- ["${libdir}/", {"type": "var", "name": "item"}]
- }
- }
- , "else": {"type": "var", "name": "item"}
- }
- }
- }
+ [ "Version: "
+ , {"type": "var", "name": "pkg-version", "default": "unknown"}
]
}
- }
- ]
+ , { "type": "join"
+ , "$1":
+ [ "Description: Pkg-config for "
+ , {"type": "var", "name": "pkg-name"}
+ , ", generated by JustBuild"
+ ]
+ }
+ , "URL: unknown"
+ , { "type": "join"
+ , "separator": " "
+ , "$1":
+ { "type": "++"
+ , "$1":
+ [ ["Cflags:", "-I${includedir}"]
+ , {"type": "var", "name": "pkg-cflags"}
+ ]
+ }
+ }
+ , { "type": "join"
+ , "separator": " "
+ , "$1":
+ { "type": "++"
+ , "$1":
+ [ ["Libs:"]
+ , { "type": "if"
+ , "cond": {"type": "var", "name": "flat-libs"}
+ , "then": ["-L${libdir}"]
+ }
+ , {"type": "var", "name": "pkg-ldflags"}
+ ]
+ }
+ }
+ ]
+ }
}
}
}
@@ -450,6 +589,7 @@
, "hdrs"
, "private-hdrs"
, "compile-deps"
+ , "cflags-files"
]
, "expression":
{ "type": "let*"
@@ -503,6 +643,10 @@
, "key": {"type": "var", "name": "work src_name"}
, "value": {"type": "var", "name": "src_val"}
}
+ , { "type": "var"
+ , "name": "cflags-files"
+ , "default": {"type": "empty_map"}
+ }
]
}
]
@@ -671,6 +815,7 @@
, "stage"
, "compile-deps"
, "compile-args"
+ , "cflags-files"
, "defaults-transition"
]
, "imports":
@@ -804,6 +949,8 @@
, "link-args-deps": "link-args-deps"
, "run-libs-deps": "run-libs-deps"
, "run-libs-args-deps": "run-libs-args-deps"
+ , "cflags-files-deps": "cflags-files-deps"
+ , "ldflags-files-deps": "ldflags-files-deps"
, "lib artifact": "lib artifact"
}
, "expression":
@@ -823,6 +970,9 @@
}
}
]
+ , [ "cflags-files"
+ , {"type": "CALL_EXPRESSION", "name": "cflags-files-deps"}
+ ]
, ["link-deps", {"type": "CALL_EXPRESSION", "name": "link-deps"}]
, ["lib", {"type": "CALL_EXPRESSION", "name": "lib artifact"}]
, [ "link-args"
@@ -844,6 +994,9 @@
, "$1": {"type": "CALL_EXPRESSION", "name": "run-libs-args-deps"}
}
]
+ , [ "ldflags-files"
+ , {"type": "CALL_EXPRESSION", "name": "ldflags-files-deps"}
+ ]
, ["deps-fieldnames", {"type": "var", "name": "public-fieldnames"}]
, ["compile-deps", {"type": "CALL_EXPRESSION", "name": "compile-deps"}]
, [ "compile-args"
@@ -857,10 +1010,14 @@
}
}
]
+ , [ "cflags-files"
+ , {"type": "CALL_EXPRESSION", "name": "cflags-files-deps"}
+ ]
, [ "package"
- , { "type": "singleton_map"
- , "key": "name"
- , "value": {"type": "var", "name": "pkg-name"}
+ , { "type": "let*"
+ , "bindings": [["name", {"type": "var", "name": "pkg-name"}]]
+ , "body":
+ {"type": "env", "vars": ["name", "cflags-files", "ldflags-files"]}
}
]
]
@@ -914,6 +1071,8 @@
, "link-args"
, "run-libs"
, "run-libs-args"
+ , "cflags-files"
+ , "ldflags-files"
, "defaults-transition"
]
, "imports":
@@ -1005,6 +1164,14 @@
[ {"type": "var", "name": "objects"}
, {"type": "var", "name": "link-deps"}
, {"type": "var", "name": "run-libs"}
+ , { "type": "var"
+ , "name": "cflags-files"
+ , "default": {"type": "empty_map"}
+ }
+ , { "type": "var"
+ , "name": "ldflags-files"
+ , "default": {"type": "empty_map"}
+ }
]
}
, "env":
@@ -1070,6 +1237,8 @@
, "link-args-deps": "link-args-deps"
, "run-libs-deps": "run-libs-deps"
, "run-libs-args-deps": "run-libs-args-deps"
+ , "cflags-files-deps": "cflags-files-deps"
+ , "ldflags-files-deps": "ldflags-files-deps"
, "shared artifact": "shared artifact"
}
, "expression":
@@ -1089,6 +1258,9 @@
}
}
]
+ , [ "cflags-files"
+ , {"type": "CALL_EXPRESSION", "name": "cflags-files-deps"}
+ ]
, ["link-deps", {"type": "CALL_EXPRESSION", "name": "link-deps"}]
, ["link-args", {"type": "CALL_EXPRESSION", "name": "link-args-deps"}]
, ["run-libs", {"type": "CALL_EXPRESSION", "name": "run-libs-deps"}]
@@ -1104,6 +1276,9 @@
}
}
]
+ , [ "ldflags-files"
+ , {"type": "CALL_EXPRESSION", "name": "ldflags-files-deps"}
+ ]
, ["lib", {"type": "CALL_EXPRESSION", "name": "shared artifact"}]
, ["deps-fieldnames", {"type": "var", "name": "public-fieldnames"}]
, ["compile-deps", {"type": "CALL_EXPRESSION", "name": "compile-deps"}]
@@ -1118,6 +1293,9 @@
}
}
]
+ , [ "cflags-files"
+ , {"type": "CALL_EXPRESSION", "name": "cflags-files-deps"}
+ ]
, ["link-deps", {"type": "CALL_EXPRESSION", "name": "link-deps"}]
, ["link-args", {"type": "CALL_EXPRESSION", "name": "link-args-deps"}]
, [ "run-libs"
@@ -1140,6 +1318,9 @@
}
}
]
+ , [ "ldflags-files"
+ , {"type": "CALL_EXPRESSION", "name": "ldflags-files-deps"}
+ ]
, [ "package"
, { "type": "let*"
, "bindings":
@@ -1156,7 +1337,10 @@
}
]
]
- , "body": {"type": "env", "vars": ["name", "version"]}
+ , "body":
+ { "type": "env"
+ , "vars": ["name", "version", "cflags-files", "ldflags-files"]
+ }
}
]
]
@@ -1211,6 +1395,8 @@
, "link-args"
, "run-libs"
, "run-libs-args"
+ , "cflags-files"
+ , "ldflags-files"
, "defaults-transition"
]
, "imports":
@@ -1295,6 +1481,14 @@
[ {"type": "var", "name": "objects"}
, {"type": "var", "name": "link-deps"}
, {"type": "var", "name": "run-libs"}
+ , { "type": "var"
+ , "name": "cflags-files"
+ , "default": {"type": "empty_map"}
+ }
+ , { "type": "var"
+ , "name": "ldflags-files"
+ , "default": {"type": "empty_map"}
+ }
]
}
, "cmd":
@@ -1348,6 +1542,8 @@
, "link-args-deps": "link-args-deps"
, "run-libs-deps": "run-libs-deps"
, "run-libs-args-deps": "run-libs-args-deps"
+ , "cflags-files-deps": "cflags-files-deps"
+ , "ldflags-files-deps": "ldflags-files-deps"
, "binary": "bin artifact"
}
, "expression":
@@ -1379,6 +1575,12 @@
, [ "run-libs-args"
, {"type": "CALL_EXPRESSION", "name": "run-libs-args-deps"}
]
+ , [ "cflags-files"
+ , {"type": "CALL_EXPRESSION", "name": "cflags-files-deps"}
+ ]
+ , [ "ldflags-files"
+ , {"type": "CALL_EXPRESSION", "name": "ldflags-files-deps"}
+ ]
, ["package", {"type": "singleton_map", "key": "to_bin", "value": true}]
]
, "body":
diff --git a/rules/CC/RULES b/rules/CC/RULES
index 91fcf3d..730d45b 100644
--- a/rules/CC/RULES
+++ b/rules/CC/RULES
@@ -624,7 +624,8 @@
, "expression":
{ "type": "let*"
, "bindings":
- [ [ "install-stage"
+ [ ["pc-install-dir", "share/pkgconfig"]
+ , [ "install-stage"
, { "type": "disjoint_map_union"
, "msg": "install stages may not overlap"
, "$1":
@@ -770,11 +771,32 @@
]
}
]
+ , [ "pkg-flag-files"
+ , { "type": "map_union"
+ , "$1":
+ [ { "type": "lookup"
+ , "key": "cflags-files"
+ , "map": {"type": "var", "name": "package"}
+ , "default": {"type": "empty_map"}
+ }
+ , { "type": "lookup"
+ , "key": "ldflags-files"
+ , "map": {"type": "var", "name": "package"}
+ , "default": {"type": "empty_map"}
+ }
+ ]
+ }
+ ]
, ["pkg-libs", {"type": "var", "name": "libraries"}]
, ["flat-libs", {"type": "FIELD", "name": "flat-libs"}]
]
, "body":
- {"type": "CALL_EXPRESSION", "name": "pkg-config"}
+ { "type": "map_union"
+ , "$1":
+ [ {"type": "CALL_EXPRESSION", "name": "pkg-config"}
+ , {"type": "var", "name": "pkg-flag-files"}
+ ]
+ }
}
, "else": {"type": "empty_map"}
}
@@ -800,7 +822,7 @@
, "$1": {"type": "var", "name": "libraries"}
}
, { "type": "to_subdir"
- , "subdir": "share/pkgconfig"
+ , "subdir": {"type": "var", "name": "pc-install-dir"}
, "$1": {"type": "var", "name": "pkg-config"}
}
]
diff --git a/rules/CC/prebuilt/EXPRESSIONS b/rules/CC/prebuilt/EXPRESSIONS
index ca576f4..fc901d7 100644
--- a/rules/CC/prebuilt/EXPRESSIONS
+++ b/rules/CC/prebuilt/EXPRESSIONS
@@ -88,13 +88,16 @@
}
, "prebuilt result":
{ "vars":
- [ "name"
+ [ "ENV"
+ , "name"
, "version"
, "stage"
, "cflags"
, "ldflags"
, "libs"
, "hdrs"
+ , "config_reader"
+ , "pkg-configs"
, "deps-fieldnames"
]
, "imports":
@@ -105,6 +108,9 @@
, "link-args-deps": ["./", "..", "link-args-deps"]
, "run-libs-deps": ["./", "..", "run-libs-deps"]
, "run-libs-args-deps": ["./", "..", "run-libs-args-deps"]
+ , "cflags-files-deps": ["./", "..", "cflags-files-deps"]
+ , "ldflags-files-deps": ["./", "..", "ldflags-files-deps"]
+ , "default-ENV": ["./", "..", "default-ENV"]
}
, "expression":
{ "type": "let*"
@@ -225,6 +231,179 @@
}
}
]
+ , [ "ENV"
+ , { "type": "map_union"
+ , "$1":
+ { "type": "++"
+ , "$1":
+ [ {"type": "CALL_EXPRESSION", "name": "default-ENV"}
+ , [ { "type": "var"
+ , "name": "ENV"
+ , "default": {"type": "empty_map"}
+ }
+ ]
+ ]
+ }
+ }
+ ]
+ , [ "main-pkg-config"
+ , { "type": "foldl"
+ , "range": {"type": "var", "name": "pkg-configs", "default": []}
+ , "start": null
+ , "accum_var": "name"
+ , "var": "config"
+ , "body":
+ { "type": "if"
+ , "cond": {"type": "var", "name": "name"}
+ , "then": {"type": "var", "name": "name"}
+ , "else":
+ { "type": "join"
+ , "$1": {"type": "keys", "$1": {"type": "var", "name": "config"}}
+ }
+ }
+ }
+ ]
+ , [ "reader-inputs"
+ , { "type": "to_subdir"
+ , "subdir": "lib"
+ , "$1":
+ { "type": "map_union"
+ , "$1":
+ [ {"type": "var", "name": "libs"}
+ , { "type": "to_subdir"
+ , "subdir": "pkgconfig"
+ , "flat": true
+ , "$1":
+ { "type": "map_union"
+ , "$1": {"type": "var", "name": "pkg-configs", "default": []}
+ }
+ }
+ ]
+ }
+ }
+ ]
+ , [ "cflags-filename"
+ , {"type": "join", "$1": [{"type": "var", "name": "name"}, ".cflags"]}
+ ]
+ , [ "cflags-file"
+ , { "type": "to_subdir"
+ , "subdir": {"type": "var", "name": "stage"}
+ , "$1":
+ { "type": "if"
+ , "cond": {"type": "var", "name": "pkg-configs"}
+ , "then":
+ { "type": "ACTION"
+ , "inputs":
+ { "type": "map_union"
+ , "$1":
+ [ {"type": "var", "name": "config_reader"}
+ , {"type": "var", "name": "reader-inputs"}
+ ]
+ }
+ , "cmd":
+ [ "./config_reader"
+ , {"type": "var", "name": "cflags-filename"}
+ , {"type": "var", "name": "main-pkg-config"}
+ ]
+ , "env": {"type": "var", "name": "ENV"}
+ , "outs": [{"type": "var", "name": "cflags-filename"}]
+ }
+ , "else": {"type": "empty_map"}
+ }
+ }
+ ]
+ , [ "cflags-files"
+ , { "type": "map_union"
+ , "$1":
+ [ {"type": "CALL_EXPRESSION", "name": "cflags-files-deps"}
+ , {"type": "var", "name": "cflags-file"}
+ ]
+ }
+ ]
+ , [ "compile-args"
+ , { "type": "++"
+ , "$1":
+ [ {"type": "var", "name": "compile-args"}
+ , { "type": "if"
+ , "cond": {"type": "var", "name": "cflags-file"}
+ , "then":
+ [ { "type": "join"
+ , "$1":
+ { "type": "++"
+ , "$1":
+ [ ["@"]
+ , { "type": "keys"
+ , "$1": {"type": "var", "name": "cflags-file"}
+ }
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ , [ "ldflags-filename"
+ , {"type": "join", "$1": [{"type": "var", "name": "name"}, ".ldflags"]}
+ ]
+ , [ "ldflags-file"
+ , { "type": "to_subdir"
+ , "subdir": {"type": "var", "name": "stage"}
+ , "$1":
+ { "type": "if"
+ , "cond": {"type": "var", "name": "pkg-configs"}
+ , "then":
+ { "type": "ACTION"
+ , "inputs":
+ { "type": "map_union"
+ , "$1":
+ [ {"type": "var", "name": "config_reader"}
+ , {"type": "var", "name": "reader-inputs"}
+ ]
+ }
+ , "cmd":
+ [ "./config_reader"
+ , {"type": "var", "name": "ldflags-filename"}
+ , {"type": "var", "name": "main-pkg-config"}
+ ]
+ , "env": {"type": "var", "name": "ENV"}
+ , "outs": [{"type": "var", "name": "ldflags-filename"}]
+ }
+ , "else": {"type": "empty_map"}
+ }
+ }
+ ]
+ , [ "ldflags-files"
+ , { "type": "map_union"
+ , "$1":
+ [ {"type": "CALL_EXPRESSION", "name": "ldflags-files-deps"}
+ , {"type": "var", "name": "ldflags-file"}
+ ]
+ }
+ ]
+ , [ "run-libs-args"
+ , { "type": "++"
+ , "$1":
+ [ {"type": "var", "name": "run-libs-args"}
+ , { "type": "if"
+ , "cond": {"type": "var", "name": "ldflags-file"}
+ , "then":
+ [ { "type": "join"
+ , "$1":
+ { "type": "++"
+ , "$1":
+ [ ["@"]
+ , { "type": "keys"
+ , "$1": {"type": "var", "name": "ldflags-file"}
+ }
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ }
+ ]
, [ "package"
, { "type": "let*"
, "bindings":
@@ -241,7 +420,10 @@
}
]
]
- , "body": {"type": "env", "vars": ["name", "version"]}
+ , "body":
+ { "type": "env"
+ , "vars": ["name", "version", "cflags-files", "ldflags-files"]
+ }
}
]
]
diff --git a/rules/CC/prebuilt/RULES b/rules/CC/prebuilt/RULES
index be2bacc..16f9f26 100644
--- a/rules/CC/prebuilt/RULES
+++ b/rules/CC/prebuilt/RULES
@@ -1,8 +1,13 @@
{ "library":
{ "doc": ["A prebuilt C++ library"]
- , "target_fields": ["lib", "hdrs", "deps"]
+ , "target_fields": ["lib", "hdrs", "deps", "pkg-config"]
, "string_fields":
["name", "version", "stage", "defines", "cflags", "ldflags"]
+ , "implicit":
+ { "defaults": [["./", "..", "defaults"]]
+ , "config_reader": [["CC", "prebuilt/read_pkgconfig.py"]]
+ }
+ , "config_vars": ["ENV"]
, "field_doc":
{ "name":
[ "The name of the library (without leading \"lib\" or trailing file name"
@@ -32,6 +37,13 @@
["List of compile flags set for this target and its consumers."]
, "ldflags":
["Additional linker flags (typically for linking system libraries)."]
+ , "pkg-config":
+ [ "Pkg-config file for optional infer of public cflags and ldflags. If"
+ , "multiple files are specified (e.g., one depends on the other), the"
+ , "first one is used as entry. Note that if this field is non-empty the"
+ , "tool \"pkg-config\" must be available in \"PATH\", which is taken"
+ , "from [\"CC\", \"defaults\"] or the \"ENV\" variable."
+ ]
}
, "artifacts_doc":
[ "The actual library (libname.a or libname.so). Only static libraries are"
@@ -67,7 +79,9 @@
]
}
, "imports":
- { "artifacts_list": ["./", "../..", "field_artifacts_list"]
+ { "artifacts": ["./", "../..", "field_artifacts"]
+ , "artifacts_list": ["./", "../..", "field_artifacts_list"]
+ , "stage_field": ["", "stage_singleton_field"]
, "prebuilt result": "prebuilt result"
}
, "expression":
@@ -112,6 +126,19 @@
, "body": {"type": "CALL_EXPRESSION", "name": "artifacts_list"}
}
]
+ , [ "config_reader"
+ , { "type": "let*"
+ , "bindings":
+ [["fieldname", "config_reader"], ["location", "config_reader"]]
+ , "body": {"type": "CALL_EXPRESSION", "name": "stage_field"}
+ }
+ ]
+ , [ "pkg-configs"
+ , { "type": "let*"
+ , "bindings": [["fieldname", "pkg-config"]]
+ , "body": {"type": "CALL_EXPRESSION", "name": "artifacts_list"}
+ }
+ ]
, ["deps-fieldnames", ["deps"]]
]
, "body": {"type": "CALL_EXPRESSION", "name": "prebuilt result"}
diff --git a/rules/CC/prebuilt/read_pkgconfig.py b/rules/CC/prebuilt/read_pkgconfig.py
new file mode 100755
index 0000000..cb4154f
--- /dev/null
+++ b/rules/CC/prebuilt/read_pkgconfig.py
@@ -0,0 +1,75 @@
+#!/usr/bin/env python3
+# Copyright 2023 Huawei Cloud Computing Technology Co., Ltd.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import os
+import subprocess
+import sys
+from pathlib import Path
+
+
+def run_pkgconfig(args: list[str], env: dict[str, str]) -> str:
+ result = subprocess.run(["pkg-config"] + args, env=env, capture_output=True)
+ if result.returncode != 0:
+ print(result.stderr.decode("utf-8"), file=sys.stderr)
+ exit(1)
+ return result.stdout.decode("utf-8").strip()
+
+
+def read_ldflags(pkg: str, env: dict[str, str]) -> str:
+ def libname(filename: str) -> str:
+ return filename.split(".")[0]
+
+ local_libs = {
+ libname(f)
+ for it in os.walk(".") for f in it[2] if f.startswith("lib")
+ }
+
+ link_flags = run_pkgconfig(["--libs-only-l", pkg], env).split(" ")
+
+ # deduplicate, keep right-most
+ seen: set[str] = set()
+ link_flags = [
+ f for f in link_flags[::-1] if f not in seen and not seen.add(f)
+ ][::-1]
+
+ def is_local(flag: str) -> bool:
+ if not flag.startswith("-l"):
+ return False
+ lib = libname(flag[3:]) if flag.startswith("-l:") else f"lib{flag[2:]}"
+ return lib in local_libs
+
+ return " ".join([f for f in link_flags if not is_local(f)])
+
+
+def read_pkgconfig():
+ if len(sys.argv) < 3:
+ print(f"usage: read_pkgconfig OUT_NAME PC_FILE")
+ exit(1)
+
+ name = sys.argv[1]
+ pkg = Path(sys.argv[2]).stem
+ env = dict(os.environ, PKG_CONFIG_PATH="./lib/pkgconfig")
+
+ if name.endswith(".cflags"):
+ data = run_pkgconfig(["--cflags-only-other", pkg], env)
+ else:
+ data = read_ldflags(pkg, env)
+
+ with open(f"{name}", 'w') as f:
+ f.write(data)
+
+
+if __name__ == "__main__":
+ read_pkgconfig()
diff --git a/rules/CC/test/RULES b/rules/CC/test/RULES
index 60f33ab..b46d6b0 100644
--- a/rules/CC/test/RULES
+++ b/rules/CC/test/RULES
@@ -115,6 +115,8 @@
, "link-args-deps": ["./", "..", "link-args-deps"]
, "run-libs-deps": ["./", "..", "run-libs-deps"]
, "run-libs-args-deps": ["./", "..", "run-libs-args-deps"]
+ , "cflags-files-deps": ["./", "..", "cflags-files-deps"]
+ , "ldflags-files-deps": ["./", "..", "ldflags-files-deps"]
, "binary": ["./", "..", "bin artifact"]
, "host transition": ["transitions", "for host"]
}
@@ -163,6 +165,9 @@
, ["defaults-transition", {"type": "var", "name": "host-trans"}]
, ["deps-transition", {"type": "var", "name": "host-trans"}]
, ["deps-fieldnames", ["private-deps"]]
+ , [ "cflags-files"
+ , {"type": "CALL_EXPRESSION", "name": "cflags-files-deps"}
+ ]
, ["compile-deps", {"type": "CALL_EXPRESSION", "name": "compile-deps"}]
, [ "compile-args"
, { "type": "++"
@@ -178,6 +183,9 @@
]
}
]
+ , [ "ldflags-files"
+ , {"type": "CALL_EXPRESSION", "name": "ldflags-files-deps"}
+ ]
, ["link-deps", {"type": "CALL_EXPRESSION", "name": "link-deps"}]
, [ "link-args"
, { "type": "++"