mirror of
https://github.com/servo/servo.git
synced 2025-07-23 07:13:52 +01:00
Auto merge of #14244 - upsuper:buildtime-bindgen, r=emilio
Use build script to generate binding files <!-- Please describe your changes on the following line: --> This is a WIP patch to make rust-bindgen a build time dependency of style component for stylo. This should make things more automatic. I convert majority of `regen.py` to `build_gecko.rs`. It currently doesn't work on Windows, because of servo/rust-bindgen#271 (it works when I fix the generated file manually, though). I haven't tested other platforms. It would break servo's CI for geckolib, because: 1. it needs libclang (which is probably easy to solve) 2. it needs `MOZ_OBJDIR` to be passed in so that it can generate bindings @Manishearth @emilio Do you agree with this change? Do you have suggestion for the issues above? --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [ ] `./mach build -d` does not report any errors - [ ] `./mach test-tidy` does not report any errors - [ ] These changes fix #__ (github issue number if applicable). <!-- Either: --> - [ ] There are tests for these changes OR - [ ] These changes do not require tests because _____ <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/14244) <!-- Reviewable:end -->
This commit is contained in:
commit
872ec89a9c
12 changed files with 747 additions and 890 deletions
74
Cargo.lock
generated
74
Cargo.lock
generated
|
@ -68,6 +68,14 @@ dependencies = [
|
||||||
"odds 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
"odds 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aster"
|
||||||
|
version = "0.34.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"syntex_syntax 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "audio-video-metadata"
|
name = "audio-video-metadata"
|
||||||
version = "0.1.2"
|
version = "0.1.2"
|
||||||
|
@ -281,6 +289,14 @@ dependencies = [
|
||||||
"unicode-normalization 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"unicode-normalization 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cexpr"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"nom 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -295,6 +311,16 @@ dependencies = [
|
||||||
"libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clang-sys"
|
||||||
|
version = "0.11.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clippy_lints"
|
name = "clippy_lints"
|
||||||
version = "0.0.98"
|
version = "0.0.98"
|
||||||
|
@ -1379,6 +1405,26 @@ dependencies = [
|
||||||
"leak 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"leak 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libbindgen"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"aster 0.34.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"cexpr 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"clang-sys 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"env_logger 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"quasi 0.26.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"quasi_codegen 0.26.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"regex 0.1.76 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"syntex_syntax 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.17"
|
version = "0.2.17"
|
||||||
|
@ -2067,6 +2113,26 @@ dependencies = [
|
||||||
"util 0.0.1",
|
"util 0.0.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quasi"
|
||||||
|
version = "0.26.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"syntex_errors 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"syntex_syntax 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quasi_codegen"
|
||||||
|
version = "0.26.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"aster 0.34.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"syntex 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"syntex_errors 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"syntex_syntax 0.50.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quickersort"
|
name = "quickersort"
|
||||||
version = "2.1.0"
|
version = "2.1.0"
|
||||||
|
@ -2601,6 +2667,7 @@ dependencies = [
|
||||||
"html5ever-atoms 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"html5ever-atoms 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libbindgen 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"nsstring_vendor 0.1.0",
|
"nsstring_vendor 0.1.0",
|
||||||
|
@ -2616,6 +2683,7 @@ dependencies = [
|
||||||
"quickersort 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"quickersort 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rayon 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rayon 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"regex 0.1.76 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"selectors 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"selectors 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 0.8.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -3212,6 +3280,7 @@ dependencies = [
|
||||||
"checksum angle 0.1.2 (git+https://github.com/servo/angle?branch=servo)" = "<none>"
|
"checksum angle 0.1.2 (git+https://github.com/servo/angle?branch=servo)" = "<none>"
|
||||||
"checksum app_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "636ee56f12e31dbc11dc0a1ac6004f08b04e6e6595963716fc8130e90d4e04cf"
|
"checksum app_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "636ee56f12e31dbc11dc0a1ac6004f08b04e6e6595963716fc8130e90d4e04cf"
|
||||||
"checksum arrayvec 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)" = "80a137392e2e92ce7387c063d98a11f0d47115426c5f8759657af3c7b385c860"
|
"checksum arrayvec 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)" = "80a137392e2e92ce7387c063d98a11f0d47115426c5f8759657af3c7b385c860"
|
||||||
|
"checksum aster 0.34.0 (registry+https://github.com/rust-lang/crates.io-index)" = "88bb8ecdf6a7eaddb7bfd872ebf5e085d343ca42ce98c582dba8046e3450b524"
|
||||||
"checksum audio-video-metadata 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "03da2550cb89fe3faf218c179261c26cf7891c4234707c15f5d09ebb32ae2400"
|
"checksum audio-video-metadata 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "03da2550cb89fe3faf218c179261c26cf7891c4234707c15f5d09ebb32ae2400"
|
||||||
"checksum azure 0.9.1 (git+https://github.com/servo/rust-azure)" = "<none>"
|
"checksum azure 0.9.1 (git+https://github.com/servo/rust-azure)" = "<none>"
|
||||||
"checksum backtrace 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "346d7644f0b5f9bc73082d3b2236b69a05fd35cce0cfa3724e184e6a5c9e2a2f"
|
"checksum backtrace 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "346d7644f0b5f9bc73082d3b2236b69a05fd35cce0cfa3724e184e6a5c9e2a2f"
|
||||||
|
@ -3230,8 +3299,10 @@ dependencies = [
|
||||||
"checksum byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0fc10e8cc6b2580fda3f36eb6dc5316657f812a3df879a44a66fc9f0fdbc4855"
|
"checksum byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0fc10e8cc6b2580fda3f36eb6dc5316657f812a3df879a44a66fc9f0fdbc4855"
|
||||||
"checksum bytes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c129aff112dcc562970abb69e2508b40850dd24c274761bb50fb8a0067ba6c27"
|
"checksum bytes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c129aff112dcc562970abb69e2508b40850dd24c274761bb50fb8a0067ba6c27"
|
||||||
"checksum caseless 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b6893f86ac0c9275b5cbba9212ccd71020b447d4c3e2eebad70e1bc47fdd6dfb"
|
"checksum caseless 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b6893f86ac0c9275b5cbba9212ccd71020b447d4c3e2eebad70e1bc47fdd6dfb"
|
||||||
|
"checksum cexpr 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "393a5f0088efbe41f9d1fcd062f24e83c278608420e62109feb2c8abee07de7d"
|
||||||
"checksum cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de1e760d7b6535af4241fca8bd8adf68e2e7edacc6b29f5d399050c5e48cf88c"
|
"checksum cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de1e760d7b6535af4241fca8bd8adf68e2e7edacc6b29f5d399050c5e48cf88c"
|
||||||
"checksum cgl 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "8bdd78cca65a739cb5475dbf6b6bbb49373e327f4a6f2b499c0f98632df38c10"
|
"checksum cgl 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "8bdd78cca65a739cb5475dbf6b6bbb49373e327f4a6f2b499c0f98632df38c10"
|
||||||
|
"checksum clang-sys 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "19911f7964ce61a02d382adee8400f919d0fedd53c5441e3d6a9858ba73e249e"
|
||||||
"checksum clippy_lints 0.0.98 (registry+https://github.com/rust-lang/crates.io-index)" = "4329699b62341fd3ce3ebe13ade6c87d35b8778091e0c2f6da51399e081b9671"
|
"checksum clippy_lints 0.0.98 (registry+https://github.com/rust-lang/crates.io-index)" = "4329699b62341fd3ce3ebe13ade6c87d35b8778091e0c2f6da51399e081b9671"
|
||||||
"checksum cmake 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "dfcf5bcece56ef953b8ea042509e9dcbdfe97820b7e20d86beb53df30ed94978"
|
"checksum cmake 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "dfcf5bcece56ef953b8ea042509e9dcbdfe97820b7e20d86beb53df30ed94978"
|
||||||
"checksum cocoa 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6d24ed9a15e9c0892cdb20c7acc3e50441501b990ee6dc318c176981829a7941"
|
"checksum cocoa 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6d24ed9a15e9c0892cdb20c7acc3e50441501b990ee6dc318c176981829a7941"
|
||||||
|
@ -3313,6 +3384,7 @@ dependencies = [
|
||||||
"checksum lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "49247ec2a285bb3dcb23cbd9c35193c025e7251bfce77c1d5da97e6362dffe7f"
|
"checksum lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "49247ec2a285bb3dcb23cbd9c35193c025e7251bfce77c1d5da97e6362dffe7f"
|
||||||
"checksum leak 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bd100e01f1154f2908dfa7d02219aeab25d0b9c7fa955164192e3245255a0c73"
|
"checksum leak 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bd100e01f1154f2908dfa7d02219aeab25d0b9c7fa955164192e3245255a0c73"
|
||||||
"checksum leaky-cow 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "40a8225d44241fd324a8af2806ba635fc7c8a7e9a7de4d5cf3ef54e71f5926fc"
|
"checksum leaky-cow 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "40a8225d44241fd324a8af2806ba635fc7c8a7e9a7de4d5cf3ef54e71f5926fc"
|
||||||
|
"checksum libbindgen 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6a46e95efa501b2940e9c81dbb727e557b39b41f77f1170aba6eed5a546e9964"
|
||||||
"checksum libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)" = "044d1360593a78f5c8e5e710beccdc24ab71d1f01bc19a29bcacdba22e8475d8"
|
"checksum libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)" = "044d1360593a78f5c8e5e710beccdc24ab71d1f01bc19a29bcacdba22e8475d8"
|
||||||
"checksum libloading 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "eceb2637ee9a27c7f19764048a9f377e40e3a70a322722f348e6bc7704d565f2"
|
"checksum libloading 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "eceb2637ee9a27c7f19764048a9f377e40e3a70a322722f348e6bc7704d565f2"
|
||||||
"checksum libressl-pnacl-sys 2.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "cbc058951ab6a3ef35ca16462d7642c4867e6403520811f28537a4e2f2db3e71"
|
"checksum libressl-pnacl-sys 2.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "cbc058951ab6a3ef35ca16462d7642c4867e6403520811f28537a4e2f2db3e71"
|
||||||
|
@ -3367,6 +3439,8 @@ dependencies = [
|
||||||
"checksum pkg-config 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8cee804ecc7eaf201a4a207241472cc870e825206f6c031e3ee2a72fa425f2fa"
|
"checksum pkg-config 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8cee804ecc7eaf201a4a207241472cc870e825206f6c031e3ee2a72fa425f2fa"
|
||||||
"checksum pnacl-build-helper 1.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "61c9231d31aea845007443d62fcbb58bb6949ab9c18081ee1e09920e0cf1118b"
|
"checksum pnacl-build-helper 1.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "61c9231d31aea845007443d62fcbb58bb6949ab9c18081ee1e09920e0cf1118b"
|
||||||
"checksum png 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "06208e2ee243e3118a55dda9318f821f206d8563fb8d4df258767f8e62bb0997"
|
"checksum png 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "06208e2ee243e3118a55dda9318f821f206d8563fb8d4df258767f8e62bb0997"
|
||||||
|
"checksum quasi 0.26.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ab7992920bf5bc5f1ed6fdc49090bf665cd00b3aa4b78c16ac3465286257db1"
|
||||||
|
"checksum quasi_codegen 0.26.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d52e5e2c92ffdad67a9b86ad27ad999bf1a652723f1d4cc93b7cf6c272b5f8e0"
|
||||||
"checksum quickersort 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e952ea7699262481636004bc4ab8afaccf2bc13f91b79d1aee6617bd8fc39651"
|
"checksum quickersort 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e952ea7699262481636004bc4ab8afaccf2bc13f91b79d1aee6617bd8fc39651"
|
||||||
"checksum quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "07589615d719a60c8dd8a4622e7946465dfef20d1a428f969e3443e7386d5f45"
|
"checksum quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "07589615d719a60c8dd8a4622e7946465dfef20d1a428f969e3443e7386d5f45"
|
||||||
"checksum quote 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1e0c9bc6bfb0a60d539aab6e338207c1a5456e62f5bd5375132cee119aa4b3"
|
"checksum quote 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1e0c9bc6bfb0a60d539aab6e338207c1a5456e62f5bd5375132cee119aa4b3"
|
||||||
|
|
|
@ -14,6 +14,7 @@ doctest = false
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
gecko = ["nsstring_vendor", "num_cpus", "rayon/unstable"]
|
gecko = ["nsstring_vendor", "num_cpus", "rayon/unstable"]
|
||||||
|
bindgen = ["libbindgen", "regex"]
|
||||||
servo = ["serde/unstable", "serde", "serde_derive", "heapsize_derive",
|
servo = ["serde/unstable", "serde", "serde_derive", "heapsize_derive",
|
||||||
"style_traits/servo", "app_units/plugins", "servo_atoms", "html5ever-atoms",
|
"style_traits/servo", "app_units/plugins", "servo_atoms", "html5ever-atoms",
|
||||||
"cssparser/heap_size", "cssparser/serde-serialization",
|
"cssparser/heap_size", "cssparser/serde-serialization",
|
||||||
|
@ -65,5 +66,8 @@ version = "1.0"
|
||||||
kernel32-sys = "0.2"
|
kernel32-sys = "0.2"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
|
lazy_static = "0.2"
|
||||||
|
libbindgen = {version = "0.1.1", optional = true}
|
||||||
phf_codegen = "0.7.20"
|
phf_codegen = "0.7.20"
|
||||||
|
regex = {version = "0.1", optional = true}
|
||||||
walkdir = "0.1"
|
walkdir = "0.1"
|
||||||
|
|
|
@ -5,8 +5,3 @@ This directory contains simple tools for generating the Rust bindings for [stylo
|
||||||
## `setup_bindgen.sh`
|
## `setup_bindgen.sh`
|
||||||
|
|
||||||
This clones Servo's version of bindgen, and uses `llvm-3.8` library to build it. It will then be used to generate the Rust bindings.
|
This clones Servo's version of bindgen, and uses `llvm-3.8` library to build it. It will then be used to generate the Rust bindings.
|
||||||
|
|
||||||
## `regen.sh`
|
|
||||||
|
|
||||||
This will regenerate the bindings for the `ServoBindings.h` file in your gecko
|
|
||||||
build. The generated bindings live in `components/style/gecko_bindings/bindings.rs`. For structs, the bindings are in `components/style/gecko_bindings/structs_*`
|
|
||||||
|
|
|
@ -1,820 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
|
|
||||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
||||||
|
|
||||||
from __future__ import print_function
|
|
||||||
|
|
||||||
import re
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import argparse
|
|
||||||
import platform
|
|
||||||
import copy
|
|
||||||
import subprocess
|
|
||||||
import fileinput
|
|
||||||
|
|
||||||
import regen_atoms
|
|
||||||
|
|
||||||
DESCRIPTION = 'Regenerate the rust version of the structs or the bindings file.'
|
|
||||||
TOOLS_DIR = os.path.dirname(os.path.abspath(__file__))
|
|
||||||
COMMON_BUILD_KEY = "__common__"
|
|
||||||
|
|
||||||
COMPILATION_TARGETS = {
|
|
||||||
# Flags common for all the targets.
|
|
||||||
COMMON_BUILD_KEY: {
|
|
||||||
"flags": [
|
|
||||||
"--no-unstable-rust",
|
|
||||||
],
|
|
||||||
"clang_flags": [
|
|
||||||
"-x", "c++", "-std=c++14",
|
|
||||||
"-DTRACING=1", "-DIMPL_LIBXUL", "-DMOZ_STYLO_BINDINGS=1",
|
|
||||||
"-DMOZILLA_INTERNAL_API", "-DRUST_BINDGEN", "-DMOZ_STYLO"
|
|
||||||
],
|
|
||||||
"search_dirs": [
|
|
||||||
"{}/dist/include",
|
|
||||||
"{}/dist/include/nspr",
|
|
||||||
"{}/../nsprpub/pr/include"
|
|
||||||
],
|
|
||||||
"includes": [
|
|
||||||
"{}/mozilla-config.h",
|
|
||||||
],
|
|
||||||
},
|
|
||||||
# Generation of style structs.
|
|
||||||
"structs": {
|
|
||||||
"target_dir": "../gecko_bindings",
|
|
||||||
"flags": [
|
|
||||||
"--enable-cxx-namespaces",
|
|
||||||
# FIXME(emilio): Incrementally remove these. Probably mozilla::css
|
|
||||||
# and mozilla::dom are easier.
|
|
||||||
"--raw-line", "pub use self::root::*;",
|
|
||||||
"--raw-line", "pub use self::root::mozilla::*;",
|
|
||||||
"--raw-line", "pub use self::root::mozilla::css::*;",
|
|
||||||
"--raw-line", "pub use self::root::mozilla::dom::*;",
|
|
||||||
"--generate", "types,vars",
|
|
||||||
],
|
|
||||||
"includes": [
|
|
||||||
"{}/dist/include/gfxFontConstants.h",
|
|
||||||
"{}/dist/include/nsThemeConstants.h",
|
|
||||||
"{}/dist/include/mozilla/dom/AnimationEffectReadOnlyBinding.h",
|
|
||||||
"{}/dist/include/mozilla/ServoElementSnapshot.h",
|
|
||||||
"{}/dist/include/mozilla/dom/Element.h",
|
|
||||||
"{}/dist/include/mozilla/ServoBindings.h",
|
|
||||||
],
|
|
||||||
"files": [
|
|
||||||
"{}/dist/include/nsStyleStruct.h",
|
|
||||||
],
|
|
||||||
"build_kinds": {
|
|
||||||
"debug": {
|
|
||||||
"clang_flags": [
|
|
||||||
"-DDEBUG=1",
|
|
||||||
"-DJS_DEBUG=1",
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"release": {
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"raw_lines": [
|
|
||||||
"use atomic_refcell::AtomicRefCell;",
|
|
||||||
"use data::ElementData;",
|
|
||||||
],
|
|
||||||
"blacklist_types": [
|
|
||||||
"nsString",
|
|
||||||
],
|
|
||||||
"whitelist_vars": [
|
|
||||||
"NS_THEME_.*",
|
|
||||||
"NODE_.*",
|
|
||||||
"NS_FONT_.*",
|
|
||||||
"NS_STYLE_.*",
|
|
||||||
"NS_CORNER_.*",
|
|
||||||
"NS_RADIUS_.*",
|
|
||||||
"BORDER_COLOR_.*",
|
|
||||||
"BORDER_STYLE_.*"
|
|
||||||
],
|
|
||||||
"whitelist": [
|
|
||||||
"RawGecko.*",
|
|
||||||
"mozilla::ServoElementSnapshot.*",
|
|
||||||
"mozilla::ConsumeStyleBehavior",
|
|
||||||
"mozilla::LazyComputeBehavior",
|
|
||||||
"mozilla::css::SheetParsingMode",
|
|
||||||
"mozilla::SkipRootBehavior",
|
|
||||||
"mozilla::DisplayItemClip", # Needed because bindgen generates
|
|
||||||
# specialization tests for this even
|
|
||||||
# though it shouldn't.
|
|
||||||
".*ThreadSafe.*Holder",
|
|
||||||
"AnonymousContent",
|
|
||||||
"AudioContext",
|
|
||||||
"CapturingContentInfo",
|
|
||||||
"ConsumeStyleBehavior",
|
|
||||||
"DefaultDelete",
|
|
||||||
"DOMIntersectionObserverEntry",
|
|
||||||
"Element",
|
|
||||||
"FontFamilyList",
|
|
||||||
"FontFamilyListRefCnt",
|
|
||||||
"FontFamilyName",
|
|
||||||
"FontFamilyType",
|
|
||||||
"FragmentOrURL",
|
|
||||||
"FrameRequestCallback",
|
|
||||||
"gfxAlternateValue",
|
|
||||||
"gfxFontFeature",
|
|
||||||
"gfxFontVariation",
|
|
||||||
"GridNamedArea",
|
|
||||||
"Image",
|
|
||||||
"ImageURL",
|
|
||||||
"LazyComputeBehavior",
|
|
||||||
"nsAttrName",
|
|
||||||
"nsAttrValue",
|
|
||||||
"nsBorderColors",
|
|
||||||
"nscolor",
|
|
||||||
"nsChangeHint",
|
|
||||||
"nsCSSKeyword",
|
|
||||||
"nsCSSPropertyID",
|
|
||||||
"nsCSSRect",
|
|
||||||
"nsCSSRect_heap",
|
|
||||||
"nsCSSShadowArray",
|
|
||||||
"nsCSSValue",
|
|
||||||
"nsCSSValueFloatColor",
|
|
||||||
"nsCSSValueGradient",
|
|
||||||
"nsCSSValueGradientStop",
|
|
||||||
"nsCSSValueList",
|
|
||||||
"nsCSSValueList_heap",
|
|
||||||
"nsCSSValuePair_heap",
|
|
||||||
"nsCSSValuePairList",
|
|
||||||
"nsCSSValuePairList_heap",
|
|
||||||
"nsCSSValueTokenStream",
|
|
||||||
"nsCSSValueTriplet_heap",
|
|
||||||
"nsCursorImage",
|
|
||||||
"nsFont",
|
|
||||||
"nsIAtom",
|
|
||||||
"nsMainThreadPtrHandle",
|
|
||||||
"nsMainThreadPtrHolder",
|
|
||||||
"nsMargin",
|
|
||||||
"nsRect",
|
|
||||||
"nsRestyleHint",
|
|
||||||
"nsresult",
|
|
||||||
"nsSize",
|
|
||||||
"nsStyleBackground",
|
|
||||||
"nsStyleBorder",
|
|
||||||
"nsStyleColor",
|
|
||||||
"nsStyleColumn",
|
|
||||||
"nsStyleContent",
|
|
||||||
"nsStyleContentData",
|
|
||||||
"nsStyleContext",
|
|
||||||
"nsStyleCoord",
|
|
||||||
"nsStyleCounterData",
|
|
||||||
"nsStyleDisplay",
|
|
||||||
"nsStyleEffects",
|
|
||||||
"nsStyleFilter",
|
|
||||||
"nsStyleFont",
|
|
||||||
"nsStyleGradient",
|
|
||||||
"nsStyleGradientStop",
|
|
||||||
"nsStyleImage",
|
|
||||||
"nsStyleImageLayers",
|
|
||||||
"nsStyleList",
|
|
||||||
"nsStyleMargin",
|
|
||||||
"nsStyleOutline",
|
|
||||||
"nsStylePadding",
|
|
||||||
"nsStylePosition",
|
|
||||||
"nsStyleSVG",
|
|
||||||
"nsStyleSVGReset",
|
|
||||||
"nsStyleTable",
|
|
||||||
"nsStyleTableBorder",
|
|
||||||
"nsStyleText",
|
|
||||||
"nsStyleTextReset",
|
|
||||||
"nsStyleUIReset",
|
|
||||||
"nsStyleUnion",
|
|
||||||
"nsStyleUnit",
|
|
||||||
"nsStyleUserInterface",
|
|
||||||
"nsStyleVariables",
|
|
||||||
"nsStyleVisibility",
|
|
||||||
"nsStyleXUL",
|
|
||||||
"nsTArray",
|
|
||||||
"nsTArrayHeader",
|
|
||||||
"pair",
|
|
||||||
"Position",
|
|
||||||
"Runnable",
|
|
||||||
"ServoAttrSnapshot",
|
|
||||||
"ServoElementSnapshot",
|
|
||||||
"SheetParsingMode",
|
|
||||||
"Side",
|
|
||||||
"StaticRefPtr",
|
|
||||||
"StyleAnimation",
|
|
||||||
"StyleBasicShape",
|
|
||||||
"StyleBasicShapeType",
|
|
||||||
"StyleClipPath",
|
|
||||||
"StyleClipPathGeometryBox",
|
|
||||||
"StyleTransition",
|
|
||||||
"mozilla::UniquePtr",
|
|
||||||
"mozilla::DefaultDelete",
|
|
||||||
],
|
|
||||||
"bitfield_enum_types": ["nsChangeHint", "nsRestyleHint"],
|
|
||||||
"opaque_types": [
|
|
||||||
"atomic___base",
|
|
||||||
"nsAString_internal_char_traits",
|
|
||||||
"nsAString_internal_incompatible_char_type",
|
|
||||||
"nsACString_internal_char_traits",
|
|
||||||
"nsACString_internal_incompatible_char_type",
|
|
||||||
"RefPtr_Proxy",
|
|
||||||
"RefPtr_Proxy_member_function",
|
|
||||||
"nsAutoPtr_Proxy",
|
|
||||||
"nsAutoPtr_Proxy_member_function",
|
|
||||||
"mozilla::detail::PointerType",
|
|
||||||
"mozilla::Pair_Base",
|
|
||||||
"mozilla::SupportsWeakPtr",
|
|
||||||
"SupportsWeakPtr",
|
|
||||||
"mozilla::detail::WeakReference",
|
|
||||||
"mozilla::WeakPtr",
|
|
||||||
"nsWritingIterator_reference", "nsReadingIterator_reference",
|
|
||||||
"nsTObserverArray", # <- Inherits from nsAutoTObserverArray<T, 0>
|
|
||||||
"nsTHashtable", # <- Inheriting from inner typedefs that clang
|
|
||||||
# doesn't expose properly.
|
|
||||||
"nsRefPtrHashtable", "nsDataHashtable", "nsClassHashtable", # <- Ditto
|
|
||||||
"nsIDocument_SelectorCache", # <- Inherits from nsExpirationTracker<.., 4>
|
|
||||||
"nsIPresShell_ScrollAxis", # <- For some reason the alignment of this is 4
|
|
||||||
# for clang.
|
|
||||||
"nsPIDOMWindow", # <- Takes the vtable from a template parameter, and we can't
|
|
||||||
# generate it conditionally.
|
|
||||||
"JS::Rooted",
|
|
||||||
"mozilla::Maybe",
|
|
||||||
"gfxSize", # <- union { struct { T width; T height; }; T components[2] };
|
|
||||||
"gfxSize_Super", # Ditto.
|
|
||||||
"mozilla::ErrorResult", # Causes JSWhyMagic to be included & handled incorrectly.
|
|
||||||
],
|
|
||||||
"manual_fixups": [
|
|
||||||
["root::nsString", "::nsstring::nsStringRepr"]
|
|
||||||
],
|
|
||||||
"servo_mapped_generic_types": [
|
|
||||||
{
|
|
||||||
"generic": True,
|
|
||||||
"gecko": "mozilla::ServoUnsafeCell",
|
|
||||||
"servo": "::std::cell::UnsafeCell"
|
|
||||||
}, {
|
|
||||||
"generic": True,
|
|
||||||
"gecko": "mozilla::ServoCell",
|
|
||||||
"servo": "::std::cell::Cell"
|
|
||||||
}, {
|
|
||||||
"generic": False,
|
|
||||||
"gecko": "ServoNodeData",
|
|
||||||
"servo": "AtomicRefCell<ElementData>",
|
|
||||||
}
|
|
||||||
],
|
|
||||||
},
|
|
||||||
# Generation of the ffi bindings.
|
|
||||||
"bindings": {
|
|
||||||
"target_dir": "../gecko_bindings",
|
|
||||||
"raw_lines": [
|
|
||||||
"pub use nsstring::{nsACString, nsAString};",
|
|
||||||
"type nsACString_internal = nsACString;",
|
|
||||||
"type nsAString_internal = nsAString;"
|
|
||||||
],
|
|
||||||
"flags": [
|
|
||||||
"--generate", "functions",
|
|
||||||
"--disable-name-namespacing",
|
|
||||||
],
|
|
||||||
"match_headers": [
|
|
||||||
"ServoBindingList.h",
|
|
||||||
"ServoBindings.h",
|
|
||||||
"ServoTypes.h",
|
|
||||||
"nsStyleStructList.h",
|
|
||||||
],
|
|
||||||
"files": [
|
|
||||||
"{}/dist/include/mozilla/ServoBindings.h",
|
|
||||||
],
|
|
||||||
# Types to just use from the `structs` target.
|
|
||||||
"structs_types": [
|
|
||||||
"RawGeckoDocument",
|
|
||||||
"RawGeckoElement",
|
|
||||||
"RawGeckoNode",
|
|
||||||
"ThreadSafeURIHolder",
|
|
||||||
"ThreadSafePrincipalHolder",
|
|
||||||
"ConsumeStyleBehavior",
|
|
||||||
"LazyComputeBehavior",
|
|
||||||
"SkipRootBehavior",
|
|
||||||
"FontFamilyList",
|
|
||||||
"FontFamilyType",
|
|
||||||
"ServoElementSnapshot",
|
|
||||||
"SheetParsingMode",
|
|
||||||
"StyleBasicShape",
|
|
||||||
"StyleBasicShapeType",
|
|
||||||
"StyleClipPath",
|
|
||||||
"nsCSSKeyword",
|
|
||||||
"nsCSSShadowArray",
|
|
||||||
"nsCSSValue",
|
|
||||||
"nsCSSValueSharedList",
|
|
||||||
"nsChangeHint",
|
|
||||||
"nsCursorImage",
|
|
||||||
"nsFont",
|
|
||||||
"nsIAtom",
|
|
||||||
"nsRestyleHint",
|
|
||||||
"nsStyleBackground",
|
|
||||||
"nsStyleBorder",
|
|
||||||
"nsStyleColor",
|
|
||||||
"nsStyleColumn",
|
|
||||||
"nsStyleContent",
|
|
||||||
"nsStyleContext",
|
|
||||||
"nsStyleCoord",
|
|
||||||
"nsStyleCoord_Calc",
|
|
||||||
"nsStyleCoord_CalcValue",
|
|
||||||
"nsStyleDisplay",
|
|
||||||
"nsStyleEffects",
|
|
||||||
"nsStyleFont",
|
|
||||||
"nsStyleGradient",
|
|
||||||
"nsStyleGradientStop",
|
|
||||||
"nsStyleImage",
|
|
||||||
"nsStyleImageLayers",
|
|
||||||
"nsStyleImageLayers_Layer",
|
|
||||||
"nsStyleImageLayers_LayerType",
|
|
||||||
"nsStyleImageRequest",
|
|
||||||
"nsStyleList",
|
|
||||||
"nsStyleMargin",
|
|
||||||
"nsStyleOutline",
|
|
||||||
"nsStylePadding",
|
|
||||||
"nsStylePosition",
|
|
||||||
"nsStyleQuoteValues",
|
|
||||||
"nsStyleSVG",
|
|
||||||
"nsStyleSVGReset",
|
|
||||||
"nsStyleTable",
|
|
||||||
"nsStyleTableBorder",
|
|
||||||
"nsStyleText",
|
|
||||||
"nsStyleTextReset",
|
|
||||||
"nsStyleUIReset",
|
|
||||||
"nsStyleUnion",
|
|
||||||
"nsStyleUnit",
|
|
||||||
"nsStyleUserInterface",
|
|
||||||
"nsStyleVariables",
|
|
||||||
"nsStyleVisibility",
|
|
||||||
"nsStyleXUL",
|
|
||||||
"nscoord",
|
|
||||||
"nsresult",
|
|
||||||
],
|
|
||||||
"array_types": {
|
|
||||||
"uintptr_t": "usize",
|
|
||||||
},
|
|
||||||
"servo_nullable_arc_types": [
|
|
||||||
"ServoComputedValues",
|
|
||||||
"ServoCssRules",
|
|
||||||
"RawServoStyleSheet",
|
|
||||||
"RawServoDeclarationBlock",
|
|
||||||
"RawServoStyleRule",
|
|
||||||
],
|
|
||||||
"servo_owned_types": [
|
|
||||||
{
|
|
||||||
"name": "RawServoStyleSet",
|
|
||||||
"opaque": True,
|
|
||||||
}, {
|
|
||||||
"name": "StyleChildrenIterator",
|
|
||||||
"opaque": True,
|
|
||||||
}, {
|
|
||||||
"name": "ServoElementSnapshot",
|
|
||||||
"opaque": False,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"servo_immutable_borrow_types": [
|
|
||||||
"RawGeckoNode",
|
|
||||||
"RawGeckoElement",
|
|
||||||
"RawGeckoDocument",
|
|
||||||
"RawServoDeclarationBlockStrong",
|
|
||||||
],
|
|
||||||
"servo_borrow_types": [
|
|
||||||
"nsCSSValue",
|
|
||||||
],
|
|
||||||
"whitelist_functions": [
|
|
||||||
"Servo_.*",
|
|
||||||
"Gecko_.*"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
|
|
||||||
"atoms": {
|
|
||||||
"custom_build": regen_atoms.build,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def platform_dependent_defines():
|
|
||||||
ret = []
|
|
||||||
|
|
||||||
if os.name == "posix":
|
|
||||||
ret.append("-DOS_POSIX=1")
|
|
||||||
|
|
||||||
system = platform.system()
|
|
||||||
if system == "Linux":
|
|
||||||
ret.append("-DOS_LINUX=1")
|
|
||||||
elif system == "Darwin":
|
|
||||||
ret.append("-DOS_MACOSX=1")
|
|
||||||
elif system == "Windows":
|
|
||||||
ret.append("-DOS_WIN=1")
|
|
||||||
ret.append("-DWIN32=1")
|
|
||||||
msvc_platform = os.environ["PLATFORM"]
|
|
||||||
if msvc_platform == "X86":
|
|
||||||
ret.append("--target=i686-pc-win32")
|
|
||||||
elif msvc_platform == "X64":
|
|
||||||
ret.append("--target=x86_64-pc-win32")
|
|
||||||
else:
|
|
||||||
raise Exception("Only MSVC builds are supported on Windows")
|
|
||||||
# For compatibility with MSVC 2015
|
|
||||||
ret.append("-fms-compatibility-version=19")
|
|
||||||
# To enable the builtin __builtin_offsetof so that CRT wouldn't
|
|
||||||
# use reinterpret_cast in offsetof() which is not allowed inside
|
|
||||||
# static_assert().
|
|
||||||
ret.append("-D_CRT_USE_BUILTIN_OFFSETOF")
|
|
||||||
# Enable hidden attribute (which is not supported by MSVC and
|
|
||||||
# thus not enabled by default with a MSVC-compatibile build)
|
|
||||||
# to exclude hidden symbols from the generated file.
|
|
||||||
ret.append("-DHAVE_VISIBILITY_HIDDEN_ATTRIBUTE=1")
|
|
||||||
else:
|
|
||||||
raise Exception("Unknown platform")
|
|
||||||
|
|
||||||
return ret
|
|
||||||
|
|
||||||
|
|
||||||
def extend_object(obj, other):
|
|
||||||
if not obj or not other:
|
|
||||||
return obj
|
|
||||||
|
|
||||||
if isinstance(obj, list) and isinstance(other, list):
|
|
||||||
obj.extend(other)
|
|
||||||
return
|
|
||||||
|
|
||||||
assert isinstance(obj, dict) and isinstance(other, dict)
|
|
||||||
|
|
||||||
for key in other.keys():
|
|
||||||
if key in obj:
|
|
||||||
extend_object(obj[key], other[key])
|
|
||||||
else:
|
|
||||||
obj[key] = copy.deepcopy(other[key])
|
|
||||||
|
|
||||||
|
|
||||||
def build(objdir, target_name, debug, debugger, kind_name=None,
|
|
||||||
output_filename=None, bindgen=None, skip_test=False,
|
|
||||||
verbose=False):
|
|
||||||
assert target_name in COMPILATION_TARGETS
|
|
||||||
|
|
||||||
current_target = COMPILATION_TARGETS[target_name]
|
|
||||||
if COMMON_BUILD_KEY in COMPILATION_TARGETS:
|
|
||||||
current_target = copy.deepcopy(COMPILATION_TARGETS[COMMON_BUILD_KEY])
|
|
||||||
extend_object(current_target, COMPILATION_TARGETS[target_name])
|
|
||||||
|
|
||||||
assert ((kind_name is None and "build_kinds" not in current_target) or
|
|
||||||
(kind_name in current_target["build_kinds"]))
|
|
||||||
|
|
||||||
if "custom_build" in current_target:
|
|
||||||
print("[CUSTOM] {}::{} in \"{}\"... ".format(target_name, kind_name, objdir), end='')
|
|
||||||
sys.stdout.flush()
|
|
||||||
ret = current_target["custom_build"](objdir, verbose=True)
|
|
||||||
if ret != 0:
|
|
||||||
print("FAIL")
|
|
||||||
else:
|
|
||||||
print("OK")
|
|
||||||
|
|
||||||
return ret
|
|
||||||
|
|
||||||
if bindgen is None:
|
|
||||||
bindgen = os.path.join(TOOLS_DIR, "rust-bindgen")
|
|
||||||
|
|
||||||
if os.path.isdir(bindgen):
|
|
||||||
bindgen = ["cargo", "run", "--manifest-path",
|
|
||||||
os.path.join(bindgen, "Cargo.toml"), "--features", "llvm_stable", "--release", "--"]
|
|
||||||
else:
|
|
||||||
bindgen = [bindgen]
|
|
||||||
|
|
||||||
if kind_name is not None:
|
|
||||||
current_target = copy.deepcopy(current_target)
|
|
||||||
extend_object(current_target, current_target["build_kinds"][kind_name])
|
|
||||||
|
|
||||||
target_dir = None
|
|
||||||
if output_filename is None and "target_dir" in current_target:
|
|
||||||
target_dir = current_target["target_dir"]
|
|
||||||
|
|
||||||
if output_filename is None:
|
|
||||||
output_filename = "{}.rs".format(target_name)
|
|
||||||
|
|
||||||
if kind_name is not None:
|
|
||||||
output_filename = "{}_{}.rs".format(target_name, kind_name)
|
|
||||||
|
|
||||||
if target_dir:
|
|
||||||
output_filename = "{}/{}".format(target_dir, output_filename)
|
|
||||||
|
|
||||||
print("[BINDGEN] {}::{} in \"{}\"... ".format(target_name, kind_name, objdir), end='')
|
|
||||||
sys.stdout.flush()
|
|
||||||
|
|
||||||
flags = []
|
|
||||||
|
|
||||||
# Types we have to fixup since we insert them manually.
|
|
||||||
#
|
|
||||||
# Bindgen only allows us to add stuff outside of the root module. This
|
|
||||||
# wasn't intended to add new types, but we do so, so we postprocess the
|
|
||||||
# bindgen output to fixup the path to these types.
|
|
||||||
fixups = []
|
|
||||||
|
|
||||||
if "manual_fixups" in current_target:
|
|
||||||
fixups = current_target["manual_fixups"]
|
|
||||||
|
|
||||||
# This makes an FFI-safe void type that can't be matched on
|
|
||||||
# &VoidType is UB to have, because you can match on it
|
|
||||||
# to produce a reachable unreachable. If it's wrapped in
|
|
||||||
# a struct as a private field it becomes okay again
|
|
||||||
#
|
|
||||||
# Not 100% sure of how safe this is, but it's what we're using
|
|
||||||
# in the XPCOM ffi too
|
|
||||||
# https://github.com/nikomatsakis/rust-memory-model/issues/2
|
|
||||||
def zero_size_type(ty, flags):
|
|
||||||
flags.append("--blacklist-type")
|
|
||||||
flags.append(ty)
|
|
||||||
flags.append("--raw-line")
|
|
||||||
flags.append("enum {0}Void{{ }}".format(ty))
|
|
||||||
flags.append("--raw-line")
|
|
||||||
flags.append("pub struct {0}({0}Void);".format(ty))
|
|
||||||
|
|
||||||
if "flags" in current_target:
|
|
||||||
flags.extend(current_target["flags"])
|
|
||||||
|
|
||||||
clang_flags = []
|
|
||||||
|
|
||||||
if "clang_flags" in current_target:
|
|
||||||
clang_flags.extend(current_target["clang_flags"])
|
|
||||||
|
|
||||||
clang_flags.extend(platform_dependent_defines())
|
|
||||||
|
|
||||||
if platform.system() == "Windows":
|
|
||||||
flags.append("--use-msvc-mangling")
|
|
||||||
|
|
||||||
if "raw_lines" in current_target:
|
|
||||||
for raw_line in current_target["raw_lines"]:
|
|
||||||
flags.append("--raw-line")
|
|
||||||
flags.append(raw_line)
|
|
||||||
|
|
||||||
if "search_dirs" in current_target:
|
|
||||||
for dir_name in current_target["search_dirs"]:
|
|
||||||
clang_flags.append("-I")
|
|
||||||
clang_flags.append(dir_name.format(objdir))
|
|
||||||
|
|
||||||
if "includes" in current_target:
|
|
||||||
for file_name in current_target["includes"]:
|
|
||||||
clang_flags.append("-include")
|
|
||||||
clang_flags.append(file_name.format(objdir))
|
|
||||||
|
|
||||||
if "whitelist" in current_target:
|
|
||||||
for header in current_target["whitelist"]:
|
|
||||||
flags.append("--whitelist-type")
|
|
||||||
flags.append(header)
|
|
||||||
|
|
||||||
if "whitelist_functions" in current_target:
|
|
||||||
for header in current_target["whitelist_functions"]:
|
|
||||||
flags.append("--whitelist-function")
|
|
||||||
flags.append(header)
|
|
||||||
|
|
||||||
if "whitelist_vars" in current_target:
|
|
||||||
for header in current_target["whitelist_vars"]:
|
|
||||||
flags.append("--whitelist-var")
|
|
||||||
flags.append(header)
|
|
||||||
|
|
||||||
if "bitfield_enum_types" in current_target:
|
|
||||||
for ty in current_target["bitfield_enum_types"]:
|
|
||||||
flags.append("--bitfield-enum")
|
|
||||||
flags.append(ty)
|
|
||||||
|
|
||||||
if "opaque_types" in current_target:
|
|
||||||
for ty in current_target["opaque_types"]:
|
|
||||||
flags.append("--opaque-type")
|
|
||||||
flags.append(ty)
|
|
||||||
|
|
||||||
if "array_types" in current_target:
|
|
||||||
for cpp_type, rust_type in current_target["array_types"].items():
|
|
||||||
flags.append("--blacklist-type")
|
|
||||||
flags.append("nsTArrayBorrowed_{}".format(cpp_type))
|
|
||||||
flags.append("--raw-line")
|
|
||||||
flags.append("pub type nsTArrayBorrowed_{0}<'a> = &'a mut ::gecko_bindings::structs::nsTArray<{1}>;"
|
|
||||||
.format(cpp_type, rust_type))
|
|
||||||
|
|
||||||
if "blacklist_types" in current_target:
|
|
||||||
for ty in current_target["blacklist_types"]:
|
|
||||||
flags.append("--blacklist-type")
|
|
||||||
flags.append(ty)
|
|
||||||
|
|
||||||
if "servo_nullable_arc_types" in current_target:
|
|
||||||
for ty in current_target["servo_nullable_arc_types"]:
|
|
||||||
flags.append("--blacklist-type")
|
|
||||||
flags.append("{}Strong".format(ty))
|
|
||||||
flags.append("--raw-line")
|
|
||||||
flags.append("pub type {0}Strong = ::gecko_bindings::sugar::ownership::Strong<{0}>;"
|
|
||||||
.format(ty))
|
|
||||||
flags.append("--blacklist-type")
|
|
||||||
flags.append("{}BorrowedOrNull".format(ty))
|
|
||||||
flags.append("--raw-line")
|
|
||||||
flags.append("pub type {0}BorrowedOrNull<'a> = \
|
|
||||||
Option<&'a {0}>;".format(ty))
|
|
||||||
flags.append("--blacklist-type")
|
|
||||||
flags.append("{}Borrowed".format(ty))
|
|
||||||
flags.append("--raw-line")
|
|
||||||
flags.append("pub type {0}Borrowed<'a> = &'a {0};".format(ty))
|
|
||||||
zero_size_type(ty, flags)
|
|
||||||
|
|
||||||
if "servo_immutable_borrow_types" in current_target:
|
|
||||||
for ty in current_target.get("servo_immutable_borrow_types", []) + current_target.get("servo_borrow_types", []):
|
|
||||||
flags.append("--blacklist-type")
|
|
||||||
flags.append("{}Borrowed".format(ty))
|
|
||||||
flags.append("--raw-line")
|
|
||||||
flags.append("pub type {0}Borrowed<'a> = &'a {0};".format(ty))
|
|
||||||
flags.append("--blacklist-type")
|
|
||||||
flags.append("{}BorrowedOrNull".format(ty))
|
|
||||||
flags.append("--raw-line")
|
|
||||||
flags.append("pub type {0}BorrowedOrNull<'a> = Option<&'a {0}>;".format(ty))
|
|
||||||
if "servo_borrow_types" in current_target:
|
|
||||||
for ty in current_target["servo_borrow_types"]:
|
|
||||||
flags.append("--blacklist-type")
|
|
||||||
flags.append("{}BorrowedMut".format(ty))
|
|
||||||
flags.append("--raw-line")
|
|
||||||
flags.append("pub type {0}BorrowedMut<'a> = &'a mut {0};".format(ty))
|
|
||||||
flags.append("--blacklist-type")
|
|
||||||
flags.append("{}BorrowedMutOrNull".format(ty))
|
|
||||||
flags.append("--raw-line")
|
|
||||||
flags.append("pub type {0}BorrowedMutOrNull<'a> = \
|
|
||||||
Option<&'a mut {0}>;".format(ty))
|
|
||||||
# Right now the only immutable borrow types are ones which we import
|
|
||||||
# from the |structs| module. As such, we don't need to create an opaque
|
|
||||||
# type with zero_size_type. If we ever introduce immutable borrow types
|
|
||||||
# which _do_ need to be opaque, we'll need a separate mode.
|
|
||||||
|
|
||||||
if "servo_mapped_generic_types" in current_target:
|
|
||||||
for ty in current_target["servo_mapped_generic_types"]:
|
|
||||||
flags.append("--blacklist-type")
|
|
||||||
flags.append(ty["gecko"])
|
|
||||||
|
|
||||||
gecko_name = ty["gecko"].split("::")[-1]
|
|
||||||
flags.append("--raw-line")
|
|
||||||
flags.append("pub type {0}{2} = {1}{2};".format(gecko_name, ty["servo"], "<T>" if ty["generic"] else ""))
|
|
||||||
fixups.append(["root::{}".format(ty["gecko"]), "::gecko_bindings::structs::{}".format(gecko_name)])
|
|
||||||
|
|
||||||
if "servo_owned_types" in current_target:
|
|
||||||
for entry in current_target["servo_owned_types"]:
|
|
||||||
ty = entry["name"]
|
|
||||||
flags.append("--blacklist-type")
|
|
||||||
flags.append("{}Borrowed".format(ty))
|
|
||||||
flags.append("--raw-line")
|
|
||||||
flags.append("pub type {0}Borrowed<'a> = &'a {0};".format(ty))
|
|
||||||
flags.append("--blacklist-type")
|
|
||||||
flags.append("{}BorrowedMut".format(ty))
|
|
||||||
flags.append("--raw-line")
|
|
||||||
flags.append("pub type {0}BorrowedMut<'a> = &'a mut {0};".format(ty))
|
|
||||||
flags.append("--blacklist-type")
|
|
||||||
flags.append("{}Owned".format(ty))
|
|
||||||
flags.append("--raw-line")
|
|
||||||
flags.append("pub type {0}Owned = ::gecko_bindings::sugar::ownership::Owned<{0}>;".format(ty))
|
|
||||||
flags.append("--blacklist-type")
|
|
||||||
flags.append("{}BorrowedOrNull".format(ty))
|
|
||||||
flags.append("--raw-line")
|
|
||||||
flags.append("pub type {0}BorrowedOrNull<'a> = Option<&'a {0}>;"
|
|
||||||
.format(ty))
|
|
||||||
flags.append("--blacklist-type")
|
|
||||||
flags.append("{}BorrowedMutOrNull".format(ty))
|
|
||||||
flags.append("--raw-line")
|
|
||||||
flags.append("pub type {0}BorrowedMutOrNull<'a> = Option<&'a mut {0}>;"
|
|
||||||
.format(ty))
|
|
||||||
flags.append("--blacklist-type")
|
|
||||||
flags.append("{}OwnedOrNull".format(ty))
|
|
||||||
flags.append("--raw-line")
|
|
||||||
flags.append("pub type {0}OwnedOrNull = ::gecko_bindings::sugar::ownership::OwnedOrNull<{0}>;".format(ty))
|
|
||||||
if entry["opaque"]:
|
|
||||||
zero_size_type(ty, flags)
|
|
||||||
|
|
||||||
if "structs_types" in current_target:
|
|
||||||
for ty in current_target["structs_types"]:
|
|
||||||
flags.append("--blacklist-type")
|
|
||||||
flags.append(ty)
|
|
||||||
flags.append("--raw-line")
|
|
||||||
flags.append("use gecko_bindings::structs::{};".format(ty))
|
|
||||||
|
|
||||||
# TODO: this is hacky, figure out a better way to do it without
|
|
||||||
# hardcoding everything...
|
|
||||||
if ty.startswith("nsStyle"):
|
|
||||||
flags.extend([
|
|
||||||
"--raw-line",
|
|
||||||
"unsafe impl Send for {} {{}}".format(ty),
|
|
||||||
"--raw-line",
|
|
||||||
"unsafe impl Sync for {} {{}}".format(ty),
|
|
||||||
])
|
|
||||||
|
|
||||||
flags.append("-o")
|
|
||||||
flags.append(output_filename)
|
|
||||||
|
|
||||||
assert len(current_target["files"]) == 1
|
|
||||||
flags.append(current_target["files"][0].format(objdir))
|
|
||||||
|
|
||||||
flags = bindgen + flags + ["--"] + clang_flags
|
|
||||||
|
|
||||||
if verbose:
|
|
||||||
print(flags)
|
|
||||||
|
|
||||||
output = ""
|
|
||||||
try:
|
|
||||||
if debug:
|
|
||||||
flags = [debugger, "--args"] + flags
|
|
||||||
subprocess.check_call(flags)
|
|
||||||
else:
|
|
||||||
output = subprocess.check_output(flags, stderr=subprocess.STDOUT,
|
|
||||||
universal_newlines=True)
|
|
||||||
except subprocess.CalledProcessError as e:
|
|
||||||
print("FAIL\n", e.output)
|
|
||||||
return 1
|
|
||||||
|
|
||||||
generated = fileinput.input(output_filename, inplace=True)
|
|
||||||
for line in generated:
|
|
||||||
for fixup in fixups:
|
|
||||||
line = re.sub("\\b{}\\b".format(fixup[0]), fixup[1], line)
|
|
||||||
print(line, end='')
|
|
||||||
generated.close()
|
|
||||||
|
|
||||||
print("OK")
|
|
||||||
print("(please test with ./mach test-stylo)")
|
|
||||||
|
|
||||||
if verbose:
|
|
||||||
print(output)
|
|
||||||
|
|
||||||
return 0
|
|
||||||
|
|
||||||
|
|
||||||
def builds_for(target_name, kind):
|
|
||||||
if target_name == "all":
|
|
||||||
for target in COMPILATION_TARGETS.keys():
|
|
||||||
if target == COMMON_BUILD_KEY:
|
|
||||||
continue
|
|
||||||
|
|
||||||
if "build_kinds" in COMPILATION_TARGETS[target]:
|
|
||||||
for kind in COMPILATION_TARGETS[target]["build_kinds"].keys():
|
|
||||||
yield (target, kind)
|
|
||||||
else:
|
|
||||||
yield (target, None)
|
|
||||||
return
|
|
||||||
|
|
||||||
target = COMPILATION_TARGETS[target_name]
|
|
||||||
if "build_kinds" in target:
|
|
||||||
if kind is None:
|
|
||||||
for kind in target["build_kinds"].keys():
|
|
||||||
yield(target_name, kind)
|
|
||||||
else:
|
|
||||||
yield (target_name, kind)
|
|
||||||
return
|
|
||||||
|
|
||||||
yield (target_name, None)
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
parser = argparse.ArgumentParser(description=DESCRIPTION)
|
|
||||||
parser.add_argument('--target', default='all',
|
|
||||||
help='The target to build, either "structs" or "bindings"')
|
|
||||||
parser.add_argument('--kind',
|
|
||||||
help='Kind of build')
|
|
||||||
parser.add_argument('--bindgen',
|
|
||||||
help='Override bindgen binary')
|
|
||||||
parser.add_argument('--output', '-o',
|
|
||||||
help='Output of the script')
|
|
||||||
parser.add_argument('--skip-test',
|
|
||||||
action='store_true',
|
|
||||||
help='Skip automatic tests, useful for debugging')
|
|
||||||
parser.add_argument('--verbose', '-v',
|
|
||||||
action='store_true',
|
|
||||||
help='Be... verbose')
|
|
||||||
parser.add_argument('--debug',
|
|
||||||
action='store_true',
|
|
||||||
help='Try to use a debugger to debug bindgen commands (default: gdb)')
|
|
||||||
parser.add_argument('--debugger', default='gdb',
|
|
||||||
help='Debugger to use. Only used if --debug is passed.')
|
|
||||||
parser.add_argument('objdir')
|
|
||||||
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
if not os.path.isdir(args.objdir):
|
|
||||||
print("\"{}\" doesn't seem to be a directory".format(args.objdir))
|
|
||||||
return 1
|
|
||||||
|
|
||||||
if (args.target != "all" and args.target not in COMPILATION_TARGETS) or args.target == COMMON_BUILD_KEY:
|
|
||||||
print("{} is not a valid compilation target.".format(args.target))
|
|
||||||
print("Valid compilation targets are:")
|
|
||||||
for target in COMPILATION_TARGETS.keys():
|
|
||||||
if target != COMMON_BUILD_KEY:
|
|
||||||
print("\t * {}".format(target))
|
|
||||||
return 1
|
|
||||||
|
|
||||||
current_target = COMPILATION_TARGETS.get(args.target, {})
|
|
||||||
if args.kind and "build_kinds" in current_target and args.kind not in current_target["build_kinds"]:
|
|
||||||
print("{} is not a valid build kind.".format(args.kind))
|
|
||||||
print("Valid build kinds are:")
|
|
||||||
for kind in current_target["build_kinds"].keys():
|
|
||||||
print("\t * {}".format(kind))
|
|
||||||
return 1
|
|
||||||
|
|
||||||
for target, kind in builds_for(args.target, args.kind):
|
|
||||||
ret = build(args.objdir, target, kind_name=kind,
|
|
||||||
debug=args.debug, debugger=args.debugger,
|
|
||||||
bindgen=args.bindgen, skip_test=args.skip_test,
|
|
||||||
output_filename=args.output,
|
|
||||||
verbose=args.verbose)
|
|
||||||
if ret != 0:
|
|
||||||
print("{}::{} failed".format(target, kind))
|
|
||||||
return ret
|
|
||||||
|
|
||||||
return 0
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
sys.exit(main())
|
|
|
@ -1,37 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
||||||
|
|
||||||
set -o errexit
|
|
||||||
set -o nounset
|
|
||||||
set -o pipefail
|
|
||||||
|
|
||||||
TOOLS_DIR="$(dirname ${0})"
|
|
||||||
|
|
||||||
if [[ ${#} -eq 0 ]]; then
|
|
||||||
echo "Usage: ${0} /path/to/gecko/objdir [other-regen.py-flags]"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check for rust-bindgen
|
|
||||||
if [[ ! -d "${TOOLS_DIR}/rust-bindgen" ]]; then
|
|
||||||
echo "rust-bindgen not found. Run setup_bindgen.sh first."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check for /usr/include
|
|
||||||
if [[ ! -d /usr/include ]]; then
|
|
||||||
echo "/usr/include doesn't exist." \
|
|
||||||
"Mac users may need to run 'xcode-select --install.'"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "$(uname)" == "Linux" ]]; then
|
|
||||||
LIBCLANG_PATH=/usr/lib/llvm-3.8/lib
|
|
||||||
else
|
|
||||||
LIBCLANG_PATH="$(brew --prefix llvm38)/lib/llvm-3.8/lib"
|
|
||||||
fi
|
|
||||||
|
|
||||||
"./${TOOLS_DIR}/regen.py" --target all "${@}"
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
import re
|
import re
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
PRELUDE = """
|
PRELUDE = """
|
||||||
|
@ -231,8 +232,10 @@ def write_pseudo_element_helper(atoms, target_filename):
|
||||||
f.write("}\n")
|
f.write("}\n")
|
||||||
|
|
||||||
|
|
||||||
def build(objdir, verbose=False):
|
if len(sys.argv) != 2:
|
||||||
atoms = collect_atoms(objdir)
|
print("Usage: {} objdir".format(sys.argv[0]))
|
||||||
write_atom_macro(atoms, "../gecko_string_cache/atom_macro.rs")
|
exit(2)
|
||||||
write_pseudo_element_helper(atoms, "../gecko/generated/gecko_pseudo_element_helper.rs")
|
|
||||||
return 0
|
atoms = collect_atoms(sys.argv[1])
|
||||||
|
write_atom_macro(atoms, "../gecko_string_cache/atom_macro.rs")
|
||||||
|
write_pseudo_element_helper(atoms, "../gecko/generated/gecko_pseudo_element_helper.rs")
|
||||||
|
|
|
@ -28,11 +28,3 @@ fi
|
||||||
|
|
||||||
export LD_LIBRARY_PATH="${LIBCLANG_PATH}"
|
export LD_LIBRARY_PATH="${LIBCLANG_PATH}"
|
||||||
export DYLD_LIBRARY_PATH="${LIBCLANG_PATH}"
|
export DYLD_LIBRARY_PATH="${LIBCLANG_PATH}"
|
||||||
|
|
||||||
# Don't try to clone twice.
|
|
||||||
if [[ ! -d rust-bindgen ]]; then
|
|
||||||
git clone https://github.com/servo/rust-bindgen.git
|
|
||||||
fi
|
|
||||||
|
|
||||||
cd rust-bindgen
|
|
||||||
cargo build --features llvm_stable --release
|
|
||||||
|
|
|
@ -2,6 +2,12 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate lazy_static;
|
||||||
|
#[cfg(feature = "bindgen")]
|
||||||
|
extern crate libbindgen;
|
||||||
|
#[cfg(feature = "bindgen")]
|
||||||
|
extern crate regex;
|
||||||
extern crate walkdir;
|
extern crate walkdir;
|
||||||
extern crate phf_codegen;
|
extern crate phf_codegen;
|
||||||
|
|
||||||
|
@ -12,6 +18,14 @@ use std::path::Path;
|
||||||
use std::process::{Command, exit};
|
use std::process::{Command, exit};
|
||||||
use walkdir::WalkDir;
|
use walkdir::WalkDir;
|
||||||
|
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
mod build_gecko;
|
||||||
|
|
||||||
|
#[cfg(not(feature = "gecko"))]
|
||||||
|
mod build_gecko {
|
||||||
|
pub fn generate() {}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
fn find_python() -> String {
|
fn find_python() -> String {
|
||||||
if Command::new("python2.7.exe").arg("--version").output().is_ok() {
|
if Command::new("python2.7.exe").arg("--version").output().is_ok() {
|
||||||
|
@ -39,8 +53,7 @@ fn find_python() -> String {
|
||||||
}.to_owned()
|
}.to_owned()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn generate_properties() {
|
||||||
println!("cargo:rerun-if-changed=build.rs");
|
|
||||||
for entry in WalkDir::new("properties") {
|
for entry in WalkDir::new("properties") {
|
||||||
let entry = entry.unwrap();
|
let entry = entry.unwrap();
|
||||||
match entry.path().extension().and_then(|e| e.to_str()) {
|
match entry.path().extension().and_then(|e| e.to_str()) {
|
||||||
|
@ -82,3 +95,9 @@ fn main() {
|
||||||
map.build(&mut file).unwrap();
|
map.build(&mut file).unwrap();
|
||||||
write!(&mut file, ";\n").unwrap();
|
write!(&mut file, ";\n").unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
println!("cargo:rerun-if-changed=build.rs");
|
||||||
|
generate_properties();
|
||||||
|
build_gecko::generate();
|
||||||
|
}
|
||||||
|
|
617
components/style/build_gecko.rs
Normal file
617
components/style/build_gecko.rs
Normal file
|
@ -0,0 +1,617 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
mod common {
|
||||||
|
use std::env;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
pub static ref OUTDIR_PATH: PathBuf = PathBuf::from(env::var("OUT_DIR").unwrap()).join("gecko");
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const STRUCTS_DEBUG_FILE: &'static str = "structs_debug.rs";
|
||||||
|
pub const STRUCTS_RELEASE_FILE: &'static str = "structs_release.rs";
|
||||||
|
pub const BINDINGS_FILE: &'static str = "bindings.rs";
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, PartialEq)]
|
||||||
|
pub enum BuildType {
|
||||||
|
Debug,
|
||||||
|
Release,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn structs_file(build_type: BuildType) -> &'static str {
|
||||||
|
match build_type {
|
||||||
|
BuildType::Debug => STRUCTS_DEBUG_FILE,
|
||||||
|
BuildType::Release => STRUCTS_RELEASE_FILE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "bindgen")]
|
||||||
|
mod bindings {
|
||||||
|
use libbindgen::{Builder, CodegenConfig};
|
||||||
|
use regex::Regex;
|
||||||
|
use std::collections::HashSet;
|
||||||
|
use std::env;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::{BufWriter, Read, Write};
|
||||||
|
use std::path::PathBuf;
|
||||||
|
use std::sync::Mutex;
|
||||||
|
use super::common::*;
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
static ref INCLUDE_RE: Regex = Regex::new(r#"#include\s*"(.+?)""#).unwrap();
|
||||||
|
static ref DISTDIR_PATH: PathBuf = PathBuf::from(env::var("MOZ_DIST").unwrap());
|
||||||
|
static ref SEARCH_PATHS: Vec<PathBuf> = vec![
|
||||||
|
DISTDIR_PATH.join("include"),
|
||||||
|
DISTDIR_PATH.join("include/nspr"),
|
||||||
|
];
|
||||||
|
static ref ADDED_PATHS: Mutex<HashSet<PathBuf>> = Mutex::new(HashSet::new());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn search_include(name: &str) -> Option<PathBuf> {
|
||||||
|
for path in SEARCH_PATHS.iter() {
|
||||||
|
let file = path.join(name);
|
||||||
|
if file.is_file() {
|
||||||
|
return Some(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_headers_recursively(path: PathBuf, added_paths: &mut HashSet<PathBuf>) {
|
||||||
|
if added_paths.contains(&path) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let mut file = File::open(&path).unwrap();
|
||||||
|
let mut content = String::new();
|
||||||
|
file.read_to_string(&mut content).unwrap();
|
||||||
|
println!("cargo:rerun-if-changed={}", path.to_str().unwrap());
|
||||||
|
added_paths.insert(path);
|
||||||
|
// Find all includes and add them recursively
|
||||||
|
for cap in INCLUDE_RE.captures_iter(&content) {
|
||||||
|
if let Some(path) = search_include(cap.at(1).unwrap()) {
|
||||||
|
add_headers_recursively(path, added_paths);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_include(name: &str) -> String {
|
||||||
|
let mut added_paths = ADDED_PATHS.lock().unwrap();
|
||||||
|
let file = search_include(name).unwrap();
|
||||||
|
let result = String::from(file.to_str().unwrap());
|
||||||
|
add_headers_recursively(file, &mut *added_paths);
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
trait BuilderExt {
|
||||||
|
fn get_initial_builder(build_type: BuildType) -> Builder;
|
||||||
|
fn include<T: Into<String>>(self, file: T) -> Builder;
|
||||||
|
fn zero_size_type(self, ty: &str) -> Builder;
|
||||||
|
fn borrowed_type(self, ty: &str) -> Builder;
|
||||||
|
fn mutable_borrowed_type(self, ty: &str) -> Builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BuilderExt for Builder {
|
||||||
|
fn get_initial_builder(build_type: BuildType) -> Builder {
|
||||||
|
let mut builder = Builder::default().no_unstable_rust();
|
||||||
|
let args = [
|
||||||
|
"-x", "c++", "-std=c++14",
|
||||||
|
"-DTRACING=1", "-DIMPL_LIBXUL", "-DMOZ_STYLO_BINDINGS=1",
|
||||||
|
"-DMOZILLA_INTERNAL_API", "-DRUST_BINDGEN", "-DMOZ_STYLO"
|
||||||
|
];
|
||||||
|
for &arg in args.iter() {
|
||||||
|
builder = builder.clang_arg(arg);
|
||||||
|
}
|
||||||
|
for dir in SEARCH_PATHS.iter() {
|
||||||
|
builder = builder.clang_arg("-I").clang_arg(dir.to_str().unwrap());
|
||||||
|
}
|
||||||
|
builder = builder.include(add_include("mozilla-config.h"));
|
||||||
|
|
||||||
|
if build_type == BuildType::Debug {
|
||||||
|
builder = builder.clang_arg("-DDEBUG=1").clang_arg("-DJS_DEBUG=1");
|
||||||
|
}
|
||||||
|
if cfg!(target_family = "unix") {
|
||||||
|
builder = builder.clang_arg("-DOS_POSIX=1");
|
||||||
|
}
|
||||||
|
if cfg!(target_os = "linux") {
|
||||||
|
builder = builder.clang_arg("-DOS_LINUX=1");
|
||||||
|
} else if cfg!(target_os = "macos") {
|
||||||
|
builder = builder.clang_arg("-DOS_MACOSX=1");
|
||||||
|
} else if cfg!(target_env = "msvc") {
|
||||||
|
builder = builder.clang_arg("-DOS_WIN=1").clang_arg("-DWIN32=1")
|
||||||
|
// For compatibility with MSVC 2015
|
||||||
|
.clang_arg("-fms-compatibility-version=19")
|
||||||
|
// To enable the builtin __builtin_offsetof so that CRT wouldn't
|
||||||
|
// use reinterpret_cast in offsetof() which is not allowed inside
|
||||||
|
// static_assert().
|
||||||
|
.clang_arg("-D_CRT_USE_BUILTIN_OFFSETOF")
|
||||||
|
// Enable hidden attribute (which is not supported by MSVC and
|
||||||
|
// thus not enabled by default with a MSVC-compatibile build)
|
||||||
|
// to exclude hidden symbols from the generated file.
|
||||||
|
.clang_arg("-DHAVE_VISIBILITY_HIDDEN_ATTRIBUTE=1");
|
||||||
|
if cfg!(target_pointer_width = "32") {
|
||||||
|
builder = builder.clang_arg("--target=i686-pc-win32");
|
||||||
|
} else {
|
||||||
|
builder = builder.clang_arg("--target=x86_64-pc-win32");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
panic!("Unknown platform");
|
||||||
|
}
|
||||||
|
builder
|
||||||
|
}
|
||||||
|
fn include<T: Into<String>>(self, file: T) -> Builder {
|
||||||
|
self.clang_arg("-include").clang_arg(file)
|
||||||
|
}
|
||||||
|
// This makes an FFI-safe void type that can't be matched on
|
||||||
|
// &VoidType is UB to have, because you can match on it
|
||||||
|
// to produce a reachable unreachable. If it's wrapped in
|
||||||
|
// a struct as a private field it becomes okay again
|
||||||
|
//
|
||||||
|
// Not 100% sure of how safe this is, but it's what we're using
|
||||||
|
// in the XPCOM ffi too
|
||||||
|
// https://github.com/nikomatsakis/rust-memory-model/issues/2
|
||||||
|
fn zero_size_type(self, ty: &str) -> Builder {
|
||||||
|
self.hide_type(ty)
|
||||||
|
.raw_line(format!("enum {}Void {{ }}", ty))
|
||||||
|
.raw_line(format!("pub struct {0}({0}Void);", ty))
|
||||||
|
}
|
||||||
|
fn borrowed_type(self, ty: &str) -> Builder {
|
||||||
|
self.hide_type(format!("{}Borrowed", ty))
|
||||||
|
.raw_line(format!("pub type {0}Borrowed<'a> = &'a {0};", ty))
|
||||||
|
.hide_type(format!("{}BorrowedOrNull", ty))
|
||||||
|
.raw_line(format!("pub type {0}BorrowedOrNull<'a> = Option<&'a {0}>;", ty))
|
||||||
|
}
|
||||||
|
fn mutable_borrowed_type(self, ty: &str) -> Builder {
|
||||||
|
self.borrowed_type(ty)
|
||||||
|
.hide_type(format!("{}BorrowedMut", ty))
|
||||||
|
.raw_line(format!("pub type {0}BorrowedMut<'a> = &'a mut {0};", ty))
|
||||||
|
.hide_type(format!("{}BorrowedMutOrNull", ty))
|
||||||
|
.raw_line(format!("pub type {0}BorrowedMutOrNull<'a> = Option<&'a mut {0}>;", ty))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write_binding_file(builder: Builder, file: &str) {
|
||||||
|
let bindings = builder.generate().expect("Unable to generate bindings");
|
||||||
|
let binding_file = File::create(&OUTDIR_PATH.join(file)).unwrap();
|
||||||
|
bindings.write(Box::new(BufWriter::new(binding_file))).expect("Unable to write output");
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn generate_structs(build_type: BuildType) {
|
||||||
|
let mut builder = Builder::get_initial_builder(build_type)
|
||||||
|
.enable_cxx_namespaces()
|
||||||
|
.with_codegen_config(CodegenConfig {
|
||||||
|
types: true,
|
||||||
|
vars: true,
|
||||||
|
..CodegenConfig::nothing()
|
||||||
|
})
|
||||||
|
.header(add_include("nsStyleStruct.h"))
|
||||||
|
.include(add_include("gfxFontConstants.h"))
|
||||||
|
.include(add_include("nsThemeConstants.h"))
|
||||||
|
.include(add_include("mozilla/dom/AnimationEffectReadOnlyBinding.h"))
|
||||||
|
.include(add_include("mozilla/ServoElementSnapshot.h"))
|
||||||
|
.include(add_include("mozilla/dom/Element.h"))
|
||||||
|
.include(add_include("mozilla/ServoBindings.h"))
|
||||||
|
// FIXME(emilio): Incrementally remove these "pub use"s. Probably
|
||||||
|
// mozilla::css and mozilla::dom are easier.
|
||||||
|
.raw_line("pub use self::root::*;")
|
||||||
|
.raw_line("pub use self::root::mozilla::*;")
|
||||||
|
.raw_line("pub use self::root::mozilla::css::*;")
|
||||||
|
.raw_line("pub use self::root::mozilla::dom::*;")
|
||||||
|
.raw_line("use atomic_refcell::AtomicRefCell;")
|
||||||
|
.raw_line("use data::ElementData;")
|
||||||
|
.hide_type("nsString")
|
||||||
|
.bitfield_enum("nsChangeHint")
|
||||||
|
.bitfield_enum("nsRestyleHint");
|
||||||
|
let whitelist_vars = [
|
||||||
|
"NS_THEME_.*",
|
||||||
|
"NODE_.*",
|
||||||
|
"NS_FONT_.*",
|
||||||
|
"NS_STYLE_.*",
|
||||||
|
"NS_CORNER_.*",
|
||||||
|
"NS_RADIUS_.*",
|
||||||
|
"BORDER_COLOR_.*",
|
||||||
|
"BORDER_STYLE_.*"
|
||||||
|
];
|
||||||
|
let whitelist = [
|
||||||
|
"RawGecko.*",
|
||||||
|
"mozilla::ServoElementSnapshot.*",
|
||||||
|
"mozilla::ConsumeStyleBehavior",
|
||||||
|
"mozilla::LazyComputeBehavior",
|
||||||
|
"mozilla::css::SheetParsingMode",
|
||||||
|
"mozilla::SkipRootBehavior",
|
||||||
|
"mozilla::DisplayItemClip", // Needed because bindgen generates
|
||||||
|
// specialization tests for this even
|
||||||
|
// though it shouldn't.
|
||||||
|
".*ThreadSafe.*Holder",
|
||||||
|
"AnonymousContent",
|
||||||
|
"AudioContext",
|
||||||
|
"CapturingContentInfo",
|
||||||
|
"ConsumeStyleBehavior",
|
||||||
|
"DefaultDelete",
|
||||||
|
"DOMIntersectionObserverEntry",
|
||||||
|
"Element",
|
||||||
|
"FontFamilyList",
|
||||||
|
"FontFamilyListRefCnt",
|
||||||
|
"FontFamilyName",
|
||||||
|
"FontFamilyType",
|
||||||
|
"FragmentOrURL",
|
||||||
|
"FrameRequestCallback",
|
||||||
|
"gfxAlternateValue",
|
||||||
|
"gfxFontFeature",
|
||||||
|
"gfxFontVariation",
|
||||||
|
"GridNamedArea",
|
||||||
|
"Image",
|
||||||
|
"ImageURL",
|
||||||
|
"LazyComputeBehavior",
|
||||||
|
"nsAttrName",
|
||||||
|
"nsAttrValue",
|
||||||
|
"nsBorderColors",
|
||||||
|
"nscolor",
|
||||||
|
"nsChangeHint",
|
||||||
|
"nsCSSKeyword",
|
||||||
|
"nsCSSPropertyID",
|
||||||
|
"nsCSSRect",
|
||||||
|
"nsCSSRect_heap",
|
||||||
|
"nsCSSShadowArray",
|
||||||
|
"nsCSSValue",
|
||||||
|
"nsCSSValueFloatColor",
|
||||||
|
"nsCSSValueGradient",
|
||||||
|
"nsCSSValueGradientStop",
|
||||||
|
"nsCSSValueList",
|
||||||
|
"nsCSSValueList_heap",
|
||||||
|
"nsCSSValuePair_heap",
|
||||||
|
"nsCSSValuePairList",
|
||||||
|
"nsCSSValuePairList_heap",
|
||||||
|
"nsCSSValueTokenStream",
|
||||||
|
"nsCSSValueTriplet_heap",
|
||||||
|
"nsCursorImage",
|
||||||
|
"nsFont",
|
||||||
|
"nsIAtom",
|
||||||
|
"nsMainThreadPtrHandle",
|
||||||
|
"nsMainThreadPtrHolder",
|
||||||
|
"nsMargin",
|
||||||
|
"nsRect",
|
||||||
|
"nsRestyleHint",
|
||||||
|
"nsresult",
|
||||||
|
"nsSize",
|
||||||
|
"nsStyleBackground",
|
||||||
|
"nsStyleBorder",
|
||||||
|
"nsStyleColor",
|
||||||
|
"nsStyleColumn",
|
||||||
|
"nsStyleContent",
|
||||||
|
"nsStyleContentData",
|
||||||
|
"nsStyleContext",
|
||||||
|
"nsStyleCoord",
|
||||||
|
"nsStyleCounterData",
|
||||||
|
"nsStyleDisplay",
|
||||||
|
"nsStyleEffects",
|
||||||
|
"nsStyleFilter",
|
||||||
|
"nsStyleFont",
|
||||||
|
"nsStyleGradient",
|
||||||
|
"nsStyleGradientStop",
|
||||||
|
"nsStyleImage",
|
||||||
|
"nsStyleImageLayers",
|
||||||
|
"nsStyleList",
|
||||||
|
"nsStyleMargin",
|
||||||
|
"nsStyleOutline",
|
||||||
|
"nsStylePadding",
|
||||||
|
"nsStylePosition",
|
||||||
|
"nsStyleSVG",
|
||||||
|
"nsStyleSVGReset",
|
||||||
|
"nsStyleTable",
|
||||||
|
"nsStyleTableBorder",
|
||||||
|
"nsStyleText",
|
||||||
|
"nsStyleTextReset",
|
||||||
|
"nsStyleUIReset",
|
||||||
|
"nsStyleUnion",
|
||||||
|
"nsStyleUnit",
|
||||||
|
"nsStyleUserInterface",
|
||||||
|
"nsStyleVariables",
|
||||||
|
"nsStyleVisibility",
|
||||||
|
"nsStyleXUL",
|
||||||
|
"nsTArray",
|
||||||
|
"nsTArrayHeader",
|
||||||
|
"pair",
|
||||||
|
"Position",
|
||||||
|
"Runnable",
|
||||||
|
"ServoAttrSnapshot",
|
||||||
|
"ServoElementSnapshot",
|
||||||
|
"SheetParsingMode",
|
||||||
|
"mozilla::Side",
|
||||||
|
"StaticRefPtr",
|
||||||
|
"StyleAnimation",
|
||||||
|
"StyleBasicShape",
|
||||||
|
"StyleBasicShapeType",
|
||||||
|
"StyleClipPath",
|
||||||
|
"StyleClipPathGeometryBox",
|
||||||
|
"StyleTransition",
|
||||||
|
"mozilla::UniquePtr",
|
||||||
|
"mozilla::DefaultDelete",
|
||||||
|
];
|
||||||
|
let opaque_types = [
|
||||||
|
"atomic___base", "std::atomic__My_base",
|
||||||
|
"nsAString_internal_char_traits",
|
||||||
|
"nsAString_internal_incompatible_char_type",
|
||||||
|
"nsACString_internal_char_traits",
|
||||||
|
"nsACString_internal_incompatible_char_type",
|
||||||
|
"RefPtr_Proxy",
|
||||||
|
"RefPtr_Proxy_member_function",
|
||||||
|
"nsAutoPtr_Proxy",
|
||||||
|
"nsAutoPtr_Proxy_member_function",
|
||||||
|
"mozilla::detail::PointerType",
|
||||||
|
"mozilla::Pair_Base",
|
||||||
|
"mozilla::SupportsWeakPtr",
|
||||||
|
"SupportsWeakPtr",
|
||||||
|
"mozilla::detail::WeakReference",
|
||||||
|
"mozilla::WeakPtr",
|
||||||
|
"nsWritingIterator_reference", "nsReadingIterator_reference",
|
||||||
|
"nsTObserverArray", // <- Inherits from nsAutoTObserverArray<T, 0>
|
||||||
|
"nsTHashtable", // <- Inheriting from inner typedefs that clang
|
||||||
|
// doesn't expose properly.
|
||||||
|
"nsRefPtrHashtable", "nsDataHashtable", "nsClassHashtable", // <- Ditto
|
||||||
|
"nsIDocument_SelectorCache", // <- Inherits from nsExpirationTracker<.., 4>
|
||||||
|
"nsIPresShell_ScrollAxis", // <- For some reason the alignment of this is 4
|
||||||
|
// for clang.
|
||||||
|
"nsPIDOMWindow", // <- Takes the vtable from a template parameter, and we can't
|
||||||
|
// generate it conditionally.
|
||||||
|
"JS::Rooted",
|
||||||
|
"mozilla::Maybe",
|
||||||
|
"gfxSize", // <- union { struct { T width; T height; }; T components[2] };
|
||||||
|
"gfxSize_Super", // Ditto.
|
||||||
|
"mozilla::ErrorResult", // Causes JSWhyMagic to be included & handled incorrectly.
|
||||||
|
];
|
||||||
|
struct MappedGenericType {
|
||||||
|
generic: bool,
|
||||||
|
gecko: &'static str,
|
||||||
|
servo: &'static str,
|
||||||
|
}
|
||||||
|
let servo_mapped_generic_types = [
|
||||||
|
MappedGenericType {
|
||||||
|
generic: true,
|
||||||
|
gecko: "mozilla::ServoUnsafeCell",
|
||||||
|
servo: "::std::cell::UnsafeCell"
|
||||||
|
},
|
||||||
|
MappedGenericType {
|
||||||
|
generic: true,
|
||||||
|
gecko: "mozilla::ServoCell",
|
||||||
|
servo: "::std::cell::Cell"
|
||||||
|
},
|
||||||
|
MappedGenericType {
|
||||||
|
generic: false,
|
||||||
|
gecko: "ServoNodeData",
|
||||||
|
servo: "AtomicRefCell<ElementData>",
|
||||||
|
}
|
||||||
|
];
|
||||||
|
struct Fixup {
|
||||||
|
pat: String,
|
||||||
|
rep: String
|
||||||
|
}
|
||||||
|
let mut fixups = vec![
|
||||||
|
Fixup {
|
||||||
|
pat: "root::nsString".into(),
|
||||||
|
rep: "::nsstring::nsStringRepr".into()
|
||||||
|
},
|
||||||
|
];
|
||||||
|
for &var in whitelist_vars.iter() {
|
||||||
|
builder = builder.whitelisted_var(var);
|
||||||
|
}
|
||||||
|
for &ty in whitelist.iter() {
|
||||||
|
builder = builder.whitelisted_type(ty);
|
||||||
|
}
|
||||||
|
for &ty in opaque_types.iter() {
|
||||||
|
builder = builder.opaque_type(ty);
|
||||||
|
}
|
||||||
|
for ty in servo_mapped_generic_types.iter() {
|
||||||
|
let gecko_name = ty.gecko.rsplit("::").next().unwrap();
|
||||||
|
builder = builder.hide_type(ty.gecko)
|
||||||
|
.raw_line(format!("pub type {0}{2} = {1}{2};", gecko_name, ty.servo,
|
||||||
|
if ty.generic { "<T>" } else { "" }));
|
||||||
|
fixups.push(Fixup {
|
||||||
|
pat: format!("root::{}", ty.gecko),
|
||||||
|
rep: format!("::gecko_bindings::structs::{}", gecko_name)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
let mut result = builder.generate().expect("Unable to generate bindings").to_string();
|
||||||
|
for fixup in fixups.iter() {
|
||||||
|
result = Regex::new(&format!(r"\b{}\b", fixup.pat)).unwrap().replace_all(&result, fixup.rep.as_str());
|
||||||
|
}
|
||||||
|
File::create(&OUTDIR_PATH.join(structs_file(build_type))).unwrap()
|
||||||
|
.write_all(&result.into_bytes()).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn generate_bindings() {
|
||||||
|
let mut builder = Builder::get_initial_builder(BuildType::Release)
|
||||||
|
.disable_name_namespacing()
|
||||||
|
.with_codegen_config(CodegenConfig {
|
||||||
|
functions: true,
|
||||||
|
..CodegenConfig::nothing()
|
||||||
|
})
|
||||||
|
.header(add_include("mozilla/ServoBindings.h"))
|
||||||
|
.hide_type("nsACString_internal")
|
||||||
|
.hide_type("nsAString_internal")
|
||||||
|
.raw_line("pub use nsstring::{nsACString, nsAString};")
|
||||||
|
.raw_line("type nsACString_internal = nsACString;")
|
||||||
|
.raw_line("type nsAString_internal = nsAString;")
|
||||||
|
.whitelisted_function("Servo_.*")
|
||||||
|
.whitelisted_function("Gecko_.*");
|
||||||
|
let structs_types = [
|
||||||
|
"RawGeckoDocument",
|
||||||
|
"RawGeckoElement",
|
||||||
|
"RawGeckoNode",
|
||||||
|
"ThreadSafeURIHolder",
|
||||||
|
"ThreadSafePrincipalHolder",
|
||||||
|
"ConsumeStyleBehavior",
|
||||||
|
"LazyComputeBehavior",
|
||||||
|
"SkipRootBehavior",
|
||||||
|
"FontFamilyList",
|
||||||
|
"FontFamilyType",
|
||||||
|
"ServoElementSnapshot",
|
||||||
|
"SheetParsingMode",
|
||||||
|
"StyleBasicShape",
|
||||||
|
"StyleBasicShapeType",
|
||||||
|
"StyleClipPath",
|
||||||
|
"nsCSSKeyword",
|
||||||
|
"nsCSSShadowArray",
|
||||||
|
"nsCSSValue",
|
||||||
|
"nsCSSValueSharedList",
|
||||||
|
"nsChangeHint",
|
||||||
|
"nsCursorImage",
|
||||||
|
"nsFont",
|
||||||
|
"nsIAtom",
|
||||||
|
"nsRestyleHint",
|
||||||
|
"nsStyleBackground",
|
||||||
|
"nsStyleBorder",
|
||||||
|
"nsStyleColor",
|
||||||
|
"nsStyleColumn",
|
||||||
|
"nsStyleContent",
|
||||||
|
"nsStyleContext",
|
||||||
|
"nsStyleCoord",
|
||||||
|
"nsStyleCoord_Calc",
|
||||||
|
"nsStyleCoord_CalcValue",
|
||||||
|
"nsStyleDisplay",
|
||||||
|
"nsStyleEffects",
|
||||||
|
"nsStyleFont",
|
||||||
|
"nsStyleGradient",
|
||||||
|
"nsStyleGradientStop",
|
||||||
|
"nsStyleImage",
|
||||||
|
"nsStyleImageLayers",
|
||||||
|
"nsStyleImageLayers_Layer",
|
||||||
|
"nsStyleImageLayers_LayerType",
|
||||||
|
"nsStyleImageRequest",
|
||||||
|
"nsStyleList",
|
||||||
|
"nsStyleMargin",
|
||||||
|
"nsStyleOutline",
|
||||||
|
"nsStylePadding",
|
||||||
|
"nsStylePosition",
|
||||||
|
"nsStyleQuoteValues",
|
||||||
|
"nsStyleSVG",
|
||||||
|
"nsStyleSVGReset",
|
||||||
|
"nsStyleTable",
|
||||||
|
"nsStyleTableBorder",
|
||||||
|
"nsStyleText",
|
||||||
|
"nsStyleTextReset",
|
||||||
|
"nsStyleUIReset",
|
||||||
|
"nsStyleUnion",
|
||||||
|
"nsStyleUnit",
|
||||||
|
"nsStyleUserInterface",
|
||||||
|
"nsStyleVariables",
|
||||||
|
"nsStyleVisibility",
|
||||||
|
"nsStyleXUL",
|
||||||
|
"nscoord",
|
||||||
|
"nsresult",
|
||||||
|
];
|
||||||
|
struct ArrayType {
|
||||||
|
cpp_type: &'static str,
|
||||||
|
rust_type: &'static str
|
||||||
|
}
|
||||||
|
let array_types = [
|
||||||
|
ArrayType { cpp_type: "uintptr_t", rust_type: "usize" },
|
||||||
|
];
|
||||||
|
let servo_nullable_arc_types = [
|
||||||
|
"ServoComputedValues",
|
||||||
|
"ServoCssRules",
|
||||||
|
"RawServoStyleSheet",
|
||||||
|
"RawServoDeclarationBlock",
|
||||||
|
"RawServoStyleRule",
|
||||||
|
];
|
||||||
|
struct ServoOwnedType {
|
||||||
|
name: &'static str,
|
||||||
|
opaque: bool,
|
||||||
|
}
|
||||||
|
let servo_owned_types = [
|
||||||
|
ServoOwnedType { name: "RawServoStyleSet", opaque: true },
|
||||||
|
ServoOwnedType { name: "StyleChildrenIterator", opaque: true },
|
||||||
|
ServoOwnedType { name: "ServoElementSnapshot", opaque: false },
|
||||||
|
];
|
||||||
|
let servo_immutable_borrow_types = [
|
||||||
|
"RawGeckoNode",
|
||||||
|
"RawGeckoElement",
|
||||||
|
"RawGeckoDocument",
|
||||||
|
"RawServoDeclarationBlockStrong",
|
||||||
|
];
|
||||||
|
let servo_borrow_types = [
|
||||||
|
"nsCSSValue",
|
||||||
|
];
|
||||||
|
for &ty in structs_types.iter() {
|
||||||
|
builder = builder.hide_type(ty)
|
||||||
|
.raw_line(format!("use gecko_bindings::structs::{};", ty));
|
||||||
|
// TODO this is hacky, figure out a better way to do it without
|
||||||
|
// hardcoding everything...
|
||||||
|
if ty.starts_with("nsStyle") {
|
||||||
|
builder = builder
|
||||||
|
.raw_line(format!("unsafe impl Send for {} {{}}", ty))
|
||||||
|
.raw_line(format!("unsafe impl Sync for {} {{}}", ty));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for &ArrayType { cpp_type, rust_type } in array_types.iter() {
|
||||||
|
builder = builder.hide_type(format!("nsTArrayBorrowed_{}", cpp_type))
|
||||||
|
.raw_line(format!("pub type nsTArrayBorrowed_{}<'a> = &'a mut ::gecko_bindings::structs::nsTArray<{}>;",
|
||||||
|
cpp_type, rust_type))
|
||||||
|
}
|
||||||
|
for &ty in servo_nullable_arc_types.iter() {
|
||||||
|
builder = builder
|
||||||
|
.hide_type(format!("{}Strong", ty))
|
||||||
|
.raw_line(format!("pub type {0}Strong = ::gecko_bindings::sugar::ownership::Strong<{0}>;", ty))
|
||||||
|
.borrowed_type(ty)
|
||||||
|
.zero_size_type(ty);
|
||||||
|
}
|
||||||
|
for &ServoOwnedType { name, opaque } in servo_owned_types.iter() {
|
||||||
|
builder = builder
|
||||||
|
.hide_type(format!("{}Owned", name))
|
||||||
|
.raw_line(format!("pub type {0}Owned = ::gecko_bindings::sugar::ownership::Owned<{0}>;", name))
|
||||||
|
.hide_type(format!("{}OwnedOrNull", name))
|
||||||
|
.raw_line(format!("pub type {0}OwnedOrNull = ::gecko_bindings::sugar::ownership::OwnedOrNull<{0}>;",
|
||||||
|
name))
|
||||||
|
.mutable_borrowed_type(name);
|
||||||
|
if opaque {
|
||||||
|
builder = builder.zero_size_type(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for &ty in servo_immutable_borrow_types.iter() {
|
||||||
|
builder = builder.borrowed_type(ty);
|
||||||
|
}
|
||||||
|
for &ty in servo_borrow_types.iter() {
|
||||||
|
builder = builder.mutable_borrowed_type(ty);
|
||||||
|
// Right now the only immutable borrow types are ones which we import
|
||||||
|
// from the |structs| module. As such, we don't need to create an opaque
|
||||||
|
// type with zero_size_type. If we ever introduce immutable borrow types
|
||||||
|
// which _do_ need to be opaque, we'll need a separate mode.
|
||||||
|
}
|
||||||
|
write_binding_file(builder, BINDINGS_FILE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "bindgen"))]
|
||||||
|
mod bindings {
|
||||||
|
use std::fs;
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
use super::common::*;
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
static ref BINDINGS_PATH: PathBuf = Path::new(file!()).parent().unwrap().join("gecko_bindings");
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn generate_structs(build_type: BuildType) {
|
||||||
|
let file = structs_file(build_type);
|
||||||
|
let source = BINDINGS_PATH.join(file);
|
||||||
|
println!("cargo:rerun-if-changed={}", source.display());
|
||||||
|
fs::copy(source, OUTDIR_PATH.join(file)).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn generate_bindings() {
|
||||||
|
let source = BINDINGS_PATH.join(BINDINGS_FILE);
|
||||||
|
println!("cargo:rerun-if-changed={}", source.display());
|
||||||
|
fs::copy(source, OUTDIR_PATH.join(BINDINGS_FILE)).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn generate() {
|
||||||
|
use self::common::*;
|
||||||
|
use std::fs;
|
||||||
|
fs::create_dir_all(&*OUTDIR_PATH).unwrap();
|
||||||
|
bindings::generate_structs(BuildType::Debug);
|
||||||
|
bindings::generate_structs(BuildType::Release);
|
||||||
|
bindings::generate_bindings();
|
||||||
|
}
|
|
@ -3,22 +3,23 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#[allow(dead_code, improper_ctypes, non_camel_case_types)]
|
#[allow(dead_code, improper_ctypes, non_camel_case_types)]
|
||||||
pub mod bindings;
|
pub mod bindings {
|
||||||
|
include!(concat!(env!("OUT_DIR"), "/gecko/bindings.rs"));
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME: We allow `improper_ctypes` (for now), because the lint doesn't allow
|
// FIXME: We allow `improper_ctypes` (for now), because the lint doesn't allow
|
||||||
// foreign structs to have `PhantomData`. We should remove this once the lint
|
// foreign structs to have `PhantomData`. We should remove this once the lint
|
||||||
// ignores this case.
|
// ignores this case.
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
#[allow(dead_code, improper_ctypes, non_camel_case_types, non_snake_case, non_upper_case_globals)]
|
#[allow(dead_code, improper_ctypes, non_camel_case_types, non_snake_case, non_upper_case_globals)]
|
||||||
pub mod structs {
|
pub mod structs {
|
||||||
include!("structs_debug.rs");
|
cfg_if! {
|
||||||
}
|
if #[cfg(debug_assertions)] {
|
||||||
|
include!(concat!(env!("OUT_DIR"), "/gecko/structs_debug.rs"));
|
||||||
#[cfg(not(debug_assertions))]
|
} else {
|
||||||
#[allow(dead_code, improper_ctypes, non_camel_case_types, non_snake_case, non_upper_case_globals)]
|
include!(concat!(env!("OUT_DIR"), "/gecko/structs_release.rs"));
|
||||||
pub mod structs {
|
}
|
||||||
include!("structs_release.rs");
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod sugar;
|
pub mod sugar;
|
||||||
|
|
|
@ -9,6 +9,9 @@ name = "geckoservo"
|
||||||
path = "lib.rs"
|
path = "lib.rs"
|
||||||
crate-type = ["staticlib", "rlib"]
|
crate-type = ["staticlib", "rlib"]
|
||||||
|
|
||||||
|
[features]
|
||||||
|
bindgen = ["style/bindgen"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
app_units = "0.3"
|
app_units = "0.3"
|
||||||
cssparser = {version = "0.7"}
|
cssparser = {version = "0.7"}
|
||||||
|
|
|
@ -384,6 +384,9 @@ class MachCommands(CommandBase):
|
||||||
@Command('build-geckolib',
|
@Command('build-geckolib',
|
||||||
description='Build a static library of components used by Gecko',
|
description='Build a static library of components used by Gecko',
|
||||||
category='build')
|
category='build')
|
||||||
|
@CommandArgument('--with-gecko',
|
||||||
|
default=None,
|
||||||
|
help='Build with Gecko dist directory')
|
||||||
@CommandArgument('--jobs', '-j',
|
@CommandArgument('--jobs', '-j',
|
||||||
default=None,
|
default=None,
|
||||||
help='Number of jobs to run in parallel')
|
help='Number of jobs to run in parallel')
|
||||||
|
@ -393,12 +396,18 @@ class MachCommands(CommandBase):
|
||||||
@CommandArgument('--release', '-r',
|
@CommandArgument('--release', '-r',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
help='Build in release mode')
|
help='Build in release mode')
|
||||||
def build_geckolib(self, jobs=None, verbose=False, release=False):
|
def build_geckolib(self, with_gecko=None, jobs=None, verbose=False, release=False):
|
||||||
self.set_use_stable_rust()
|
self.set_use_stable_rust()
|
||||||
self.ensure_bootstrapped()
|
self.ensure_bootstrapped()
|
||||||
|
|
||||||
|
env = self.build_env(is_build=True)
|
||||||
|
env["CARGO_TARGET_DIR"] = path.join(self.context.topdir, "target", "geckolib").encode("UTF-8")
|
||||||
|
|
||||||
ret = None
|
ret = None
|
||||||
opts = []
|
opts = []
|
||||||
|
if with_gecko is not None:
|
||||||
|
opts += ["--features", "bindgen"]
|
||||||
|
env["MOZ_DIST"] = path.abspath(with_gecko)
|
||||||
if jobs is not None:
|
if jobs is not None:
|
||||||
opts += ["-j", jobs]
|
opts += ["-j", jobs]
|
||||||
if verbose:
|
if verbose:
|
||||||
|
@ -406,9 +415,6 @@ class MachCommands(CommandBase):
|
||||||
if release:
|
if release:
|
||||||
opts += ["--release"]
|
opts += ["--release"]
|
||||||
|
|
||||||
env = self.build_env(is_build=True)
|
|
||||||
env["CARGO_TARGET_DIR"] = path.join(self.context.topdir, "target", "geckolib").encode("UTF-8")
|
|
||||||
|
|
||||||
build_start = time()
|
build_start = time()
|
||||||
with cd(path.join("ports", "geckolib")):
|
with cd(path.join("ports", "geckolib")):
|
||||||
ret = call(["cargo", "build"] + opts, env=env, verbose=verbose)
|
ret = call(["cargo", "build"] + opts, env=env, verbose=verbose)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue