diff options
author | Oliver Reiche <oliver.reiche@huawei.com> | 2023-01-20 16:20:30 +0100 |
---|---|---|
committer | Oliver Reiche <oliver.reiche@huawei.com> | 2023-01-20 16:20:30 +0100 |
commit | 89b76f2558da0c41280b9eb389384824babfbef6 (patch) | |
tree | 489057736f3fcc4f9e14bcb27e14eb0effbd815a /rules/CC | |
parent | 25981eeccf645ddc6338bed0b159014f210f4326 (diff) | |
parent | e75f101e8b988adb458e594ffaaaebc0c01f65df (diff) | |
download | rules-cc-89b76f2558da0c41280b9eb389384824babfbef6.tar.gz |
Merge commit 'e75f101e8b988adb458e594ffaaaebc0c01f65df' into rules-cc
Diffstat (limited to 'rules/CC')
-rw-r--r-- | rules/CC/EXPRESSIONS | 384 | ||||
-rw-r--r-- | rules/CC/RULES | 28 | ||||
-rw-r--r-- | rules/CC/prebuilt/EXPRESSIONS | 186 | ||||
-rw-r--r-- | rules/CC/prebuilt/RULES | 31 | ||||
-rwxr-xr-x | rules/CC/prebuilt/read_pkgconfig.py | 75 | ||||
-rw-r--r-- | rules/CC/test/RULES | 8 |
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": "++" |