libutil|rs: bring back c++ interop with zngur

Change-Id: Ia9e9881f464d5b25110b56fb9d72ed30463eaeee
This commit is contained in:
eldritch horrors
2026-06-28 12:47:18 +00:00
parent d9ecb5301e
commit 91663cca2d
25 changed files with 1509 additions and 9 deletions
Generated
+675 -1
View File
@@ -2,18 +2,287 @@
# It is not intended for manual editing.
version = 4
[[package]]
name = "aho-corasick"
version = "1.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301"
dependencies = [
"memchr",
]
[[package]]
name = "allocator-api2"
version = "0.2.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
[[package]]
name = "anstream"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
"is_terminal_polyfill",
"utf8parse",
]
[[package]]
name = "anstyle"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000"
[[package]]
name = "anstyle-parse"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc"
dependencies = [
"windows-sys",
]
[[package]]
name = "anstyle-wincon"
version = "3.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d"
dependencies = [
"anstyle",
"once_cell_polyfill",
"windows-sys",
]
[[package]]
name = "ar_archive_writer"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4087686b4b0a3427190bae57a1d9a478dbb2d40c5dc1bd6e2b6d797913bdd348"
dependencies = [
"object",
]
[[package]]
name = "ariadne"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72fe02fc62033df9ba41cba57ee19acf5e742511a140c7dbc3a873e19a19a1bd"
dependencies = [
"unicode-width",
"yansi",
]
[[package]]
name = "askama"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b79091df18a97caea757e28cd2d5fda49c6cd4bd01ddffd7ff01ace0c0ad2c28"
dependencies = [
"askama_derive",
"askama_escape",
"humansize",
"num-traits",
"percent-encoding",
]
[[package]]
name = "askama_derive"
version = "0.12.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19fe8d6cb13c4714962c072ea496f3392015f0989b1a2847bb4b2d9effd71d83"
dependencies = [
"askama_parser",
"basic-toml",
"mime",
"mime_guess",
"proc-macro2",
"quote",
"serde",
"syn",
]
[[package]]
name = "askama_escape"
version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "619743e34b5ba4e9703bba34deac3427c72507c7159f5fd030aea8cac0cfe341"
[[package]]
name = "askama_parser"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "acb1161c6b64d1c3d83108213c2a2533a342ac225aabd0bda218278c2ddb00c0"
dependencies = [
"nom",
]
[[package]]
name = "autocfg"
version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53"
[[package]]
name = "basic-toml"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba62675e8242a4c4e806d12f11d136e626e6c8361d6b829310732241652a178a"
dependencies = [
"serde",
]
[[package]]
name = "block-buffer"
version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
dependencies = [
"generic-array",
]
[[package]]
name = "cc"
version = "1.2.65"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e228eec9be7c17ccb640b59b36a5cd805ea2a564a4c5e162c2f659fea30d3b96"
dependencies = [
"find-msvc-tools",
"shlex",
]
[[package]]
name = "cfg-if"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
[[package]]
name = "chumsky"
version = "1.0.0-alpha.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e82d74e6c83060ec269fe9e0d408d6de4a1645d525f9a0bbbb841ba4efd91ac"
dependencies = [
"hashbrown 0.15.5",
"regex-automata",
"serde",
"stacker",
"unicode-ident",
"unicode-segmentation",
]
[[package]]
name = "clap"
version = "4.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ddb117e43bbf7dacf0a4190fef4d345b9bad68dfc649cb349e7d17d28428e51"
dependencies = [
"clap_builder",
"clap_derive",
]
[[package]]
name = "clap_builder"
version = "4.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f"
dependencies = [
"anstream",
"anstyle",
"clap_lex",
"strsim",
]
[[package]]
name = "clap_derive"
version = "4.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2ce8604710f6733aa641a2b3731eaa1e8b3d9973d5e3565da11800813f997a9"
dependencies = [
"heck",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "clap_lex"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9"
[[package]]
name = "colorchoice"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570"
[[package]]
name = "countme"
version = "3.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7704b5fdd17b18ae31c4c1da5a2e0305a2bf17b5249300a9ee9ed7b72114c636"
[[package]]
name = "cpufeatures"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
dependencies = [
"libc",
]
[[package]]
name = "crypto-common"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a"
dependencies = [
"generic-array",
"typenum",
]
[[package]]
name = "digest"
version = "0.10.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [
"block-buffer",
"crypto-common",
]
[[package]]
name = "dissimilar"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59f8e79d1fbf76bdfbde321e902714bf6c49df88a7dda6fc682fc2979226962d"
[[package]]
name = "either"
version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e"
[[package]]
name = "equivalent"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
[[package]]
name = "expect-test"
version = "1.5.0"
@@ -24,17 +293,123 @@ dependencies = [
"once_cell",
]
[[package]]
name = "find-msvc-tools"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
[[package]]
name = "foldhash"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
[[package]]
name = "generic-array"
version = "0.14.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
dependencies = [
"typenum",
"version_check",
]
[[package]]
name = "hashbrown"
version = "0.14.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
[[package]]
name = "hashbrown"
version = "0.15.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
dependencies = [
"allocator-api2",
"equivalent",
"foldhash",
]
[[package]]
name = "hashbrown"
version = "0.17.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
[[package]]
name = "heck"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "hex"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
[[package]]
name = "humansize"
version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6cb51c9a029ddc91b07a787f1d86b53ccfa49b0e86688c946ebe8d3555685dd7"
dependencies = [
"libm",
]
[[package]]
name = "indexmap"
version = "2.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9"
dependencies = [
"equivalent",
"hashbrown 0.17.1",
]
[[package]]
name = "is_terminal_polyfill"
version = "1.70.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695"
[[package]]
name = "itertools"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57"
dependencies = [
"either",
]
[[package]]
name = "libc"
version = "0.2.186"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66"
[[package]]
name = "libm"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981"
[[package]]
name = "licxxbridge"
version = "0.0.0"
dependencies = [
"clap",
"zngur",
]
[[package]]
name = "lix"
version = "0.0.0"
dependencies = [
"lix-doc",
"zngur",
]
[[package]]
@@ -46,12 +421,125 @@ dependencies = [
"rowan",
]
[[package]]
name = "memchr"
version = "2.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4"
[[package]]
name = "mime"
version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
[[package]]
name = "mime_guess"
version = "2.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e"
dependencies = [
"mime",
"unicase",
]
[[package]]
name = "minimal-lexical"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]]
name = "nom"
version = "7.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
dependencies = [
"memchr",
"minimal-lexical",
]
[[package]]
name = "num-traits"
version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
"autocfg",
]
[[package]]
name = "object"
version = "0.37.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe"
dependencies = [
"memchr",
]
[[package]]
name = "once_cell"
version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
[[package]]
name = "once_cell_polyfill"
version = "1.70.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe"
[[package]]
name = "percent-encoding"
version = "2.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
[[package]]
name = "proc-macro2"
version = "1.0.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
dependencies = [
"unicode-ident",
]
[[package]]
name = "psm"
version = "0.1.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "645dbe486e346d9b5de3ef16ede18c26e6c70ad97418f4874b8b1889d6e761ea"
dependencies = [
"ar_archive_writer",
"cc",
]
[[package]]
name = "quote"
version = "1.0.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
dependencies = [
"proc-macro2",
]
[[package]]
name = "regex-automata"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59b23e92ee4318893fa3fe3e6fb365258efbfe6ac6ab30f090cdcbb7aa37efa9"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da"
[[package]]
name = "rnix"
version = "0.12.0"
@@ -68,7 +556,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a542b0253fa46e632d27a1dc5cf7b930de4df8659dc6e720b647fc72147ae3d"
dependencies = [
"countme",
"hashbrown",
"hashbrown 0.14.5",
"rustc-hash",
"text-size",
]
@@ -79,8 +567,194 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]]
name = "serde"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
dependencies = [
"serde_core",
"serde_derive",
]
[[package]]
name = "serde_core"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "sha2"
version = "0.10.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
dependencies = [
"cfg-if",
"cpufeatures",
"digest",
]
[[package]]
name = "shlex"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba"
[[package]]
name = "stacker"
version = "0.1.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "640c8cdd92b6b12f5bcb1803ca3bbf5ab96e5e6b6b96b9ab77dabe9e880b3190"
dependencies = [
"cc",
"cfg-if",
"libc",
"psm",
"windows-sys",
]
[[package]]
name = "strsim"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "syn"
version = "2.0.118"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "text-size"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f18aa187839b2bdb1ad2fa35ead8c4c2976b64e4363c386d45ac0f7ee85c9233"
[[package]]
name = "typenum"
version = "1.20.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20"
[[package]]
name = "unicase"
version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142"
[[package]]
name = "unicode-ident"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
[[package]]
name = "unicode-segmentation"
version = "1.13.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c6f5d3c3b1bf09027a88a6bc961fc00497d651009560b5463668dc81b0fa87a8"
[[package]]
name = "unicode-width"
version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af"
[[package]]
name = "utf8parse"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "version_check"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]]
name = "windows-link"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
[[package]]
name = "windows-sys"
version = "0.61.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
dependencies = [
"windows-link",
]
[[package]]
name = "yansi"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec"
[[package]]
name = "zngur"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fc912d12934b4d04aabc52c14db6fc88ae8aa5a47902f27e8759c2de254723f"
dependencies = [
"zngur-generator",
]
[[package]]
name = "zngur-def"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f27e49a62db537cea43a6c122ded7eda99c4ac0ca1d7cfd74f2bf6a6c88712d"
dependencies = [
"indexmap",
"itertools",
]
[[package]]
name = "zngur-generator"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ffad8c6994c477023aba7613bdf17c470003bbd191846d3096e84ffecf86d4c"
dependencies = [
"askama",
"hex",
"indexmap",
"itertools",
"sha2",
"zngur-def",
"zngur-parser",
]
[[package]]
name = "zngur-parser"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d66c1b85ca6eab9576df5de31758cb1f9046b4ce47b25f45dabcb0fc7ef8789"
dependencies = [
"ariadne",
"chumsky",
"itertools",
"zngur-def",
]
+6
View File
@@ -3,11 +3,17 @@ resolver = "2"
members = [
"lix/lix-doc",
"lix/lix-rs",
"tools/licxxbridge",
]
[workspace.package]
edition = "2021"
[workspace.dependencies]
clap = "4"
syn = "2.0"
zngur = "0.10"
[profile.dev]
opt-level = 1
+3
View File
@@ -12,3 +12,6 @@ default = []
[dependencies]
lix-doc.path = "../lix-doc"
[build-dependencies]
zngur.workspace = true
+16
View File
@@ -0,0 +1,16 @@
use std::{env, fs};
fn main() {
// this is a hack to let rust-analyzer find the generated code. we could
// also include! from MESON_BUILD_DIR directly, but rust-analyzer cannot
// be told to look there. not with any method we came across yet anyway.
fs::write(
format!("{}/generated.rs", env::var("OUT_DIR").expect("OUT_DIR")),
fs::read(format!(
"{}/lix/lix-rs/main.zng.rs",
env::var("MESON_BUILD_DIR").expect("MESON_BUILD_DIR")
))
.expect("read main.zng.rs"),
)
.expect("write generated.rs");
}
+19
View File
@@ -0,0 +1,19 @@
// always use conservative layouts, and use auto offset for anything that isn't critical for
// system performance. field offsets are kind of fucky anyway unless repr(C) is used, and we
// rarely have such types to expose. we *should* try to avoid exposing fields except for any
// tuple types, and even then it'd probably be better to find safer ways to do things. doing
// it anyway is not unsafe as such since zngur does have compile-time layout checks to avoid
// nasty surprises, but field offsets are still dependent on platform and compiler versions.
//
// types are generally sorted by category for builtin types or parent module for the others.
// type definitions should live as close to their least stdlib component as possible: result
// types generally live with their Ok variant types, error types generally live in dedicated
// module files, collection types live with the most reasonable parameter type. these aren't
// hard and fast rules though, just use some judgement. we just want to keep the definitions
// in a readable and maintainable state without scattering bits of types all over the place.
merge "./primitives.zng";
merge "./std-common.zng";
merge "./tuples.zng";
merge "./src/lib.zng";
+33
View File
@@ -1,4 +1,37 @@
lix_rs_files += files(
'Cargo.toml',
# keep-sorted start
'src/ffi_test.rs',
'src/lib.rs',
# keep-sorted end
)
lixrs_zngur_bridge = custom_target(
command : [
licxxbridge,
'generate',
'--in=@INPUT@',
'--out-header=@OUTPUT0@',
'--out-shared-header=@OUTPUT1@',
'--out-impl=@OUTPUT2@',
'--out-rs=@OUTPUT3@',
'--out-deps=@DEPFILE@',
],
input : files('main.zng'),
output : [ '@BASENAME@.gen.hh', 'zngur.gen.hh', '@BASENAME@.gen.cc', '@PLAINNAME@.rs' ],
depfile : '@PLAINNAME@.d',
install : true,
install_dir : [ includedir / 'lix/lix-rs', includedir / 'lix/lix-rs', false, false ],
)
liblix_generated_headers += [ lixrs_zngur_bridge[0], lixrs_zngur_bridge[1] ]
liblix_sources += lixrs_zngur_bridge[2]
lix_rs_files += lixrs_zngur_bridge[3]
liblix_sources += files('utils.cc')
install_headers(
files('utils.hh'),
subdir : 'lix/lix-rs',
preserve_path : true,
)
+22
View File
@@ -0,0 +1,22 @@
// primitives go here. other modules *may* extend primitive declarations, and if a primitive
// operation is used only very rare that may help readability. in general we want to collect
// anything that's used a lot here to not clutter the remainder of our ffi definition files.
type bool {
#layout(size = 1, align = 1);
}
type [u8] {
wellknown_traits(?Sized);
fn as_ptr(&self) -> *const u8;
fn len(&self) -> usize;
}
type str {
wellknown_traits(?Sized);
fn as_bytes(&self) -> &[u8];
fn as_ptr(&self) -> *const u8;
fn len(&self) -> usize;
}
+55
View File
@@ -0,0 +1,55 @@
use std::{error::Error, io};
use crate::ffi;
#[derive(Clone, Copy)]
pub struct TestMultiplyAddLenArgs {
pub a: u64,
pub b: u64,
}
pub trait SetB {
fn set_b(&mut self, b: u64);
}
impl SetB for TestMultiplyAddLenArgs {
fn set_b(&mut self, b: u64) {
self.b = b;
}
}
impl TestMultiplyAddLenArgs {
pub fn new(a: u64, b: u64) -> Self {
Self { a, b }
}
}
pub(crate) fn test_multiply_add_len(args: TestMultiplyAddLenArgs, s: &Vec<String>) -> (String, u64) {
let result = args.a * args.b + s.len() as u64;
(
format!("({} * {} + {s:?}.len()) = {result}", args.a, args.b),
result,
)
}
pub(crate) fn test_result() -> Result<(), Box<dyn Error>> {
Err(Box::new(io::Error::new(
io::ErrorKind::Other,
"errors travel freely",
)))
}
pub(crate) fn test_option_some() -> Option<u64> {
Some(1)
}
pub(crate) fn test_option_none() -> Option<u64> {
None
}
pub(crate) fn test_exceptions(f: Box<dyn Fn() -> Result<(), ffi::Error>>) -> String {
match f() {
Ok(()) => "".into(),
Err(e) => e.to_string(),
}
}
+27
View File
@@ -0,0 +1,27 @@
use ::std::error::Error as Error;
use ::std::option::Option as Option;
use ::std::result::Result as Result;
use ::std::string::String as String;
use ::std::vec::Vec as Vec;
mod crate::ffi_test {
type TestMultiplyAddLenArgs {
#layout_conservative(size = 16, align = 8);
wellknown_traits(Copy);
field a (offset = auto, type = u64);
field b (offset = auto, type = u64);
fn new(u64, u64) -> TestMultiplyAddLenArgs;
fn set_b(&mut self, u64) use SetB;
}
fn test_multiply_add_len(TestMultiplyAddLenArgs, &Vec<String>) -> (String, u64);
fn test_result() -> Result<(), Box<dyn Error>>;
fn test_option_some() -> Option<u64>;
fn test_option_none() -> Option<u64>;
fn test_exceptions(Box<dyn Fn() -> Result<(), crate::ffi::Error>>) -> String;
}
+34
View File
@@ -1 +1,35 @@
extern crate lix_doc;
mod generated {
include!(concat!(env!("OUT_DIR"), "/generated.rs"));
}
mod ffi {
use std::{
error,
fmt::{Debug, Display},
slice::from_raw_parts,
};
pub unsafe fn from_raw_parts_u8<'a>(data: *const u8, length: usize) -> &'a [u8] {
from_raw_parts(data, length)
}
pub(crate) use crate::generated::cpp::Error;
impl Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(&self.to_string())
}
}
impl Debug for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(&self.to_string())
}
}
impl error::Error for Error {}
}
mod ffi_test;
+30
View File
@@ -0,0 +1,30 @@
merge "./ffi_test.zng";
mod crate::ffi {
use ::std::result::Result as Result;
use ::std::string::String as String;
fn from_raw_parts_u8(*const u8, usize) -> &[u8];
type Error {
#layout_conservative(size = 16, align = 8);
#cpp_value "0" "::std::exception_ptr";
}
extern "C++" {
impl Error {
safe fn to_string(&self) -> String;
}
}
type Result<(), Error> {
#layout_conservative(size = 16, align = 8);
constructor Ok(());
constructor Err(Error);
}
type Box<dyn Fn() -> Result<(), Error>> {
#layout_conservative(size = 16, align = 8);
}
}
+73
View File
@@ -0,0 +1,73 @@
// common rust stdlib types go here.
use ::std::string::String as String;
use ::std::vec::Vec as Vec;
mod ::std::borrow {
type Cow<str> {
#layout_conservative(size = 24, align = 8);
fn into_owned(self) -> String;
}
}
mod ::std::error {
type Box<dyn Error> {
#layout_conservative(size = 16, align = 8);
wellknown_traits(Debug);
fn to_string(&self) -> String;
}
}
mod ::std::io {
type Error {
#layout_conservative(size = 16, align = 8);
}
}
mod ::std::option {
type Option<u64> {
#layout_conservative(size = 16, align = 8);
constructor Some(u64);
constructor None;
fn unwrap(self) -> u64;
}
}
mod ::std::result {
use ::std::error::Error as Error;
type Result<(), Box<dyn Error>> {
#layout_conservative(size = 16, align = 8);
constructor Ok(());
constructor Err(Box<dyn Error>);
fn unwrap(self) -> ();
fn unwrap_err(self) -> Box<dyn Error>;
}
}
mod ::std::string {
type String {
#layout_conservative(size = 24, align = 8);
fn as_bytes(&self) -> &[u8];
fn as_str(&self) -> &str;
fn from(&str) -> String;
fn from_utf8_lossy(&[u8]) -> ::std::borrow::Cow<str>;
}
}
mod ::std::vec {
type Vec<String> {
#layout_conservative(size = 24, align = 8);
fn new() -> Vec<String>;
fn push(&mut self, String);
fn len(&self) -> usize;
}
}
+11
View File
@@ -0,0 +1,11 @@
// tuple types of exclusively stdlib types go here. seems like a good place for them anyway.
use ::std::option::Option as Option;
use ::std::string::String as String;
type (String, u64) {
#layout_conservative(size = 32, align = 8);
field 0 (offset = 0, type = String);
field 1 (offset = auto, type = u64);
}
+48
View File
@@ -0,0 +1,48 @@
#include "utils.hh"
#include "libutil/charptr-cast.hh"
#include "lix/lix-rs/main.gen.hh"
namespace rust {
::std::string_view to_std_string_view(Ref<Str> s)
{
return {nix::charptr_cast<const char *>(s.as_ptr()), s.len()};
}
::std::string_view std::string::to_std_string_view(const String & s)
{
auto data = s.as_bytes();
return {nix::charptr_cast<const char *>(data.as_ptr()), data.len()};
}
::std::string to_std_string(Ref<Str> s)
{
return ::std::string(to_std_string_view(s));
}
::std::string std::string::to_std_string(const String & s)
{
return ::std::string(to_std_string_view(s));
}
String to_string(::std::string_view sv)
{
auto slice = lix::ffi::from_raw_parts_u8(nix::charptr_cast<const uint8_t *>(sv.begin()), sv.size());
return String::from_utf8_lossy(slice).into_owned();
}
std::string::String Impl<lix::ffi::Error, Inherent>::to_string(Ref<lix::ffi::Error> ptr)
{
using String = std::string::String;
try {
::std::rethrow_exception(ptr.cpp());
} catch (const ::std::exception & ex) { // NOLINT(lix-foreign-exceptions)
auto slice =
lix::ffi::from_raw_parts_u8(nix::charptr_cast<const uint8_t *>(ex.what()), strlen(ex.what()));
return String::from_utf8_lossy(slice).into_owned();
} catch (...) {
return String::from("Unknown exception!"_rs);
}
}
}
+202
View File
@@ -0,0 +1,202 @@
#pragma once
///@file convenience utilities for working with the rust ffi bits
#include <cassert>
#include <exception>
#include <optional>
#include <string_view>
#include <type_traits>
#include <variant>
// this header requires `std` to mean `::std`
#include "lix/lix-rs/zngur.gen.hh"
// bunch of forward declarations to avoid including all other headers.
namespace rust {
template<typename...>
struct Box;
template<typename...>
struct Dyn;
template<typename...>
struct Fn;
template<typename>
struct Ref;
struct Str;
namespace std::option {
template<typename...>
struct Option;
}
namespace std::result {
template<typename...>
struct Result;
}
namespace std::string {
struct String;
}
namespace std::vec {
template<typename...>
struct Vec;
}
using std::option::Option;
using std::result::Result;
using std::string::String;
using std::vec::Vec;
namespace lix::ffi {
struct Error;
}
}
// here come the *actual* utilities
namespace rust {
/// marker that turns a value into an Ok result when returned
template<typename V>
struct as_ok
{
V v;
explicit as_ok(V v) : v(::std::move(v)) {}
template<typename Err>
operator Result<V, Err>()
{
return Result<V, Err>::Ok(::std::move(v));
}
};
/// marker that turns a value into an Err result when returned
template<typename V>
struct as_err
{
V v;
explicit as_err(V v) : v(::std::move(v)) {}
template<typename Ok>
operator Result<Ok, V>()
{
return Result<Ok, V>::Err(::std::move(v));
}
};
/// wrapper that turns a C++ function object into a `Box<dyn Fn...>`. the function objects
/// *must not* throw exceptions, otherwise the program will just abort. only use this when
/// you are absolutely certain that your function does not throw! if you aren't certain it
/// will throw. if you *are* certain it will throw anyway. passed callables must be marked
/// `noexcept` to serve as a reminder, if not marked the conversions will not be provided.
template<typename Func>
struct make_box_fn_noexcept
{
Func fn;
explicit make_box_fn_noexcept(Func fn) : fn(::std::move(fn)) {}
template<typename R, typename... Args>
requires requires(Func fn, Args... args) {
{ fn(::std::move(args)...) } noexcept -> ::std::same_as<R>;
}
operator Box<Dyn<Fn<R, Args...>>>() const
{
return Box<Dyn<Fn<R, Args...>>>::make_box(::std::move(fn));
}
};
/// wrapper that turns a C++ function object into a `Box<dyn Fn...>`. the function objects
/// passed here may throw exceptions. to allow for this their return value is wrapped in a
/// `Result<T, lix::ffi::Error>` and exceptions are automatically turned into Err results.
template<typename Fn>
auto make_box_fn(Fn fn)
{
return make_box_fn_noexcept([fn{::std::move(fn)}]<typename... Args>(Args &&... args) noexcept {
using result_inner = decltype(fn(::std::forward<Args>(args)...));
using result_type =
Result<::std::conditional_t<::std::is_void_v<result_inner>, Unit, result_inner>, lix::ffi::Error>;
try {
if constexpr (::std::is_void_v<result_inner>) {
fn(::std::forward<Args>(args)...);
return result_type(as_ok(::rust::Unit()));
} else {
return result_type(as_ok(fn(::std::forward<Args>(args)...)));
}
} catch (...) {
// make the error type dependent to delay type checking
using error_type = ::std::enable_if_t<!::std::is_void_v<Fn>, lix::ffi::Error>;
return result_type(as_err(error_type::build(::std::current_exception())));
}
});
}
::std::string_view to_std_string_view(Ref<Str> s);
::std::string to_std_string(Ref<Str> s);
namespace std::string {
::std::string_view to_std_string_view(const String & s);
::std::string to_std_string(const String & s);
}
String to_string(::std::string_view sv);
// enum type matching
namespace matches {
struct Ok;
struct Err;
}
template<typename Tag, typename T>
struct match
{
T value;
operator T()
{
return ::std::move(value);
}
};
namespace std::result {
template<typename... Args>
auto to_std(Result<Args...> r)
{
using result_type = ::std::
variant<match<matches::Ok, decltype(r.unwrap())>, match<matches::Err, decltype(r.unwrap_err())>>;
if (r.matches_Ok()) {
return result_type(match<matches::Ok, decltype(r.unwrap())>{r.unwrap()});
} else {
return result_type(match<matches::Err, decltype(r.unwrap_err())>{r.unwrap_err()});
}
}
template<typename Ok, typename Err, ::std::invocable<Ok> FnOk, ::std::invocable<Err> FnErr>
auto match_result(Result<Ok, Err> r, FnOk ok, FnErr err)
-> ::std::common_type_t<::std::invoke_result_t<FnOk, Ok>, ::std::invoke_result_t<FnErr, Err>>
{
return r.matches_Ok() ? ok(r.unwrap()) : err(r.unwrap_err());
}
}
namespace std::option {
template<typename... Args>
auto to_std(Option<Args...> r)
{
using result_type = ::std::optional<decltype(r.unwrap())>;
if (r.matches_Some()) {
return result_type{r.unwrap()};
} else {
return result_type{};
}
}
}
}
namespace nix {
using namespace rust::lix;
}
+12 -8
View File
@@ -89,6 +89,11 @@ config_h = configure_file(
install_headers(config_h, subdir : 'lix')
# we only collect sources and generated headers here. real headers are collected and
# installed by each subdir due to how meson generates paths for headers it installs.
liblix_sources = []
liblix_generated_headers = embedded_sandbox_headers
lix_rs_files = files(
'../Cargo.toml',
'../Cargo.lock',
@@ -98,11 +103,6 @@ subdir('lix-rs')
# Subcomponents: these link into artifacts themselves, and have interdependencies.
subdir('lix-doc')
# we only collect sources and generated headers here. real headers are collected and
# installed by each subdir due to how meson generates paths for headers it installs.
liblix_sources = []
liblix_generated_headers = embedded_sandbox_headers
subdir('libutil')
subdir('libstore')
subdir('libfetchers')
@@ -156,6 +156,10 @@ if host_machine.system() == 'freebsd'
dependencies += [ libprocstat ]
endif
lixrs_cargo_env = {
'MESON_BUILD_DIR': meson.project_build_root(),
}
lixrs = custom_target(
'liblixrs',
input : lix_rs_files,
@@ -171,9 +175,7 @@ lixrs = custom_target(
cargo_jobs_args,
],
console : true,
env : {
'MESON_BUILD_DIR': meson.project_build_root(),
},
env : lixrs_cargo_env,
)
if meson.can_run_host_binaries()
@@ -187,6 +189,8 @@ if meson.can_run_host_binaries()
cargo_jobs_args,
],
suite : 'check',
env : lixrs_cargo_env,
timeout : 300,
)
endif
+2
View File
@@ -502,6 +502,8 @@ if enable_docs
mdbook = find_program('mdbook', native : true)
endif
subdir('tools/licxxbridge')
# Used to workaround https://github.com/mesonbuild/meson/issues/2320 in lix/nix/meson.build.
installcmd = find_program('install', native : true)
+4
View File
@@ -112,3 +112,7 @@ option('builtin-dep-closure', type : 'array',
option('cargo-jobs', type : 'integer', value : 0,
description : 'Value to pass for Cargo -j. Use 0 to omit',
)
option('licxxbridge', type : 'string', value : '',
description : 'optional path to an existing licxxbridge executable. must be built from the current source tree, beware when setting this',
)
+4
View File
@@ -46,6 +46,10 @@ def go(
str(jobs),
"-header-filter",
r"lix/[^/]+/.*\.hh",
"-exclude-header-filter",
r"\.gen\.hh$",
"-source-filter",
r"(?!.*\.gen\.cc$).*",
]
if werror:
args += ["-warnings-as-errors", "*"]
+35
View File
@@ -287,6 +287,7 @@ let
./scripts/meson.build
(fileset.fileFilter (f: lib.strings.hasSuffix ".wrap" f.name) ./subprojects)
./subprojects/aws_sdk
./tools
# Required for meson to generate Cargo wraps
./Cargo.lock
./Cargo.toml
@@ -338,6 +339,36 @@ stdenv.mkDerivation (finalAttrs: {
]
);
# precompile the bridge generator since the zngur parser takes so long to build. this way we can
# cache the generator in ci and for devshells, both of which decrease cycle times by quite a bit
licxxbridge = rustPlatform.buildRustPackage {
pname = "licxxbridge";
version = "0.0.0";
src = fileset.toSource {
root = ./.;
fileset = fileset.unions [
./Cargo.toml
./Cargo.lock
./tools/licxxbridge
# these are only needed to let cargo parse the manifests at all, they're not used elsewise
./lix/lix-doc/Cargo.toml
./lix/lix-doc/src/lib.rs
./lix/lix-rs/Cargo.toml
./lix/lix-rs/src/lib.rs
];
};
cargoDeps = rustPlatform.importCargoLock { lockFile = ./Cargo.lock; };
cargoBuildFlags = [
"-p"
"licxxbridge"
];
cargoTestFlags = [
"-p"
"licxxbridge"
];
meta.mainProgram = "licxxbridge";
};
buildTestShell =
if hostPlatform.isLinux then
"${pkgsStatic.bash}/bin"
@@ -419,6 +450,7 @@ stdenv.mkDerivation (finalAttrs: {
# musl doesn't support fibers, and we can't detect this with meson alone.
++ lib.optional hostPlatform.isMusl "-Ddisable-fibers=true"
++ lib.optional (finalAttrs.dontBuild && !lintInsteadOfBuild) "-Denable-build=false"
++ lib.optional (!finalAttrs.dontBuild) "-Dlicxxbridge=${lib.getExe finalAttrs.licxxbridge}"
++ lib.optional lintInsteadOfBuild "-Dlix-clang-tidy-checks-path=${lix-clang-tidy}/lib/liblix-clang-tidy.${
if hostPlatform.isDarwin then "dylib" else "so"
}"
@@ -879,6 +911,9 @@ stdenv.mkDerivation (finalAttrs: {
unset PYTHONPATH
export MANPATH=$out/share/man:''${MANPATH:-}
# default build dir. lets rust-analyzer find generated code
export MESON_BUILD_DIR="$PWD/build"
# Make bash completion work.
XDG_DATA_DIRS+=:$out/share
+90
View File
@@ -0,0 +1,90 @@
#include "lix/libutil/error.hh"
#include "lix/libutil/types.hh"
#include "lix/lix-rs/main.gen.hh"
#include "lix/lix-rs/utils.hh"
#include "zngur.gen.hh"
#include "gtest/gtest.h"
#include <cstdint>
#include <gtest/gtest.h>
#include <utility>
#include <variant>
namespace nix {
TEST(rustSupport, testMultiplyAddLen)
{
auto vec = rust::Vec<rust::String>::new_();
vec.push(rust::String::from("1"_rs));
vec.push(rust::String::from("2"_rs));
vec.push(rust::String::from("3"_rs));
vec.push(rust::String::from("4"_rs));
vec.push(rust::String::from("5"_rs));
auto args = ffi_test::TestMultiplyAddLenArgs::new_(20, 1);
args.set_b(5);
auto product = ffi_test::test_multiply_add_len(args, std::move(vec));
ASSERT_EQ(to_std_string(product.f0.as_str()), R"-((20 * 5 + ["1", "2", "3", "4", "5"].len()) = 105)-");
ASSERT_EQ(product.f1, 20 * 5 + 5);
}
TEST(rustSupport, testResult)
{
auto result = ffi_test::test_result();
ASSERT_TRUE(result.matches_Err());
EXPECT_DEATH(result.unwrap(), "called `Result::unwrap\\(\\)` on an `Err`");
auto msg = to_std_string(result.unwrap_err().to_string());
ASSERT_EQ(msg, "errors travel freely");
std::visit(
overloaded{
[](rust::match<rust::matches::Ok, rust::Unit>) { FAIL(); },
[](rust::match<rust::matches::Err, rust::Box<rust::Dyn<rust::std::error::Error>>> e) {
auto msg = to_std_string(e.value.to_string());
ASSERT_EQ(msg, "errors travel freely");
}
},
to_std(ffi_test::test_result())
);
std::visit(
overloaded{
[](rust::Unit) { FAIL(); },
[](rust::Box<rust::Dyn<rust::std::error::Error>> e) {
auto msg = to_std_string(e.to_string());
ASSERT_EQ(msg, "errors travel freely");
}
},
to_std(ffi_test::test_result())
);
match_result(
ffi_test::test_result(),
[](rust::Unit) { FAIL(); },
[](rust::Box<rust::Dyn<rust::std::error::Error>> e) {
auto msg = to_std_string(e.to_string());
ASSERT_EQ(msg, "errors travel freely");
}
);
}
TEST(rustSupport, testOption)
{
ASSERT_EQ(to_std(ffi_test::test_option_some()), 1);
ASSERT_FALSE(to_std(ffi_test::test_option_none()).has_value());
}
TEST(rustSupport, testResultFromCxx)
{
using rust::make_box_fn, ffi_test::test_exceptions;
auto result = test_exceptions(make_box_fn([]() -> ::rust::Unit { throw Error("test"); }));
ASSERT_EQ(to_std_string(result), "\x1B[31;1merror:\x1B[0m test");
result = test_exceptions(make_box_fn([] { throw Error("test"); }));
ASSERT_EQ(to_std_string(result), "\x1B[31;1merror:\x1B[0m test");
result = test_exceptions(make_box_fn([] {}));
ASSERT_EQ(to_std_string(result), "");
}
}
+9
View File
@@ -27,6 +27,7 @@ libutil_test_support_sources = files(
libutil_test_support = library(
'lixutil-test-support',
libutil_test_support_sources,
liblix_generated_headers,
dependencies : [
liblix,
rapidcheck,
@@ -66,6 +67,7 @@ libutil_tests_sources = files(
'libutil/paths-setting.cc',
'libutil/pool.cc',
'libutil/references.cc',
'libutil/rust.cc',
'libutil/serialise.cc',
'libutil/suggestions.cc',
'libutil/tarfile.cc',
@@ -82,6 +84,7 @@ libutil_tests_sources = files(
libutil_tester = executable(
'liblixutil-tests',
libutil_tests_sources,
liblix_generated_headers,
dependencies : [
libasanoptions,
rapidcheck,
@@ -115,6 +118,7 @@ libstore_test_support_sources = files(
libstore_test_support = library(
'lixstore-test-support',
libstore_test_support_sources,
liblix_generated_headers,
dependencies : [
liblixutil_test_support,
liblix,
@@ -150,6 +154,7 @@ libstore_tests_sources = files(
libstore_tester = executable(
'liblixstore-tests',
libstore_tests_sources,
liblix_generated_headers,
dependencies : [
libasanoptions,
liblixstore_test_support,
@@ -182,6 +187,7 @@ libexpr_test_support_sources = files(
libexpr_test_support = library(
'lixexpr-test-support',
libexpr_test_support_sources,
liblix_generated_headers,
dependencies : [
liblixstore_test_support,
liblix,
@@ -214,6 +220,7 @@ libexpr_tests_sources = files(
libexpr_tester = executable(
'liblixexpr-tests',
libexpr_tests_sources,
liblix_generated_headers,
dependencies : [
libasanoptions,
liblixexpr_test_support,
@@ -242,6 +249,7 @@ test(
libcmd_tester = executable(
'liblix-tests',
files('libcmd/args.cc'),
liblix_generated_headers,
dependencies : [
libasanoptions,
liblix,
@@ -277,6 +285,7 @@ libmain_tests_sources = files(
libmain_tester = executable(
'liblixmain-tests',
libmain_tests_sources,
liblix_generated_headers,
dependencies : [
liblix,
gtest,
+12
View File
@@ -0,0 +1,12 @@
[package]
name = "licxxbridge"
edition = "2021"
description = "small cxxbridge alternative that lets us use cxx versions nixpkgs doesn't have"
[[bin]]
name = "licxxbridge"
path = "main.rs"
[dependencies]
clap = { workspace = true, features = ["derive"] }
zngur.workspace = true
+63
View File
@@ -0,0 +1,63 @@
use std::{fs, path::PathBuf};
use clap::{Parser, Subcommand};
#[derive(Parser)]
struct Args {
#[command(subcommand)]
command: Command,
}
#[derive(Subcommand, Clone)]
enum Command {
Generate {
#[arg(long = "in")]
input: PathBuf,
#[arg(long)]
out_rs: PathBuf,
#[arg(long)]
out_header: PathBuf,
#[arg(long)]
out_shared_header: PathBuf,
#[arg(long)]
out_impl: PathBuf,
#[arg(long)]
out_deps: PathBuf,
},
}
fn main() {
let args = Args::parse();
match args.command {
Command::Generate {
input,
out_rs,
out_header,
out_shared_header,
out_impl,
out_deps,
} => {
// create an empty impl file if zngur doesn't expose anything to make life easier
fs::write(&out_impl, "").expect("failed to touch impl file");
zngur::Zngur::from_zng_file(input)
.with_rs_file(out_rs)
.with_cpp_file(out_impl)
.with_h_file(&out_header)
.with_crate_name("lix")
.with_zng_header(&out_shared_header)
.with_depfile(out_deps)
.generate();
let content = fs::read_to_string(&out_header).expect("failed to read generated header");
fs::write(
&out_header,
content.replace(
"#include <zngur.h>",
&format!("#include \"{}\"", out_shared_header.display()),
),
).expect("failed to rewrite generated header");
}
}
}
+24
View File
@@ -0,0 +1,24 @@
licxxbridge = get_option('licxxbridge')
if licxxbridge == ''
licxxbridge = custom_target(
'licxxbridge',
input : files(
'../../Cargo.toml',
'../../Cargo.lock',
'Cargo.toml',
'main.rs',
),
output : 'licxxbridge',
command : [
cargo,
'-Z', 'unstable-options',
'build',
'--artifact-dir=@0@'.format(meson.current_build_dir()),
'-p',
'licxxbridge',
cargo_jobs_args,
],
console : true,
)
endif