mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-07-01 02:41:48 +00:00
Compare commits
759 Commits
v2025.0.0-
...
v2027.0.0-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b9bd3e5754 | ||
|
|
35dd61cde5 | ||
|
|
44b9cc1398 | ||
|
|
8992dcdc99 | ||
|
|
7a2a982e66 | ||
|
|
9e85f3cf55 | ||
|
|
b37e2d9343 | ||
|
|
2b43541b94 | ||
|
|
33f91589b4 | ||
|
|
4c4996e638 | ||
|
|
cfbd7a5af2 | ||
|
|
f5990e8b40 | ||
|
|
b56b843c8a | ||
|
|
35e4a18e86 | ||
|
|
7ff312bb69 | ||
|
|
2fb5271cc9 | ||
|
|
b1aaabc1c6 | ||
|
|
f1b9be551b | ||
|
|
3972b01c51 | ||
|
|
5c719ced5f | ||
|
|
7d34f43e44 | ||
|
|
e369c721ca | ||
|
|
871769c815 | ||
|
|
ca7718cb08 | ||
|
|
5e7e5306df | ||
|
|
6447011bc3 | ||
|
|
bb5ee73e46 | ||
|
|
c46b54a523 | ||
|
|
7290766482 | ||
|
|
bd5141e254 | ||
|
|
e364087e99 | ||
|
|
0277759d44 | ||
|
|
7aabc19977 | ||
|
|
f9899eb73f | ||
|
|
ef676aca70 | ||
|
|
6b8be313c7 | ||
|
|
ab53d51c6f | ||
|
|
5003939b64 | ||
|
|
ab259c2e89 | ||
|
|
8fb5a1985a | ||
|
|
cf4f6ce4b6 | ||
|
|
1e50471d2c | ||
|
|
c575a23e8e | ||
|
|
4522cca70f | ||
|
|
850a148aad | ||
|
|
0a4e44ea06 | ||
|
|
a7e7f6912a | ||
|
|
76ee08e0b4 | ||
|
|
ee0a8a1e56 | ||
|
|
f701132392 | ||
|
|
3dbdfa1839 | ||
|
|
1ce2854a1e | ||
|
|
ee3d55e848 | ||
|
|
d59f1732bb | ||
|
|
d5d67d874b | ||
|
|
8c20da44c8 | ||
|
|
855ef10d58 | ||
|
|
90d90f334d | ||
|
|
909f8a1dc4 | ||
|
|
be72d543ad | ||
|
|
f8ed2a4d92 | ||
|
|
dbffe6e8ac | ||
|
|
5cd97c6353 | ||
|
|
e8490eb242 | ||
|
|
e5b7613b78 | ||
|
|
2639e0365b | ||
|
|
08f11488b0 | ||
|
|
632749e6f3 | ||
|
|
b0829356fa | ||
|
|
ed904851eb | ||
|
|
2cfd58f119 | ||
|
|
129cbbe11d | ||
|
|
45db0fd45e | ||
|
|
bd1dcc4358 | ||
|
|
96004f9bb5 | ||
|
|
9fd4ccf95b | ||
|
|
4e6b9706ff | ||
|
|
55e52bc2b7 | ||
|
|
c280fce147 | ||
|
|
183328384b | ||
|
|
d4311d5a29 | ||
|
|
7f35104012 | ||
|
|
73c26dcf89 | ||
|
|
0d9e850e22 | ||
|
|
46a3318324 | ||
|
|
f209ecb0cb | ||
|
|
f89cf2e441 | ||
|
|
3e4e9c9b01 | ||
|
|
78fa67099e | ||
|
|
9ac7e286f5 | ||
|
|
5fd9e1e72a | ||
|
|
94399dd7e0 | ||
|
|
0a0adebd89 | ||
|
|
6eba91bc04 | ||
|
|
c01f0c3d46 | ||
|
|
d203541b7b | ||
|
|
13852760f6 | ||
|
|
dffa2542c9 | ||
|
|
ed7982563b | ||
|
|
2d11946d98 | ||
|
|
c42fde5d07 | ||
|
|
23f5725853 | ||
|
|
3b7d0e7bf5 | ||
|
|
0dd77e55cb | ||
|
|
1ab705b354 | ||
|
|
dbf22c98b4 | ||
|
|
9c523f98f5 | ||
|
|
0089e518cb | ||
|
|
2f918900ff | ||
|
|
48077cdb91 | ||
|
|
6e9ed8b7f1 | ||
|
|
e0e774abde | ||
|
|
b251d16ef7 | ||
|
|
76881e2940 | ||
|
|
2245dccff6 | ||
|
|
b3aeee18c8 | ||
|
|
feee88f40d | ||
|
|
12223ff188 | ||
|
|
79f6351073 | ||
|
|
ef95333a89 | ||
|
|
343e748643 | ||
|
|
0478176e47 | ||
|
|
db95f55394 | ||
|
|
e678a338b4 | ||
|
|
3871cab6e8 | ||
|
|
22ed224035 | ||
|
|
8d36df671b | ||
|
|
373eedc77b | ||
|
|
e93c8cdb29 | ||
|
|
c78bd942bb | ||
|
|
e2f901822c | ||
|
|
cd0e7fb7d7 | ||
|
|
60098b0685 | ||
|
|
f3af50fc8e | ||
|
|
8aa312fb6f | ||
|
|
b66a66b693 | ||
|
|
09680072ac | ||
|
|
946ab9e98f | ||
|
|
5905a3ba27 | ||
|
|
484cbabc06 | ||
|
|
b445d48033 | ||
|
|
a6892b6cd5 | ||
|
|
f308e9873a | ||
|
|
8799733838 | ||
|
|
fa65657746 | ||
|
|
412d189507 | ||
|
|
b85a0d5cf3 | ||
|
|
2875fd7d7c | ||
|
|
24e2d2d676 | ||
|
|
1530fccbd0 | ||
|
|
2fc86a155d | ||
|
|
f03df5388e | ||
|
|
efedc5d69a | ||
|
|
8d248f61fd | ||
|
|
3497a7d09f | ||
|
|
ef24c1df97 | ||
|
|
abeaa40e38 | ||
|
|
7c1a22376b | ||
|
|
8d7bed791c | ||
|
|
fa08679762 | ||
|
|
69ecd02aec | ||
|
|
72d7a07635 | ||
|
|
d36b1d0dd9 | ||
|
|
7142fb1f5f | ||
|
|
6bac1cbc1a | ||
|
|
89c1fc156d | ||
|
|
708bf7d815 | ||
|
|
082de35ad7 | ||
|
|
4b39853483 | ||
|
|
d7550a02f7 | ||
|
|
f6558c4815 | ||
|
|
0304f50141 | ||
|
|
44d42759a4 | ||
|
|
c3b327d57b | ||
|
|
26771e38fb | ||
|
|
1ccafdc13f | ||
|
|
6d92e2501d | ||
|
|
82ce317083 | ||
|
|
a3ce880334 | ||
|
|
e6bb29e2f1 | ||
|
|
633603dc3d | ||
|
|
f2dd81c839 | ||
|
|
f55564729b | ||
|
|
e13d237390 | ||
|
|
ccc9740d56 | ||
|
|
ffe296892c | ||
|
|
22b58c1853 | ||
|
|
ddc5220ed4 | ||
|
|
a77441b78a | ||
|
|
676f2f84d7 | ||
|
|
edde38a41a | ||
|
|
c655b7a893 | ||
|
|
057f5ddf81 | ||
|
|
2361959ff1 | ||
|
|
6cfa21364e | ||
|
|
fb399eef3d | ||
|
|
e2517b7a21 | ||
|
|
3355383fe9 | ||
|
|
fbee476fd2 | ||
|
|
fbbc4bc53c | ||
|
|
05c080328b | ||
|
|
c01e318370 | ||
|
|
5dfc664b93 | ||
|
|
89b97a21d8 | ||
|
|
075cc4a20f | ||
|
|
f99692f287 | ||
|
|
2af8c59858 | ||
|
|
4d74ea6278 | ||
|
|
a4cf2ea6ec | ||
|
|
b205f3e1b4 | ||
|
|
be67432a5e | ||
|
|
1955dcddb3 | ||
|
|
e12d78a70a | ||
|
|
d3fbebc0a9 | ||
|
|
1991af34a5 | ||
|
|
7a3df6175e | ||
|
|
a6f601453a | ||
|
|
6c16e846fa | ||
|
|
ca05ffa1b9 | ||
|
|
de718f7ae5 | ||
|
|
5368e8c6ed | ||
|
|
25eacfa226 | ||
|
|
22d12d2345 | ||
|
|
abd312f3d0 | ||
|
|
b4823569a4 | ||
|
|
0cb4df7e05 | ||
|
|
231ec348fe | ||
|
|
d32e60233f | ||
|
|
1596e2fd7a | ||
|
|
79a9d7f987 | ||
|
|
0877d130be | ||
|
|
89555383cc | ||
|
|
de315947e9 | ||
|
|
b7cd03adc4 | ||
|
|
6e3f48daeb | ||
|
|
0e5a6f38d8 | ||
|
|
cc8eaf3ed7 | ||
|
|
dd6c830768 | ||
|
|
3dee19a435 | ||
|
|
55a97f0c11 | ||
|
|
b1f7e6d6f2 | ||
|
|
ca3137b291 | ||
|
|
e1da917270 | ||
|
|
0a38400734 | ||
|
|
b96264f042 | ||
|
|
a15152712f | ||
|
|
17cae787e7 | ||
|
|
02de5f710e | ||
|
|
e63899e63a | ||
|
|
ba37e7eb3c | ||
|
|
7036bd509e | ||
|
|
8fe3cfb325 | ||
|
|
a4572a01b7 | ||
|
|
f14af97dc7 | ||
|
|
631521a980 | ||
|
|
c49fc29046 | ||
|
|
40ce42712f | ||
|
|
659710a79a | ||
|
|
d059cbc157 | ||
|
|
08297430b5 | ||
|
|
85a8fc9943 | ||
|
|
36811211be | ||
|
|
2f0990e9d2 | ||
|
|
0695a4db89 | ||
|
|
3960045663 | ||
|
|
92010c175f | ||
|
|
90ee11a9e0 | ||
|
|
828199befb | ||
|
|
d04e15b957 | ||
|
|
d98ad815b1 | ||
|
|
1c35a3a5ff | ||
|
|
b248663386 | ||
|
|
9c60da1319 | ||
|
|
21d921184a | ||
|
|
26e299115f | ||
|
|
07192285f6 | ||
|
|
ed94e3af3e | ||
|
|
3cd282d9b0 | ||
|
|
49b4b064cf | ||
|
|
bd78215b43 | ||
|
|
c13b2f45c1 | ||
|
|
ea986427aa | ||
|
|
dcd397e007 | ||
|
|
e2cc9e0059 | ||
|
|
2e21a41f87 | ||
|
|
52b353fe57 | ||
|
|
1efaaefd78 | ||
|
|
71b6e8ec58 | ||
|
|
1a835fec01 | ||
|
|
d3cc185382 | ||
|
|
0ad595c33c | ||
|
|
7cb29ce70b | ||
|
|
93bf6c70ba | ||
|
|
a7ae22d764 | ||
|
|
822457d45b | ||
|
|
baa20fa239 | ||
|
|
75321f1d84 | ||
|
|
cd6fee7fea | ||
|
|
517344fe80 | ||
|
|
b0e588fd49 | ||
|
|
0f0e93722e | ||
|
|
b39744b562 | ||
|
|
72bba2491a | ||
|
|
f9307de04c | ||
|
|
15dcdebe21 | ||
|
|
98f933eca5 | ||
|
|
0c3c2c1fda | ||
|
|
da47f06d70 | ||
|
|
c898853b4d | ||
|
|
bd2211119f | ||
|
|
13626063dc | ||
|
|
7e6077c546 | ||
|
|
4d126b158c | ||
|
|
e22f76ce73 | ||
|
|
e648b9c86d | ||
|
|
23658a8c62 | ||
|
|
155b3d45e7 | ||
|
|
d62ab12855 | ||
|
|
1921d7b79a | ||
|
|
ac1705ae2b | ||
|
|
9dbb0c8c3d | ||
|
|
b2584c6bdf | ||
|
|
53df127535 | ||
|
|
d2611d4ad5 | ||
|
|
764ada9b66 | ||
|
|
b60b2b64bd | ||
|
|
a0976a1fd9 | ||
|
|
bfff891b5c | ||
|
|
35aee1d78d | ||
|
|
b3b515e1dd | ||
|
|
296986397b | ||
|
|
297f0d1b03 | ||
|
|
ad29d45dfb | ||
|
|
6e704370b3 | ||
|
|
7533b323d1 | ||
|
|
18321e5551 | ||
|
|
b31fd17d05 | ||
|
|
48ce2dcc8d | ||
|
|
b799b285b3 | ||
|
|
3b345fe218 | ||
|
|
eee30c49e2 | ||
|
|
adbe95e610 | ||
|
|
01e71e73ce | ||
|
|
b44a80c07a | ||
|
|
25d11524e8 | ||
|
|
5898cdd5c3 | ||
|
|
e2b6beb28a | ||
|
|
d86a2ec83b | ||
|
|
0690d3d832 | ||
|
|
304b98c0c9 | ||
|
|
72541c10e6 | ||
|
|
00445f4f27 | ||
|
|
8fc3767b30 | ||
|
|
5ab0409c15 | ||
|
|
5a6c895b87 | ||
|
|
1600e773f4 | ||
|
|
4caa16e254 | ||
|
|
f80874dd4b | ||
|
|
92f0a3c961 | ||
|
|
e52f400687 | ||
|
|
dc335ddedb | ||
|
|
ff1b2a205e | ||
|
|
5017393b3a | ||
|
|
d9f8fded09 | ||
|
|
a9f3fc6b2c | ||
|
|
1cad4f64a4 | ||
|
|
58cb395d76 | ||
|
|
24d6e87447 | ||
|
|
f81c42e700 | ||
|
|
fa71fb55a2 | ||
|
|
45d7549ca9 | ||
|
|
afbaa43539 | ||
|
|
a14545102f | ||
|
|
25e6549398 | ||
|
|
cd92b07321 | ||
|
|
fc9e413ce1 | ||
|
|
e41b33960a | ||
|
|
df77580a15 | ||
|
|
09a6bc9a25 | ||
|
|
007526089e | ||
|
|
666d1638ce | ||
|
|
c5f7a2b4ac | ||
|
|
638d265b33 | ||
|
|
6125227836 | ||
|
|
e37c35746a | ||
|
|
995bc98ccf | ||
|
|
2de03c9601 | ||
|
|
8e459a4f2a | ||
|
|
58d7c07343 | ||
|
|
9b08f0244c | ||
|
|
7032de3d5d | ||
|
|
03d9e96877 | ||
|
|
159e18ce05 | ||
|
|
257d0e0824 | ||
|
|
b65f159c3f | ||
|
|
11a0c36737 | ||
|
|
0f6693594c | ||
|
|
148fcdca85 | ||
|
|
93521420c8 | ||
|
|
12a1475ee4 | ||
|
|
1240ee1bf4 | ||
|
|
da90ffd24a | ||
|
|
17a03514ba | ||
|
|
9ebc4b32ae | ||
|
|
ce60bd5035 | ||
|
|
468a3c6d95 | ||
|
|
4350ea769c | ||
|
|
83397392f4 | ||
|
|
786d22049b | ||
|
|
86137c49f5 | ||
|
|
4edf52d3b6 | ||
|
|
a41fb460a9 | ||
|
|
d4985b8ba0 | ||
|
|
1538370034 | ||
|
|
a931a6554f | ||
|
|
eef1bf33de | ||
|
|
78b6d61e88 | ||
|
|
e7dd5dca82 | ||
|
|
a27df8ec24 | ||
|
|
85507a6c65 | ||
|
|
b74f84f876 | ||
|
|
54e9c76e03 | ||
|
|
203487a6aa | ||
|
|
57344ef3b2 | ||
|
|
3232630a38 | ||
|
|
46d401553e | ||
|
|
df244cd198 | ||
|
|
9e63dcfb16 | ||
|
|
934bf7bf05 | ||
|
|
2a757eaeb5 | ||
|
|
fe49cbe429 | ||
|
|
0470e51569 | ||
|
|
72fdca3507 | ||
|
|
dee50bf500 | ||
|
|
939a9ceee1 | ||
|
|
b670a59b5b | ||
|
|
9b12ddb595 | ||
|
|
76625fa0f9 | ||
|
|
bb130b67b8 | ||
|
|
469bb3290d | ||
|
|
02a0adc653 | ||
|
|
0c99073b94 | ||
|
|
d631fa8e4b | ||
|
|
78b14c5204 | ||
|
|
19d385d149 | ||
|
|
d0cc7e4eca | ||
|
|
807dffed35 | ||
|
|
529bab6ca1 | ||
|
|
f46c81cfe3 | ||
|
|
9ccd73108b | ||
|
|
38d8929f48 | ||
|
|
cc73236a06 | ||
|
|
f8720a628c | ||
|
|
156bd71fef | ||
|
|
6e44187ff6 | ||
|
|
e2cbdf9718 | ||
|
|
66cce1835c | ||
|
|
6fe5da7289 | ||
|
|
03f0fc4dea | ||
|
|
80c391e182 | ||
|
|
70f36cce7e | ||
|
|
564c1f2de2 | ||
|
|
a1b642a402 | ||
|
|
f9b3efb712 | ||
|
|
782459dff4 | ||
|
|
945d416d07 | ||
|
|
4bca79b9af | ||
|
|
68285dae77 | ||
|
|
5e3dba672a | ||
|
|
e943424609 | ||
|
|
4225b732fd | ||
|
|
39d05ebe7c | ||
|
|
6ba7189373 | ||
|
|
31d1aa62c1 | ||
|
|
cc41a0ed24 | ||
|
|
b6ae9e9cc9 | ||
|
|
f1e4eafaa0 | ||
|
|
41d4826694 | ||
|
|
220f4e1ba4 | ||
|
|
d5edb4060d | ||
|
|
ae44295024 | ||
|
|
e08fdeba21 | ||
|
|
544553a58f | ||
|
|
4910436b10 | ||
|
|
a7349f00ef | ||
|
|
e493da3486 | ||
|
|
838c5fbcd7 | ||
|
|
32ba751e58 | ||
|
|
62a6a77bbf | ||
|
|
c81bd0c909 | ||
|
|
38a239b531 | ||
|
|
c497e4ec22 | ||
|
|
6dbff902fa | ||
|
|
9a1b4245fa | ||
|
|
be72e0ecd8 | ||
|
|
e222efaa01 | ||
|
|
e69c5710b3 | ||
|
|
52b33edcbd | ||
|
|
f772bb141d | ||
|
|
278efa6384 | ||
|
|
e876452967 | ||
|
|
5c95966d44 | ||
|
|
c8900cadc3 | ||
|
|
5058b48dea | ||
|
|
882233bede | ||
|
|
1921d019b7 | ||
|
|
144e79a614 | ||
|
|
c3fc7c829d | ||
|
|
4ce8930342 | ||
|
|
38b09a6dfd | ||
|
|
d7cd71589a | ||
|
|
60198c0bec | ||
|
|
54f0e11fc0 | ||
|
|
a954091ea2 | ||
|
|
bf653d9895 | ||
|
|
5a9e0abe44 | ||
|
|
5cab27fdd5 | ||
|
|
de82ed434d | ||
|
|
4dd3a36d2e | ||
|
|
ce63770970 | ||
|
|
92f8c89267 | ||
|
|
1eecaaf337 | ||
|
|
892e062316 | ||
|
|
9807d60566 | ||
|
|
c51f65bd4f | ||
|
|
c387a7ecae | ||
|
|
82132c3272 | ||
|
|
715cbb6b76 | ||
|
|
9d40b993f8 | ||
|
|
92ee5bc523 | ||
|
|
847c3120d3 | ||
|
|
5012ad7499 | ||
|
|
7ae4333c81 | ||
|
|
145450b73d | ||
|
|
b91864a5ec | ||
|
|
0941251375 | ||
|
|
7d178615fa | ||
|
|
806d56e564 | ||
|
|
65f3345407 | ||
|
|
5e1c6a84ce | ||
|
|
a0af0fd572 | ||
|
|
f377a9c573 | ||
|
|
62338c7287 | ||
|
|
49e3e4a0be | ||
|
|
59dbfc9c2d | ||
|
|
9607c6c10d | ||
|
|
6ef5b85758 | ||
|
|
b6de7acbdb | ||
|
|
fe28fa1ded | ||
|
|
b7eb9fb8f9 | ||
|
|
1d58c5025e | ||
|
|
b4a8d33486 | ||
|
|
0a3ccf93c6 | ||
|
|
d92f17b014 | ||
|
|
4c225ef2c1 | ||
|
|
561078ce29 | ||
|
|
d312bccfeb | ||
|
|
9826539198 | ||
|
|
33f7067216 | ||
|
|
ac1836ec44 | ||
|
|
57e10755fd | ||
|
|
8ec22b7d5c | ||
|
|
a04c40f589 | ||
|
|
b4bec566f0 | ||
|
|
d76827db48 | ||
|
|
602c4caa02 | ||
|
|
661c321fe2 | ||
|
|
d1de7663d3 | ||
|
|
b040059108 | ||
|
|
0798ac53d0 | ||
|
|
ded7c87d63 | ||
|
|
2acf111f56 | ||
|
|
aa7dd258c4 | ||
|
|
ca51197486 | ||
|
|
91142ba5fe | ||
|
|
969664ceaa | ||
|
|
1e545c38a8 | ||
|
|
6eb652e10e | ||
|
|
fff73ee6e1 | ||
|
|
bade0a8716 | ||
|
|
453335e354 | ||
|
|
c289562a06 | ||
|
|
07345712dc | ||
|
|
425bf83036 | ||
|
|
6adad7bad7 | ||
|
|
280d2c7e32 | ||
|
|
edc3963955 | ||
|
|
c58be2580d | ||
|
|
f40bd3593d | ||
|
|
3cc541f261 | ||
|
|
811b130968 | ||
|
|
d39dfd64ea | ||
|
|
661bae568f | ||
|
|
01f85abcfe | ||
|
|
396f8203ac | ||
|
|
4a43ddbacf | ||
|
|
0921054a28 | ||
|
|
f738fc92f0 | ||
|
|
a0f38f83f9 | ||
|
|
876be30724 | ||
|
|
de318fab91 | ||
|
|
8b8b634f65 | ||
|
|
fd2e0c0427 | ||
|
|
a66fa339dc | ||
|
|
44a45d44e2 | ||
|
|
af652817d9 | ||
|
|
5a16b0e108 | ||
|
|
71c050389a | ||
|
|
83fa422338 | ||
|
|
3113627be6 | ||
|
|
f2d2500d1d | ||
|
|
63e623d70b | ||
|
|
9e8d37c03b | ||
|
|
ad09d73dd6 | ||
|
|
3fd33b1f72 | ||
|
|
043c155087 | ||
|
|
7a6c7af412 | ||
|
|
8588b5e520 | ||
|
|
debb52156c | ||
|
|
23e71e10e4 | ||
|
|
44c0bbc4a9 | ||
|
|
a48f3c35f4 | ||
|
|
7c91b81906 | ||
|
|
eb8583596c | ||
|
|
dfd1084526 | ||
|
|
2cfe114c78 | ||
|
|
caae5357b7 | ||
|
|
22e91bfacd | ||
|
|
67e1b5fe95 | ||
|
|
27e07d6787 | ||
|
|
e49d452e46 | ||
|
|
5c0edc2410 | ||
|
|
309b370223 | ||
|
|
f620141e0d | ||
|
|
5f3cf517d3 | ||
|
|
328a781040 | ||
|
|
ebf83e4340 | ||
|
|
9f6f267f5c | ||
|
|
21980c7447 | ||
|
|
75fc4d18ef | ||
|
|
8f81b7723d | ||
|
|
fe45265a3a | ||
|
|
0f313c672f | ||
|
|
aaf139320e | ||
|
|
89c5d98fe9 | ||
|
|
defcc02806 | ||
|
|
e6e928d670 | ||
|
|
f03e0cdf6a | ||
|
|
412c042c6c | ||
|
|
f44c3eda43 | ||
|
|
018dcaea4f | ||
|
|
85ffb7814b | ||
|
|
6207992709 | ||
|
|
42a433b6fa | ||
|
|
2c857cd82a | ||
|
|
1c220ebc60 | ||
|
|
1cfed736ce | ||
|
|
46b5631ba7 | ||
|
|
d2b19d8928 | ||
|
|
9a5f73d787 | ||
|
|
db552317e7 | ||
|
|
03cb3c70b4 | ||
|
|
ac907f755a | ||
|
|
a3b12b3bd9 | ||
|
|
cbc9264468 | ||
|
|
28ac2e3554 | ||
|
|
58c0cd46b1 | ||
|
|
115a02211c | ||
|
|
f553dee6cb | ||
|
|
e8d2d1c39a | ||
|
|
7cc7fa1845 | ||
|
|
cbdb4e81f6 | ||
|
|
05c7fd929b | ||
|
|
0c824bd447 | ||
|
|
ed18b41198 | ||
|
|
6745fc7c2f | ||
|
|
40af8db28a | ||
|
|
5ac132f6a2 | ||
|
|
dd72a78aa4 | ||
|
|
36e0c9d6db | ||
|
|
95b9bd880b | ||
|
|
2054d0f57e | ||
|
|
ee22482f4a | ||
|
|
796dbd3b86 | ||
|
|
0424e5ba36 | ||
|
|
f7dddb8014 | ||
|
|
68715aa484 | ||
|
|
fad06ae1e7 | ||
|
|
40caabea23 | ||
|
|
59dc9ad8f4 | ||
|
|
2b1c5aa4fc | ||
|
|
0bada2e102 | ||
|
|
ee281ea448 | ||
|
|
bedfc09268 | ||
|
|
4023cdc80a | ||
|
|
12885015ed | ||
|
|
f23bece791 | ||
|
|
7ebd45ef4d | ||
|
|
25c2e26ef8 | ||
|
|
f1e032f5e6 | ||
|
|
22a04bf470 | ||
|
|
77ee9bdd30 | ||
|
|
c6d801d2d6 | ||
|
|
768fa5f973 | ||
|
|
a621cebbd6 | ||
|
|
8870d98f80 | ||
|
|
2d6f02d15b | ||
|
|
96f0b2482c | ||
|
|
8ca99c7cb7 | ||
|
|
59bc53b9b8 | ||
|
|
94c62ed3ec | ||
|
|
28cb7cf757 | ||
|
|
dcf5f55a30 | ||
|
|
f65f9ed693 | ||
|
|
8f57e4c566 | ||
|
|
37e7bfe4f9 | ||
|
|
679892e8e1 | ||
|
|
4adfa8bf64 | ||
|
|
5d9a553104 | ||
|
|
5acb4109ff | ||
|
|
fc83d4868c | ||
|
|
a65f6b94ee | ||
|
|
d97a749d84 | ||
|
|
2085ab3d47 | ||
|
|
0cfff31439 | ||
|
|
a71cee1112 | ||
|
|
968bdf0d06 | ||
|
|
f150b36108 | ||
|
|
f856c05a08 | ||
|
|
09a93b86dc | ||
|
|
8102516300 | ||
|
|
b541174255 | ||
|
|
9a7710ebd3 | ||
|
|
bc6553cd2b | ||
|
|
dced751a72 | ||
|
|
83615c6024 | ||
|
|
a8a5d1609b | ||
|
|
f82e1c9d48 | ||
|
|
466a4a52fa | ||
|
|
fe80d72fba | ||
|
|
fde264b041 | ||
|
|
95da92db04 | ||
|
|
d389317c3a | ||
|
|
50db16c0c0 | ||
|
|
6b1e656659 | ||
|
|
eab93f4fdc | ||
|
|
f0a1955fd7 | ||
|
|
b8ff3fcee2 | ||
|
|
69af7785f6 | ||
|
|
6281ec0810 | ||
|
|
64e5e6db59 | ||
|
|
180349bd06 | ||
|
|
22f086aba8 | ||
|
|
84075997c6 | ||
|
|
ba1b97cd78 | ||
|
|
f93bacc5c5 | ||
|
|
38e246c34f | ||
|
|
a884863f19 | ||
|
|
554024767e |
20
.bazelignore
Normal file
20
.bazelignore
Normal file
@@ -0,0 +1,20 @@
|
||||
build_cmake
|
||||
build-cmake
|
||||
|
||||
# Auto generated by vscode
|
||||
apriltag/bin
|
||||
cameraserver/bin
|
||||
cameraserver/multiCameraServer/bin
|
||||
cscore/bin
|
||||
fieldImages/bin
|
||||
hal/bin
|
||||
developerRobot/bin
|
||||
ntcore/bin
|
||||
romiVendordep/bin
|
||||
wpilibNewCommands/bin
|
||||
wpilibj/bin
|
||||
wpimath/bin
|
||||
wpinet/bin
|
||||
wpiutil/bin
|
||||
wpiunits/bin
|
||||
xrpVendordep/bin
|
||||
75
.bazelrc
Normal file
75
.bazelrc
Normal file
@@ -0,0 +1,75 @@
|
||||
try-import %workspace%/bazel_auth.rc
|
||||
try-import %workspace%/user.bazelrc
|
||||
|
||||
common --noenable_bzlmod --enable_workspace
|
||||
# Resolves to --config=linux on Linux, --config=macos on Mac, --windows on windows
|
||||
common --enable_platform_specific_config
|
||||
|
||||
# Make bazel 8 work for us.
|
||||
common --enable_workspace
|
||||
build --experimental_cc_static_library
|
||||
build --experimental_cc_shared_library
|
||||
|
||||
build --java_language_version=21
|
||||
build --java_runtime_version=remotejdk_21
|
||||
build --tool_java_language_version=21
|
||||
build --tool_java_runtime_version=remotejdk_21
|
||||
|
||||
test --test_output=errors
|
||||
test --test_verbose_timeout_warnings
|
||||
|
||||
import %workspace%/shared/bazel/compiler_flags/sanitizers.rc
|
||||
import %workspace%/shared/bazel/compiler_flags/linux_flags.rc
|
||||
import %workspace%/shared/bazel/compiler_flags/osx_flags.rc
|
||||
import %workspace%/shared/bazel/compiler_flags/roborio_flags.rc
|
||||
import %workspace%/shared/bazel/compiler_flags/systemcore_flags.rc
|
||||
import %workspace%/shared/bazel/compiler_flags/windows_flags.rc
|
||||
import %workspace%/shared/bazel/compiler_flags/coverage_flags.rc
|
||||
|
||||
# Alias toolchain names to what wpilibsuite uses for CI/Artifact naming
|
||||
build:athena --config=roborio
|
||||
build:linuxarm32 --config=raspibookworm32
|
||||
build:linuxarm64 --config=bookworm64
|
||||
|
||||
build:build_java --test_tag_filters=allwpilib-build-java --build_tag_filters=allwpilib-build-java
|
||||
build:build_cpp --test_tag_filters=+allwpilib-build-cpp --build_tag_filters=+allwpilib-build-cpp
|
||||
build:no_example --test_tag_filters=-wpi-example --build_tag_filters=-wpi-example
|
||||
test:no_example --test_tag_filters=-wpi-example --build_tag_filters=-wpi-example
|
||||
common:skip_robotpy --test_tag_filters=-robotpy --build_tag_filters=-robotpy
|
||||
|
||||
# Build Buddy Cache Setup
|
||||
build:build_buddy --bes_results_url=https://app.buildbuddy.io/invocation/
|
||||
build:build_buddy --bes_backend=grpcs://remote.buildbuddy.io
|
||||
build:build_buddy --remote_cache=grpcs://remote.buildbuddy.io
|
||||
build:build_buddy --remote_timeout=3600
|
||||
|
||||
# Additional suggestions from buildbuddy for speed
|
||||
build:build_buddy --experimental_remote_cache_compression
|
||||
build:build_buddy --experimental_remote_cache_compression_threshold=100
|
||||
build:build_buddy --noslim_profile
|
||||
build:build_buddy --experimental_profile_include_target_label
|
||||
build:build_buddy --experimental_profile_include_primary_output
|
||||
build:build_buddy --nolegacy_important_outputs
|
||||
|
||||
common:build_buddy_readonly --noremote_upload_local_results
|
||||
|
||||
# This config should be used locally. It downloads more than the CI version
|
||||
build:remote_user --config=build_buddy
|
||||
build:remote_user --config=build_buddy_readonly
|
||||
build:remote_user --remote_download_toplevel
|
||||
|
||||
build:ci --config=build_buddy
|
||||
build:ci --remote_download_minimal
|
||||
|
||||
build --build_metadata=REPO_URL=https://github.com/wpilibsuite/allwpilib.git
|
||||
|
||||
common --define="WPILIB_VERSION=2025.424242.3.1-unknown"
|
||||
|
||||
# List of artifact types to build in CI.
|
||||
# Anything else gets skipped to speed up CI.
|
||||
common:ci --repo_env="WPI_PUBLISH_CLASSIFIER_FILTER=headers,sources,linuxsystemcore,linuxsystemcoredebug,linuxsystemcorestatic,linuxsystemcorestaticdebug,linuxx86-64,linuxx86-64debug,linuxx86-64static,linuxx86-64staticdebug,osxuniversal,osxuniversaldebug,osxuniversalstatic,osxuniversalstaticdebug,windowsarm64,windowsarm64debug,windowsarm64static,windowsarm64staticdebug,windowsx86-64,windowsx86-64debug,windowsx86-64static,windowsx86-64staticdebug"
|
||||
|
||||
# The 2 configurations for windows are very slow to build each time.
|
||||
# Instead, skip the cross transition for ARM on x86, and the reverse on x86.
|
||||
common:ci_windows_x86 --repo_env="WPI_PUBLISH_CLASSIFIER_FILTER=headers,sources,linuxsystemcore,linuxsystemcoredebug,linuxsystemcorestatic,linuxsystemcorestaticdebug,linuxx86-64,linuxx86-64debug,linuxx86-64static,linuxx86-64staticdebug,osxuniversal,osxuniversaldebug,osxuniversalstatic,osxuniversalstaticdebug,windowsx86-64,windowsx86-64debug,windowsx86-64static,windowsx86-64staticdebug"
|
||||
common:ci_windows_arm --repo_env="WPI_PUBLISH_CLASSIFIER_FILTER=headers,sources,linuxsystemcore,linuxsystemcoredebug,linuxsystemcorestatic,linuxsystemcorestaticdebug,linuxx86-64,linuxx86-64debug,linuxx86-64static,linuxx86-64staticdebug,osxuniversal,osxuniversaldebug,osxuniversalstatic,osxuniversalstaticdebug,windowsarm64,windowsarm64debug,windowsarm64static,windowsarm64staticdebug"
|
||||
1
.bazelversion
Normal file
1
.bazelversion
Normal file
@@ -0,0 +1 @@
|
||||
8.4.1
|
||||
@@ -45,6 +45,8 @@ Checks:
|
||||
-clang-diagnostic-#warnings,
|
||||
-clang-diagnostic-pedantic,
|
||||
clang-analyzer-*,
|
||||
-clang-analyzer-optin.cplusplus.UninitializedObject,
|
||||
-clang-analyzer-security.FloatLoopCounter,
|
||||
cppcoreguidelines-slicing,
|
||||
google-build-namespaces,
|
||||
google-explicit-constructor,
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
color: false
|
||||
definitions: [cmake/modules]
|
||||
line_length: 100
|
||||
list_expansion: favour-inlining
|
||||
quiet: false
|
||||
unsafe: false
|
||||
|
||||
2
.gitattributes
vendored
2
.gitattributes
vendored
@@ -28,3 +28,5 @@
|
||||
|
||||
# Generated files
|
||||
*/src/generated/** linguist-generated
|
||||
*/robotpy_native_build_info.bzl linguist-generated
|
||||
*/robotpy_pybind_build_info.bzl linguist-generated
|
||||
|
||||
2
.github/ISSUE_TEMPLATE/bug_report.md
vendored
2
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -2,7 +2,7 @@
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: bug
|
||||
labels: 'type: bug'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
2
.github/ISSUE_TEMPLATE/feature_request.md
vendored
2
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@@ -2,7 +2,7 @@
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: enhancement
|
||||
labels: 'type: feature'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
2
.github/ISSUE_TEMPLATE/question.md
vendored
2
.github/ISSUE_TEMPLATE/question.md
vendored
@@ -2,7 +2,7 @@
|
||||
name: Question
|
||||
about: Ask about features or parts of this project
|
||||
title: ''
|
||||
labels: ''
|
||||
labels: 'type: support'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
67
.github/actions/pregen/action.yml
vendored
Normal file
67
.github/actions/pregen/action.yml
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
name: 'Setup and run pregeneration'
|
||||
description: 'Sets up the dependencies needed to generate generated files and runs all generation scripts'
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- name: Set up Python 3.12
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.12'
|
||||
- name: Install jinja and protobuf
|
||||
run: python -m pip install jinja2 protobuf grpcio-tools
|
||||
shell: bash
|
||||
- name: Install protobuf and perl dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y protobuf-compiler liblist-moreutils-perl
|
||||
wget https://github.com/HebiRobotics/QuickBuffers/releases/download/1.3.3/protoc-gen-quickbuf-1.3.3-linux-x86_64.exe
|
||||
chmod +x protoc-gen-quickbuf-1.3.3-linux-x86_64.exe
|
||||
shell: bash
|
||||
|
||||
- name: Regenerate ntcore
|
||||
run: ./ntcore/generate_topics.py
|
||||
shell: bash
|
||||
|
||||
- name: Regenerate imgui
|
||||
run: |
|
||||
./thirdparty/imgui_suite/generate_fonts.sh
|
||||
./thirdparty/imgui_suite/generate_gl3w.py
|
||||
shell: bash
|
||||
|
||||
- name: Regenerate HIDs
|
||||
run: |
|
||||
./wpilibc/generate_hids.py
|
||||
./wpilibj/generate_hids.py
|
||||
./wpilibNewCommands/generate_hids.py
|
||||
shell: bash
|
||||
|
||||
- name: Regenerate PWM motor controllers
|
||||
run: |
|
||||
./wpilibc/generate_pwm_motor_controllers.py
|
||||
./wpilibj/generate_pwm_motor_controllers.py
|
||||
shell: bash
|
||||
|
||||
- name: Regenerate mrcal minimath
|
||||
run: ./wpical/generate_mrcal.py
|
||||
shell: bash
|
||||
|
||||
- name: Regenerate wpimath
|
||||
run: |
|
||||
./wpimath/generate_nanopb.py
|
||||
./wpimath/generate_numbers.py
|
||||
./wpimath/generate_quickbuf.py --quickbuf_plugin protoc-gen-quickbuf-1.3.3-linux-x86_64.exe
|
||||
shell: bash
|
||||
|
||||
- name: Regenerate Commands v3
|
||||
run: |
|
||||
./commandsv3/generate_files.py --quickbuf_plugin protoc-gen-quickbuf-1.3.3-linux-x86_64.exe
|
||||
shell: bash
|
||||
|
||||
- name: Regenerate wpiunits
|
||||
run: ./wpiunits/generate_units.py
|
||||
shell: bash
|
||||
|
||||
- name: Regenerate wpiutil nanopb
|
||||
run: ./wpiutil/generate_nanopb.py
|
||||
shell: bash
|
||||
38
.github/actions/setup-build-buddy/action.yml
vendored
Normal file
38
.github/actions/setup-build-buddy/action.yml
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
name: 'Setup BuildBuddy acache'
|
||||
description: 'Sets up the build buddy cache to be readonly / writing based on the presence of environment variables'
|
||||
|
||||
inputs:
|
||||
token:
|
||||
description: 'Build Buddy API token'
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
# Sets up build buddy when no secret is found for the API key. This is most likely because this is triggered from an action from a fork instead of the main allwpilib repo.
|
||||
- name: Setup without key
|
||||
env:
|
||||
API_KEY: ${{ inputs.token }}
|
||||
if: ${{ env.API_KEY == '' }}
|
||||
shell: bash
|
||||
run: |
|
||||
echo "No API key secret detected, will setup readonly cache"
|
||||
echo "build:ci --config=build_buddy_readonly" > bazel_auth.rc
|
||||
|
||||
# Set up the readonly key only if this build is for a pull request. Push builds happen in the forks repository,
|
||||
# so the user should set their own buildbuddy api keys up there. Only enabling it for PR's should reduce heavy
|
||||
# and more random load on the cache.
|
||||
if [ "${{ github.event_name }}" = "pull_request" ]; then
|
||||
echo "Assuming this is a pull request from a fork. Setting up the readonly api key"
|
||||
echo "build:ci --remote_header=x-buildbuddy-api-key=QIOV65PTW1tVal3AJbe7" >> bazel_auth.rc
|
||||
else
|
||||
echo "Not setting up readonly key for trigger ${{ github.event_name }} since this is not a pull request, it is most likely a forks push. See the buildbuddy setup guide in README-Bazel.md to set up caching on your fork"
|
||||
fi
|
||||
|
||||
- name: Set with key
|
||||
env:
|
||||
API_KEY: ${{ inputs.token }}
|
||||
if: ${{ env.API_KEY != '' }}
|
||||
shell: bash
|
||||
run: |
|
||||
echo "API Key detected!"
|
||||
echo "build:build_buddy --remote_header=x-buildbuddy-api-key=${{ env.API_KEY }}" > bazel_auth.rc
|
||||
62
.github/labeler.yml
vendored
Normal file
62
.github/labeler.yml
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
'2027':
|
||||
- base-branch: '2027'
|
||||
'component: apriltag':
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: apriltag/**
|
||||
'component: command-based':
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: wpilibNewCommands/**
|
||||
'component: cscore':
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: cscore/**
|
||||
'component: datalogtool':
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: datalogtool/**
|
||||
'component: epilogue':
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: epilogue-*/**
|
||||
'component: examples':
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: wpilib*Examples/**
|
||||
'component: glass':
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: glass/**
|
||||
'component: hal':
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: hal/**
|
||||
'component: ntcore':
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: ntcore/**
|
||||
'component: outlineviewer':
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: outlineviewer/**
|
||||
'component: sysid':
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: sysid/**
|
||||
'component: wpilibc':
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: wpilibc/**
|
||||
'component: wpilibj':
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: wpilibj/**
|
||||
'component: wpimath':
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: wpimath/**
|
||||
'component: wpinet':
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: wpinet/**
|
||||
'component: wpiunits':
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: wpiunits/**
|
||||
'component: wpiutil':
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: wpiutil/**
|
||||
'component: wpical':
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: wpical/**
|
||||
'component: usage reporting':
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: hal/src/generate/**
|
||||
'attn: NI':
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: hal/src/generate/**
|
||||
@@ -3,7 +3,10 @@
|
||||
{
|
||||
"aql": {
|
||||
"items.find": {
|
||||
"repo": "wpilib-mvn-development",
|
||||
"$or":[
|
||||
{ "repo": "wpilib-mvn-development-local" },
|
||||
{ "repo": "wpilib-mvn-development-2027-local" }
|
||||
],
|
||||
"path": { "$nmatch":"*edu/wpi/first/thirdparty*" },
|
||||
"$or":[
|
||||
{
|
||||
|
||||
120
.github/workflows/bazel.yml
vendored
Normal file
120
.github/workflows/bazel.yml
vendored
Normal file
@@ -0,0 +1,120 @@
|
||||
name: Bazel
|
||||
|
||||
on: [pull_request, push]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build-windows:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- { name: "Windows (native)", os: windows-2022, action: "test", config: "--config=ci_windows_x86", }
|
||||
- { name: "Windows (arm)", os: windows-2022, action: "build", config: "--config=windows_arm --config=ci_windows_arm", }
|
||||
|
||||
name: "Build ${{ matrix.name }}"
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with: { fetch-depth: 0 }
|
||||
- uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: 21
|
||||
architecture: x64
|
||||
|
||||
- id: Setup_build_buddy
|
||||
uses: ./.github/actions/setup-build-buddy
|
||||
with:
|
||||
token: ${{ secrets.BUILDBUDDY_API_KEY }}
|
||||
|
||||
- name: bazel ${{ matrix.action }}
|
||||
run: bazel ${{ matrix.action }} -k ... --config=ci ${{ matrix.config }} --verbose_failures
|
||||
shell: bash
|
||||
|
||||
build-mac:
|
||||
name: "Mac"
|
||||
runs-on: macos-14
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with: { fetch-depth: 0 }
|
||||
|
||||
- uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: 21
|
||||
|
||||
- id: Setup_build_buddy
|
||||
uses: ./.github/actions/setup-build-buddy
|
||||
with:
|
||||
token: ${{ secrets.BUILDBUDDY_API_KEY }}
|
||||
|
||||
- name: bazel test (release)
|
||||
run: bazel test -k ... --config=ci -c opt --nojava_header_compilation --verbose_failures
|
||||
shell: bash
|
||||
|
||||
build-linux:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- { name: "Linux", os: ubuntu-24.04, container: "wpilib/systemcore-cross-ubuntu:2027-24.04", action: "test", config: "", }
|
||||
name: "${{ matrix.name }}"
|
||||
runs-on: ${{ matrix.os }}
|
||||
container: ${{ matrix.container }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with: { fetch-depth: 0 }
|
||||
- uses: bazelbuild/setup-bazelisk@v3
|
||||
|
||||
- id: Setup_build_buddy
|
||||
uses: ./.github/actions/setup-build-buddy
|
||||
with:
|
||||
token: ${{ secrets.BUILDBUDDY_API_KEY }}
|
||||
|
||||
- uses: bazel-contrib/setup-bazel@0.15.0
|
||||
with:
|
||||
bazelisk-cache: true
|
||||
repository-cache: true
|
||||
bazelisk-version: 1.x
|
||||
|
||||
- name: bazel ${{ matrix.action }} (release)
|
||||
run: bazel ${{ matrix.action }} ... --config=ci -c opt ${{ matrix.config }} -k --verbose_failures
|
||||
|
||||
buildifier:
|
||||
name: "buildifier"
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Set up Go 1.15.x
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
cache: false
|
||||
go-version: 1.15.x
|
||||
id: go
|
||||
|
||||
- name: Install Buildifier
|
||||
run: |
|
||||
cd $(mktemp -d)
|
||||
GO111MODULE=on go get github.com/bazelbuild/buildtools/buildifier@6.0.0
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
with: { fetch-depth: 0 }
|
||||
|
||||
- name: Run buildifier
|
||||
run: buildifier -warnings all --lint=fix -r .
|
||||
|
||||
- name: Check Output
|
||||
run: git --no-pager diff --exit-code HEAD
|
||||
|
||||
- name: Generate diff
|
||||
run: git diff HEAD > bazel-lint-fixes.patch
|
||||
if: ${{ failure() }}
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ matrix.platform }}-bazel-lint-fixes
|
||||
path: bazel-lint-fixes.patch
|
||||
if: ${{ failure() }}
|
||||
57
.github/workflows/cmake-android.yml
vendored
Normal file
57
.github/workflows/cmake-android.yml
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
name: CMake Android
|
||||
|
||||
on: [pull_request, push]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
SCCACHE_WEBDAV_ENDPOINT: "https://frcmaven.wpi.edu/artifactory/wpilib-generic-cache-cmake-local"
|
||||
SCCACHE_WEBDAV_KEY_PREFIX: "sccache"
|
||||
|
||||
jobs:
|
||||
build:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- os: ubuntu-24.04
|
||||
name: Android Arm64
|
||||
abi: arm64-v8a
|
||||
- os: ubuntu-24.04
|
||||
name: Android X64
|
||||
abi: "x86_64"
|
||||
|
||||
name: "Build - ${{ matrix.name }}"
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: nttld/setup-ndk@v1
|
||||
id: setup-ndk
|
||||
with:
|
||||
ndk-version: r27c
|
||||
add-to-path: false
|
||||
|
||||
- uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: 21
|
||||
|
||||
- name: Install sccache
|
||||
uses: mozilla-actions/sccache-action@v0.0.9
|
||||
|
||||
- name: Install dependencies
|
||||
run: sudo apt-get update && sudo apt-get install -y ninja-build
|
||||
|
||||
- name: configure
|
||||
run: cmake --preset with-sccache -DCMAKE_BUILD_TYPE=RelWithDebInfo -DWITH_WPILIB=OFF -DWITH_GUI=OFF -DWITH_CSCORE=OFF -DWITH_TESTS=OFF -DWITH_SIMULATION_MODULES=OFF -DWITH_JAVA=ON -DBUILD_SHARED_LIBS=ON -DCMAKE_TOOLCHAIN_FILE=${{ steps.setup-ndk.outputs.ndk-path }}/build/cmake/android.toolchain.cmake -DANDROID_ABI="${{ matrix.abi }}" -DANDROID_PLATFORM=android-24
|
||||
env:
|
||||
SCCACHE_WEBDAV_USERNAME: ${{ secrets.ARTIFACTORY_USERNAME }}
|
||||
SCCACHE_WEBDAV_PASSWORD: ${{ secrets.ARTIFACTORY_PASSWORD }}
|
||||
|
||||
- name: build
|
||||
run: cmake --build build-cmake --parallel $(nproc)
|
||||
env:
|
||||
SCCACHE_WEBDAV_USERNAME: ${{ secrets.ARTIFACTORY_USERNAME }}
|
||||
SCCACHE_WEBDAV_PASSWORD: ${{ secrets.ARTIFACTORY_PASSWORD }}
|
||||
69
.github/workflows/cmake.yml
vendored
69
.github/workflows/cmake.yml
vendored
@@ -16,15 +16,18 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- os: ubuntu-22.04
|
||||
- os: ubuntu-24.04
|
||||
name: Linux
|
||||
container: wpilib/roborio-cross-ubuntu:2024-22.04
|
||||
flags: "--preset with-java-sccache -DCMAKE_BUILD_TYPE=Release -DWITH_EXAMPLES=ON"
|
||||
container: wpilib/systemcore-cross-ubuntu:2027-24.04
|
||||
flags: "--preset with-java-and-sccache -DCMAKE_BUILD_TYPE=Release -DWITH_EXAMPLES=ON"
|
||||
- os: macOS-14
|
||||
name: macOS
|
||||
container: ""
|
||||
env: "PATH=\"/opt/homebrew/opt/protobuf@3/bin:$PATH\""
|
||||
flags: "--preset sccache -DCMAKE_BUILD_TYPE=Release -DWITH_JAVA=OFF -DWITH_EXAMPLES=ON -DCMAKE_LIBRARY_PATH=/opt/homebrew/opt/protobuf@3/lib -DProtobuf_INCLUDE_DIR=/opt/homebrew/opt/protobuf@3/include -DProtobuf_PROTOC_EXECUTABLE=/opt/homebrew/opt/protobuf@3/bin/protoc"
|
||||
flags: "--preset with-sccache -DCMAKE_BUILD_TYPE=Release -DWITH_EXAMPLES=ON"
|
||||
- os: windows-2022
|
||||
name: Windows
|
||||
container: ""
|
||||
flags: '--preset with-sccache -DCMAKE_BUILD_TYPE=Release -DWITH_EXAMPLES=ON -DUSE_SYSTEM_FMTLIB=ON -DUSE_SYSTEM_LIBUV=ON -DUSE_SYSTEM_EIGEN=OFF -DCMAKE_TOOLCHAIN_FILE="$Env:RUNNER_WORKSPACE/vcpkg/scripts/buildsystems/vcpkg.cmake" -DVCPKG_INSTALL_OPTIONS=--clean-after-build -DVCPKG_TARGET_TRIPLET=x64-windows-release -DVCPKG_HOST_TRIPLET=x64-windows-release'
|
||||
|
||||
name: "Build - ${{ matrix.name }}"
|
||||
runs-on: ${{ matrix.os }}
|
||||
@@ -32,17 +35,31 @@ jobs:
|
||||
steps:
|
||||
- name: Install dependencies (Linux)
|
||||
if: runner.os == 'Linux'
|
||||
run: sudo apt-get update && sudo apt-get install -y libopencv-dev libopencv4.5-java libprotobuf-dev protobuf-compiler ninja-build
|
||||
run: sudo apt-get update && sudo apt-get install -y libopencv-dev libopencv-java ninja-build
|
||||
|
||||
- name: Install dependencies (macOS)
|
||||
run: brew install opencv protobuf@3 ninja
|
||||
if: runner.os == 'macOS'
|
||||
run: brew install opencv ninja
|
||||
|
||||
- uses: ilammy/msvc-dev-cmd@v1.13.0
|
||||
if: runner.os == 'Windows'
|
||||
|
||||
- name: Install CMake (Windows only)
|
||||
if: runner.os == 'Windows'
|
||||
uses: lukka/get-cmake@v3.29.3
|
||||
|
||||
- name: Install sccache
|
||||
uses: mozilla-actions/sccache-action@v0.0.5
|
||||
uses: mozilla-actions/sccache-action@v0.0.9
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Run vcpkg (Windows only)
|
||||
if: runner.os == 'Windows'
|
||||
uses: lukka/run-vcpkg@v11.5
|
||||
with:
|
||||
vcpkgDirectory: ${{ runner.workspace }}/vcpkg
|
||||
vcpkgGitCommitId: 37c3e63a1306562f7f59c4c3c8892ddd50fdf992 # HEAD on 2024-02-24
|
||||
|
||||
- name: configure
|
||||
run: cmake ${{ matrix.flags }}
|
||||
env:
|
||||
@@ -56,42 +73,12 @@ jobs:
|
||||
SCCACHE_WEBDAV_PASSWORD: ${{ secrets.ARTIFACTORY_PASSWORD }}
|
||||
|
||||
- name: test
|
||||
if: runner.os != 'Windows'
|
||||
working-directory: build-cmake
|
||||
run: ctest --output-on-failure
|
||||
|
||||
build-windows:
|
||||
name: "Build - Windows"
|
||||
runs-on: windows-2022
|
||||
steps:
|
||||
- uses: ilammy/msvc-dev-cmd@v1.13.0
|
||||
|
||||
- name: Install CMake
|
||||
uses: lukka/get-cmake@v3.29.3
|
||||
|
||||
- name: Run sccache-cache
|
||||
uses: mozilla-actions/sccache-action@v0.0.5
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Run vcpkg
|
||||
uses: lukka/run-vcpkg@v11.5
|
||||
with:
|
||||
vcpkgDirectory: ${{ runner.workspace }}/vcpkg
|
||||
vcpkgGitCommitId: 37c3e63a1306562f7f59c4c3c8892ddd50fdf992 # HEAD on 2024-02-24
|
||||
|
||||
- name: configure
|
||||
run: cmake --preset sccache -DCMAKE_BUILD_TYPE=Release -DWITH_JAVA=OFF -DWITH_EXAMPLES=ON -DUSE_SYSTEM_FMTLIB=ON -DUSE_SYSTEM_LIBUV=ON -DUSE_SYSTEM_EIGEN=OFF -DCMAKE_TOOLCHAIN_FILE=${{ runner.workspace }}/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_INSTALL_OPTIONS=--clean-after-build -DVCPKG_TARGET_TRIPLET=x64-windows-release -DVCPKG_HOST_TRIPLET=x64-windows-release
|
||||
env:
|
||||
SCCACHE_WEBDAV_USERNAME: ${{ secrets.ARTIFACTORY_USERNAME }}
|
||||
SCCACHE_WEBDAV_PASSWORD: ${{ secrets.ARTIFACTORY_PASSWORD }}
|
||||
|
||||
- name: build
|
||||
run: cmake --build build-cmake --parallel $(nproc)
|
||||
env:
|
||||
SCCACHE_WEBDAV_USERNAME: ${{ secrets.ARTIFACTORY_USERNAME }}
|
||||
SCCACHE_WEBDAV_PASSWORD: ${{ secrets.ARTIFACTORY_PASSWORD }}
|
||||
|
||||
- name: test
|
||||
- name: test (windows)
|
||||
if: runner.os == 'Windows'
|
||||
working-directory: build-cmake
|
||||
# UnitTest_test segfaults on exit occasionally
|
||||
run: ctest --output-on-failure -E 'UnitTest'
|
||||
|
||||
113
.github/workflows/comment-command.yml
vendored
113
.github/workflows/comment-command.yml
vendored
@@ -1,113 +0,0 @@
|
||||
name: Comment Commands
|
||||
on:
|
||||
issue_comment:
|
||||
types: [ created ]
|
||||
|
||||
jobs:
|
||||
format:
|
||||
if: github.event.issue.pull_request && startsWith(github.event.comment.body, '/format')
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: React Rocket
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const {owner, repo} = context.issue
|
||||
github.rest.reactions.createForIssueComment({
|
||||
owner,
|
||||
repo,
|
||||
comment_id: context.payload.comment.id,
|
||||
content: "rocket",
|
||||
});
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
token: ${{ secrets.COMMENT_COMMAND_PAT_TOKEN }}
|
||||
- name: Fetch all history and metadata
|
||||
run: |
|
||||
git checkout -b pr
|
||||
git branch -f main origin/main
|
||||
- name: Checkout PR
|
||||
run: |
|
||||
gh pr checkout $NUMBER
|
||||
env:
|
||||
GITHUB_TOKEN: "${{ secrets.COMMENT_COMMAND_PAT_TOKEN }}"
|
||||
NUMBER: ${{ github.event.issue.number }}
|
||||
- name: Set up Python 3.10
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.10'
|
||||
- name: Setup Java
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: 17
|
||||
- name: Install wpiformat
|
||||
run: pip3 install wpiformat==2024.40
|
||||
- name: Run wpiformat
|
||||
run: wpiformat
|
||||
- name: Run spotlessApply
|
||||
run: ./gradlew spotlessApply
|
||||
- name: Commit
|
||||
run: |
|
||||
# Set credentials
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
||||
# Commit
|
||||
git commit -am "Formatting fixes"
|
||||
git push
|
||||
|
||||
pregen:
|
||||
if: github.event.issue.pull_request && startsWith(github.event.comment.body, '/pregen')
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: React Rocket
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const {owner, repo} = context.issue
|
||||
github.rest.reactions.createForIssueComment({
|
||||
owner,
|
||||
repo,
|
||||
comment_id: context.payload.comment.id,
|
||||
content: "rocket",
|
||||
});
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
token: ${{ secrets.COMMENT_COMMAND_PAT_TOKEN }}
|
||||
- name: Checkout PR
|
||||
run: |
|
||||
gh pr checkout $NUMBER
|
||||
env:
|
||||
GITHUB_TOKEN: "${{ secrets.COMMENT_COMMAND_PAT_TOKEN }}"
|
||||
NUMBER: ${{ github.event.issue.number }}
|
||||
- name: Set up Python 3.9
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: 3.9
|
||||
- name: Install jinja
|
||||
run: python -m pip install jinja2
|
||||
- name: Install protobuf dependencies
|
||||
run: sudo apt-get update && sudo apt-get install -y protobuf-compiler && wget https://github.com/HebiRobotics/QuickBuffers/releases/download/1.3.3/protoc-gen-quickbuf-1.3.3-linux-x86_64.exe && chmod +x protoc-gen-quickbuf-1.3.3-linux-x86_64.exe
|
||||
- name: Run hal
|
||||
run: ./hal/generate_usage_reporting.py
|
||||
- name: Run ntcore
|
||||
run: ./ntcore/generate_topics.py
|
||||
- name: Run wpimath
|
||||
run: ./wpimath/generate_numbers.py && ./wpimath/generate_quickbuf.py --quickbuf_plugin=protoc-gen-quickbuf-1.3.3-linux-x86_64.exe
|
||||
- name: Run HIDs
|
||||
run: ./wpilibj/generate_hids.py && ./wpilibc/generate_hids.py && ./wpilibNewCommands/generate_hids.py
|
||||
- name: Run PWM Controllers
|
||||
run: ./wpilibj/generate_pwm_motor_controllers.py && ./wpilibc/generate_pwm_motor_controllers.py
|
||||
- name: Run imgui gl3w
|
||||
run: ./thirdparty/imgui_suite/generate_gl3w.py
|
||||
- name: Run imgui fonts
|
||||
run: ./thirdparty/imgui_suite/generate_fonts.sh
|
||||
- name: Commit
|
||||
run: |
|
||||
# Set credentials
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
||||
# Commit
|
||||
git commit -am "Regenerate pregenerated files"
|
||||
git push
|
||||
66
.github/workflows/documentation.yml
vendored
66
.github/workflows/documentation.yml
vendored
@@ -1,66 +0,0 @@
|
||||
name: Documentation
|
||||
|
||||
on: [push, workflow_dispatch]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
BASE_PATH: allwpilib/docs
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
name: "Documentation - Publish"
|
||||
runs-on: ubuntu-22.04
|
||||
if: github.repository == 'wpilibsuite/allwpilib' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v'))
|
||||
concurrency: ci-docs-publish
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
- uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: 17
|
||||
- name: Set environment variables (Development)
|
||||
run: |
|
||||
echo "BRANCH=development" >> $GITHUB_ENV
|
||||
if: github.ref == 'refs/heads/main'
|
||||
- name: Set environment variables (Tag)
|
||||
run: |
|
||||
echo "EXTRA_GRADLE_ARGS=-PreleaseMode" >> $GITHUB_ENV
|
||||
echo "BRANCH=beta" >> $GITHUB_ENV
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
- name: Set environment variables (Release)
|
||||
run: |
|
||||
echo "EXTRA_GRADLE_ARGS=-PreleaseMode" >> $GITHUB_ENV
|
||||
echo "BRANCH=release" >> $GITHUB_ENV
|
||||
if: startsWith(github.ref, 'refs/tags/v') && !contains(github.ref, 'alpha') && !contains(github.ref, 'beta')
|
||||
- name: Build with Gradle
|
||||
run: ./gradlew docs:generateJavaDocs docs:doxygen -PbuildServer ${{ env.EXTRA_GRADLE_ARGS }}
|
||||
- name: Install SSH Client 🔑
|
||||
uses: webfactory/ssh-agent@v0.9.0
|
||||
with:
|
||||
ssh-private-key: ${{ secrets.GH_DEPLOY_KEY }}
|
||||
- name: Deploy 🚀
|
||||
uses: JamesIves/github-pages-deploy-action@v4.6.1
|
||||
with:
|
||||
ssh-key: true
|
||||
repository-name: wpilibsuite/wpilibsuite.github.io
|
||||
branch: allwpilib-${{ env.BRANCH }}
|
||||
clean: true
|
||||
single-commit: true
|
||||
folder: docs/build/docs
|
||||
- name: Trigger Workflow
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
github-token: ${{ secrets.DISPATCH_PAT_TOKEN }}
|
||||
script: |
|
||||
github.rest.actions.createWorkflowDispatch({
|
||||
owner: context.repo.owner,
|
||||
repo: 'wpilibsuite.github.io',
|
||||
workflow_id: 'static.yml',
|
||||
ref: 'main',
|
||||
})
|
||||
8
.github/workflows/fix_compile_commands.py
vendored
8
.github/workflows/fix_compile_commands.py
vendored
@@ -18,9 +18,9 @@ def main():
|
||||
for obj in data:
|
||||
out_args = []
|
||||
|
||||
# Filter out -isystem flags that cause false positives
|
||||
iter_args = iter(obj["arguments"])
|
||||
for arg in iter_args:
|
||||
# Filter out -isystem flags that cause false positives
|
||||
if arg == "-isystem":
|
||||
next_arg = next(iter_args)
|
||||
|
||||
@@ -28,6 +28,12 @@ def main():
|
||||
# error: conflicting types for '_mm_prefetch' [clang-diagnostic-error]
|
||||
if not next_arg.startswith("/usr/lib/gcc/"):
|
||||
out_args += ["-isystem", next_arg]
|
||||
# Replace GCC warning argument with one Clang recognizes
|
||||
elif arg == "-Wno-maybe-uninitialized":
|
||||
out_args.append("-Wno-uninitialized")
|
||||
# Skip GCC-specific warning argument
|
||||
elif arg == "-Wno-error=restrict":
|
||||
pass
|
||||
else:
|
||||
out_args.append(arg)
|
||||
|
||||
|
||||
14
.github/workflows/gradle-wrapper-validation.yml
vendored
14
.github/workflows/gradle-wrapper-validation.yml
vendored
@@ -1,14 +0,0 @@
|
||||
name: "Validate Gradle Wrapper"
|
||||
on: [pull_request, push]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
validation:
|
||||
name: "Validation"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: gradle/actions/wrapper-validation@v3
|
||||
169
.github/workflows/gradle.yml
vendored
169
.github/workflows/gradle.yml
vendored
@@ -7,25 +7,33 @@ concurrency:
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
validation:
|
||||
name: "Validation"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: gradle/actions/wrapper-validation@v4
|
||||
|
||||
build-docker:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- container: wpilib/roborio-cross-ubuntu:2024-22.04
|
||||
artifact-name: Athena
|
||||
build-options: "-Ponlylinuxathena"
|
||||
- container: wpilib/raspbian-cross-ubuntu:bullseye-22.04
|
||||
- container: wpilib/systemcore-cross-ubuntu:2027-24.04
|
||||
artifact-name: SystemCore
|
||||
build-options: "-Ponlylinuxsystemcore"
|
||||
- container: wpilib/raspbian-cross-ubuntu:2027-bookworm-24.04
|
||||
artifact-name: Arm32
|
||||
build-options: "-Ponlylinuxarm32"
|
||||
- container: wpilib/aarch64-cross-ubuntu:bullseye-22.04
|
||||
- container: wpilib/aarch64-cross-ubuntu:2027-bookworm-24.04
|
||||
artifact-name: Arm64
|
||||
build-options: "-Ponlylinuxarm64"
|
||||
- container: wpilib/ubuntu-base:22.04
|
||||
- container: wpilib/systemcore-cross-ubuntu:2027-24.04
|
||||
artifact-name: Linux
|
||||
build-options: "-Ponlylinuxx86-64"
|
||||
name: "Build - ${{ matrix.artifact-name }}"
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-24.04
|
||||
needs: [validation]
|
||||
steps:
|
||||
- name: Free Disk Space
|
||||
uses: jlumbroso/free-disk-space@main
|
||||
@@ -42,7 +50,7 @@ jobs:
|
||||
fetch-depth: 0
|
||||
- name: Set release environment variable
|
||||
run: echo "EXTRA_GRADLE_ARGS=-PreleaseMode" >> $GITHUB_ENV
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
if: startsWith(github.ref, 'refs/tags/v2027')
|
||||
- name: Build with Gradle
|
||||
uses: addnab/docker-run-action@v3
|
||||
with:
|
||||
@@ -96,12 +104,14 @@ jobs:
|
||||
task: "build"
|
||||
outputs: "build/allOutputs"
|
||||
- os: windows-2022
|
||||
artifact-name: Win32
|
||||
architecture: x86
|
||||
artifact-name: Win64FFI
|
||||
architecture: x64
|
||||
task: ":ntcoreffi:build"
|
||||
build-options: "-Pntcoreffibuild -Pbuildwinarm64"
|
||||
outputs: "ntcoreffi/build/outputs"
|
||||
name: "Build - ${{ matrix.artifact-name }}"
|
||||
runs-on: ${{ matrix.os }}
|
||||
needs: [validation]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
@@ -109,7 +119,7 @@ jobs:
|
||||
- uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: 17
|
||||
java-version: 21
|
||||
architecture: ${{ matrix.architecture }}
|
||||
- name: Import Developer ID Certificate
|
||||
uses: wpilibsuite/import-signing-certificate@v2
|
||||
@@ -119,19 +129,16 @@ jobs:
|
||||
keychain-password: ${{ secrets.APPLE_KEYCHAIN_PASSWORD }}
|
||||
if: |
|
||||
matrix.artifact-name == 'macOS' && (github.repository == 'wpilibsuite/allwpilib' &&
|
||||
(github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v')))
|
||||
(github.ref == 'refs/heads/2027' || startsWith(github.ref, 'refs/tags/v2027')))
|
||||
- name: Set Keychain Lock Timeout
|
||||
run: security set-keychain-settings -lut 3600
|
||||
run: security set-keychain-settings -lut 21600
|
||||
if: |
|
||||
matrix.artifact-name == 'macOS' && (github.repository == 'wpilibsuite/allwpilib' &&
|
||||
(github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v')))
|
||||
(github.ref == 'refs/heads/2027' || startsWith(github.ref, 'refs/tags/v2027')))
|
||||
- name: Set release environment variable
|
||||
run: echo "EXTRA_GRADLE_ARGS=-PreleaseMode" >> $GITHUB_ENV
|
||||
shell: bash
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
- name: Set Java Heap Size
|
||||
run: sed -i 's/-Xmx2g/-Xmx1g/g' gradle.properties
|
||||
if: matrix.artifact-name == 'Win32'
|
||||
if: startsWith(github.ref, 'refs/tags/v2027')
|
||||
- name: Check disk free space (Windows)
|
||||
run: wmic logicaldisk get caption, freespace
|
||||
if: matrix.os == 'windows-2022'
|
||||
@@ -159,7 +166,7 @@ jobs:
|
||||
run: ./gradlew copyAllOutputs --build-cache -PbuildServer -PskipJavaFormat -PdeveloperID=${{ secrets.APPLE_DEVELOPER_ID }} ${{ matrix.build-options }} ${{ env.EXTRA_GRADLE_ARGS }}
|
||||
if: |
|
||||
matrix.artifact-name == 'macOS' && (github.repository == 'wpilibsuite/allwpilib' &&
|
||||
(github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v')))
|
||||
(github.ref == 'refs/heads/2027' || startsWith(github.ref, 'refs/tags/v2027')))
|
||||
- name: Check disk free space (Windows)
|
||||
run: wmic logicaldisk get caption, freespace
|
||||
if: matrix.os == 'windows-2022'
|
||||
@@ -173,7 +180,8 @@ jobs:
|
||||
|
||||
build-documentation:
|
||||
name: "Build - Documentation"
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-24.04
|
||||
needs: [validation]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
@@ -181,12 +189,12 @@ jobs:
|
||||
- uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: 17
|
||||
java-version: 21
|
||||
- name: Set release environment variable
|
||||
run: echo "EXTRA_GRADLE_ARGS=-PreleaseMode" >> $GITHUB_ENV
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
if: startsWith(github.ref, 'refs/tags/v2027')
|
||||
- name: Build with Gradle
|
||||
run: ./gradlew docs:zipDocs --build-cache -PbuildServer ${{ env.EXTRA_GRADLE_ARGS }}
|
||||
run: ./gradlew docs:zipDocs --build-cache -PbuildServer -PdocWarningsAsErrors ${{ env.EXTRA_GRADLE_ARGS }}
|
||||
env:
|
||||
ARTIFACTORY_PUBLISH_USERNAME: ${{ secrets.ARTIFACTORY_USERNAME }}
|
||||
ARTIFACTORY_PUBLISH_PASSWORD: ${{ secrets.ARTIFACTORY_PASSWORD }}
|
||||
@@ -195,15 +203,82 @@ jobs:
|
||||
name: Documentation
|
||||
path: docs/build/outputs
|
||||
|
||||
publish:
|
||||
name: "Documentation - Publish"
|
||||
runs-on: ubuntu-22.04
|
||||
if: github.repository == 'wpilibsuite/allwpilib' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v'))
|
||||
needs: [build-documentation]
|
||||
concurrency: ci-docs-publish
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
- name: Download docs artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: Documentation
|
||||
- name: Make output directories
|
||||
run: |
|
||||
mkdir -p docs/tmp/doxygen/html
|
||||
mkdir -p docs/tmp/javadoc
|
||||
- name: Extract docs
|
||||
run: |
|
||||
unzip _GROUP_edu_wpi_first_wpilibc_ID_documentation_CLS.zip -d docs/tmp/doxygen/html
|
||||
unzip _GROUP_edu_wpi_first_wpilibj_ID_documentation_CLS.zip -d docs/tmp/javadoc
|
||||
- name: Set environment variables (Development)
|
||||
run: |
|
||||
echo "BRANCH=development" >> $GITHUB_ENV
|
||||
if: github.ref == 'refs/heads/main'
|
||||
- name: Set environment variables (Tag)
|
||||
run: |
|
||||
echo "EXTRA_GRADLE_ARGS=-PreleaseMode" >> $GITHUB_ENV
|
||||
echo "BRANCH=beta" >> $GITHUB_ENV
|
||||
if: startsWith(github.ref, 'refs/tags/v') && !contains(github.ref, '2027')
|
||||
- name: Set environment variables (Release)
|
||||
run: |
|
||||
echo "EXTRA_GRADLE_ARGS=-PreleaseMode" >> $GITHUB_ENV
|
||||
echo "BRANCH=release" >> $GITHUB_ENV
|
||||
if: startsWith(github.ref, 'refs/tags/v') && !contains(github.ref, 'alpha') && !contains(github.ref, 'beta') && !contains(github.ref, '2027')
|
||||
- name: Set environment variables (2027)
|
||||
run: |
|
||||
echo "EXTRA_GRADLE_ARGS=-PreleaseMode" >> $GITHUB_ENV
|
||||
echo "BRANCH=2027" >> $GITHUB_ENV
|
||||
if: startsWith(github.ref, 'refs/tags/v') && contains(github.ref, '2027')
|
||||
- name: Install SSH Client 🔑
|
||||
uses: webfactory/ssh-agent@v0.9.0
|
||||
with:
|
||||
ssh-private-key: ${{ secrets.GH_DEPLOY_KEY }}
|
||||
- name: Deploy 🚀
|
||||
uses: JamesIves/github-pages-deploy-action@v4.6.1
|
||||
with:
|
||||
ssh-key: true
|
||||
repository-name: wpilibsuite/wpilibsuite.github.io
|
||||
branch: allwpilib-${{ env.BRANCH }}
|
||||
clean: true
|
||||
single-commit: true
|
||||
folder: docs/tmp
|
||||
- name: Trigger Workflow
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
github-token: ${{ secrets.DISPATCH_PAT_TOKEN }}
|
||||
script: |
|
||||
github.rest.actions.createWorkflowDispatch({
|
||||
owner: context.repo.owner,
|
||||
repo: 'wpilibsuite.github.io',
|
||||
workflow_id: 'static.yml',
|
||||
ref: 'main',
|
||||
})
|
||||
|
||||
combine:
|
||||
name: Combine
|
||||
needs: [build-docker, build-host, build-documentation]
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Free Disk Space
|
||||
if: |
|
||||
github.repository == 'wpilibsuite/allwpilib' &&
|
||||
(github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v'))
|
||||
(github.ref == 'refs/heads/2027' || startsWith(github.ref, 'refs/tags/v2027'))
|
||||
uses: jlumbroso/free-disk-space@main
|
||||
with:
|
||||
tool-cache: false
|
||||
@@ -216,48 +291,48 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
if: |
|
||||
github.repository == 'wpilibsuite/allwpilib' &&
|
||||
(github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v'))
|
||||
(github.ref == 'refs/heads/2027' || startsWith(github.ref, 'refs/tags/v2027'))
|
||||
with:
|
||||
repository: wpilibsuite/build-tools
|
||||
- uses: actions/download-artifact@v4
|
||||
if: |
|
||||
github.repository == 'wpilibsuite/allwpilib' &&
|
||||
(github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v'))
|
||||
(github.ref == 'refs/heads/2027' || startsWith(github.ref, 'refs/tags/v2027'))
|
||||
with:
|
||||
path: combiner/products/build/allOutputs
|
||||
- name: Flatten Artifacts
|
||||
if: |
|
||||
github.repository == 'wpilibsuite/allwpilib' &&
|
||||
(github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v'))
|
||||
(github.ref == 'refs/heads/2027' || startsWith(github.ref, 'refs/tags/v2027'))
|
||||
run: rsync -a --delete combiner/products/build/allOutputs/*/* combiner/products/build/allOutputs/
|
||||
- name: Check version number exists
|
||||
if: |
|
||||
github.repository == 'wpilibsuite/allwpilib' &&
|
||||
(github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v'))
|
||||
(github.ref == 'refs/heads/2027' || startsWith(github.ref, 'refs/tags/v2027'))
|
||||
run: |
|
||||
cat combiner/products/build/allOutputs/version.txt
|
||||
test -s combiner/products/build/allOutputs/version.txt
|
||||
- uses: actions/setup-java@v4
|
||||
if: |
|
||||
github.repository == 'wpilibsuite/allwpilib' &&
|
||||
(github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v'))
|
||||
(github.ref == 'refs/heads/2027' || startsWith(github.ref, 'refs/tags/v2027'))
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: 17
|
||||
- name: Combine (Main)
|
||||
java-version: 21
|
||||
- name: Combine (2027)
|
||||
if: |
|
||||
github.repository == 'wpilibsuite/allwpilib' &&
|
||||
github.ref == 'refs/heads/main'
|
||||
run: cd combiner && ./gradlew publish -Pallwpilib
|
||||
github.ref == 'refs/heads/2027'
|
||||
run: cd combiner && ./gradlew publish -Pallwpilib -Pbuild2027
|
||||
env:
|
||||
RUN_AZURE_ARTIFACTORY_RELEASE: "TRUE"
|
||||
ARTIFACTORY_PUBLISH_USERNAME: ${{ secrets.ARTIFACTORY_USERNAME }}
|
||||
ARTIFACTORY_PUBLISH_PASSWORD: ${{ secrets.ARTIFACTORY_PASSWORD }}
|
||||
- name: Combine (Release)
|
||||
- name: Combine (2027 Release)
|
||||
if: |
|
||||
github.repository == 'wpilibsuite/allwpilib' &&
|
||||
startsWith(github.ref, 'refs/tags/v')
|
||||
run: cd combiner && ./gradlew publish -Pallwpilib -PreleaseRepoPublish
|
||||
startsWith(github.ref, 'refs/tags/v2027')
|
||||
run: cd combiner && ./gradlew publish -Pallwpilib -PreleaseRepoPublish -Pbuild2027
|
||||
env:
|
||||
RUN_AZURE_ARTIFACTORY_RELEASE: "TRUE"
|
||||
ARTIFACTORY_PUBLISH_USERNAME: ${{ secrets.ARTIFACTORY_USERNAME }}
|
||||
@@ -265,25 +340,7 @@ jobs:
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: |
|
||||
github.repository == 'wpilibsuite/allwpilib' &&
|
||||
(github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v'))
|
||||
(github.ref == 'refs/heads/2027' || startsWith(github.ref, 'refs/tags/v2027'))
|
||||
with:
|
||||
name: Maven
|
||||
path: ~/releases
|
||||
|
||||
dispatch:
|
||||
name: dispatch
|
||||
needs: [combine]
|
||||
strategy:
|
||||
matrix:
|
||||
repo: ['SmartDashboard', 'PathWeaver', 'Shuffleboard', 'RobotBuilder']
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: peter-evans/repository-dispatch@v3
|
||||
if: |
|
||||
github.repository == 'wpilibsuite/allwpilib' &&
|
||||
startsWith(github.ref, 'refs/tags/v')
|
||||
with:
|
||||
token: ${{ secrets.TOOL_REPO_ACCESS_TOKEN }}
|
||||
repository: wpilibsuite/${{ matrix.repo }}
|
||||
event-type: tag
|
||||
client-payload: '{"package_name": "allwpilib", "package_version": "${{ github.ref_name }}"}'
|
||||
|
||||
14
.github/workflows/labeler.yml
vendored
Normal file
14
.github/workflows/labeler.yml
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
name: "Pull Request Labeler"
|
||||
on:
|
||||
- pull_request_target
|
||||
|
||||
jobs:
|
||||
labeler:
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/labeler@v5
|
||||
with:
|
||||
sync-labels: true
|
||||
57
.github/workflows/lint-format.yml
vendored
57
.github/workflows/lint-format.yml
vendored
@@ -11,9 +11,16 @@ concurrency:
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
validation:
|
||||
name: "Validation"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: gradle/actions/wrapper-validation@v4
|
||||
|
||||
wpiformat:
|
||||
name: "wpiformat"
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
@@ -22,14 +29,16 @@ jobs:
|
||||
run: |
|
||||
git checkout -b pr
|
||||
git branch -f main origin/main
|
||||
- name: Set up Python 3.10
|
||||
- name: Set up Python 3.12
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.10'
|
||||
python-version: '3.12'
|
||||
- name: Install wpiformat
|
||||
run: pip3 install wpiformat==2024.40
|
||||
run: |
|
||||
python -m venv ${{ runner.temp }}/wpiformat
|
||||
${{ runner.temp }}/wpiformat/bin/pip3 install wpiformat==2025.34
|
||||
- name: Run
|
||||
run: wpiformat
|
||||
run: ${{ runner.temp }}/wpiformat/bin/wpiformat
|
||||
- name: Check output
|
||||
run: git --no-pager diff --exit-code HEAD
|
||||
- name: Generate diff
|
||||
@@ -50,8 +59,9 @@ jobs:
|
||||
|
||||
tidy:
|
||||
name: "clang-tidy"
|
||||
runs-on: ubuntu-22.04
|
||||
container: wpilib/roborio-cross-ubuntu:2024-22.04
|
||||
runs-on: ubuntu-24.04
|
||||
needs: [validation]
|
||||
container: wpilib/ubuntu-base:24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
@@ -61,27 +71,30 @@ jobs:
|
||||
git config --global --add safe.directory /__w/allwpilib/allwpilib
|
||||
git checkout -b pr
|
||||
git branch -f main origin/main
|
||||
- name: Set up Python 3.10
|
||||
- name: Set up Python 3.12
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.10'
|
||||
python-version: '3.12'
|
||||
- name: Install wpiformat
|
||||
run: pip3 install wpiformat==2024.40
|
||||
run: |
|
||||
python -m venv ${{ runner.temp }}/wpiformat
|
||||
${{ runner.temp }}/wpiformat/bin/pip3 install wpiformat==2025.34
|
||||
- name: Create compile_commands.json
|
||||
run: |
|
||||
./gradlew generateCompileCommands -Ptoolchain-optional-roboRio
|
||||
./.github/workflows/fix_compile_commands.py build/TargetedCompileCommands/linuxx86-64release/compile_commands.json
|
||||
./.github/workflows/fix_compile_commands.py build/TargetedCompileCommands/linuxx86-64debug/compile_commands.json
|
||||
- name: List changed files
|
||||
run: wpiformat -list-changed-files
|
||||
run: ${{ runner.temp }}/wpiformat/bin/wpiformat -list-changed-files
|
||||
- name: Run clang-tidy release
|
||||
run: wpiformat -no-format -tidy-changed -compile-commands=build/TargetedCompileCommands/linuxx86-64release -vv
|
||||
run: ${{ runner.temp }}/wpiformat/bin/wpiformat -no-format -tidy-changed -compile-commands=build/TargetedCompileCommands/linuxx86-64release -vv
|
||||
- name: Run clang-tidy debug
|
||||
run: wpiformat -no-format -tidy-changed -compile-commands=build/TargetedCompileCommands/linuxx86-64debug -vv
|
||||
run: ${{ runner.temp }}/wpiformat/bin/wpiformat -no-format -tidy-changed -compile-commands=build/TargetedCompileCommands/linuxx86-64debug -vv
|
||||
javaformat:
|
||||
name: "Java format"
|
||||
runs-on: ubuntu-22.04
|
||||
container: wpilib/ubuntu-base:22.04
|
||||
runs-on: ubuntu-24.04
|
||||
needs: [validation]
|
||||
container: wpilib/systemcore-cross-ubuntu:2027-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
@@ -110,17 +123,3 @@ jobs:
|
||||
echo '' >> $GITHUB_STEP_SUMMARY
|
||||
echo '```' >> $GITHUB_STEP_SUMMARY
|
||||
if: ${{ failure() }}
|
||||
|
||||
documentation:
|
||||
name: "Documentation"
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: 21
|
||||
- name: Build with Gradle
|
||||
run: ./gradlew docs:zipDocs -PbuildServer -PdocWarningsAsErrors ${{ env.EXTRA_GRADLE_ARGS }}
|
||||
|
||||
28
.github/workflows/pregenerate.yml
vendored
28
.github/workflows/pregenerate.yml
vendored
@@ -13,35 +13,13 @@ concurrency:
|
||||
jobs:
|
||||
update:
|
||||
name: "Update"
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Set up Python 3.9
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: 3.9
|
||||
- name: Install jinja
|
||||
run: python -m pip install jinja2
|
||||
- name: Install protobuf dependencies
|
||||
run: sudo apt-get update && sudo apt-get install -y protobuf-compiler && wget https://github.com/HebiRobotics/QuickBuffers/releases/download/1.3.3/protoc-gen-quickbuf-1.3.3-linux-x86_64.exe && chmod +x protoc-gen-quickbuf-1.3.3-linux-x86_64.exe
|
||||
- name: Run hal
|
||||
run: ./hal/generate_usage_reporting.py
|
||||
- name: Run ntcore
|
||||
run: ./ntcore/generate_topics.py
|
||||
- name: Run wpimath
|
||||
run: ./wpimath/generate_numbers.py && ./wpimath/generate_quickbuf.py --quickbuf_plugin=protoc-gen-quickbuf-1.3.3-linux-x86_64.exe
|
||||
- name: Run wpiunits
|
||||
run: ./wpiunits/generate_units.py
|
||||
- name: Run HIDs
|
||||
run: ./wpilibj/generate_hids.py && ./wpilibc/generate_hids.py && ./wpilibNewCommands/generate_hids.py
|
||||
- name: Run PWM Controllers
|
||||
run: ./wpilibj/generate_pwm_motor_controllers.py && ./wpilibc/generate_pwm_motor_controllers.py
|
||||
- name: Run imgui gl3w
|
||||
run: ./thirdparty/imgui_suite/generate_gl3w.py
|
||||
- name: Run imgui fonts
|
||||
run: ./thirdparty/imgui_suite/generate_fonts.sh
|
||||
- name: Run pregen
|
||||
uses: ./.github/actions/pregen
|
||||
- name: Add untracked files to index so they count as changes
|
||||
run: git add -A
|
||||
- name: Check output
|
||||
|
||||
10
.github/workflows/sanitizers.yml
vendored
10
.github/workflows/sanitizers.yml
vendored
@@ -29,19 +29,19 @@ jobs:
|
||||
ctest-env: ""
|
||||
ctest-flags: ""
|
||||
name: "${{ matrix.name }}"
|
||||
runs-on: ubuntu-22.04
|
||||
container: wpilib/roborio-cross-ubuntu:2024-22.04
|
||||
runs-on: ubuntu-24.04
|
||||
container: wpilib/roborio-cross-ubuntu:2025-24.04
|
||||
steps:
|
||||
- name: Install Dependencies
|
||||
run: sudo apt-get update && sudo apt-get install -y libopencv-dev libopencv4.5-java clang-14 libprotobuf-dev protobuf-compiler ninja-build
|
||||
run: sudo apt-get update && sudo apt-get install -y libopencv-dev libopencv-java clang-18 ninja-build
|
||||
|
||||
- name: Install sccache
|
||||
uses: mozilla-actions/sccache-action@v0.0.5
|
||||
uses: mozilla-actions/sccache-action@v0.0.9
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: configure
|
||||
run: mkdir build && cd build && cmake -G Ninja -DCMAKE_C_COMPILER_LAUNCHER=sccache -DCMAKE_CXX_COMPILER_LAUNCHER=sccache -DCMAKE_C_COMPILER:FILEPATH=/usr/bin/clang-14 -DCMAKE_CXX_COMPILER:FILEPATH=/usr/bin/clang++-14 -DWITH_JAVA=OFF ${{ matrix.cmake-flags }} ..
|
||||
run: mkdir build && cd build && cmake -G Ninja -DCMAKE_C_COMPILER_LAUNCHER=sccache -DCMAKE_CXX_COMPILER_LAUNCHER=sccache -DCMAKE_C_COMPILER:FILEPATH=/usr/bin/clang-18 -DCMAKE_CXX_COMPILER:FILEPATH=/usr/bin/clang++-18 -DWITH_JAVA=OFF ${{ matrix.cmake-flags }} ..
|
||||
env:
|
||||
SCCACHE_WEBDAV_USERNAME: ${{ secrets.ARTIFACTORY_USERNAME }}
|
||||
SCCACHE_WEBDAV_PASSWORD: ${{ secrets.ARTIFACTORY_PASSWORD }}
|
||||
|
||||
168
.github/workflows/sentinel-build.yml
vendored
Normal file
168
.github/workflows/sentinel-build.yml
vendored
Normal file
@@ -0,0 +1,168 @@
|
||||
name: Sentinel Build (No Cache)
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: "15 3 * * Sat" # 11:15PM EST every Friday
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
validation:
|
||||
name: "Validation"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: gradle/actions/wrapper-validation@v4
|
||||
|
||||
build-docker:
|
||||
if: (github.repository_owner == 'wpilibsuite' && github.ref == 'refs/heads/main') || github.event_name != 'schedule'
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- container: wpilib/systemcore-cross-ubuntu:2027-24.04
|
||||
artifact-name: SystemCore
|
||||
build-options: "-Ponlylinuxsystemcore"
|
||||
- container: wpilib/raspbian-cross-ubuntu:2027-bookworm-24.04
|
||||
artifact-name: Arm32
|
||||
build-options: "-Ponlylinuxarm32"
|
||||
- container: wpilib/aarch64-cross-ubuntu:2027-bookworm-24.04
|
||||
artifact-name: Arm64
|
||||
build-options: "-Ponlylinuxarm64"
|
||||
- container: wpilib/systemcore-cross-ubuntu:2027-24.04
|
||||
artifact-name: Linux
|
||||
build-options: "-Ponlylinuxx86-64"
|
||||
name: "Build - ${{ matrix.artifact-name }}"
|
||||
runs-on: ubuntu-24.04
|
||||
needs: [validation]
|
||||
steps:
|
||||
- name: Free Disk Space
|
||||
uses: jlumbroso/free-disk-space@main
|
||||
with:
|
||||
tool-cache: false
|
||||
android: true
|
||||
dotnet: true
|
||||
haskell: true
|
||||
large-packages: false
|
||||
docker-images: false
|
||||
swap-storage: false
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Build with Gradle
|
||||
uses: addnab/docker-run-action@v3
|
||||
with:
|
||||
image: ${{ matrix.container }}
|
||||
options: -v ${{ github.workspace }}:/work -w /work -e GITHUB_REF -e CI
|
||||
run: df . && rm -f semicolon_delimited_script && echo $GITHUB_REF && ./gradlew build -PbuildServer -PskipJavaFormat ${{ matrix.build-options }}
|
||||
- name: Check free disk space
|
||||
run: df .
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ matrix.artifact-name }}
|
||||
path: build/allOutputs
|
||||
|
||||
build-host:
|
||||
if: (github.repository_owner == 'wpilibsuite' && github.ref == 'refs/heads/main') || github.event_name != 'schedule'
|
||||
env:
|
||||
MACOSX_DEPLOYMENT_TARGET: 13.3
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- os: windows-2022
|
||||
artifact-name: Win64Debug
|
||||
architecture: x64
|
||||
task: "build"
|
||||
build-options: "-PciDebugOnly"
|
||||
outputs: "build/allOutputs"
|
||||
- os: windows-2022
|
||||
artifact-name: Win64Release
|
||||
architecture: x64
|
||||
build-options: "-PciReleaseOnly"
|
||||
task: "copyAllOutputs"
|
||||
outputs: "build/allOutputs"
|
||||
- os: windows-2022
|
||||
artifact-name: WinArm64Debug
|
||||
architecture: x64
|
||||
task: "build"
|
||||
build-options: "-PciDebugOnly -Pbuildwinarm64 -Ponlywindowsarm64"
|
||||
outputs: "build/allOutputs"
|
||||
- os: windows-2022
|
||||
artifact-name: WinArm64Release
|
||||
architecture: x64
|
||||
build-options: "-PciReleaseOnly -Pbuildwinarm64 -Ponlywindowsarm64"
|
||||
task: "copyAllOutputs"
|
||||
outputs: "build/allOutputs"
|
||||
- os: macOS-14
|
||||
artifact-name: macOS
|
||||
architecture: aarch64
|
||||
task: "build"
|
||||
outputs: "build/allOutputs"
|
||||
- os: windows-2022
|
||||
artifact-name: Win64FFI
|
||||
architecture: x64
|
||||
task: ":ntcoreffi:build"
|
||||
build-options: "-Pntcoreffibuild -Pbuildwinarm64"
|
||||
outputs: "ntcoreffi/build/outputs"
|
||||
name: "Build - ${{ matrix.artifact-name }}"
|
||||
runs-on: ${{ matrix.os }}
|
||||
needs: [validation]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: 21
|
||||
architecture: ${{ matrix.architecture }}
|
||||
- name: Import Developer ID Certificate
|
||||
uses: wpilibsuite/import-signing-certificate@v2
|
||||
with:
|
||||
certificate-data: ${{ secrets.APPLE_CERTIFICATE_DATA }}
|
||||
certificate-passphrase: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
|
||||
keychain-password: ${{ secrets.APPLE_KEYCHAIN_PASSWORD }}
|
||||
if: |
|
||||
matrix.artifact-name == 'macOS' && (github.repository_owner == 'wpilibsuite' && github.ref == 'refs/heads/main')
|
||||
- name: Set Keychain Lock Timeout
|
||||
run: security set-keychain-settings -lut 21600
|
||||
if: |
|
||||
matrix.artifact-name == 'macOS' && (github.repository_owner == 'wpilibsuite' && github.ref == 'refs/heads/main')
|
||||
- name: Check disk free space (Windows)
|
||||
run: wmic logicaldisk get caption, freespace
|
||||
if: matrix.os == 'windows-2022'
|
||||
- name: Check disk free space pre-cleanup (macOS)
|
||||
run: df -h .
|
||||
if: matrix.os == 'macOS-14'
|
||||
- name: Cleanup disk space
|
||||
# CodeQL: 5G
|
||||
# go: 748M
|
||||
# Android: 12G
|
||||
run: |
|
||||
rm -rf /Users/runner/hostedtoolcache/CodeQL
|
||||
rm -rf /Users/runner/hostedtoolcache/go
|
||||
rm -rf /Users/runner/Library/Android
|
||||
if: matrix.os == 'macOS-14'
|
||||
- name: Check disk free space post-cleanup (macOS)
|
||||
run: df -h .
|
||||
if: matrix.os == 'macOS-14'
|
||||
- name: Build with Gradle
|
||||
run: ./gradlew ${{ matrix.task }} -PbuildServer -PskipJavaFormat ${{ matrix.build-options }}
|
||||
- name: Sign Libraries with Developer ID
|
||||
run: ./gradlew copyAllOutputs -PbuildServer -PskipJavaFormat -PdeveloperID=${{ secrets.APPLE_DEVELOPER_ID }} ${{ matrix.build-options }}
|
||||
if: |
|
||||
matrix.artifact-name == 'macOS' && (github.repository_owner == 'wpilibsuite' && github.ref == 'refs/heads/main')
|
||||
- name: Check disk free space (Windows)
|
||||
run: wmic logicaldisk get caption, freespace
|
||||
if: matrix.os == 'windows-2022'
|
||||
- name: Check disk free space (macOS)
|
||||
run: df -h .
|
||||
if: matrix.os == 'macOS-14'
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ matrix.artifact-name }}
|
||||
path: ${{ matrix.outputs }}
|
||||
150
.github/workflows/tools.yml
vendored
150
.github/workflows/tools.yml
vendored
@@ -1,150 +0,0 @@
|
||||
name: Tools
|
||||
|
||||
on: [pull_request, push]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
YEAR: 2025
|
||||
|
||||
jobs:
|
||||
build-artifacts:
|
||||
name: "Build - WPILib"
|
||||
runs-on: ubuntu-22.04
|
||||
env:
|
||||
DISPLAY: ':10'
|
||||
steps:
|
||||
- name: Free Disk Space
|
||||
uses: jlumbroso/free-disk-space@main
|
||||
with:
|
||||
tool-cache: false
|
||||
android: true
|
||||
dotnet: true
|
||||
haskell: true
|
||||
large-packages: false
|
||||
docker-images: false
|
||||
swap-storage: false
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Build WPILib with Gradle
|
||||
uses: addnab/docker-run-action@v3
|
||||
with:
|
||||
image: wpilib/roborio-cross-ubuntu:2024-22.04
|
||||
options: -v ${{ github.workspace }}:/work -w /work -e GITHUB_REF -e CI -e DISPLAY
|
||||
run: df . && rm -f semicolon_delimited_script && ./gradlew :wpilibc:publish :wpilibj:publish :wpilibNewCommands:publish :hal:publish :cameraserver:publish :ntcore:publish :cscore:publish :wpimath:publish :wpinet:publish :wpiutil:publish :apriltag:publish :wpiunits:publish :simulation:halsim_gui:publish :simulation:halsim_ds_socket:publish :fieldImages:publish -x test -x Javadoc -x doxygen --build-cache && cp -r /root/releases/maven/development /work
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: MavenArtifacts
|
||||
path: |
|
||||
development
|
||||
retention-days: 1
|
||||
|
||||
Robotbuilder:
|
||||
name: "Build - RobotBuilder"
|
||||
needs: [build-artifacts]
|
||||
runs-on: ubuntu-22.04
|
||||
env:
|
||||
DISPLAY: ':10'
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
repository: wpilibsuite/robotbuilder
|
||||
fetch-depth: 0
|
||||
- uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: MavenArtifacts
|
||||
- name: Patch RobotBuilder to use local development
|
||||
run: cd src/main/resources/export && echo "wpi.maven.useLocal = false" >> java/build.gradle && echo "wpi.maven.useFrcMavenLocalDevelopment = true" >> java/build.gradle && echo "wpi.versions.wpilibVersion = '$YEAR.424242.+'" >> java/build.gradle && echo "wpi.versions.wpimathVersion = '$YEAR.424242.+'" >> java/build.gradle && echo "wpi.maven.useLocal = false" >> cpp/build.gradle && echo "wpi.maven.useFrcMavenLocalDevelopment = true" >> cpp/build.gradle && echo "wpi.versions.wpilibVersion = '$YEAR.424242.+'" >> cpp/build.gradle && echo "wpi.versions.wpimathVersion = '$YEAR.424242.+'" >> cpp/build.gradle
|
||||
- name: Install and run xvfb
|
||||
run: sudo apt-get update && sudo apt-get install -y xvfb && Xvfb $DISPLAY &
|
||||
- name: Move artifacts
|
||||
run: mkdir -p ~/releases/maven/development && cp -r edu ~/releases/maven/development
|
||||
- uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: 17
|
||||
distribution: 'temurin'
|
||||
- name: Build RobotBuilder with Gradle
|
||||
run: ./gradlew build test --tests 'robotbuilder.exporters.*' -x htmlSanityCheck -PbuildServer -PreleaseMode ; cat build/test-results/test/TEST-robotbuilder.exporters.*.xml ;
|
||||
- name: Summarize RobotBuilder Test Results
|
||||
uses: EnricoMi/publish-unit-test-result-action@v2
|
||||
if: always()
|
||||
with:
|
||||
files: |
|
||||
build/test-results/test/TEST*.xml
|
||||
check_run: false
|
||||
comment_mode: off
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: always()
|
||||
with:
|
||||
name: RobotBuilderTestResults
|
||||
path: |
|
||||
build/reports/
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: RobotBuilder Build
|
||||
path: |
|
||||
build/libs/
|
||||
retention-days: 7
|
||||
|
||||
Shuffleboard:
|
||||
name: "Build - Shuffleboard"
|
||||
needs: [build-artifacts]
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
repository: wpilibsuite/shuffleboard
|
||||
fetch-depth: 0
|
||||
- name: Patch Shuffleboard to use local development
|
||||
run: sed -i "s/wpilibTools.deps.wpilibVersion.*/wpilibTools.deps.wpilibVersion = \'$YEAR\.424242\.+\'/" app/app.gradle && sed -i "s/wpilibTools.deps.wpilibVersion.*/wpilibTools.deps.wpilibVersion = \'$YEAR\.424242\.+\'/" plugins/cameraserver/cameraserver.gradle && sed -i "s/wpilibTools.deps.wpilibVersion.*/wpilibTools.deps.wpilibVersion = \'$YEAR\.424242\.+\'/" plugins/networktables/networktables.gradle
|
||||
- uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: MavenArtifacts
|
||||
- uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: 17
|
||||
distribution: 'temurin'
|
||||
- name: Move artifacts
|
||||
run: mkdir -p ~/releases/maven/development && cp -r edu ~/releases/maven/development
|
||||
- name: Install dependencies
|
||||
run: sudo apt-get install -y libgtk2.0-0
|
||||
- name: Build with Gradle
|
||||
run: ./gradlew build -x Javadoc
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Shuffleboard Build
|
||||
path: |
|
||||
build/allOutputs/
|
||||
retention-days: 7
|
||||
|
||||
PathWeaver:
|
||||
name: "Build - PathWeaver"
|
||||
needs: [build-artifacts]
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
repository: wpilibsuite/PathWeaver
|
||||
fetch-depth: 0
|
||||
- name: Patch PathWeaver to use local development
|
||||
run: sed -i "s/wpilibTools.deps.wpilibVersion.*/wpilibTools.deps.wpilibVersion = \'$YEAR\.424242\.+\'/" dependencies.gradle
|
||||
- uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: MavenArtifacts
|
||||
- uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: 17
|
||||
distribution: 'temurin'
|
||||
- name: Move artifacts
|
||||
run: mkdir -p ~/releases/maven/development && cp -r edu ~/releases/maven/development
|
||||
- name: Build with Gradle
|
||||
run: ./gradlew build
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: PathWeaver Build
|
||||
path: |
|
||||
build/allOutputs/
|
||||
retention-days: 7
|
||||
58
.github/workflows/upstream-utils.yml
vendored
58
.github/workflows/upstream-utils.yml
vendored
@@ -13,7 +13,7 @@ concurrency:
|
||||
jobs:
|
||||
update:
|
||||
name: "Update"
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
@@ -22,10 +22,10 @@ jobs:
|
||||
run: |
|
||||
git checkout -b pr
|
||||
git branch -f main origin/main
|
||||
- name: Set up Python 3.9
|
||||
- name: Set up Python 3.12
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: 3.9
|
||||
python-version: '3.12'
|
||||
- name: Configure committer identity
|
||||
run: |
|
||||
git config --global user.email "you@example.com"
|
||||
@@ -35,107 +35,117 @@ jobs:
|
||||
cd upstream_utils
|
||||
./apriltag.py clone
|
||||
./apriltag.py copy-src
|
||||
./apriltag.py format-patch
|
||||
- name: Run argparse_lib.py
|
||||
run: |
|
||||
cd upstream_utils
|
||||
./argparse_lib.py clone
|
||||
./argparse_lib.py copy-src
|
||||
- name: Run concurrentqueue.py
|
||||
run: |
|
||||
cd upstream_utils
|
||||
./concurrentqueue.py clone
|
||||
./concurrentqueue.py copy-src
|
||||
./argparse_lib.py format-patch
|
||||
- name: Run eigen.py
|
||||
run: |
|
||||
cd upstream_utils
|
||||
./eigen.py clone
|
||||
./eigen.py copy-src
|
||||
./eigen.py format-patch
|
||||
- name: Run expected.py
|
||||
run: |
|
||||
cd upstream_utils
|
||||
./expected.py clone
|
||||
./expected.py copy-src
|
||||
./expected.py format-patch
|
||||
- name: Run fmt.py
|
||||
run: |
|
||||
cd upstream_utils
|
||||
./fmt.py clone
|
||||
./fmt.py copy-src
|
||||
./fmt.py format-patch
|
||||
- name: Run gcem.py
|
||||
run: |
|
||||
cd upstream_utils
|
||||
./gcem.py clone
|
||||
./gcem.py copy-src
|
||||
./gcem.py format-patch
|
||||
- name: Run gl3w.py
|
||||
run: |
|
||||
cd upstream_utils
|
||||
./gl3w.py clone
|
||||
./gl3w.py copy-src
|
||||
./gl3w.py format-patch
|
||||
- name: Run glfw.py
|
||||
run: |
|
||||
cd upstream_utils
|
||||
./glfw.py clone
|
||||
./glfw.py copy-src
|
||||
./glfw.py format-patch
|
||||
- name: Run googletest.py
|
||||
run: |
|
||||
cd upstream_utils
|
||||
./googletest.py clone
|
||||
./googletest.py copy-src
|
||||
./googletest.py format-patch
|
||||
- name: Run imgui.py
|
||||
run: |
|
||||
cd upstream_utils
|
||||
./imgui.py clone
|
||||
./imgui.py copy-src
|
||||
./imgui.py format-patch
|
||||
- name: Run implot.py
|
||||
run: |
|
||||
cd upstream_utils
|
||||
./implot.py clone
|
||||
./implot.py copy-src
|
||||
./implot.py format-patch
|
||||
- name: Run json.py
|
||||
run: |
|
||||
cd upstream_utils
|
||||
./json.py clone
|
||||
./json.py copy-src
|
||||
./json.py format-patch
|
||||
- name: Run libuv.py
|
||||
run: |
|
||||
cd upstream_utils
|
||||
./libuv.py clone
|
||||
./libuv.py copy-src
|
||||
./libuv.py format-patch
|
||||
- name: Run llvm.py
|
||||
run: |
|
||||
cd upstream_utils
|
||||
./llvm.py clone
|
||||
./llvm.py copy-src
|
||||
./llvm.py format-patch
|
||||
- name: Run mpack.py
|
||||
run: |
|
||||
cd upstream_utils
|
||||
./mpack.py clone
|
||||
./mpack.py copy-src
|
||||
- name: Run stack_walker.py
|
||||
run: |
|
||||
cd upstream_utils
|
||||
./stack_walker.py clone
|
||||
./stack_walker.py copy-src
|
||||
- name: Run memory.py
|
||||
run: |
|
||||
cd upstream_utils
|
||||
./memory.py clone
|
||||
./memory.py copy-src
|
||||
- name: Run protobuf.py
|
||||
run: |
|
||||
cd upstream_utils
|
||||
./protobuf.py clone
|
||||
./protobuf.py copy-src
|
||||
./mpack.py format-patch
|
||||
- name: Run sleipnir.py
|
||||
run: |
|
||||
cd upstream_utils
|
||||
./sleipnir.py clone
|
||||
./sleipnir.py copy-src
|
||||
./sleipnir.py format-patch
|
||||
- name: Run stb.py
|
||||
run: |
|
||||
cd upstream_utils
|
||||
./stb.py clone
|
||||
./stb.py copy-src
|
||||
./stb.py format-patch
|
||||
- name: Run upb.py
|
||||
run: |
|
||||
cd upstream_utils
|
||||
./upb.py clone
|
||||
./upb.py copy-src
|
||||
./upb.py format-patch
|
||||
- name: Add untracked files to index so they count as changes
|
||||
run: git add -A
|
||||
- name: Check output
|
||||
run: git --no-pager diff --exit-code HEAD
|
||||
run: |
|
||||
set +e
|
||||
git --no-pager diff --exit-code HEAD ':!*.bazel'
|
||||
git_exit_code=$?
|
||||
if test "$git_exit_code" -ne "0"; then
|
||||
echo "::error ::upstream_utils check failed. This is usually caused by a bad script or the copied files differing from what the script outputs. You can learn more about using upstream_utils to modify thirdparty libraries at https://github.com/wpilibsuite/allwpilib/blob/main/upstream_utils/README.md"
|
||||
exit $git_exit_code
|
||||
fi
|
||||
|
||||
9
.gitignore
vendored
9
.gitignore
vendored
@@ -15,6 +15,8 @@ networktables.json
|
||||
ntcore/connectionlistenertest.json
|
||||
ntcore/timesynctest.json
|
||||
|
||||
nanopb_pb2.py
|
||||
|
||||
# Created by the jenkins test script
|
||||
test-reports
|
||||
|
||||
@@ -239,7 +241,7 @@ compile_commands.json
|
||||
|
||||
# clang configuration and clangd cache
|
||||
.clang
|
||||
.clangd/
|
||||
.clangd
|
||||
.cache/
|
||||
|
||||
imgui.ini
|
||||
@@ -249,9 +251,10 @@ imgui.ini
|
||||
/bazel-*
|
||||
user.bazelrc
|
||||
coverage_report/
|
||||
bazel_auth.rc
|
||||
|
||||
# ctest
|
||||
/Testing/
|
||||
|
||||
# protobuf
|
||||
!wpiprotoplugin.jar
|
||||
# Meson
|
||||
.meson-subproject*
|
||||
|
||||
11
.styleguide
11
.styleguide
@@ -14,6 +14,7 @@ modifiableFileExclude {
|
||||
thirdparty/
|
||||
\.patch$
|
||||
gradlew
|
||||
BUILD.bazel
|
||||
}
|
||||
|
||||
generatedFileExclude {
|
||||
@@ -22,6 +23,13 @@ generatedFileExclude {
|
||||
fieldImages/src/main/native/resources/
|
||||
apriltag/src/test/resources/
|
||||
wpilibc/src/generated/
|
||||
|
||||
apriltag/src/main/python/
|
||||
apriltag/src/test/python/
|
||||
wpilibc/src/main/python/
|
||||
wpilibc/src/test/python/
|
||||
xrpVendordep/src/main/python/
|
||||
xrpVendordep/src/test/python/
|
||||
}
|
||||
|
||||
repoRootNameOverride {
|
||||
@@ -33,8 +41,8 @@ includeOtherLibs {
|
||||
^cameraserver/
|
||||
^cscore
|
||||
^fmt/
|
||||
^glass/
|
||||
^gtest/
|
||||
^google/
|
||||
^hal/
|
||||
^imgui
|
||||
^implot
|
||||
@@ -45,6 +53,7 @@ includeOtherLibs {
|
||||
^support/
|
||||
^units/
|
||||
^unsupported/
|
||||
^upb/
|
||||
^vision/
|
||||
^wpi/
|
||||
^wpigui
|
||||
|
||||
128
BUILD.bazel
Normal file
128
BUILD.bazel
Normal file
@@ -0,0 +1,128 @@
|
||||
load("@aspect_bazel_lib//lib:write_source_files.bzl", "write_source_files")
|
||||
load("@rules_pkg//:mappings.bzl", "pkg_files")
|
||||
load("@rules_python//python:pip.bzl", "compile_pip_requirements")
|
||||
load("//shared/bazel/rules:publishing.bzl", "publish_all")
|
||||
|
||||
exports_files([
|
||||
"LICENSE.md",
|
||||
"ThirdPartyNotices.txt",
|
||||
])
|
||||
|
||||
pkg_files(
|
||||
name = "license_pkg_files",
|
||||
srcs = [
|
||||
"LICENSE.md",
|
||||
"ThirdPartyNotices.txt",
|
||||
],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
# bazel build //:requirements.lock
|
||||
compile_pip_requirements(
|
||||
name = "requirements",
|
||||
extra_args = ["--allow-unsafe"],
|
||||
requirements_in = "requirements.txt",
|
||||
requirements_txt = "requirements_lock.txt",
|
||||
requirements_windows = "//:requirements_windows_lock.txt",
|
||||
# compile_pip_requirements does not respect target_compatible_with for some of the targets it generates under the hood
|
||||
tags = ["no-systemcore"],
|
||||
)
|
||||
|
||||
alias(
|
||||
name = "quickbuf_protoc",
|
||||
actual = select({
|
||||
"@platforms//os:windows": "@quickbuffer_protoc_windows//file",
|
||||
"@rules_bzlmodrio_toolchains//conditions:osx_aarch64": "@quickbuffer_protoc_osx_aarch64//file",
|
||||
"@rules_bzlmodrio_toolchains//conditions:osx_x86_64": "@quickbuffer_protoc_osx_x86-64//file",
|
||||
"@rules_bzlmodrio_toolchains//constraints/combined:is_linux": "@quickbuffer_protoc_linux//file",
|
||||
}),
|
||||
tags = ["pregeneration"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
# This is a helper to run all of the pregeneration scripts at once.
|
||||
write_source_files(
|
||||
name = "write_all",
|
||||
additional_update_targets = [
|
||||
"//hal:write_hal",
|
||||
"//ntcore:write_ntcore",
|
||||
"//wpilibc:write_wpilibc",
|
||||
"//wpilibcExamples:write_example_project_list",
|
||||
"//wpilibj:write_wpilibj",
|
||||
"//wpilibjExamples:write_example_project_list",
|
||||
"//wpilibNewCommands:write_wpilib_new_commands",
|
||||
"//commandsv3:write_commandsv3",
|
||||
"//wpimath:write_wpimath",
|
||||
"//wpiunits:write_wpiunits",
|
||||
"//wpiutil:write_wpiutil",
|
||||
],
|
||||
tags = ["pregeneration"],
|
||||
)
|
||||
|
||||
publish_all(
|
||||
name = "publish",
|
||||
targets = [
|
||||
"//apriltag:apriltag-cpp_publish.publish",
|
||||
"//apriltag:apriltag-java_publish.publish",
|
||||
"//cameraserver:cameraserver-cpp_publish.publish",
|
||||
"//cameraserver:cameraserver-java_publish.publish",
|
||||
"//cscore:cscore-cpp_publish.publish",
|
||||
"//cscore:cscore-java_publish.publish",
|
||||
"//datalog:datalog-cpp_publish.publish",
|
||||
"//datalog:datalog-java_publish.publish",
|
||||
"//datalogtool:datalogtool_publish.publish",
|
||||
"//docs:wpilibj_publish.publish",
|
||||
"//epilogue-processor:processor-java_publish.publish",
|
||||
"//epilogue-runtime:epilogue-java_publish.publish",
|
||||
"//fieldImages:fieldImages-cpp_publish.publish",
|
||||
"//fieldImages:fieldImages-java_publish.publish",
|
||||
"//glass:glass-cpp_publish.publish",
|
||||
"//glass:glassapp_publish.publish",
|
||||
"//glass:glassnt-cpp_publish.publish",
|
||||
"//hal:hal-java_publish.publish",
|
||||
"//hal:wpiHal-cpp_publish.publish",
|
||||
"//ntcore:ntcore-cpp_publish.publish",
|
||||
"//ntcore:ntcore-java_publish.publish",
|
||||
"//ntcoreffi:ntcoreffi-cpp_publish.publish",
|
||||
"//outlineviewer:outlineviewer_publish.publish",
|
||||
"//processstarter:processstarter_publish.publish",
|
||||
"//romiVendordep:romiVendordep-cpp_publish.publish",
|
||||
"//romiVendordep:romiVendordep-java_publish.publish",
|
||||
"//simulation/halsim_ds_socket:halsim_ds_socket-cpp_publish.publish",
|
||||
"//simulation/halsim_gui:halsim_gui-cpp_publish.publish",
|
||||
"//simulation/halsim_ws_client:halsim_ws_client-cpp_publish.publish",
|
||||
"//simulation/halsim_ws_core:halsim_ws_core-cpp_publish.publish",
|
||||
"//simulation/halsim_ws_server:halsim_ws_server-cpp_publish.publish",
|
||||
"//simulation/halsim_xrp:halsim_xrp-cpp_publish.publish",
|
||||
"//sysid:sysid_publish.publish",
|
||||
"//thirdparty/googletest:googletest-cpp_publish.publish",
|
||||
"//thirdparty/imgui_suite:imguiSuite-cpp_publish.publish",
|
||||
"//wpical:wpical_publish.publish",
|
||||
"//wpigui:wpigui-cpp_publish.publish",
|
||||
"//wpilibNewCommands:wpilibNewCommands-cpp_publish.publish",
|
||||
"//wpilibNewCommands:wpilibNewCommands-java_publish.publish",
|
||||
"//commandsv3:commandsv3-java_publish.publish",
|
||||
"//wpilibc:wpilibc-cpp_publish.publish",
|
||||
"//wpilibcExamples:commands_publish.publish",
|
||||
"//wpilibcExamples:examples_publish.publish",
|
||||
"//wpilibcExamples:templates_publish.publish",
|
||||
"//wpilibj:wpilibj-java_publish.publish",
|
||||
"//wpilibjExamples:commands_publish.publish",
|
||||
"//wpilibjExamples:examples_publish.publish",
|
||||
"//wpilibjExamples:templates_publish.publish",
|
||||
"//wpimath:wpimath-cpp_publish.publish",
|
||||
"//wpimath:wpimath-java_publish.publish",
|
||||
"//wpinet:wpinet-cpp_publish.publish",
|
||||
"//wpinet:wpinet-java_publish.publish",
|
||||
"//wpiunits:wpiunits-java_publish.publish",
|
||||
"//wpiutil:wpiutil-cpp_publish.publish",
|
||||
"//wpiutil:wpiutil-java_publish.publish",
|
||||
"//xrpVendordep:xrpVendordep-cpp_publish.publish",
|
||||
"//xrpVendordep:xrpVendordep-java_publish.publish",
|
||||
] + select({
|
||||
"@platforms//cpu:x86_64": [
|
||||
"//docs:wpilibc_publish.publish",
|
||||
],
|
||||
"//conditions:default": [],
|
||||
}),
|
||||
)
|
||||
@@ -66,8 +66,17 @@ set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
|
||||
option(BUILD_SHARED_LIBS "Build with shared libs (needed for JNI)" ON)
|
||||
option(WITH_JAVA "Include Java and JNI in the build" OFF)
|
||||
option(WITH_JAVA_SOURCE "Build Java source jars" ${WITH_JAVA})
|
||||
option(WITH_DOCS "Build Doxygen docs (needs Git for versioning)" OFF)
|
||||
cmake_dependent_option(
|
||||
DOCS_WARNINGS_AS_ERRORS
|
||||
"Make docs warnings into errors"
|
||||
OFF
|
||||
WITH_DOCS
|
||||
OFF
|
||||
)
|
||||
option(WITH_CSCORE "Build cscore (needs OpenCV)" ON)
|
||||
option(WITH_NTCORE "Build ntcore" ON)
|
||||
option(WITH_WPICAL "Build wpical" OFF)
|
||||
option(WITH_WPIMATH "Build wpimath" ON)
|
||||
cmake_dependent_option(
|
||||
WITH_WPIUNITS
|
||||
@@ -81,7 +90,7 @@ option(WITH_EXAMPLES "Build examples" OFF)
|
||||
option(WITH_TESTS "Build unit tests (requires internet connection)" ON)
|
||||
option(WITH_GUI "Build GUI items" ON)
|
||||
option(WITH_SIMULATION_MODULES "Build simulation modules" ON)
|
||||
option(WITH_PROTOBUF "Build protobuf support" ON)
|
||||
option(WITH_BENCHMARK "Build the benchmark project" ON)
|
||||
|
||||
# Options for using a package manager (e.g., vcpkg) for certain dependencies.
|
||||
option(USE_SYSTEM_FMTLIB "Use system fmtlib" OFF)
|
||||
@@ -123,22 +132,24 @@ set(java_lib_dest java)
|
||||
if(WITH_JAVA OR WITH_JAVA_SOURCE)
|
||||
set(CMAKE_JAVA_COMPILE_FLAGS "-encoding" "UTF8" "-Xlint:unchecked")
|
||||
find_package(Java REQUIRED COMPONENTS Development)
|
||||
find_package(JNI REQUIRED COMPONENTS JVM)
|
||||
else()
|
||||
# Protoc requires the java runtime
|
||||
find_package(Java REQUIRED COMPONENTS Runtime)
|
||||
if(NOT ANDROID)
|
||||
find_package(JNI REQUIRED COMPONENTS JVM)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WITH_DOCS)
|
||||
find_package(Doxygen REQUIRED)
|
||||
find_package(Git REQUIRED)
|
||||
include(AddDoxygenDocs)
|
||||
add_doxygen_docs()
|
||||
endif()
|
||||
|
||||
if(WITH_WPICAL)
|
||||
find_package(Ceres CONFIG REQUIRED)
|
||||
endif()
|
||||
|
||||
find_package(LIBSSH CONFIG 0.7.1)
|
||||
|
||||
set(CMAKE_FIND_PACKAGE_PREFER_CONFIG ON)
|
||||
if(WITH_PROTOBUF)
|
||||
set(protobuf_MODULE_COMPATIBLE ON CACHE BOOL "" FORCE)
|
||||
find_package(Protobuf REQUIRED)
|
||||
find_program(PROTOC_COMPILER protoc REQUIRED)
|
||||
endif()
|
||||
set(CMAKE_FIND_PACKAGE_PREFER_CONFIG OFF)
|
||||
|
||||
get_property(isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
||||
|
||||
if(isMultiConfig)
|
||||
@@ -256,6 +267,9 @@ if(WITH_TESTS)
|
||||
enable_testing()
|
||||
add_subdirectory(thirdparty/googletest)
|
||||
include(GoogleTest)
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/catch2/extras")
|
||||
add_subdirectory(thirdparty/catch2)
|
||||
include(Catch)
|
||||
endif()
|
||||
|
||||
if(USE_SYSTEM_LIBUV)
|
||||
@@ -269,9 +283,13 @@ endif()
|
||||
set(FILENAME_DEP_REPLACE "get_filename_component(SELF_DIR \"$\{CMAKE_CURRENT_LIST_FILE\}\" PATH)")
|
||||
set(SELF_DIR "$\{SELF_DIR\}")
|
||||
set(WPIUNITS_DEP_REPLACE_IMPL "find_dependency(wpiunits)")
|
||||
set(WPIANNOTATIONS_DEP_REPLACE_IMPL "find_dependency(wpiannotations)")
|
||||
set(WPIUTIL_DEP_REPLACE "find_dependency(wpiutil)")
|
||||
set(DATALOG_DEP_REPLACE "find_dependency(datalog)")
|
||||
add_subdirectory(wpiutil)
|
||||
|
||||
add_subdirectory(datalog)
|
||||
|
||||
if(WITH_NTCORE)
|
||||
set(NTCORE_DEP_REPLACE "find_dependency(ntcore)")
|
||||
set(WPINET_DEP_REPLACE "find_dependency(wpinet)")
|
||||
@@ -279,8 +297,6 @@ if(WITH_NTCORE)
|
||||
add_subdirectory(ntcore)
|
||||
endif()
|
||||
|
||||
add_subdirectory(protoplugin)
|
||||
|
||||
if(WITH_WPIMATH)
|
||||
if(WITH_JAVA)
|
||||
set(WPIUNITS_DEP_REPLACE ${WPIUNITS_DEP_REPLACE_IMPL})
|
||||
@@ -290,6 +306,10 @@ if(WITH_WPIMATH)
|
||||
add_subdirectory(wpimath)
|
||||
endif()
|
||||
|
||||
if(WITH_JAVA)
|
||||
add_subdirectory(wpiannotations)
|
||||
endif()
|
||||
|
||||
if(WITH_WPIUNITS AND NOT WITH_WPIMATH)
|
||||
# In case of building wpiunits standalone
|
||||
set(WPIUNITS_DEP_REPLACE ${WPIUNITS_DEP_REPLACE_IMPL})
|
||||
@@ -303,8 +323,10 @@ if(WITH_GUI)
|
||||
add_subdirectory(glass)
|
||||
add_subdirectory(outlineviewer)
|
||||
add_subdirectory(sysid)
|
||||
if(WITH_WPICAL)
|
||||
add_subdirectory(wpical)
|
||||
endif()
|
||||
if(LIBSSH_FOUND)
|
||||
add_subdirectory(roborioteamnumbersetter)
|
||||
add_subdirectory(datalogtool)
|
||||
endif()
|
||||
endif()
|
||||
@@ -324,12 +346,14 @@ endif()
|
||||
|
||||
if(WITH_WPILIB)
|
||||
set(APRILTAG_DEP_REPLACE "find_dependency(apriltag)")
|
||||
set(COMMANDSV3_DEP_REPLACE "find_dependency(commandsv3)")
|
||||
set(WPILIBC_DEP_REPLACE "find_dependency(wpilibc)")
|
||||
set(WPILIBJ_DEP_REPLACE "find_dependency(wpilibj)")
|
||||
set(WPILIBNEWCOMMANDS_DEP_REPLACE "find_dependency(wpilibNewCommands)")
|
||||
add_subdirectory(apriltag)
|
||||
add_subdirectory(wpilibj)
|
||||
add_subdirectory(wpilibc)
|
||||
add_subdirectory(commandsv3) # must be after wpilibj
|
||||
add_subdirectory(wpilibNewCommands)
|
||||
add_subdirectory(romiVendordep)
|
||||
add_subdirectory(xrpVendordep)
|
||||
@@ -339,6 +363,10 @@ if(WITH_WPILIB)
|
||||
add_subdirectory(developerRobot)
|
||||
endif()
|
||||
|
||||
if(WITH_BENCHMARK)
|
||||
add_subdirectory(benchmark)
|
||||
endif()
|
||||
|
||||
if(WITH_SIMULATION_MODULES)
|
||||
add_subdirectory(simulation)
|
||||
endif()
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
"cacheVariables": {}
|
||||
},
|
||||
{
|
||||
"name": "sccache",
|
||||
"name": "with-sccache",
|
||||
"displayName": "",
|
||||
"description": "Ninja config with sccache",
|
||||
"generator": "Ninja",
|
||||
@@ -36,11 +36,11 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "with-java-sccache",
|
||||
"name": "with-java-and-sccache",
|
||||
"displayName": "",
|
||||
"description": "Ninja config with Java and sccache",
|
||||
"generator": "Ninja",
|
||||
"inherits": "sccache",
|
||||
"inherits": "with-sccache",
|
||||
"binaryDir": "build-cmake",
|
||||
"cacheVariables": {
|
||||
"WITH_JAVA": "ON"
|
||||
|
||||
@@ -1,69 +1,46 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
# Contributor Community Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
We as members, contributors, and leaders pledge to make participation in our
|
||||
community a harassment-free experience for everyone, regardless of age, body
|
||||
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
||||
identity and expression, level of experience, education, socio-economic status,
|
||||
nationality, personal appearance, race, religion, or sexual identity
|
||||
and orientation.
|
||||
As members, contributors, and leaders, we commit to fostering a community where everyone feels safe, respected, and valued. We are dedicated to ensuring that participation in this community is harassment-free, inclusive, and welcoming, regardless of age, body type, abilities (visible or invisible), ethnicity, gender identity or expression, sexual orientation, socioeconomic background, education, nationality, personal appearance, race, or religion.
|
||||
|
||||
We pledge to act and interact in ways that contribute to an open, welcoming,
|
||||
diverse, inclusive, and healthy community.
|
||||
We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to a positive environment for our
|
||||
community include:
|
||||
Positive and respectful behavior is essential to creating a thriving community. This includes:
|
||||
|
||||
* Exhibiting Gracious Professionalism® at all times. Gracious Professionalism
|
||||
* Practicing **Gracious Professionalism®** at all times. Gracious Professionalism
|
||||
is a way of doing things that encourages high-quality work, emphasizes the
|
||||
value of others, and respects individuals and the community.
|
||||
* Demonstrating empathy and kindness toward other people
|
||||
* Being respectful of differing opinions, viewpoints, and experiences
|
||||
* Giving and gracefully accepting constructive feedback
|
||||
* Accepting responsibility and apologizing to those affected by our mistakes,
|
||||
and learning from the experience
|
||||
* Focusing on what is best not just for us as individuals, but for the
|
||||
overall community
|
||||
* Showing empathy, kindness, and patience.
|
||||
* Respecting diverse perspectives and experiences.
|
||||
* Giving and receiving constructive feedback with openness and humility.
|
||||
* Owning mistakes, apologizing when necessary, and learning from them.
|
||||
* Prioritizing the well-being and success of the entire community over individual interests.
|
||||
|
||||
Examples of unacceptable behavior include:
|
||||
Unacceptable behavior include:
|
||||
|
||||
* The use of sexualized language or imagery, and sexual attention or
|
||||
advances of any kind
|
||||
* Using sexualized language, imagery, or making inappropriate advances
|
||||
* Trolling, insulting or derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or email
|
||||
address, without their explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
* Harassment in any form, whether public or private.
|
||||
* Sharing private information (e.g., email or physical addresses) without explicit consent.
|
||||
|
||||
* Any behavior that is unprofessional, harmful, or exclusionary.
|
||||
|
||||
## Enforcement Responsibilities
|
||||
|
||||
Community leaders are responsible for clarifying and enforcing our standards of
|
||||
acceptable behavior and will take appropriate and fair corrective action in
|
||||
response to any behavior that they deem inappropriate, threatening, offensive,
|
||||
or harmful.
|
||||
|
||||
Community leaders have the right and responsibility to remove, edit, or reject
|
||||
comments, commits, code, wiki edits, issues, and other contributions that are
|
||||
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
||||
decisions when appropriate.
|
||||
Community leaders are responsible for maintaining these standards and will take appropriate action to address any behavior deemed harmful, threatening, or inappropriate. Actions may include removing content, issuing warnings, or, when necessary, banning individuals. Moderation decisions will be communicated transparently where appropriate.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies within all community spaces, and also applies when
|
||||
an individual is officially representing the community in public spaces.
|
||||
Examples of representing our community include using an official e-mail address,
|
||||
posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event.
|
||||
This Code of Conduct applies to all community spaces, events, and instances where individuals represent the community (e.g., official email accounts, social media posts, or in-person/virtual events).
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported to the community leaders responsible for enforcement at
|
||||
[conduct@wpilib.org](mailto:conduct@wpilib.org).
|
||||
[wpilib@wpi.edu](mailto:wpilib@wpi.edu).
|
||||
All complaints will be reviewed and investigated promptly and fairly.
|
||||
|
||||
All community leaders are obligated to respect the privacy and security of the
|
||||
@@ -79,7 +56,7 @@ the consequences for any action they deem in violation of this Code of Conduct:
|
||||
**Community Impact**: Use of inappropriate language or other behavior deemed
|
||||
unprofessional or unwelcome in the community.
|
||||
|
||||
**Consequence**: A private, written warning from community leaders, providing
|
||||
**Consequence**: A warning from community leaders, providing
|
||||
clarity around the nature of the violation and an explanation of why the
|
||||
behavior was inappropriate. A public apology may be requested.
|
||||
|
||||
@@ -115,6 +92,9 @@ individual, or aggression toward or disparagement of classes of individuals.
|
||||
**Consequence**: A permanent ban from any sort of public interaction within
|
||||
the community.
|
||||
|
||||
## A Note on Kindness
|
||||
Building a community isn’t just about rules—it’s about connection. Every interaction is an opportunity to be understanding, compassionate, and supportive. Being a good human is the key to our ethos.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||
|
||||
@@ -4,6 +4,7 @@ So you want to contribute your changes back to WPILib. Great! We have a few cont
|
||||
|
||||
- [General Contribution Rules](#general-contribution-rules)
|
||||
- [What to Contribute](#what-to-contribute)
|
||||
- [Contribution Process](#contribution-process)
|
||||
- [Coding Guidelines](#coding-guidelines)
|
||||
- [Submitting Changes](#submitting-changes)
|
||||
- [Pull Request Format](#pull-request-format)
|
||||
@@ -30,57 +31,33 @@ So you want to contribute your changes back to WPILib. Great! We have a few cont
|
||||
- Features must be added to Java (WPILibJ), C++ (WPILibC), with rare exceptions.
|
||||
- Most of Python (RobotPy) is created by wrapping WPILibC with pybind11 via robotpy-build. However, new features to the command framework should also be submitted to [robotpy-commands-v2](https://github.com/robotpy/robotpy-commands-v2) as the command framework is reimplemented in Python.
|
||||
- During competition season, we will not merge any new feature additions. We want to ensure that the API is stable during the season to help minimize issues for teams.
|
||||
- Ask about large changes before spending a bunch of time on them! You can create a new issue on our GitHub tracker for feature request/discussion and talk about it with us there.
|
||||
- Ask about large changes before spending a bunch of time on them! See [Contribution Process](#contribution-process) for where to ask.
|
||||
- Features that make it easier for teams with less experience to be more successful are more likely to be accepted.
|
||||
- Features in WPILib should be broadly applicable to all teams. Anything that is team specific should not be submitted.
|
||||
- As a rule, we are happy with the general structure of WPILib. We are not interested in major rewrites of all of WPILib. We are open to talking about ideas, but backwards compatibility is very important for WPILib, so be sure to keep this in mind when proposing major changes.
|
||||
- Generally speaking, we do not accept code for specific sensors. We have to be able to test the sensor in hardware on the WPILib test bed. Additionally, hardware availability for teams is important. Therefore, as a general rule, the library only directly supports hardware that is in the Kit of Parts. If you are a company interested in getting a sensor into the Kit of Parts, please contact FIRST directly at frcparts@firstinspires.org.
|
||||
|
||||
## Contribution Process
|
||||
|
||||
Have an idea to make WPILib better? Here's some steps to go from idea to implementation:
|
||||
|
||||
1. (Optional) **Discuss it in the Discord.** The programming discussion channel in the [Unofficial FIRST Robotics Competition Discord Server](https://discord.com/invite/frc) is a popular choice for initial discussion about ideas because many WPILib developers are active there and the live messaging nature of the platform is well suited for initial discussion (particularly for smaller changes). Note that the unofficial Discord server is not a mandatory step in the development process and is not endorsed by FIRST®.
|
||||
2. (Recommended) **Open a GitHub issue.** GitHub issues are another way to get initial feedback about an idea before working on an implementation. Compared to the unofficial Discord server, GitHub issues have much wider visibility and are better suited for serious discussions about major changes. Getting feedback about an idea (whether in the unofficial Discord server or in a GitHub issue) before working on the implementation is recommended to avoid working on a change that will be rejected, though some ideas are pretty safe.
|
||||
3. (Rare) **Create a design document in GitHub.** Sometimes, a change is so large that a design document is necessary to fully flesh out the details (and get feedback on them) before starting on an implementation. This is done through a pull request that adds the design document (as a Markdown file) to the repository. This is extremely rare, and it is sometimes done concurrently with the implementation if the change doesn't need much debate but is large enough to require a design document.
|
||||
4. (Mandatory) **Create a GitHub pull request.** This is how you implement the changes, and is the focus of most of the rest of this document.
|
||||
|
||||
## Coding Guidelines
|
||||
|
||||
WPILib uses modified Google style guides for both C++ and Java, which can be found in the [styleguide repository](https://github.com/wpilibsuite/styleguide). Autoformatters are available for many popular editors at https://github.com/google/styleguide. Running wpiformat is required for all contributions and is enforced by our continuous integration system.
|
||||
While the library should be fully formatted according to the styles, additional elements of the style guide were not followed when the library was initially created. All new code should follow the guidelines. If you are looking for some easy ramp-up tasks, finding areas that don't follow the style guide and fixing them is very welcome.
|
||||
|
||||
### Math documentation
|
||||
|
||||
When writing math expressions in documentation, use https://www.unicodeit.net/ to convert LaTeX to a Unicode equivalent that's easier to read. Not all expressions will translate (e.g., superscripts of superscripts) so focus on making it readable by someone who isn't familiar with LaTeX. If content on multiple lines needs to be aligned in Doxygen/Javadoc comments (e.g., integration/summation limits, matrices packed with square brackets and superscripts for them), put them in @verbatim/@endverbatim blocks in Doxygen or `<pre>` tags in Javadoc so they render with monospace font.
|
||||
|
||||
The LaTeX to Unicode conversions can also be done locally via the unicodeit Python package. To install it, execute:
|
||||
```bash
|
||||
pip install --user unicodeit
|
||||
```
|
||||
|
||||
Here's example usage:
|
||||
```bash
|
||||
$ python -m unicodeit.cli 'x_{k+1} = Ax_k + Bu_k'
|
||||
xₖ₊₁ = Axₖ + Buₖ
|
||||
```
|
||||
|
||||
On Linux, this process can be streamlined further by adding the following Bash function to your .bashrc (requires `wl-clipboard` on Wayland or `xclip` on X11):
|
||||
```bash
|
||||
# Converts LaTeX to Unicode, prints the result, and copies it to the clipboard
|
||||
uc() {
|
||||
if [ $WAYLAND_DISPLAY ]; then
|
||||
python -m unicodeit.cli $@ | tee >(wl-copy -n)
|
||||
else
|
||||
python -m unicodeit.cli $@ | tee >(xclip -sel)
|
||||
fi
|
||||
}
|
||||
```
|
||||
|
||||
Here's example usage:
|
||||
```bash
|
||||
$ uc 'x_{k+1} = Ax_k + Bu_k'
|
||||
xₖ₊₁ = Axₖ + Buₖ
|
||||
```
|
||||
|
||||
## Submitting Changes
|
||||
|
||||
### Pull Request Format
|
||||
|
||||
Changes should be submitted as a Pull Request against the main branch of WPILib. For most changes, commits will be squashed upon merge. For particularly large changes, multiple commits are ok, but assume one commit unless asked otherwise. We may ask you to break a PR into multiple standalone PRs or commits for rebase within one PR to separate unrelated changes. No change will be merged unless it is up to date with the current main branch. We do this to make sure that the git history isn't too cluttered.
|
||||
|
||||
During the build season, breaking changes or other changes intended for the next season can be created as a pull request against the development branch of WPILib. After the season is over, the changes in the development branch will be merged into main.
|
||||
Particularly large and/or breaking changes should be targeted to the 2027 branch, which targets the [SystemCore Robot Controller](https://community.firstinspires.org/introducing-the-future-mobile-robot-controller). The intent is minimize changes for 2026, to allow development to focus on preparing for 2027.
|
||||
|
||||
### Merge Process
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ This article contains instructions on building projects using a development buil
|
||||
|
||||
Development builds are the per-commit build hosted every time a commit is pushed to the [allwpilib](https://github.com/wpilibsuite/allwpilib/) repository. These builds are then hosted on [artifactory](https://frcmaven.wpi.edu/artifactory/webapp/#/home).
|
||||
|
||||
To build a project using a development build, find the build.gradle file and open it. Then, add the following code below the plugin section and replace YEAR with the year of the development version. It is also necessary to use a 2024 GradleRIO version, ie `2024.0.0-alpha-1`
|
||||
To build a project using a development build, find the build.gradle file and open it. Then, add the following code below the plugin section and replace YEAR with the year of the development version. It is also necessary to use a 2025 GradleRIO version, ie `2025.1.1-beta-1`
|
||||
|
||||
```groovy
|
||||
wpi.maven.useLocal = false
|
||||
@@ -28,13 +28,13 @@ Java
|
||||
```groovy
|
||||
plugins {
|
||||
id "java"
|
||||
id "edu.wpi.first.GradleRIO" version "2024.0.0-alpha-1"
|
||||
id "edu.wpi.first.GradleRIO" version "2025.1.1-beta-1"
|
||||
}
|
||||
|
||||
wpi.maven.useLocal = false
|
||||
wpi.maven.useDevelopment = true
|
||||
wpi.versions.wpilibVersion = '2024.+'
|
||||
wpi.versions.wpimathVersion = '2024.+'
|
||||
wpi.versions.wpilibVersion = '2025.+'
|
||||
wpi.versions.wpimathVersion = '2025.+'
|
||||
```
|
||||
|
||||
C++
|
||||
@@ -42,13 +42,13 @@ C++
|
||||
plugins {
|
||||
id "cpp"
|
||||
id "google-test-test-suite"
|
||||
id "edu.wpi.first.GradleRIO" version "2024.0.0-alpha-1"
|
||||
id "edu.wpi.first.GradleRIO" version "2025.1.1-beta-1"
|
||||
}
|
||||
|
||||
wpi.maven.useLocal = false
|
||||
wpi.maven.useDevelopment = true
|
||||
wpi.versions.wpilibVersion = '2024.+'
|
||||
wpi.versions.wpimathVersion = '2024.+'
|
||||
wpi.versions.wpilibVersion = '2025.+'
|
||||
wpi.versions.wpimathVersion = '2025.+'
|
||||
```
|
||||
|
||||
### Development Build Documentation
|
||||
@@ -64,7 +64,7 @@ Java
|
||||
```groovy
|
||||
plugins {
|
||||
id "java"
|
||||
id "edu.wpi.first.GradleRIO" version "2024.0.0-alpha-1"
|
||||
id "edu.wpi.first.GradleRIO" version "2025.1.1-beta-1"
|
||||
}
|
||||
|
||||
wpi.maven.useLocal = false
|
||||
@@ -78,7 +78,7 @@ C++
|
||||
plugins {
|
||||
id "cpp"
|
||||
id "google-test-test-suite"
|
||||
id "edu.wpi.first.GradleRIO" version "2024.0.0-alpha-1"
|
||||
id "edu.wpi.first.GradleRIO" version "2025.1.1-beta-1"
|
||||
}
|
||||
|
||||
wpi.maven.useLocal = false
|
||||
|
||||
25
GeneratedFiles.md
Normal file
25
GeneratedFiles.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# Maintaining Generated Files
|
||||
WPILib extensively uses [metaprogramming](https://en.wikipedia.org/wiki/Metaprogramming#Code_generation) to generate code that would otherwise be tedious and error-prone to maintain. We use [Jinja](https://jinja.palletsprojects.com), a templating engine with a Python API, alongside JSON files that contain data to generate code. This document explains how to maintain these generated files and create new ones.
|
||||
|
||||
## File hierarchy
|
||||
The Python script used to generate a subproject's files will always be located in the subproject's directory, e.g. wpilibc. It will always be called `generate_<thing>.py` where `<thing>` is the name for what you're generating.
|
||||
|
||||
The templates will be located under `subproject/src/generate/main`, and generated files will be located under `subproject/src/generated/main`.
|
||||
|
||||
If the generated file is for C++, the hierarchy should be symmetrical, so if a generated header is located under `subproject/src/generated/main/native/include/frc/header.h`, the template to generate it should be located under `subproject/src/generate/main/native/include/frc/template.h.jinja`. You should pretend like `subproject/src/generate/main` is just like `subproject/src/main`, in that the file hierarchy must make sense if the files weren't generated, e.g, headers that would go in `subproject/src/main/native/include/blah` should be in `subproject/src/generated/main/native/include/blah`.
|
||||
|
||||
If the generated file is for Java, templates should be located under `subproject/src/generate/main/java`, and the hierarchy for output files should reflect the declared package of the output Java files. For example, a Jinja template at `subproject/src/main/java/template.java.jinja` with the package `edu.wpi.first.wpilibj` would be used to generate Java files located at `subproject/src/generated/main/java/edu/wpi/first/wpilibj`
|
||||
|
||||
The JSON files live under `subproject/src/generate` since they apply to both languages. One unique case is JSON files that are used by multiple subprojects, currently only JSON files shared by wpilibc and wpilibj. In that specific case, the JSON files will always be located in wpilibj since Java is the most used language.
|
||||
|
||||
## Using code generation
|
||||
If you've identified a set of files which are extremely similar, one file with lots of repetitive code, or both, you can create Jinja templates, a JSON file, and a Python script to automatically generate the code instead.
|
||||
|
||||
### Preparing files for codegen
|
||||
Once you've identified the files you want to codegen, you will need to identify parts of code that are similar, and extract the data that's different. Code needs to go into your Jinja template, while data that will be used to fill in the template goes into a JSON file. Using game controllers as an example, they have lots of similar methods to read the value of a button, check if a button has been pressed since the last check, and check if a button has been released since the last check. Those methods are code that goes in a Jinja template, with the specific button replaced with a Jinja expression. The buttons, both the name and value, go into a JSON file.
|
||||
|
||||
### Writing a Python script
|
||||
To maintain consistency with other Python scripts, copy an existing `generate_*.py` script. [generate_pwm_motor_controllers.py](./wpilibj/generate_pwm_motor_controllers.py) is a good start, since it's relatively basic. Modify the script to reference your templates and JSON file, modify the paths so the files end up in the right place, and rename the functions so they match what you're generating. An important part of the script is to give the files the correct name. Depending on files you're generating, this could be the name of the template itself (see [ntcore/generate_topics.py](./ntcore/generate_topics.py)) or it could be part of the data in the JSON file.
|
||||
|
||||
### (Re)Generating files and committing them
|
||||
Once your Python script is complete, you can run `python generate_<thing>.py` to generate the files. Once you're finished with your files, commit these files to Git. If you regenerated the files and Git indicates the files have changed, but the diff doesn't show any changes, only the line endings have changed. If you expected changes to the generated code, you didn't correctly make changes. If you didn't expect changes, you can ignore this and discard the changes. Also ensure that you've marked the Python script as executable, since this is necessary for CI workflows to run your scripts. To add your script to the CI workflows, edit [.github/workflows/pregen_all.py](.github/workflows/pregen_all.py), and add your script alongside the rest of the scripts.
|
||||
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2009-2024 FIRST and other WPILib contributors
|
||||
Copyright (c) 2009-2025 FIRST and other WPILib contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -14,54 +14,27 @@ The development repository is where development releases of every commit to [mai
|
||||
## Artifact classifiers
|
||||
We provide two base types of artifacts.
|
||||
|
||||
The first types are Java artifacts. These are usually published as `jar` files. Usually, the actual jar file is published with no classifier. The sources are published with the `-sources` classifier, and the javadocs are published with the `-javadoc` classifier.
|
||||
|
||||
The second types are native artifacts. These are usually published as `zip` files (except for the `JNI` artifact types, which are `jar` files. See below for information on this). The `-sources` and `-headers` classifiers contain the sources and headers respectively for the library. Each artifact also contains a classifier for each platform we publish. This platform is in the format `{os}{arch}`. The platform artifact only contains the binaries for a specific platform. In addition, we provide a `-all` classifier. This classifier combines all of the platform artifacts into a single artifact. This is useful for tools that cannot determine what version to use during builds. However, we recommend using the platform specific classifier when possible. Note that the binary artifacts never contain the headers, you always need the `-headers` classifier to get those.
|
||||
|
||||
## Artifact Names
|
||||
|
||||
WPILib builds four different types of artifacts.
|
||||
|
||||
##### C++ Only Libraries
|
||||
When we publish C++ only libraries, they are published with the base artifact name as their artifact name, with a `-cpp` extension. All dependencies for the library are linked as shared libraries to the binary.
|
||||
|
||||
|
||||
Example:
|
||||
```
|
||||
edu.wpi.first.wpilibc:wpilibc-cpp:version:classifier@zip
|
||||
```
|
||||
|
||||
#### Java Only Libraries
|
||||
When we publish Java only libraries, they are published with the base artifact name as their artifact name, with a `-java` extension.
|
||||
The first types are Java artifacts. These are usually published as `jar` files. Usually, the actual jar file is published with no classifier. The sources are published with the `-sources` classifier, and the javadocs are published with the `-javadoc` classifier. These artifacts are published with the base artifact name as their artifact ID, with a `-java` extension.
|
||||
|
||||
Example:
|
||||
```
|
||||
edu.wpi.first.wpilibj:wpilibj-java:version
|
||||
```
|
||||
|
||||
#### C++/Java Libraries without JNI
|
||||
For libraries that are both C++ and Java, but without a JNI component, the C++ component is published with the `basename-cpp` artifact name, and the Java component is published with the `basename-java` artifact name.
|
||||
The second types are native artifacts. These are usually published as `zip` files. The `-sources` and `-headers` classifiers contain the sources and headers respectively for the library. Each artifact also contains a classifier for each platform we publish. This platform is in the format `{os}{arch}`. The full list of supported platforms can be found in [native-utils](https://github.com/wpilibsuite/native-utils/blob/main/src/main/java/edu/wpi/first/nativeutils/WPINativeUtilsExtension.java#L94). If the library is built statically, it will have `static` appended to the classifier. Additionally, if the library was built in debug mode, `debug` will be appended to the classifier. The platform artifact only contains the binaries for a specific platform. Note that the binary artifacts never contain the headers, you always need the `-headers` classifier to get those.
|
||||
|
||||
If the library is Java and C++ and has a JNI component, the native artifact will have a shared library containing JNI entrypoints alongside the C++ shared library. This JNI shared library will have a `jni` suffix in the file name.
|
||||
|
||||
Native artifacts are published with the base artifact name as their artifact ID, with a `-cpp` extension.
|
||||
|
||||
Example:
|
||||
```
|
||||
edu.wpi.first.wpiutil:wpiutil-cpp:version:classifier@zip (C++)
|
||||
edu.wpi.first.wpiutil:wpiutil-java:version (Java)
|
||||
```
|
||||
|
||||
#### C++/Java Libraries with JNI
|
||||
For libraries that are both C++ and Java with a JNI component there are three different artifact names. For Java, the component is published as `basename-java`. For C++, the `basename-cpp` artifact contains the C++ artifacts with all dependencies linked as shared libraries to the binary. These binaries DO contain the JNI entry points. The `basename-jni` artifact contains identical C++ binaries to the `-cpp` artifact, however all of its dependencies are statically linked, and only the JNI and C entry points are exported.
|
||||
|
||||
The `-jni` artifact should only be used in cases where you want to create a self contained Java application where the native artifacts are embedded in the jar. Note in an extraction scenario, extending off of the library is never supported, which is why the C++ entry points are not exposed. The name of the library is randomly generated during extraction. For pretty much all cases, and if you ever want to extend from a native library, you should use the `-cpp` artifacts. GradleRIO uses the `-cpp` artifacts for all platforms, even desktop, for this reason.
|
||||
|
||||
Example:
|
||||
```
|
||||
edu.wpi.first.ntcore:ntcore-cpp:version:classifier@zip (C++)
|
||||
edu.wpi.first.ntcore:ntcore-jni:version:classifier (JNI jar library)
|
||||
edu.wpi.first.ntcore:ntcore-java:version (Java)
|
||||
edu.wpi.first.wpimath:wpimath-cpp:version:classifier@zip
|
||||
edu.wpi.first.wpimath:wpimath-cpp:version:windowsx86-64staticdebug@zip
|
||||
```
|
||||
|
||||
## Provided Artifacts
|
||||
This repository provides the following artifacts. Below each artifact is its dependencies. Note if ever using the `-jni` artifacts, no dependencies are needed for native binaries.
|
||||
This repository provides the following artifacts. Below each artifact is its dependencies.
|
||||
|
||||
For C++, if building with static dependencies, the listed order should be the link order in your linker.
|
||||
|
||||
|
||||
54
README-Bazel.md
Normal file
54
README-Bazel.md
Normal file
@@ -0,0 +1,54 @@
|
||||
# WPILib Bazel Support
|
||||
|
||||
WPILib is normally built with Gradle, but [Bazel](https://www.bazel.build/) can also be used to increase development speed due to the superior caching ability and the ability to use remote caching and remote execution (on select platforms)
|
||||
|
||||
|
||||
## Prerequisites
|
||||
- Install [Bazelisk](https://github.com/bazelbuild/bazelisk/releases) and add it to your path. Bazelisk is a wrapper that will download the correct version of bazel specified in the repository. Note: You can alias/rename the binary to `bazel` if you want to keep the familiar `bazel build` vs `bazelisk build` syntax.
|
||||
|
||||
## Building
|
||||
To build the entire repository, simply run `bazel build //...`. To run all of the unit tests, run `bazel test //...`
|
||||
Other examples:
|
||||
- `bazel build //wpimath/...` - Builds every target in the wpimath folder
|
||||
- `bazel test //wpiutil:wpiutil-cpp-test` - Runs only the cpp test target in the wpiutil folder
|
||||
- `bazel coverage //wpiutil/...` - (*Nix only) - Runs a code coverage report for both C++ and Java on all the targets under wpiutil
|
||||
|
||||
## User settings
|
||||
When invoking bazel, it will check if `user.bazelrc` exists for additional, user specified flags. You can use these settings to do things like always ignore buildin a specific folder, or limiting the CPU/RAM usage during a build.
|
||||
Examples:
|
||||
- `build --build_tag_filters=-wpi-example` - Do not build any targets tagged with `wpi-example` (Currently all of the targets in wpilibcExamples and wpilibjExamples contain this tag)
|
||||
- `build -c opt` - Always build optimized targets. The default compiler flags were chosen to build as fast as possible, and thus don't contain many optimizations
|
||||
- `build -k` - `-k` is analogous to the MAKE flag `--keep-going`, so the build will not stop on the first error.
|
||||
- ```
|
||||
build --local_ram_resources=HOST_RAM*.5 # Don't use more than half my RAM when building
|
||||
build --local_cpu_resources=HOST_CPUS-1 # Leave one core alone
|
||||
```
|
||||
|
||||
The default settings build all the release artifact variants relevant for your platform. The overall list of options ends up being, essentially, all the variants of (linux, osx, windows) x (debug, release) x (static, shared) x (aarch64, x86). OSX and Windows are hard to compile for from any other OS, so we by default build for your local OS and the system core, with all the variants.
|
||||
|
||||
This can be a bit expensive. If you would like to build a subset, you can specify the repo environmental variable, `WPI_PUBLISH_CLASSIFIER_FILTER`, and pick what you build for. The default is, in the .bazelrc file,
|
||||
```
|
||||
common --repo_env="WPI_PUBLISH_CLASSIFIER_FILTER=headers,sources,linuxsystemcore,linuxsystemcoredebug,linuxsystemcorestatic,linuxsystemcorestaticdebug,linuxx86-64,linuxx86-64debug,linuxx86-64static,linuxx86-64staticdebug,osxuniversal,osxuniversaldebug,osxuniversalstatic,osxuniversalstaticdebug,windowsarm64,windowsarm64debug,windowsarm64static,windowsarm64staticdebug,windowsx86-64,windowsx86-64debug,windowsx86-64static,windowsx86-64staticdebug"
|
||||
```
|
||||
|
||||
Modify this to your likings if you want to build less.
|
||||
|
||||
## Pregenerating Files
|
||||
allwpilib uses extensive use of pre-generating files that are later used to build C++ / Java libraries that are tracked by version control. Quite often,
|
||||
these pre-generation scripts use some configuration file to create multipile files inside of an output directory. While this process could be accomplished
|
||||
with a `genrule` that would require an explicit listing of every output file, which would be tedious to maintain as well as potentially confusing to people
|
||||
adding new features those libraries. Therefor, we use `@aspect_bazel_lib` and their `write_source_files` feature to generate these directories. In the event that the generation process creates more than a small handful of predictable files, a custom rule is written to generate the directory.
|
||||
|
||||
## Remote Caching
|
||||
One of the huge benefits of bazel is its remote caching ability. However, due to bazels strict build definitions it is hard to share remote cache artifacts between different computers unless our toolchains are fully hermetic, which means you are unlikely to be able to reuse the cache artifacts published from the `main` branch on your local machine like you might be able to with the `gradle` or `cmake` caches. Luckily the github actions CI machines are generally stable between runs and can reuse cache artifacts, and your local machine should remain stable, so if you set up a free buildbuddy account you can have your forks CI actions be able to use a personalized cache, as well as your local machine.
|
||||
|
||||
For the main `allwpilib` upstream, the cache is only updated on the main branch; pull requests from forks will not be able to modify the cache. However, you can set up your fork to enable its own cache by following the steps below.
|
||||
|
||||
### Setting Up API keys
|
||||
Follow the [buildbuddy authentication](https://www.buildbuddy.io/docs/guide-auth) guide to create keys. For your local machine, it is recommended that you place the following configuration line in either a `user.bazelrc` or `bazel_auth.rc` file in the repositories root directory.
|
||||
|
||||
```
|
||||
build --remote_header=<your api key>
|
||||
```
|
||||
|
||||
To get your forks CI actions using your own buildbuddy cache, follow [GitHub's](https://docs.github.com/en/actions/how-tos/security-for-github-actions/security-guides/using-secrets-in-github-actions) documentation for setting up a repository secret. The secrets key should be `BUILDBUDDY_API_KEY`, and the value should be your buildbuddy API key.
|
||||
238
README-CMAKE.md
238
README-CMAKE.md
@@ -1,238 +0,0 @@
|
||||
# WPILib CMake Support
|
||||
|
||||
WPILib is normally built with Gradle, however for some systems, such as Linux based coprocessors, Gradle doesn't work correctly, especially if cscore is needed, which requires OpenCV. Furthermore, the CMake build can be used for C++ development because it provides better build caching compared to Gradle. We provide the CMake build for these cases. Although macOS is supported, these docs will only go over Linux and Windows builds, but should mostly work for macOS as well. If you are stuck, you can look at the GitHub workflows for any OS to see how it works.
|
||||
|
||||
## Libraries that get built
|
||||
* apriltag
|
||||
* cameraserver
|
||||
* cscore
|
||||
* fieldImages
|
||||
* hal (simulation HAL only)
|
||||
* ntcore
|
||||
* romiVendordep
|
||||
* simulation extensions
|
||||
* wpigui
|
||||
* wpilib (wpilibc, wpilibj, and myRobot)
|
||||
* wpilibNewCommands
|
||||
* wpimath
|
||||
* wpinet
|
||||
* wpiunits
|
||||
* wpiutil
|
||||
* xrpVendordep
|
||||
|
||||
## GUI apps that get built
|
||||
* datalogtool
|
||||
* glass
|
||||
* outlineviewer
|
||||
* roborioteamnumbersetter
|
||||
* sysid
|
||||
* halsim_gui (if simulation extensions are enabled)
|
||||
|
||||
By default, all libraries get built with a default CMake setup. The libraries are built as shared libraries, and include the JNI libraries as well as building the Java JARs. Data Log Tool and the roboRIO Team Number Setter are only built if libssh is available.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
The protobuf library and compiler are needed for protobuf generation.
|
||||
|
||||
OpenCV needs to be findable by CMake. On systems like the Jetson, this is installed by default. Otherwise, you will need to build OpenCV from source and install it.
|
||||
|
||||
If you want JNI and Java, you will need a JDK of at least version 17 installed. In addition, you need a `JAVA_HOME` environment variable set properly and set to the JDK directory.
|
||||
|
||||
If you are building with unit tests or simulation modules, you will also need an Internet connection for the initial setup process, as CMake will clone google-test and imgui from GitHub.
|
||||
|
||||
## Build Options
|
||||
|
||||
The following build options are available:
|
||||
|
||||
* `BUILD_SHARED_LIBS` (ON Default)
|
||||
* This option will cause CMake to build static libraries instead of shared libraries. If this is off, `WITH_JAVA` must be off. Otherwise CMake will error.
|
||||
* `WITH_CSCORE` (ON Default)
|
||||
* This option will cause cscore to be built. Turning this off will implicitly disable cameraserver. If this is off, the OpenCV build requirement is removed.
|
||||
* `WITH_EXAMPLES` (OFF Default)
|
||||
* This option will build C++ examples.
|
||||
* `WITH_GUI` (ON Default)
|
||||
* This option will build GUI items. If this is off, and `WITH_SIMULATION_MODULES` is on, the simulation GUI will not be built.
|
||||
* `WITH_JAVA` (OFF Default)
|
||||
* This option will enable Java and JNI builds. If this is on, `BUILD_SHARED_LIBS` must be on. Otherwise CMake will error.
|
||||
* `WITH_JAVA_SOURCE` (`WITH_JAVA` Default)
|
||||
* This option will build Java source JARs for each enabled Java library. This does not require `WITH_JAVA` to be on, allowing source JARs to be built without the compiled JARs if desired.
|
||||
* `WITH_NTCORE` (ON Default)
|
||||
* This option will cause ntcore to be built. Turning this off will implicitly disable wpinet, and will cause an error if `WITH_WPILIB` is enabled.
|
||||
* `WITH_SIMULATION_MODULES` (ON Default)
|
||||
* This option will build simulation modules.
|
||||
* `WITH_TESTS` (ON Default)
|
||||
* This option will build C++ unit tests. These can be run via `ctest -C <config>`, where `<config>` is the build configuration, e.g. `Debug` or `Release`.
|
||||
* `WITH_WPILIB` (ON Default)
|
||||
* This option will build the HAL and wpilibc/j during the build. The HAL is the simulation HAL, unless the external HAL options are used. The CMake build has no capability to build for the roboRIO.
|
||||
* `WITH_WPIMATH` (ON Default)
|
||||
* This option will build the wpimath library. This option must be on to build wpilib.
|
||||
* `WITH_WPIUNITS` (`WITH_JAVA` Default)
|
||||
* This option will build the wpiunits library. This option must be on to build the Java wpimath library and requires `WITH_JAVA` to also be on.
|
||||
* `OPENCV_JAVA_INSTALL_DIR`
|
||||
* Set this option to the location of the archive of the OpenCV Java bindings (it should be called opencv-xxx.jar, with the x'es being version numbers). NOTE: set it to the LOCATION of the file, not the file itself!
|
||||
* `NO_WERROR` (OFF Default)
|
||||
* This option will disable the `-Werror` compilation flag for non-MSVC builds.
|
||||
* `WPILIB_TARGET_WARNINGS`
|
||||
* Add compiler flags to this option to customize compiler options like warnings.
|
||||
|
||||
## Build Setup
|
||||
|
||||
The WPILib CMake build does not allow in source builds. Because the `build` directory is used by Gradle, we recommend a `build-cmake` directory in the root. This folder is included in the gitignore. We support building with Ninja; other options like Makefiles may be broken.
|
||||
|
||||
Once you have a build folder, run CMake configuration in the root directory with the following command.
|
||||
|
||||
```
|
||||
cmake --preset default
|
||||
```
|
||||
|
||||
If you want to change any of the options, add `-DOPTIONHERE=VALUE` to the `cmake` command. This will check for any dependencies. If everything works properly this will succeed. If not, please check out the troubleshooting section for help.
|
||||
|
||||
If you want, you can also use `ccmake` in order to visually set these properties as well. [Here](https://cmake.org/cmake/help/v3.0/manual/ccmake.1.html) is the link to the documentation for that program. On Windows, you can use `cmake-gui` instead.
|
||||
|
||||
Note that if you are cross-compiling, you will need to override the protobuf options manually to point to the libraries for the target platform. Leave the protoc binary location as the path to the binary for the host platform, since protoc needs to execute on the host platform.
|
||||
|
||||
## Presets
|
||||
|
||||
The WPILib CMake setup has a variety of presets for common configurations and options used. The default sets the generator to Ninja and build directory to `build-cmake`. The other presets are `with-java` (sets `WITH_JAVA=ON`), `sccache` (sets the C/C++ compiler launcher to sccache), and `with-java-sccache` (a comibination of `with-java` and `sccache`.
|
||||
|
||||
## Building
|
||||
|
||||
Once you have CMake setup. run `cmake --build .` from the directory you configured CMake in. This will build all libraries possible. We recommend running `cmake --build .` with multiple jobs. For allwpilib, a good rule of thumb is one worker for every 2 GB of available RAM. To run a multiple job build, run the following command with x being the number of jobs you want.
|
||||
|
||||
```
|
||||
cmake --build . --parallel x
|
||||
```
|
||||
|
||||
Note: wpimath takes gigabytes of RAM to compile. Because of this, the compilers may crash while building due to a lack of memory and your computer may slow down. If you have less than 16 GB of RAM available, you may want to consider building it separately first by adding `--target wpimath` and running it with ~3 jobs to prevent crashes from running out of memory.
|
||||
|
||||
To build with a certain configuration, like `Debug` or `Release`, add `--config <config>`, where `<config>` is the name of the configuration you want to build with.
|
||||
|
||||
## Installing
|
||||
|
||||
After build, the easiest way to use the libraries is to install them. Run the following command to install the libraries. This will install them so that they can be used from external CMake projects.
|
||||
|
||||
```
|
||||
sudo cmake --build . --target install
|
||||
```
|
||||
|
||||
## Preparing to use the installed libraries
|
||||
|
||||
On Windows, make sure the directories for the libraries you built are on PATH. For wpilib, the default install location is `C:\Program Files (x86)\allwpilib`. If you built other libraries like OpenCV and protobuf from source, install them, and add the install directories to PATH. This ensures CMake can locate the libraries.
|
||||
|
||||
You will also want to add the directories where the DLLs are located (usually the `bin` subdirectory of the install directory) to PATH so they can be loaded by your program. If you are using OpenCV and Java, the `opencv_java` DLL is located in either the `lib` subdirectory if you built but didn't install OpenCV, or the `java` subdirectory if you did install OpenCV.
|
||||
|
||||
## Using the installed libraries for C++.
|
||||
|
||||
Using the libraries from C++ is the easiest way to use the built libraries.
|
||||
|
||||
To do so, create a new folder to contain your project. Add the following code below to a `CMakeLists.txt` file in that directory.
|
||||
|
||||
```cmake
|
||||
cmake_minimum_required(VERSION 3.11)
|
||||
project(vision_app) # Project Name Here
|
||||
|
||||
find_package(wpilib REQUIRED)
|
||||
|
||||
add_executable(my_vision_app main.cpp) # executable name as first parameter
|
||||
target_link_libraries(my_vision_app cameraserver ntcore cscore wpiutil)
|
||||
```
|
||||
|
||||
If you want to use other libraries or are building a robot program, `wpilibc` and `hal` should be added in the `target_link_libraries` function, along with any other libraries you plan on using, e.g. `wpimath`.
|
||||
|
||||
Add a `main.cpp` file to contain your code, and create a build folder. Move into the build folder, and run
|
||||
|
||||
```
|
||||
cmake /path/to/folder/containing/CMakeLists
|
||||
```
|
||||
|
||||
After that, run `cmake --build .`. That will create your executable. Then you should be able to run `./my_vision_app` to run your application.
|
||||
|
||||
## Using the installed libraries for Java
|
||||
|
||||
Using the built JARs is more involved than using the C++ libraries, but the additional work involves providing the paths to various libraries and JARs when needed.
|
||||
|
||||
Create a new folder to contain your project. Add the following code below to a `CMakeLists.txt` file in that directory.
|
||||
|
||||
```cmake
|
||||
cmake_minimum_required(VERSION 3.11)
|
||||
project(robot)
|
||||
|
||||
find_package(Java REQUIRED COMPONENTS Development)
|
||||
include(UseJava)
|
||||
find_package(wpilib REQUIRED)
|
||||
find_jar(opencvJar opencv-xxx PATHS ENV PATH) # Change to OpenCV version
|
||||
|
||||
file(GLOB_RECURSE JAVA_SOURCES *.java)
|
||||
# If you want Gradle compatibility or you are using one of the templates/examples, comment out the above line and uncomment this line instead:
|
||||
# file(GLOB_RECURSE JAVA_SOURCES src/main/java/*.java)
|
||||
add_jar(robot ${JAVA_SOURCES}
|
||||
INCLUDE_JARS apriltag_jar cscore_jar hal_jar ntcore_jar wpilibNewCommands_jar wpimath_jar wpinet_jar wpiutil_jar wpiunits_jar wpilibj_jar ${opencvJar})
|
||||
export_jars(TARGETS robot FILE robot.jar)
|
||||
```
|
||||
This includes all the built JARs except for the vendordeps. If you are not using a JAR/library, you may remove it.
|
||||
Add a `Main.java` file to contain your code, and create a build folder. Move into the build folder, and run
|
||||
|
||||
```
|
||||
cmake /path/to/folder/containing/CMakeLists
|
||||
```
|
||||
|
||||
After that, run `cmake --build .` to create your JAR file. To execute the JAR file, you need to include the wpilib JARs and your JAR in the classpath, and execute your Java program's entry point. If you are using cscore or cameraserver, you also need to include the path to the OpenCV JAR. If you built it from source, it will be in your OpenCV build directory. If it's installed on the system, CMake may find it from PATH, but you will likely need to locate the JAR and manually give CMake the JAR directory. If you are on Linux, you will also need to add the path of the libraries to `LD_LIBRARY_PATH`. This can be done by prepending `LD_LIBRARY_PATH=/path/to/libraries` to the Java command. If you need to add more paths, separate them with colons. The final command should look like `java -cp "robot.jar:/path/to/library_jars/*" main.package.Main`, using a semicolon to separate paths instead of a colon if you are on Windows. If you are on Linux, the final command should look more like `LD_LIBRARY_PATH=/path/to/libraries java -cp robot.jar:/path/to/library_jars/* main.package.Main`.
|
||||
|
||||
## Using vendordeps
|
||||
|
||||
Vendordeps are not included as part of the `wpilib` CMake package. However, if you want to use a vendordep, you need to use `find_package(VENDORDEP)`, where `VENDORDEP` is the name of the vendordep (case-sensitive), like `xrpVendordep` or `romiVendordep`. Note that wpilibNewCommands, while a vendordep in normal robot projects, is not built as a vendordep in CMake, and is instead included as part of the `wpilib` CMake package. After you used `find_package`, you can reference the vendordep library like normal, either by using `target_link_libraries` for C++ or `add_jar` for Java.
|
||||
|
||||
## Troubleshooting
|
||||
Below are some common issues that are run into when building.
|
||||
|
||||
#### Missing OpenCV
|
||||
|
||||
If you are missing OpenCV, you will get an error message similar to this.
|
||||
|
||||
```
|
||||
CMake Error at cscore/CMakeLists.txt:3 (find_package):
|
||||
By not providing "FindOpenCV.cmake" in CMAKE_MODULE_PATH this project has
|
||||
asked CMake to find a package configuration file provided by "OpenCV", but
|
||||
CMake did not find one.
|
||||
|
||||
Could not find a package configuration file provided by "OpenCV" with any
|
||||
of the following names:
|
||||
|
||||
OpenCVConfig.cmake
|
||||
opencv-config.cmake
|
||||
|
||||
Add the installation prefix of "OpenCV" to CMAKE_PREFIX_PATH or set
|
||||
"OpenCV_DIR" to a directory containing one of the above files. If "OpenCV"
|
||||
provides a separate development package or SDK, be sure it has been
|
||||
installed.
|
||||
```
|
||||
|
||||
If you get that, you need make sure OpenCV was installed, and then reattempt to configure. If that doesn't work, set the `OpenCV_DIR` variable to the directory where you built OpenCV.
|
||||
|
||||
#### Missing Java
|
||||
|
||||
If you are missing Java, you will get a message like the following.
|
||||
```
|
||||
CMake Error at /usr/share/cmake-3.5/Modules/FindPackageHandleStandardArgs.cmake:148 (message):
|
||||
Could NOT find Java (missing: Java_JAVA_EXECUTABLE Java_JAR_EXECUTABLE
|
||||
Java_JAVAC_EXECUTABLE Java_JAVAH_EXECUTABLE Java_JAVADOC_EXECUTABLE)
|
||||
```
|
||||
|
||||
If this happens, make sure you have a JDK of at least version 8 installed, and that your JAVA_HOME variable is set properly to point to the JDK.
|
||||
|
||||
In addition, if you do not need Java, you can disable it with `-DWITH_JAVA=OFF`.
|
||||
|
||||
#### Java: Can't find dependent libraries
|
||||
|
||||
If one of the libraries can't be found, you will get an error similar to this one:
|
||||
|
||||
```
|
||||
java.io.IOException: wpiHaljni could not be loaded from path or an embedded resource.
|
||||
attempted to load for platform /windows/x86-64/
|
||||
Last Load Error:
|
||||
C:\Program Files (x86)\allwpilib\bin\wpiHaljni.dll: Can't find dependent libraries
|
||||
```
|
||||
|
||||
If you get this error, that's usually an indication that not all your libraries are in your PATH. The two libraries that should be in your PATH are OpenCV and protobuf. If the error is coming from cscore, it's likely you're missing OpenCV. Otherwise, it's likely you're missing protobuf.
|
||||
|
||||
Note that Linux will not have this specific type of error, as it will usually tell you the dependent library you are missing. In that case, you most likely need to add the library to `LD_LIBRARY_PATH`.
|
||||
234
README-CMake.md
Normal file
234
README-CMake.md
Normal file
@@ -0,0 +1,234 @@
|
||||
# WPILib CMake Support
|
||||
|
||||
WPILib is normally built with Gradle, however for some systems, such as Linux based coprocessors, Gradle doesn't work correctly, especially if cscore is needed, which requires OpenCV. Furthermore, the CMake build can be used for C++ development because it provides better build caching compared to Gradle. We provide the CMake build for these cases. Although macOS is supported, these docs will only go over Linux and Windows builds, but should mostly work for macOS as well. If you are stuck, you can look at the GitHub workflows for any OS to see how it works.
|
||||
|
||||
## Libraries that get built
|
||||
* apriltag
|
||||
* cameraserver
|
||||
* commandsv3
|
||||
* cscore
|
||||
* fieldImages
|
||||
* hal (simulation HAL only)
|
||||
* ntcore
|
||||
* romiVendordep
|
||||
* simulation extensions
|
||||
* wpigui
|
||||
* wpilib (wpilibc, wpilibj, and myRobot)
|
||||
* wpilibNewCommands
|
||||
* wpimath
|
||||
* wpinet
|
||||
* wpiunits
|
||||
* wpiutil
|
||||
* xrpVendordep
|
||||
|
||||
## GUI apps that get built
|
||||
* datalogtool
|
||||
* glass
|
||||
* outlineviewer
|
||||
* sysid
|
||||
* halsim_gui (if simulation extensions are enabled)
|
||||
|
||||
By default, all libraries get built with a default CMake setup. The libraries are built as shared libraries, and include the JNI libraries as well as building the Java JARs. Data Log Tool and the roboRIO Team Number Setter are only built if libssh is available.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
OpenCV needs to be findable by CMake. On systems like the Jetson, this is installed by default. Otherwise, you will need to build OpenCV from source and install it.
|
||||
|
||||
If you want JNI and Java, you will need a JDK of at least version 21 installed. In addition, you need a `JAVA_HOME` environment variable set properly and set to the JDK directory.
|
||||
|
||||
If you are building with unit tests or simulation modules, you will also need an Internet connection for the initial setup process, as CMake will clone google-test and imgui from GitHub.
|
||||
|
||||
## Build Options
|
||||
|
||||
The following build options are available:
|
||||
|
||||
* `BUILD_SHARED_LIBS` (ON Default)
|
||||
* This option will cause CMake to build static libraries instead of shared libraries. If this is off, `WITH_JAVA` must be off. Otherwise CMake will error.
|
||||
* `WITH_CSCORE` (ON Default)
|
||||
* This option will cause cscore to be built. Turning this off will implicitly disable cameraserver. If this is off, the OpenCV build requirement is removed.
|
||||
* `WITH_EXAMPLES` (OFF Default)
|
||||
* This option will build C++ examples.
|
||||
* `WITH_GUI` (ON Default)
|
||||
* This option will build GUI items. If this is off, and `WITH_SIMULATION_MODULES` is on, the simulation GUI will not be built.
|
||||
* `WITH_JAVA` (OFF Default)
|
||||
* This option will enable Java and JNI builds. If this is on, `BUILD_SHARED_LIBS` must be on. Otherwise CMake will error.
|
||||
* `WITH_JAVA_SOURCE` (`WITH_JAVA` Default)
|
||||
* This option will build Java source JARs for each enabled Java library. This does not require `WITH_JAVA` to be on, allowing source JARs to be built without the compiled JARs if desired.
|
||||
* `WITH_NTCORE` (ON Default)
|
||||
* This option will cause ntcore to be built. Turning this off will implicitly disable wpinet, and will cause an error if `WITH_WPILIB` is enabled.
|
||||
* `WITH_SIMULATION_MODULES` (ON Default)
|
||||
* This option will build simulation modules.
|
||||
* `WITH_TESTS` (ON Default)
|
||||
* This option will build C++ unit tests. These can be run via `ctest -C <config>`, where `<config>` is the build configuration, e.g. `Debug` or `Release`.
|
||||
* `WITH_WPILIB` (ON Default)
|
||||
* This option will build the HAL and wpilibc/j during the build. The HAL is the simulation HAL, unless the external HAL options are used. The CMake build has no capability to build for the roboRIO.
|
||||
* `WITH_WPIMATH` (ON Default)
|
||||
* This option will build the wpimath library. This option must be on to build wpilib.
|
||||
* `WITH_WPIUNITS` (`WITH_JAVA` Default)
|
||||
* This option will build the wpiunits library. This option must be on to build the Java wpimath library and requires `WITH_JAVA` to also be on.
|
||||
* `OPENCV_JAVA_INSTALL_DIR`
|
||||
* Set this option to the location of the archive of the OpenCV Java bindings (it should be called opencv-xxx.jar, with the x'es being version numbers). NOTE: set it to the LOCATION of the file, not the file itself!
|
||||
* `NO_WERROR` (OFF Default)
|
||||
* This option will disable the `-Werror` compilation flag for non-MSVC builds.
|
||||
* `WPILIB_TARGET_WARNINGS`
|
||||
* Add compiler flags to this option to customize compiler options like warnings.
|
||||
|
||||
## Build Setup
|
||||
|
||||
The WPILib CMake build does not allow in source builds. Because the `build` directory is used by Gradle, we recommend a `build-cmake` directory in the root. This folder is included in the gitignore. We support building with Ninja; other options like Makefiles may be broken.
|
||||
|
||||
Once you have a build folder, run CMake configuration in the root directory with the following command.
|
||||
|
||||
```
|
||||
cmake --preset default
|
||||
```
|
||||
|
||||
If you want to change any of the options, add `-DOPTIONHERE=VALUE` to the `cmake` command. This will check for any dependencies. If everything works properly this will succeed. If not, please check out the troubleshooting section for help.
|
||||
|
||||
If you want, you can also use `ccmake` in order to visually set these properties as well. [Here](https://cmake.org/cmake/help/v3.0/manual/ccmake.1.html) is the link to the documentation for that program. On Windows, you can use `cmake-gui` instead.
|
||||
|
||||
## Presets
|
||||
|
||||
The WPILib CMake setup has a variety of presets for common configurations and options used. The default sets the generator to Ninja and build directory to `build-cmake`. The other presets are `with-java` (sets `WITH_JAVA=ON`), `sccache` (sets the C/C++ compiler launcher to sccache), and `with-java-sccache` (a comibination of `with-java` and `sccache`.
|
||||
|
||||
## Building
|
||||
|
||||
Once you have CMake setup. run `cmake --build .` from the directory you configured CMake in. This will build all libraries possible. We recommend running `cmake --build .` with multiple jobs. For allwpilib, a good rule of thumb is one worker for every 2 GB of available RAM. To run a multiple job build, run the following command with x being the number of jobs you want.
|
||||
|
||||
```
|
||||
cmake --build . --parallel x
|
||||
```
|
||||
|
||||
Note: wpimath takes gigabytes of RAM to compile. Because of this, the compilers may crash while building due to a lack of memory and your computer may slow down. If you have less than 16 GB of RAM available, you may want to consider building it separately first by adding `--target wpimath` and running it with ~3 jobs to prevent crashes from running out of memory.
|
||||
|
||||
To build with a certain configuration, like `Debug` or `Release`, add `--config <config>`, where `<config>` is the name of the configuration you want to build with.
|
||||
|
||||
## Installing
|
||||
|
||||
After build, the easiest way to use the libraries is to install them. Run the following command to install the libraries. This will install them so that they can be used from external CMake projects.
|
||||
|
||||
```
|
||||
sudo cmake --build . --target install
|
||||
```
|
||||
|
||||
## Preparing to use the installed libraries
|
||||
|
||||
On Windows, make sure the directories for the libraries you built are on PATH. For wpilib, the default install location is `C:\Program Files (x86)\allwpilib`. If you built other libraries like OpenCV from source, install them, and add the install directories to PATH. This ensures CMake can locate the libraries.
|
||||
|
||||
You will also want to add the directories where the DLLs are located (usually the `bin` subdirectory of the install directory) to PATH so they can be loaded by your program. If you are using OpenCV and Java, the `opencv_java` DLL is located in either the `lib` subdirectory if you built but didn't install OpenCV, or the `java` subdirectory if you did install OpenCV.
|
||||
|
||||
## Using the installed libraries for C++.
|
||||
|
||||
Using the libraries from C++ is the easiest way to use the built libraries.
|
||||
|
||||
To do so, create a new folder to contain your project. Add the following code below to a `CMakeLists.txt` file in that directory.
|
||||
|
||||
```cmake
|
||||
cmake_minimum_required(VERSION 3.11)
|
||||
project(vision_app) # Project Name Here
|
||||
|
||||
find_package(wpilib REQUIRED)
|
||||
|
||||
add_executable(my_vision_app main.cpp) # executable name as first parameter
|
||||
target_link_libraries(my_vision_app cameraserver ntcore cscore wpiutil)
|
||||
```
|
||||
|
||||
If you want to use other libraries or are building a robot program, `wpilibc` and `hal` should be added in the `target_link_libraries` function, along with any other libraries you plan on using, e.g. `wpimath`.
|
||||
|
||||
Add a `main.cpp` file to contain your code, and create a build folder. Move into the build folder, and run
|
||||
|
||||
```
|
||||
cmake /path/to/folder/containing/CMakeLists
|
||||
```
|
||||
|
||||
After that, run `cmake --build .`. That will create your executable. Then you should be able to run `./my_vision_app` to run your application.
|
||||
|
||||
## Using the installed libraries for Java
|
||||
|
||||
Using the built JARs is more involved than using the C++ libraries, but the additional work involves providing the paths to various libraries and JARs when needed.
|
||||
|
||||
Create a new folder to contain your project. Add the following code below to a `CMakeLists.txt` file in that directory.
|
||||
|
||||
```cmake
|
||||
cmake_minimum_required(VERSION 3.11)
|
||||
project(robot)
|
||||
|
||||
find_package(Java REQUIRED COMPONENTS Development)
|
||||
include(UseJava)
|
||||
find_package(wpilib REQUIRED)
|
||||
find_jar(opencvJar opencv-xxx PATHS ENV PATH) # Change to OpenCV version
|
||||
|
||||
file(GLOB_RECURSE JAVA_SOURCES *.java)
|
||||
# If you want Gradle compatibility or you are using one of the templates/examples, comment out the above line and uncomment this line instead:
|
||||
# file(GLOB_RECURSE JAVA_SOURCES src/main/java/*.java)
|
||||
add_jar(robot ${JAVA_SOURCES}
|
||||
INCLUDE_JARS apriltag_jar cscore_jar hal_jar ntcore_jar wpilibNewCommands_jar wpimath_jar wpinet_jar wpiutil_jar wpiunits_jar wpilibj_jar ${opencvJar})
|
||||
export_jars(TARGETS robot FILE robot.jar)
|
||||
```
|
||||
This includes all the built JARs except for the vendordeps. If you are not using a JAR/library, you may remove it.
|
||||
Add a `Main.java` file to contain your code, and create a build folder. Move into the build folder, and run
|
||||
|
||||
```
|
||||
cmake /path/to/folder/containing/CMakeLists
|
||||
```
|
||||
|
||||
After that, run `cmake --build .` to create your JAR file. To execute the JAR file, you need to include the wpilib JARs and your JAR in the classpath, and execute your Java program's entry point. If you are using cscore or cameraserver, you also need to include the path to the OpenCV JAR. If you built it from source, it will be in your OpenCV build directory. If it's installed on the system, CMake may find it from PATH, but you will likely need to locate the JAR and manually give CMake the JAR directory. If you are on Linux, you will also need to add the path of the libraries to `LD_LIBRARY_PATH`. This can be done by prepending `LD_LIBRARY_PATH=/path/to/libraries` to the Java command. If you need to add more paths, separate them with colons. The final command should look like `java -cp "robot.jar:/path/to/library_jars/*" main.package.Main`, using a semicolon to separate paths instead of a colon if you are on Windows. If you are on Linux, the final command should look more like `LD_LIBRARY_PATH=/path/to/libraries java -cp robot.jar:/path/to/library_jars/* main.package.Main`.
|
||||
|
||||
## Using vendordeps
|
||||
|
||||
Vendordeps are not included as part of the `wpilib` CMake package. However, if you want to use a vendordep, you need to use `find_package(VENDORDEP)`, where `VENDORDEP` is the name of the vendordep (case-sensitive), like `xrpVendordep` or `romiVendordep`. Note that wpilibNewCommands, while a vendordep in normal robot projects, is not built as a vendordep in CMake, and is instead included as part of the `wpilib` CMake package. After you used `find_package`, you can reference the vendordep library like normal, either by using `target_link_libraries` for C++ or `add_jar` for Java.
|
||||
|
||||
## Troubleshooting
|
||||
Below are some common issues that are run into when building.
|
||||
|
||||
#### Missing OpenCV
|
||||
|
||||
If you are missing OpenCV, you will get an error message similar to this.
|
||||
|
||||
```
|
||||
CMake Error at cscore/CMakeLists.txt:3 (find_package):
|
||||
By not providing "FindOpenCV.cmake" in CMAKE_MODULE_PATH this project has
|
||||
asked CMake to find a package configuration file provided by "OpenCV", but
|
||||
CMake did not find one.
|
||||
|
||||
Could not find a package configuration file provided by "OpenCV" with any
|
||||
of the following names:
|
||||
|
||||
OpenCVConfig.cmake
|
||||
opencv-config.cmake
|
||||
|
||||
Add the installation prefix of "OpenCV" to CMAKE_PREFIX_PATH or set
|
||||
"OpenCV_DIR" to a directory containing one of the above files. If "OpenCV"
|
||||
provides a separate development package or SDK, be sure it has been
|
||||
installed.
|
||||
```
|
||||
|
||||
If you get that, you need make sure OpenCV was installed, and then reattempt to configure. If that doesn't work, set the `OpenCV_DIR` variable to the directory where you built OpenCV.
|
||||
|
||||
#### Missing Java
|
||||
|
||||
If you are missing Java, you will get a message like the following.
|
||||
```
|
||||
CMake Error at /usr/share/cmake-3.5/Modules/FindPackageHandleStandardArgs.cmake:148 (message):
|
||||
Could NOT find Java (missing: Java_JAVA_EXECUTABLE Java_JAR_EXECUTABLE
|
||||
Java_JAVAC_EXECUTABLE Java_JAVAH_EXECUTABLE Java_JAVADOC_EXECUTABLE)
|
||||
```
|
||||
|
||||
If this happens, make sure you have a JDK of at least version 8 installed, and that your JAVA_HOME variable is set properly to point to the JDK.
|
||||
|
||||
In addition, if you do not need Java, you can disable it with `-DWITH_JAVA=OFF`.
|
||||
|
||||
#### Java: Can't find dependent libraries
|
||||
|
||||
If one of the libraries can't be found, you will get an error similar to this one:
|
||||
|
||||
```
|
||||
java.io.IOException: wpiHaljni could not be loaded from path or an embedded resource.
|
||||
attempted to load for platform /windows/x86-64/
|
||||
Last Load Error:
|
||||
C:\Program Files (x86)\allwpilib\bin\wpiHaljni.dll: Can't find dependent libraries
|
||||
```
|
||||
|
||||
If you get this error, that's usually an indication that not all your libraries are in your PATH. If the error is coming from cscore specifically, it's likely you're missing OpenCV. Otherwise, it's likely the wpilib libraries are not in a directory on PATH.
|
||||
|
||||
Note that Linux will not have this specific type of error, as it will usually tell you the dependent library you are missing. In that case, you most likely need to add the library to `LD_LIBRARY_PATH`.
|
||||
13
README-RobotPy.md
Normal file
13
README-RobotPy.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# robotpy in allwpilb
|
||||
allwpilib hosts a mirror of RobotPy that can be built with bazel on Linux. The intent of the mirror is to have breaking changes identified early and fixed by the PR creator so that when wpilib releases are made there is much less work required to release a RobotPy version that wraps it. It is not a goal for allwpilib to replace the RobotPy repo; it will still be considered the "source of truth" for python builds and will be responsible for building against all of the applicable architectures and multiple versions of python.
|
||||
|
||||
## Build Process
|
||||
The upstream RobotPy repository uses toml configuration files and semiwrap to produce Meson build scripts. The allwpilib fork uses these toml configuration files to auto generate bazel build scripts. In general, each project (wpiutil, wpimath, etc) defines two pybind extensions; one that simply wraps the native library, and another that adds extension(s) that and contains all of the python files for the library. Both of these subprojects have auto-generated build files; a `robotpy_native_build_info.bzl` for the lidar wraper and `robotpy_pybind_build_info.bzl` which defines the extensions and python library.
|
||||
|
||||
## Disabling robotpy builds
|
||||
Building the robotpy software on top of the standard C++/Java software can result in more than doubling the amount of time it takes to compile. To skip building the robotpy tooling you can add `--config=skip_robotpy` to the command line or to your `user.bazelrc`
|
||||
|
||||
# Syncing with robotpy
|
||||
NOTE: This process is currently unlanded while robotpy gets the 2027 branch stable
|
||||
|
||||
[Copybara](https://github.com/google/copybara) is used to maintin synchronization between the upstream robotpy repositories and the allwpilib mirror. Github actions can be manually run which will create pull requests that will update all of the robotpy files between the two repositories. The ideal process is that the allwpilib mirror is always building in CI, and once a release is created the RobotPy team can run the `wpilib -> robotpy` copybara task, make any fine tuned adjustements and create their release. In the event that additional changes are made on the robotpy side, they can run the `robotpy -> wpilib` task to push the updates back to the mirror. However the goal of the mirroring the software here is to be able to more rapidly test changes and will hopefully overwhelmingly eliminate the need for syncs this direction.
|
||||
29
README.md
29
README.md
@@ -17,6 +17,7 @@ Welcome to the WPILib project. This repository contains the HAL, WPILibJ, and WP
|
||||
- [Custom toolchain location](#custom-toolchain-location)
|
||||
- [Formatting/Linting](#formattinglinting)
|
||||
- [CMake](#cmake)
|
||||
- [Bazel](#bazel)
|
||||
- [Running examples in simulation](#running-examples-in-simulation)
|
||||
- [Publishing](#publishing)
|
||||
- [Structure and Organization](#structure-and-organization)
|
||||
@@ -41,23 +42,30 @@ Using Gradle makes building WPILib very straightforward. It only has a few depen
|
||||
|
||||
## Requirements
|
||||
|
||||
- [JDK 17](https://adoptium.net/temurin/releases/?version=17)
|
||||
- [JDK 21](https://adoptium.net/temurin/releases/?version=21)
|
||||
- Note that the JRE is insufficient; the full JDK is required
|
||||
- On Ubuntu, run `sudo apt install openjdk-17-jdk`
|
||||
- On Windows, install the JDK 17 .msi from the link above
|
||||
- On macOS, install the JDK 17 .pkg from the link above
|
||||
- On Ubuntu, run `sudo apt install openjdk-21-jdk`
|
||||
- On Windows, install the JDK 21 .msi from the link above
|
||||
- On macOS, install the JDK 21 .pkg from the link above
|
||||
- C++ compiler
|
||||
- On Linux, install GCC 11 or greater
|
||||
- On Windows, install [Visual Studio Community 2022](https://visualstudio.microsoft.com/vs/community/) and select the C++ programming language during installation (Gradle can't use the build tools for Visual Studio)
|
||||
- On macOS, install the Xcode command-line build tools via `xcode-select --install`. Xcode 13 or later is required.
|
||||
- On macOS 13.3 or newer, install Xcode 14 or later (the command-line build tools are insufficient).
|
||||
- ARM compiler toolchain
|
||||
- Run `./gradlew installRoboRioToolchain` after cloning this repository
|
||||
- If the WPILib installer was used, this toolchain is already installed
|
||||
- Raspberry Pi toolchain (optional)
|
||||
- Run `./gradlew installArm32Toolchain` after cloning this repository
|
||||
- SystemCore toolchain (required for SystemCore development)
|
||||
- Run `./gradlew installSystemCoreToolchain` after cloning this repository
|
||||
- If the WPILib installer was used, this toolchain is already installed
|
||||
|
||||
On macOS ARM, run `softwareupdate --install-rosetta`. This is necessary to be able to use the macOS x86 roboRIO toolchain on ARM.
|
||||
|
||||
On linux, run `sudo apt install gfortran`. This is necessary to be able to build WPIcal on linux platforms.
|
||||
|
||||
On linux, run `sudo apt install libx11-dev libgl-dev libxcursor-dev libxrandr-dev libxinerama-dev libxi-dev` to be able to build things depending on glfw.
|
||||
|
||||
## Setup
|
||||
|
||||
Clone the WPILib repository and follow the instructions above for installing any required tooling. The build process uses versioning information from git. Downloading the source is not sufficient to run the build.
|
||||
@@ -133,6 +141,9 @@ If you have installed the FRC Toolchain to a directory other than the default, o
|
||||
|
||||
Once a PR has been submitted, formatting can be run in CI by commenting `/format` on the PR. A new commit will be pushed with the formatting changes.
|
||||
|
||||
> [!NOTE]
|
||||
> The `/format` action has been temporarily disabled. The individual formatting commands can be run locally as shown below. Alternately, the Lint and Format action for a PR will upload a patch file that can be downloaded and applied manually.
|
||||
|
||||
#### wpiformat
|
||||
|
||||
wpiformat can be executed anywhere in the repository via `py -3 -m wpiformat` on Windows or `python3 -m wpiformat` on other platforms.
|
||||
@@ -145,11 +156,15 @@ If you only want to run the Java autoformatter, run `./gradlew spotlessApply`.
|
||||
|
||||
### Generated files
|
||||
|
||||
Several files within WPILib are generated using Jinja. If a PR is opened that modifies these templates then the files can be generated through CI by commenting `/pregen` on the PR. A new commit will be pushed with the regenerated files.
|
||||
Several files within WPILib are generated using Jinja. If a PR is opened that modifies these templates then the files can be generated through CI by commenting `/pregen` on the PR. A new commit will be pushed with the regenerated files. See [GeneratedFiles.md](GeneratedFiles.md) for more information.
|
||||
|
||||
### CMake
|
||||
|
||||
CMake is also supported for building. See [README-CMAKE.md](README-CMAKE.md).
|
||||
CMake is also supported for building. See [README-CMake.md](README-CMake.md).
|
||||
|
||||
### Bazel
|
||||
|
||||
Bazel is also supported for building. See [README-Bazel.md](README-Bazel.md).
|
||||
|
||||
## Running examples in simulation
|
||||
|
||||
|
||||
@@ -15,7 +15,8 @@ licenses, and/or restrictions:
|
||||
|
||||
Program Locations
|
||||
------- ---------
|
||||
Google Test gtest
|
||||
Google Test thirdparty/googletest/include
|
||||
thirdparty/googletest/src
|
||||
LLVM wpiutil/src/main/native/thirdparty/llvm
|
||||
wpiutil/src/test/native/cpp/llvm/
|
||||
JSON for Modern C++ wpiutil/src/main/native/thirdparty/json
|
||||
@@ -32,17 +33,28 @@ jQuery wpinet/src/main/native/resources/jquery-*
|
||||
popper.js wpinet/src/main/native/resources/popper-*
|
||||
units wpimath/src/main/native/include/units/
|
||||
Eigen wpimath/src/main/native/thirdparty/eigen/include/
|
||||
StackWalker wpiutil/src/main/native/windows/StackWalker.*
|
||||
GHC filesystem wpiutil/src/main/native/thirdparty/include/wpi/ghc/
|
||||
Team 254 Library wpilibj/src/main/java/edu/wpi/first/wpilibj/spline/SplineParameterizer.java
|
||||
wpilibj/src/main/java/edu/wpi/first/wpilibj/trajectory/TrajectoryParameterizer.java
|
||||
wpilibc/src/main/native/include/spline/SplineParameterizer.h
|
||||
wpilibc/src/main/native/include/trajectory/TrajectoryParameterizer.h
|
||||
wpilibc/src/main/native/cpp/trajectory/TrajectoryParameterizer.cpp
|
||||
Team 254 Library wpimath/src/main/java/edu/wpi/first/math/spline/SplineParameterizer.java
|
||||
wpimath/src/main/java/edu/wpi/first/math/trajectory/TrajectoryParameterizer.java
|
||||
wpimath/src/main/native/include/frc/spline/SplineParameterizer.h
|
||||
wpimath/src/main/native/include/frc/trajectory/TrajectoryParameterizer.h
|
||||
wpimath/src/main/native/cpp/trajectory/TrajectoryParameterizer.cpp
|
||||
Portable File Dialogs wpigui/src/main/native/include/portable-file-dialogs.h
|
||||
V8 export-template wpiutil/src/main/native/include/wpi/SymbolExports.h
|
||||
GCEM wpimath/src/main/native/thirdparty/gcem/include/
|
||||
Sleipnir wpimath/src/main/native/thirdparty/sleipnir
|
||||
Debugging wpiutil/src/main/native/thirdparty/debugging
|
||||
argparse wpiutil/src/main/native/thirdparty/argparse/include/wpi/argparse.h
|
||||
apriltag apriltag/src/main/native/thirdparty/apriltag
|
||||
glfw thirdparty/imgui_suite/glfw
|
||||
Dear ImGui thirdparty/imgui_suite/imgui
|
||||
implot thirdparty/imgui_suite/implot
|
||||
nanopb wpiutil/src/main/native/thirdparty/nanopb
|
||||
upb wpiutil/src/main/native/thirdparty/upb
|
||||
mrcal wpical/src/main/native/thirdparty/mrcal
|
||||
libdogleg wpical/src/main/native/thirdparty/libdogleg
|
||||
Simd hal/src/main/native/systemcore/simd
|
||||
|
||||
Additionally, glfw and nanopb were modified for use in WPILib.
|
||||
|
||||
==============================================================================
|
||||
Google Test License
|
||||
@@ -461,7 +473,7 @@ limitations under the License.
|
||||
|
||||
|
||||
==============================================================================
|
||||
MPacks License
|
||||
MPack License
|
||||
==============================================================================
|
||||
The MIT License (MIT)
|
||||
|
||||
@@ -1012,35 +1024,6 @@ Exhibit B - "Incompatible With Secondary Licenses" Notice
|
||||
defined by the Mozilla Public License, v. 2.0.
|
||||
|
||||
|
||||
===================
|
||||
StackWalker License
|
||||
===================
|
||||
Copyright (c) 2005-2013, Jochen Kalmbach
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
Neither the name of Jochen Kalmbach nor the names of its contributors may be
|
||||
used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
================
|
||||
Team 254 Library
|
||||
================
|
||||
@@ -1077,33 +1060,6 @@ and/or modify it under the terms of the Do What the **** You Want
|
||||
to Public License, Version 2, as published by the WTFPL Task Force.
|
||||
See http://www.wtfpl.net/ for more details.
|
||||
|
||||
======================
|
||||
Boost Software License
|
||||
======================
|
||||
Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
Permission is hereby granted, free of charge, to any person or organization
|
||||
obtaining a copy of the software and accompanying documentation covered by
|
||||
this license (the "Software") to use, reproduce, display, distribute,
|
||||
execute, and transmit the Software, and to prepare derivative works of the
|
||||
Software, and to permit third-parties to whom the Software is furnished to
|
||||
do so, all subject to the following:
|
||||
|
||||
The copyright notices in the Software and this entire statement, including
|
||||
the above license grant, this restriction and the following disclaimer,
|
||||
must be included in all copies of the Software, in whole or in part, and
|
||||
all derivative works of the Software, unless such copies or derivative
|
||||
works are solely in the form of machine-executable object code generated by
|
||||
a source language processor.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
||||
======
|
||||
fmtlib
|
||||
======
|
||||
@@ -1135,29 +1091,6 @@ of this Software are embedded into a machine-executable object form of such
|
||||
source code, you may redistribute such embedded portions in such object form
|
||||
without including the above copyright and permission notices.
|
||||
|
||||
==============
|
||||
GHC filesystem
|
||||
==============
|
||||
Copyright (c) 2018, Steffen Schümann <s.schuemann@pobox.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
==================
|
||||
V8 export-template
|
||||
==================
|
||||
@@ -1224,3 +1157,519 @@ Redistribution and use in source and binary forms, with or without modification,
|
||||
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
=================
|
||||
Debugging License
|
||||
=================
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021-2022 René Ferdinand Rivera Morell
|
||||
Copyright (c) 2018 Isabella Muerte
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
================
|
||||
argparse License
|
||||
================
|
||||
Copyright (c) 2018 Pranav Srinivas Kumar <pranav.srinivas.kumar@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
================
|
||||
apriltag License
|
||||
================
|
||||
BSD 2-Clause License
|
||||
|
||||
Copyright (C) 2013-2016, The Regents of The University of Michigan.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
The views and conclusions contained in the software and documentation are those
|
||||
of the authors and should not be interpreted as representing official policies,
|
||||
either expressed or implied, of the Regents of The University of Michigan.
|
||||
|
||||
============
|
||||
gl3w License
|
||||
============
|
||||
This is free and unencumbered software released into the public domain.
|
||||
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
distribute this software, either in source code form or as a compiled
|
||||
binary, for any purpose, commercial or non-commercial, and by any
|
||||
means.
|
||||
|
||||
In jurisdictions that recognize copyright laws, the author or authors
|
||||
of this software dedicate any and all copyright interest in the
|
||||
software to the public domain. We make this dedication for the benefit
|
||||
of the public at large and to the detriment of our heirs and
|
||||
successors. We intend this dedication to be an overt act of
|
||||
relinquishment in perpetuity of all present and future rights to this
|
||||
software under copyright law.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
============
|
||||
glfw License
|
||||
============
|
||||
Copyright (c) 2002-2006 Marcus Geelnard
|
||||
|
||||
Copyright (c) 2006-2019 Camilla Löwy
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would
|
||||
be appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and must not
|
||||
be misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
|
||||
==================
|
||||
Dear ImGui License
|
||||
==================
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014-2024 Omar Cornut
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
==============
|
||||
implot License
|
||||
==============
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 Evan Pezent
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
==============
|
||||
nanopb License
|
||||
==============
|
||||
Copyright (c) 2011 Petteri Aimonen <jpa at nanopb.mail.kapsi.fi>
|
||||
|
||||
This software is provided 'as-is', without any express or
|
||||
implied warranty. In no event will the authors be held liable
|
||||
for any damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any
|
||||
purpose, including commercial applications, and to alter it and
|
||||
redistribute it freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you
|
||||
must not claim that you wrote the original software. If you use
|
||||
this software in a product, an acknowledgment in the product
|
||||
documentation would be appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and
|
||||
must not be misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
|
||||
================
|
||||
upb License
|
||||
================
|
||||
Copyright 2008 Google Inc. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Code generated by the Protocol Buffer compiler is owned by the owner
|
||||
of the input file used when generating it. This code is not
|
||||
standalone and requires a support library to be linked with it. This
|
||||
support library is itself covered by the above license.
|
||||
|
||||
===========
|
||||
stb License
|
||||
===========
|
||||
This software is available under 2 licenses -- choose whichever you prefer.
|
||||
------------------------------------------------------------------------------
|
||||
ALTERNATIVE A - MIT License
|
||||
Copyright (c) 2017 Sean Barrett
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
------------------------------------------------------------------------------
|
||||
ALTERNATIVE B - Public Domain (www.unlicense.org)
|
||||
This is free and unencumbered software released into the public domain.
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
|
||||
software, either in source code form or as a compiled binary, for any purpose,
|
||||
commercial or non-commercial, and by any means.
|
||||
In jurisdictions that recognize copyright laws, the author or authors of this
|
||||
software dedicate any and all copyright interest in the software to the public
|
||||
domain. We make this dedication for the benefit of the public at large and to
|
||||
the detriment of our heirs and successors. We intend this dedication to be an
|
||||
overt act of relinquishment in perpetuity of all present and future rights to
|
||||
this software under copyright law.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
=============
|
||||
mrcal License
|
||||
=============
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright (c) 2017-2023 California Institute of Technology ("Caltech"). U.S.
|
||||
Government sponsorship acknowledged. All rights reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
=================
|
||||
libdogleg License
|
||||
=================
|
||||
Copyright 2011 Oblong Industries 2017 Dima Kogan <dima@secretsauce.net>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
|
||||
The full text of the license is available at http://www.gnu.org/licenses
|
||||
|
||||
============
|
||||
Simd License
|
||||
============
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2011-2017 Ihar Yermalayeu
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
444
WORKSPACE
Normal file
444
WORKSPACE
Normal file
@@ -0,0 +1,444 @@
|
||||
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive", "http_file")
|
||||
load("//thirdparty/ceres:repositories.bzl", "ceres_repositories")
|
||||
|
||||
ceres_repositories()
|
||||
|
||||
http_archive(
|
||||
name = "bazel_features",
|
||||
sha256 = "a015f3f2ebf4f1ac3f4ca8ea371610acb63e1903514fa8725272d381948d2747",
|
||||
strip_prefix = "bazel_features-1.31.0",
|
||||
url = "https://github.com/bazel-contrib/bazel_features/releases/download/v1.31.0/bazel_features-v1.31.0.tar.gz",
|
||||
)
|
||||
|
||||
# TODO(austin): Upgrade when the patches land.
|
||||
# https://github.com/bazelbuild/rules_cc/pull/430
|
||||
# https://github.com/bazelbuild/rules_cc/pull/431
|
||||
# https://github.com/bazelbuild/rules_cc/pull/432
|
||||
http_archive(
|
||||
name = "rules_cc",
|
||||
patch_args = ["-p1"],
|
||||
patches = ["//:shared/bazel/patches/rules_cc_windows.patch"],
|
||||
sha256 = "0d3b4f984c4c2e1acfd1378e0148d35caf2ef1d9eb95b688f8e19ce0c41bdf5b",
|
||||
strip_prefix = "rules_cc-0.1.4",
|
||||
url = "https://github.com/bazelbuild/rules_cc/releases/download/0.1.4/rules_cc-0.1.4.tar.gz",
|
||||
)
|
||||
|
||||
# TODO(austinschuh): Update to the next released apple_support once it lands.
|
||||
# This needs to contain https://github.com/bazelbuild/apple_support/commit/7009b77c98a67d3fea081c9db4dbcee8effc3b7e and should be the next release after 1.22.1
|
||||
http_archive(
|
||||
name = "build_bazel_apple_support",
|
||||
sha256 = "7d542be113180bc1da3660e51fe4792a867fb85537c9ef36a0d3366665a76803",
|
||||
strip_prefix = "apple_support-7009b77c98a67d3fea081c9db4dbcee8effc3b7e",
|
||||
url = "https://github.com/bazelbuild/apple_support/archive/7009b77c98a67d3fea081c9db4dbcee8effc3b7e.tar.gz",
|
||||
)
|
||||
|
||||
http_archive(
|
||||
name = "rules_java",
|
||||
sha256 = "d31b6c69e479ffa45460b64dc9c7792a431cac721ef8d5219fc9f603fa2ff877",
|
||||
urls = [
|
||||
"https://github.com/bazelbuild/rules_java/releases/download/8.11.0/rules_java-8.11.0.tar.gz",
|
||||
],
|
||||
)
|
||||
|
||||
http_archive(
|
||||
name = "rules_pkg",
|
||||
sha256 = "cad05f864a32799f6f9022891de91ac78f30e0fa07dc68abac92a628121b5b11",
|
||||
urls = [
|
||||
"https://github.com/bazelbuild/rules_pkg/releases/download/1.0.0/rules_pkg-1.0.0.tar.gz",
|
||||
],
|
||||
)
|
||||
|
||||
# Rules Python
|
||||
http_archive(
|
||||
name = "rules_python",
|
||||
sha256 = "9f9f3b300a9264e4c77999312ce663be5dee9a56e361a1f6fe7ec60e1beef9a3",
|
||||
strip_prefix = "rules_python-1.4.1",
|
||||
url = "https://github.com/bazel-contrib/rules_python/releases/download/1.4.1/rules_python-1.4.1.tar.gz",
|
||||
)
|
||||
|
||||
# Download Extra java rules
|
||||
http_archive(
|
||||
name = "rules_jvm_external",
|
||||
sha256 = "4f55980c25d0783b9fe43b049362018d8d79263476b5340a5491893ffcc06ab6",
|
||||
strip_prefix = "rules_jvm_external-30899314873b6ec69dc7d02c4457fbe52a6e535d",
|
||||
url = "https://github.com/bazel-contrib/rules_jvm_external/archive/30899314873b6ec69dc7d02c4457fbe52a6e535d.tar.gz",
|
||||
)
|
||||
|
||||
# Setup aspect lib
|
||||
http_archive(
|
||||
name = "aspect_bazel_lib",
|
||||
sha256 = "a8a92645e7298bbf538aa880131c6adb4cf6239bbd27230f077a00414d58e4ce",
|
||||
strip_prefix = "bazel-lib-2.7.2",
|
||||
url = "https://github.com/aspect-build/bazel-lib/releases/download/v2.7.2/bazel-lib-v2.7.2.tar.gz",
|
||||
)
|
||||
|
||||
# Download toolchains
|
||||
http_archive(
|
||||
name = "rules_bzlmodrio_toolchains",
|
||||
sha256 = "102b4507628e9724b0c1e441727762c344e40170f65ac60516168178ea33a89a",
|
||||
url = "https://github.com/wpilibsuite/rules_bzlmodrio_toolchains/releases/download/2025-1.bcr6/rules_bzlmodrio_toolchains-2025-1.bcr6.tar.gz",
|
||||
)
|
||||
|
||||
http_archive(
|
||||
name = "pybind11_bazel",
|
||||
integrity = "sha256-iwRj1wuX2pDS6t6DqiCfhIXisv4y+7CvxSJtZoSAzGw=",
|
||||
strip_prefix = "pybind11_bazel-2b6082a4d9d163a52299718113fa41e4b7978db5",
|
||||
urls = ["https://github.com/pybind/pybind11_bazel/archive/2b6082a4d9d163a52299718113fa41e4b7978db5.tar.gz"],
|
||||
)
|
||||
|
||||
http_archive(
|
||||
name = "pybind11",
|
||||
build_file = "@pybind11_bazel//:pybind11-BUILD.bazel",
|
||||
strip_prefix = "pybind11-dfe7e65b4527eeb11036402aac3a394130960bb2",
|
||||
urls = ["https://github.com/pybind/pybind11/archive/dfe7e65b4527eeb11036402aac3a394130960bb2.zip"],
|
||||
)
|
||||
|
||||
http_archive(
|
||||
name = "rules_python_pytest",
|
||||
sha256 = "e2556404ef56ea3ec938597616afc51d78e1832cfe511b196e9f2b8fd7f8f149",
|
||||
strip_prefix = "rules_python_pytest-1.1.1",
|
||||
url = "https://github.com/caseyduquettesc/rules_python_pytest/releases/download/v1.1.1/rules_python_pytest-v1.1.1.tar.gz",
|
||||
)
|
||||
|
||||
http_archive(
|
||||
name = "bazel_skylib",
|
||||
sha256 = "51b5105a760b353773f904d2bbc5e664d0987fbaf22265164de65d43e910d8ac",
|
||||
urls = [
|
||||
"https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.8.1/bazel-skylib-1.8.1.tar.gz",
|
||||
"https://github.com/bazelbuild/bazel-skylib/releases/download/1.8.1/bazel-skylib-1.8.1.tar.gz",
|
||||
],
|
||||
)
|
||||
|
||||
http_archive(
|
||||
name = "rules_doxygen",
|
||||
sha256 = "5d154d3d011208510392b5aee8ea23ec61ab858cc1f3382b6eb8c729d3b4b336",
|
||||
strip_prefix = "rules_doxygen-2.4.2",
|
||||
url = "https://github.com/TendTo/rules_doxygen/releases/download/2.4.2/rules_doxygen-2.4.2.tar.gz",
|
||||
)
|
||||
|
||||
# This gives us a repository layout which matches what normal BCR modules expect.
|
||||
# The goal here is to make it easier to depend on external projects which already
|
||||
# include @eigen without introducing multiple eigen versions.
|
||||
local_repository(
|
||||
name = "eigen",
|
||||
path = "wpimath/src/main/native/thirdparty/eigen/include/",
|
||||
)
|
||||
|
||||
load("@bazel_features//:deps.bzl", "bazel_features_deps")
|
||||
|
||||
bazel_features_deps()
|
||||
|
||||
load("@build_bazel_apple_support//lib:repositories.bzl", "apple_support_dependencies")
|
||||
|
||||
apple_support_dependencies()
|
||||
|
||||
load("@rules_cc//cc:repositories.bzl", "rules_cc_toolchains")
|
||||
|
||||
rules_cc_toolchains()
|
||||
|
||||
load("@rules_java//java:rules_java_deps.bzl", "rules_java_dependencies")
|
||||
|
||||
rules_java_dependencies()
|
||||
|
||||
# note that the following line is what is minimally required from protobuf for the java rules
|
||||
# consider using the protobuf_deps() public API from @com_google_protobuf//:protobuf_deps.bzl
|
||||
load("@com_google_protobuf//bazel/private:proto_bazel_features.bzl", "proto_bazel_features") # buildifier: disable=bzl-visibility
|
||||
|
||||
proto_bazel_features(name = "proto_bazel_features")
|
||||
|
||||
# register toolchains
|
||||
load("@rules_java//java:repositories.bzl", "rules_java_toolchains")
|
||||
|
||||
rules_java_toolchains()
|
||||
|
||||
load("@rules_python//python:repositories.bzl", "py_repositories", "python_register_toolchains")
|
||||
|
||||
py_repositories()
|
||||
|
||||
python_register_toolchains(
|
||||
name = "python_3_10",
|
||||
ignore_root_user_error = True,
|
||||
python_version = "3.10",
|
||||
)
|
||||
|
||||
load("@rules_python//python:pip.bzl", "pip_parse")
|
||||
|
||||
pip_parse(
|
||||
name = "allwpilib_pip_deps",
|
||||
python_interpreter_target = "@python_3_10_host//:python",
|
||||
requirements_lock = "//:requirements_lock.txt",
|
||||
requirements_windows = "//:requirements_windows_lock.txt",
|
||||
)
|
||||
|
||||
load("@allwpilib_pip_deps//:requirements.bzl", "install_deps")
|
||||
|
||||
install_deps()
|
||||
|
||||
load("@rules_jvm_external//:repositories.bzl", "rules_jvm_external_deps")
|
||||
|
||||
rules_jvm_external_deps()
|
||||
|
||||
load("@rules_jvm_external//:setup.bzl", "rules_jvm_external_setup")
|
||||
|
||||
rules_jvm_external_setup()
|
||||
|
||||
load("@rules_jvm_external//:defs.bzl", "maven_install")
|
||||
load("@rules_jvm_external//:specs.bzl", "maven")
|
||||
|
||||
maven_artifacts = [
|
||||
"org.ejml:ejml-simple:0.44.0",
|
||||
"com.fasterxml.jackson.core:jackson-annotations:2.19.2",
|
||||
"com.fasterxml.jackson.core:jackson-core:2.19.2",
|
||||
"com.fasterxml.jackson.core:jackson-databind:2.19.2",
|
||||
"us.hebi.quickbuf:quickbuf-runtime:1.4",
|
||||
"com.google.code.gson:gson:2.13.1",
|
||||
"edu.wpi.first.thirdparty.frc2025.opencv:opencv-java:4.10.0-3",
|
||||
maven.artifact(
|
||||
"org.junit.jupiter",
|
||||
"junit-jupiter",
|
||||
"5.10.1",
|
||||
testonly = True,
|
||||
),
|
||||
maven.artifact(
|
||||
"org.junit.platform",
|
||||
"junit-platform-console",
|
||||
"1.10.1",
|
||||
testonly = True,
|
||||
),
|
||||
maven.artifact(
|
||||
"org.junit.platform",
|
||||
"junit-platform-launcher",
|
||||
"1.10.1",
|
||||
testonly = True,
|
||||
),
|
||||
maven.artifact(
|
||||
"org.junit.platform",
|
||||
"junit-platform-reporting",
|
||||
"1.10.1",
|
||||
testonly = True,
|
||||
),
|
||||
maven.artifact(
|
||||
"com.google.code.gson",
|
||||
"gson",
|
||||
"2.10.1",
|
||||
testonly = False,
|
||||
),
|
||||
maven.artifact(
|
||||
"org.hamcrest",
|
||||
"hamcrest-all",
|
||||
"1.3",
|
||||
testonly = True,
|
||||
),
|
||||
maven.artifact(
|
||||
"com.googlecode.junit-toolbox",
|
||||
"junit-toolbox",
|
||||
"2.4",
|
||||
testonly = True,
|
||||
),
|
||||
maven.artifact(
|
||||
"org.apache.ant",
|
||||
"ant",
|
||||
"1.10.12",
|
||||
testonly = True,
|
||||
),
|
||||
maven.artifact(
|
||||
"org.apache.ant",
|
||||
"ant-junit",
|
||||
"1.10.12",
|
||||
testonly = True,
|
||||
),
|
||||
maven.artifact(
|
||||
"org.mockito",
|
||||
"mockito-core",
|
||||
"4.1.0",
|
||||
testonly = True,
|
||||
),
|
||||
maven.artifact(
|
||||
"com.google.testing.compile",
|
||||
"compile-testing",
|
||||
"0.21.0",
|
||||
testonly = True,
|
||||
),
|
||||
]
|
||||
|
||||
maven_install(
|
||||
name = "maven",
|
||||
artifacts = maven_artifacts,
|
||||
maven_install_json = "//:maven_install.json",
|
||||
repositories = [
|
||||
"https://repo1.maven.org/maven2",
|
||||
"https://frcmaven.wpi.edu/artifactory/release/",
|
||||
],
|
||||
)
|
||||
|
||||
load("@maven//:defs.bzl", "pinned_maven_install")
|
||||
|
||||
pinned_maven_install()
|
||||
|
||||
load("@aspect_bazel_lib//lib:repositories.bzl", "aspect_bazel_lib_dependencies", "aspect_bazel_lib_register_toolchains")
|
||||
|
||||
aspect_bazel_lib_dependencies()
|
||||
|
||||
aspect_bazel_lib_register_toolchains()
|
||||
|
||||
load("@rules_bzlmodrio_toolchains//:maven_deps.bzl", "setup_legacy_setup_toolchains_dependencies")
|
||||
|
||||
setup_legacy_setup_toolchains_dependencies()
|
||||
|
||||
load("@rules_bzlmodrio_toolchains//toolchains:load_toolchains.bzl", "load_toolchains")
|
||||
|
||||
load_toolchains()
|
||||
|
||||
#
|
||||
http_archive(
|
||||
name = "rules_bzlmodrio_jdk",
|
||||
sha256 = "623b8bcdba1c3140f56e940365f011d2e5d90d74c7a30ace6a8817c037c1dd61",
|
||||
url = "https://github.com/wpilibsuite/rules_bzlmodRio_jdk/releases/download/17.0.12-7.bcr1/rules_bzlmodrio_jdk-17.0.12-7.bcr1.tar.gz",
|
||||
)
|
||||
|
||||
load("@rules_bzlmodrio_jdk//:maven_deps.bzl", "setup_legacy_setup_jdk_dependencies")
|
||||
|
||||
setup_legacy_setup_jdk_dependencies()
|
||||
|
||||
register_toolchains(
|
||||
"@local_roborio//:macos",
|
||||
"@local_roborio//:linux",
|
||||
"@local_roborio//:windows",
|
||||
"@local_systemcore//:macos",
|
||||
"@local_systemcore//:linux",
|
||||
"@local_systemcore//:windows",
|
||||
"@local_raspi_bookworm_32//:macos",
|
||||
"@local_raspi_bookworm_32//:linux",
|
||||
"@local_raspi_bookworm_32//:windows",
|
||||
"@local_bookworm_32//:macos",
|
||||
"@local_bookworm_32//:linux",
|
||||
"@local_bookworm_32//:windows",
|
||||
"@local_bookworm_64//:macos",
|
||||
"@local_bookworm_64//:linux",
|
||||
"@local_bookworm_64//:windows",
|
||||
)
|
||||
|
||||
setup_legacy_setup_jdk_dependencies()
|
||||
|
||||
http_archive(
|
||||
name = "bzlmodrio-ni",
|
||||
sha256 = "fff62c3cb3e83f9a0d0a01f1739477c9ca5e9a6fac05be1ad59dafcd385801f7",
|
||||
url = "https://github.com/wpilibsuite/bzlmodRio-ni/releases/download/2025.2.0/bzlmodRio-ni-2025.2.0.tar.gz",
|
||||
)
|
||||
|
||||
load("@bzlmodrio-ni//:maven_cpp_deps.bzl", "setup_legacy_bzlmodrio_ni_cpp_dependencies")
|
||||
|
||||
setup_legacy_bzlmodrio_ni_cpp_dependencies()
|
||||
|
||||
http_archive(
|
||||
name = "bzlmodrio-opencv",
|
||||
sha256 = "867ec3e90b7efc30ff6eb68d14050e7f1e800656d390505b135069f080c5cd91",
|
||||
url = "https://github.com/wpilibsuite/bzlmodRio-opencv/releases/download/2025.4.10.0-3.bcr5/bzlmodRio-opencv-2025.4.10.0-3.bcr5.tar.gz",
|
||||
)
|
||||
|
||||
load("@bzlmodrio-opencv//:maven_cpp_deps.bzl", "setup_legacy_bzlmodrio_opencv_cpp_dependencies")
|
||||
|
||||
setup_legacy_bzlmodrio_opencv_cpp_dependencies()
|
||||
|
||||
http_archive(
|
||||
name = "bzlmodrio-libssh",
|
||||
sha256 = "f8fef627c7b393f7f6ed638e12b80ff90b2cfea11488b15214f25ce1e470723a",
|
||||
url = "https://github.com/wpilibsuite/bzlmodRio-libssh/releases/download/2024.0.105-1.bcr1/bzlmodrio-libssh-2024.0.105-1.bcr1.tar.gz",
|
||||
)
|
||||
|
||||
load("@bzlmodrio-libssh//:maven_cpp_deps.bzl", "setup_legacy_bzlmodrio_libssh_cpp_dependencies")
|
||||
|
||||
setup_legacy_bzlmodrio_libssh_cpp_dependencies()
|
||||
|
||||
# Setup quickbuf compiler
|
||||
QUICKBUF_VERSION = "1.3.2"
|
||||
|
||||
http_file(
|
||||
name = "quickbuffer_protoc_linux",
|
||||
executable = True,
|
||||
sha256 = "f9a041bccaa7040db523666ef1b5fe9f6f94e70a82c88951f18f58aadd9c50b5",
|
||||
url = "https://repo1.maven.org/maven2/us/hebi/quickbuf/protoc-gen-quickbuf/" + QUICKBUF_VERSION + "/protoc-gen-quickbuf-" + QUICKBUF_VERSION + "-linux-x86_64.exe",
|
||||
)
|
||||
|
||||
http_file(
|
||||
name = "quickbuffer_protoc_osx_x86-64",
|
||||
executable = True,
|
||||
sha256 = "ea307c2b69664ae7e7c69db4cddf5803187e5a34bceffd09a21652f0f16044f7",
|
||||
url = "https://repo1.maven.org/maven2/us/hebi/quickbuf/protoc-gen-quickbuf/" + QUICKBUF_VERSION + "/protoc-gen-quickbuf-" + QUICKBUF_VERSION + "-osx-x86_64.exe ",
|
||||
)
|
||||
|
||||
http_file(
|
||||
name = "quickbuffer_protoc_osx_aarch64",
|
||||
executable = True,
|
||||
sha256 = "a9abdee09d8b5ef0aa954b238536917313511deec11e1901994af26ade033e28",
|
||||
url = "https://repo1.maven.org/maven2/us/hebi/quickbuf/protoc-gen-quickbuf/" + QUICKBUF_VERSION + "/protoc-gen-quickbuf-" + QUICKBUF_VERSION + "-osx-aarch_64.exe ",
|
||||
)
|
||||
|
||||
http_file(
|
||||
name = "quickbuffer_protoc_windows",
|
||||
executable = True,
|
||||
sha256 = "27dc1f29764a62b5e6a813a4bcd63e81bbdc3394da760a44acae1025b4a89f1d",
|
||||
url = "https://repo1.maven.org/maven2/us/hebi/quickbuf/protoc-gen-quickbuf/" + QUICKBUF_VERSION + "/protoc-gen-quickbuf-" + QUICKBUF_VERSION + "-windows-x86_64.exe ",
|
||||
)
|
||||
|
||||
# Setup rules_proto
|
||||
http_archive(
|
||||
name = "rules_proto",
|
||||
sha256 = "0e5c64a2599a6e26c6a03d6162242d231ecc0de219534c38cb4402171def21e8",
|
||||
strip_prefix = "rules_proto-7.0.2",
|
||||
url = "https://github.com/bazelbuild/rules_proto/releases/download/7.0.2/rules_proto-7.0.2.tar.gz",
|
||||
)
|
||||
|
||||
load("@rules_proto//proto:repositories.bzl", "rules_proto_dependencies")
|
||||
|
||||
rules_proto_dependencies()
|
||||
|
||||
load("@rules_proto//proto:setup.bzl", "rules_proto_setup")
|
||||
|
||||
rules_proto_setup()
|
||||
|
||||
load("@rules_pkg//:deps.bzl", "rules_pkg_dependencies")
|
||||
|
||||
rules_pkg_dependencies()
|
||||
|
||||
load("@rules_python_pytest//python_pytest:repositories.bzl", "rules_python_pytest_dependencies")
|
||||
|
||||
rules_python_pytest_dependencies()
|
||||
|
||||
# Capture the repository environmental variables which specify the filter list for what architectures to build in CI.
|
||||
load("//shared/bazel/rules:publishing_rule.bzl", "publishing_repo")
|
||||
|
||||
publishing_repo(
|
||||
name = "com_wpilib_allwpilib_publishing_config",
|
||||
)
|
||||
|
||||
load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace")
|
||||
|
||||
bazel_skylib_workspace()
|
||||
|
||||
load("@rules_doxygen//:extensions.bzl", "doxygen_repository")
|
||||
|
||||
# Download the os specific version 1.12.0 of doxygen supporting all the indicated platforms
|
||||
doxygen_repository(
|
||||
name = "doxygen",
|
||||
executables = [
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
],
|
||||
platforms = [
|
||||
"windows",
|
||||
"mac",
|
||||
"linux",
|
||||
],
|
||||
sha256s = [
|
||||
"07f1c92cbbb32816689c725539c0951f92c6371d3d7f66dfa3192cbe88dd3138",
|
||||
"6ace7dde967d41f4e293d034a67eb2c7edd61318491ee3131112173a77344001",
|
||||
"3c42c3f3fb206732b503862d9c9c11978920a8214f223a3950bbf2520be5f647",
|
||||
],
|
||||
versions = [
|
||||
"1.12.0",
|
||||
"1.12.0",
|
||||
"1.12.0",
|
||||
],
|
||||
)
|
||||
214
apriltag/BUILD.bazel
Normal file
214
apriltag/BUILD.bazel
Normal file
@@ -0,0 +1,214 @@
|
||||
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library", "cc_test")
|
||||
load("@rules_java//java:defs.bzl", "java_binary")
|
||||
load("@rules_pkg//:mappings.bzl", "pkg_files")
|
||||
load("@rules_python//python:defs.bzl", "py_binary")
|
||||
load("//shared/bazel/rules:cc_rules.bzl", "wpilib_cc_library", "wpilib_cc_shared_library", "wpilib_cc_static_library")
|
||||
load("//shared/bazel/rules:java_rules.bzl", "wpilib_java_junit5_test")
|
||||
load("//shared/bazel/rules:jni_rules.bzl", "wpilib_jni_cc_library", "wpilib_jni_java_library")
|
||||
load("//shared/bazel/rules:packaging.bzl", "package_minimal_jni_project")
|
||||
load("//shared/bazel/rules/gen:gen-resources.bzl", "generate_resources")
|
||||
|
||||
filegroup(
|
||||
name = "doxygen-files",
|
||||
srcs = glob([
|
||||
"src/main/native/include/**/*",
|
||||
"src/main/native/thirdparty/apriltag/include/**/*",
|
||||
]),
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
pkg_files(
|
||||
name = "thirdparty-apriltag-src-pkg",
|
||||
srcs = glob(["src/main/native/thirdparty/apriltag/include/**"]),
|
||||
strip_prefix = "src/main/native/thirdparty/apriltag/include",
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "thirdparty-apriltag",
|
||||
srcs = glob(["src/main/native/thirdparty/apriltag/src/**"]),
|
||||
hdrs = glob(["src/main/native/thirdparty/apriltag/include/**"]),
|
||||
copts = select({
|
||||
"@platforms//os:osx": [
|
||||
"-Wno-format-nonliteral",
|
||||
"-Wno-gnu-zero-variadic-macro-arguments",
|
||||
"-Wno-uninitialized",
|
||||
"-Wno-sign-compare",
|
||||
"-Wno-type-limits",
|
||||
],
|
||||
"@platforms//os:windows": [
|
||||
"/wd4005",
|
||||
"/wd4018",
|
||||
"/wd4244",
|
||||
"/wd4267",
|
||||
"/wd4996",
|
||||
],
|
||||
"@rules_bzlmodrio_toolchains//constraints/combined:is_linux": [
|
||||
"-Wno-format-nonliteral",
|
||||
"-Wno-maybe-uninitialized",
|
||||
"-Wno-sign-compare",
|
||||
"-Wno-type-limits",
|
||||
],
|
||||
}),
|
||||
includes = ["src/main/native/thirdparty/apriltag/include/common"],
|
||||
strip_include_prefix = "src/main/native/thirdparty/apriltag/include",
|
||||
)
|
||||
|
||||
generate_resources(
|
||||
name = "generate-resources",
|
||||
namespace = "frc",
|
||||
prefix = "APRILTAG",
|
||||
resource_files = glob(["src/main/native/resources/**"]),
|
||||
)
|
||||
|
||||
wpilib_cc_library(
|
||||
name = "apriltag",
|
||||
srcs = [":generate-resources"] + glob(
|
||||
["src/main/native/cpp/**"],
|
||||
exclude = ["src/main/native/cpp/jni/**"],
|
||||
),
|
||||
hdrs = glob(["src/main/native/include/**/*"]),
|
||||
extra_hdr_pkg_files = [":thirdparty-apriltag-src-pkg"],
|
||||
extra_src_pkg_files = [":apriltag-java-jni-hdrs-pkg"],
|
||||
local_defines = ["WPILIB_EXPORTS"],
|
||||
strip_include_prefix = "src/main/native/include",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
":thirdparty-apriltag",
|
||||
"//wpimath",
|
||||
"//wpiutil",
|
||||
],
|
||||
)
|
||||
|
||||
wpilib_cc_shared_library(
|
||||
name = "shared/apriltag",
|
||||
auto_export_windows_symbols = False,
|
||||
dynamic_deps = [
|
||||
"//wpimath:shared/wpimath",
|
||||
"//wpiutil:shared/wpiutil",
|
||||
],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
":apriltag",
|
||||
":thirdparty-apriltag",
|
||||
],
|
||||
)
|
||||
|
||||
wpilib_cc_static_library(
|
||||
name = "static/apriltag",
|
||||
static_deps = [
|
||||
"//wpimath:static/wpimath",
|
||||
"//wpiutil:static/wpiutil",
|
||||
],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
":apriltag",
|
||||
],
|
||||
)
|
||||
|
||||
wpilib_jni_cc_library(
|
||||
name = "apriltagjni",
|
||||
srcs = glob(["src/main/native/cpp/jni/**"]),
|
||||
java_dep = ":apriltag-java",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
":apriltag",
|
||||
],
|
||||
)
|
||||
|
||||
wpilib_cc_shared_library(
|
||||
name = "shared/apriltagjni",
|
||||
auto_export_windows_symbols = False,
|
||||
dynamic_deps = [
|
||||
":shared/apriltag",
|
||||
"//wpimath:shared/wpimath",
|
||||
"//wpiutil:shared/wpiutil",
|
||||
],
|
||||
use_debug_name = False,
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [":apriltagjni"],
|
||||
)
|
||||
|
||||
wpilib_jni_java_library(
|
||||
name = "apriltag-java",
|
||||
srcs = glob(["src/main/java/**/*.java"]),
|
||||
extra_source_pkgs = ["resources"],
|
||||
maven_artifact_name = "apriltag-java",
|
||||
maven_group_id = "edu.wpi.first.apriltag",
|
||||
native_libs = [":apriltagjni"],
|
||||
resource_strip_prefix = "apriltag/src/main/native/resources",
|
||||
resources = glob(["src/main/native/resources/**"]),
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//wpimath:wpimath-java",
|
||||
"//wpiutil:wpiutil-java",
|
||||
"@bzlmodrio-opencv//libraries/java/opencv",
|
||||
"@maven//:com_fasterxml_jackson_core_jackson_annotations",
|
||||
"@maven//:com_fasterxml_jackson_core_jackson_core",
|
||||
"@maven//:com_fasterxml_jackson_core_jackson_databind",
|
||||
],
|
||||
)
|
||||
|
||||
pkg_files(
|
||||
name = "resources",
|
||||
srcs = glob(["src/main/native/resources/**"]),
|
||||
strip_prefix = "src/main/native/resources/",
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "apriltag-cpp-test",
|
||||
size = "small",
|
||||
srcs = glob(["src/test/native/cpp/**"]),
|
||||
tags = [
|
||||
"no-asan",
|
||||
],
|
||||
deps = [
|
||||
":apriltag",
|
||||
"//thirdparty/googletest",
|
||||
],
|
||||
)
|
||||
|
||||
wpilib_java_junit5_test(
|
||||
name = "apriltag-java-test",
|
||||
srcs = glob(["src/test/java/**/*.java"]),
|
||||
resource_strip_prefix = "apriltag/src/test/resources",
|
||||
resources = glob(["src/test/resources/**"]),
|
||||
deps = [
|
||||
":apriltag-java",
|
||||
"//wpimath:wpimath-java",
|
||||
"//wpiutil:wpiutil-java",
|
||||
"@bzlmodrio-opencv//libraries/java/opencv",
|
||||
"@maven//:com_fasterxml_jackson_core_jackson_databind",
|
||||
],
|
||||
)
|
||||
|
||||
cc_binary(
|
||||
name = "DevMain-Cpp",
|
||||
srcs = ["src/dev/native/cpp/main.cpp"],
|
||||
deps = [
|
||||
":apriltag",
|
||||
],
|
||||
)
|
||||
|
||||
java_binary(
|
||||
name = "DevMain-Java",
|
||||
srcs = ["src/dev/java/edu/wpi/first/apriltag/DevMain.java"],
|
||||
main_class = "edu.wpi.first.apriltag.DevMain",
|
||||
deps = [
|
||||
":apriltag-java",
|
||||
],
|
||||
)
|
||||
|
||||
py_binary(
|
||||
name = "convert_apriltag_layouts",
|
||||
srcs = ["convert_apriltag_layouts.py"],
|
||||
target_compatible_with = select({
|
||||
"@rules_bzlmodrio_toolchains//constraints/is_systemcore:systemcore": ["@platforms//:incompatible"],
|
||||
"//conditions:default": [],
|
||||
}),
|
||||
)
|
||||
|
||||
package_minimal_jni_project(
|
||||
name = "apriltag",
|
||||
maven_artifact_name = "apriltag-cpp",
|
||||
maven_group_id = "edu.wpi.first.apriltag",
|
||||
)
|
||||
@@ -103,14 +103,8 @@ model {
|
||||
return
|
||||
}
|
||||
it.cppCompiler.define 'WPILIB_EXPORTS'
|
||||
|
||||
if (it.component.name == "${nativeName}JNI") {
|
||||
lib project: ':wpimath', library: 'wpimath', linkage: 'static'
|
||||
lib project: ':wpiutil', library: 'wpiutil', linkage: 'static'
|
||||
} else {
|
||||
lib project: ':wpimath', library: 'wpimath', linkage: 'shared'
|
||||
lib project: ':wpiutil', library: 'wpiutil', linkage: 'shared'
|
||||
}
|
||||
lib project: ':wpimath', library: 'wpimath', linkage: 'shared'
|
||||
lib project: ':wpiutil', library: 'wpiutil', linkage: 'shared'
|
||||
}
|
||||
}
|
||||
tasks {
|
||||
|
||||
@@ -7,10 +7,11 @@ AprilTagFields expects.
|
||||
|
||||
The input CSV has the following format:
|
||||
|
||||
* Columns: ID, X, Y, Z, Rotation
|
||||
* Columns: ID, X, Y, Z, Z Rotation, Y Rotation
|
||||
* ID is a positive integer
|
||||
* X, Y, and Z are decimal inches
|
||||
* Rotation is yaw in degrees
|
||||
* Z Rotation is yaw in degrees
|
||||
* Y Rotation is pitch in degrees
|
||||
|
||||
The values come from a table in the layout marking diagram (e.g.,
|
||||
https://firstfrc.blob.core.windows.net/frc2024/FieldAssets/2024LayoutMarkingDiagram.pdf).
|
||||
@@ -48,13 +49,14 @@ def main():
|
||||
x = float(row[1])
|
||||
y = float(row[2])
|
||||
z = float(row[3])
|
||||
rotation = float(row[4])
|
||||
zRotation = float(row[4])
|
||||
yRotation = float(row[5])
|
||||
|
||||
# Turn yaw into quaternion
|
||||
q = geometry.Rotation3d(
|
||||
units.radians(0.0),
|
||||
units.radians(0.0),
|
||||
units.degreesToRadians(rotation),
|
||||
units.radians(0),
|
||||
units.degreesToRadians(yRotation),
|
||||
units.degreesToRadians(zRotation),
|
||||
).getQuaternion()
|
||||
|
||||
json_data["tags"].append(
|
||||
|
||||
@@ -297,7 +297,7 @@ public class AprilTagDetector implements AutoCloseable {
|
||||
* @return Results (array of AprilTagDetection)
|
||||
*/
|
||||
public AprilTagDetection[] detect(Mat img) {
|
||||
return AprilTagJNI.detect(m_native, img.cols(), img.rows(), img.cols(), img.dataAddr());
|
||||
return AprilTagJNI.detect(m_native, img.cols(), img.rows(), (int) img.step1(), img.dataAddr());
|
||||
}
|
||||
|
||||
private long m_native;
|
||||
|
||||
@@ -152,9 +152,10 @@ public class AprilTagFieldLayout {
|
||||
var pose =
|
||||
switch (origin) {
|
||||
case kBlueAllianceWallRightSide -> Pose3d.kZero;
|
||||
case kRedAllianceWallRightSide -> new Pose3d(
|
||||
new Translation3d(m_fieldDimensions.fieldLength, m_fieldDimensions.fieldWidth, 0),
|
||||
new Rotation3d(0, 0, Math.PI));
|
||||
case kRedAllianceWallRightSide ->
|
||||
new Pose3d(
|
||||
new Translation3d(m_fieldDimensions.fieldLength, m_fieldDimensions.fieldWidth, 0),
|
||||
new Rotation3d(0, 0, Math.PI));
|
||||
};
|
||||
setOrigin(pose);
|
||||
}
|
||||
|
||||
@@ -13,13 +13,17 @@ public enum AprilTagFields {
|
||||
/** 2023 Charged Up. */
|
||||
k2023ChargedUp("2023-chargedup.json"),
|
||||
/** 2024 Crescendo. */
|
||||
k2024Crescendo("2024-crescendo.json");
|
||||
k2024Crescendo("2024-crescendo.json"),
|
||||
/** 2025 Reefscape Welded (see TU 12). */
|
||||
k2025ReefscapeWelded("2025-reefscape-welded.json"),
|
||||
/** 2025 Reefscape AndyMark (see TU 12). */
|
||||
k2025ReefscapeAndyMark("2025-reefscape-andymark.json");
|
||||
|
||||
/** Base resource directory. */
|
||||
public static final String kBaseResourceDir = "/edu/wpi/first/apriltag/";
|
||||
|
||||
/** Alias to the current game. */
|
||||
public static final AprilTagFields kDefaultField = k2024Crescendo;
|
||||
public static final AprilTagFields kDefaultField = k2025ReefscapeWelded;
|
||||
|
||||
/** Resource filename. */
|
||||
public final String m_resourceFile;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "frc/apriltag/AprilTagDetector.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <numbers>
|
||||
#include <utility>
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma warning(disable : 4200)
|
||||
@@ -130,7 +130,7 @@ void AprilTagDetector::RemoveFamily(std::string_view fam) {
|
||||
apriltag_detector_remove_family(
|
||||
static_cast<apriltag_detector_t*>(m_impl),
|
||||
static_cast<apriltag_family_t*>(it->second));
|
||||
DestroyFamily(it->getKey(), it->second);
|
||||
DestroyFamily(it->first, it->second);
|
||||
m_families.erase(it);
|
||||
}
|
||||
}
|
||||
@@ -158,7 +158,7 @@ void AprilTagDetector::Destroy() {
|
||||
|
||||
void AprilTagDetector::DestroyFamilies() {
|
||||
for (auto&& entry : m_families) {
|
||||
DestroyFamily(entry.getKey(), entry.second);
|
||||
DestroyFamily(entry.first, entry.second);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#include "frc/apriltag/AprilTagFieldLayout.h"
|
||||
|
||||
#include <system_error>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <units/angle.h>
|
||||
#include <units/length.h>
|
||||
@@ -131,6 +133,8 @@ namespace frc {
|
||||
std::string_view GetResource_2022_rapidreact_json();
|
||||
std::string_view GetResource_2023_chargedup_json();
|
||||
std::string_view GetResource_2024_crescendo_json();
|
||||
std::string_view GetResource_2025_reefscape_welded_json();
|
||||
std::string_view GetResource_2025_reefscape_andymark_json();
|
||||
|
||||
} // namespace frc
|
||||
|
||||
@@ -146,6 +150,12 @@ AprilTagFieldLayout AprilTagFieldLayout::LoadField(AprilTagField field) {
|
||||
case AprilTagField::k2024Crescendo:
|
||||
fieldString = GetResource_2024_crescendo_json();
|
||||
break;
|
||||
case AprilTagField::k2025ReefscapeWelded:
|
||||
fieldString = GetResource_2025_reefscape_welded_json();
|
||||
break;
|
||||
case AprilTagField::k2025ReefscapeAndyMark:
|
||||
fieldString = GetResource_2025_reefscape_andymark_json();
|
||||
break;
|
||||
case AprilTagField::kNumFields:
|
||||
throw std::invalid_argument("Invalid Field");
|
||||
}
|
||||
|
||||
@@ -20,6 +20,12 @@ enum class AprilTagField {
|
||||
k2023ChargedUp,
|
||||
/// 2024 Crescendo.
|
||||
k2024Crescendo,
|
||||
/// 2025 Reefscape AndyMark (see TU12).
|
||||
k2025ReefscapeAndyMark,
|
||||
/// 2025 Reefscape Welded (see TU12).
|
||||
k2025ReefscapeWelded,
|
||||
/// Alias to the current game.
|
||||
kDefaultField = k2025ReefscapeWelded,
|
||||
|
||||
// This is a placeholder for denoting the last supported field. This should
|
||||
// always be the last entry in the enum and should not be used by users
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
ID,X,Y,Z,Rotation
|
||||
1,593.68,9.68,53.38,120
|
||||
2,637.21,34.79,53.38,120
|
||||
3,652.73,196.17,57.13,180
|
||||
4,652.73,218.42,57.13,180
|
||||
5,578.77,323.00,53.38,270
|
||||
6,72.5,323.00,53.38,270
|
||||
7,-1.50,218.42,57.13,0
|
||||
8,-1.50,196.17,57.13,0
|
||||
9,14.02,34.79,53.38,60
|
||||
10,57.54,9.68,53.38,60
|
||||
11,468.69,146.19,52.00,300
|
||||
12,468.69,177.10,52.00,60
|
||||
13,441.74,161.62,52.00,180
|
||||
14,209.48,161.62,52.00,0
|
||||
15,182.73,177.10,52.00,120
|
||||
16,182.73,146.19,52.00,240
|
||||
|
@@ -0,0 +1,23 @@
|
||||
ID,X,Y,Z,Z-Rotation,X-Rotation
|
||||
1,656.98,24.73,58.5,126,0
|
||||
2,656.98,291.9,58.5,234,0
|
||||
3,452.4,316.21,51.25,270,0
|
||||
4,365.2,241.44,73.54,0,30
|
||||
5,365.2,75.19,73.54,0,30
|
||||
6,530.49,129.97,12.13,300,0
|
||||
7,546.87,158.3,12.13,0,0
|
||||
8,530.49,186.63,12.13,60,0
|
||||
9,497.77,186.63,12.13,120,0
|
||||
10,481.39,158.3,12.13,180,0
|
||||
11,497.77,129.97,12.13,240,0
|
||||
12,33.91,24.73,58.5,54,0
|
||||
13,33.91,291.9,58.5,306,0
|
||||
14,325.68,241.44,73.54,180,30
|
||||
15,325.68,75.19,73.54,180,30
|
||||
16,238.49,0.42,51.25,90,0
|
||||
17,160.39,129.97,12.13,240,0
|
||||
18,144,158.3,12.13,180,0
|
||||
19,160.39,186.63,12.13,120,0
|
||||
20,193.1,186.63,12.13,60,0
|
||||
21,209.49,158.3,12.13,0,0
|
||||
22,193.1,129.97,12.13,300,0
|
||||
|
@@ -0,0 +1,404 @@
|
||||
{
|
||||
"tags": [
|
||||
{
|
||||
"ID": 1,
|
||||
"pose": {
|
||||
"translation": {
|
||||
"x": 16.687292,
|
||||
"y": 0.628142,
|
||||
"z": 1.4859
|
||||
},
|
||||
"rotation": {
|
||||
"quaternion": {
|
||||
"W": 0.4539904997395468,
|
||||
"X": 0.0,
|
||||
"Y": 0.0,
|
||||
"Z": 0.8910065241883678
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": 2,
|
||||
"pose": {
|
||||
"translation": {
|
||||
"x": 16.687292,
|
||||
"y": 7.414259999999999,
|
||||
"z": 1.4859
|
||||
},
|
||||
"rotation": {
|
||||
"quaternion": {
|
||||
"W": -0.45399049973954675,
|
||||
"X": -0.0,
|
||||
"Y": 0.0,
|
||||
"Z": 0.8910065241883679
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": 3,
|
||||
"pose": {
|
||||
"translation": {
|
||||
"x": 11.49096,
|
||||
"y": 8.031733999999998,
|
||||
"z": 1.30175
|
||||
},
|
||||
"rotation": {
|
||||
"quaternion": {
|
||||
"W": -0.7071067811865475,
|
||||
"X": -0.0,
|
||||
"Y": 0.0,
|
||||
"Z": 0.7071067811865476
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": 4,
|
||||
"pose": {
|
||||
"translation": {
|
||||
"x": 9.276079999999999,
|
||||
"y": 6.132575999999999,
|
||||
"z": 1.8679160000000001
|
||||
},
|
||||
"rotation": {
|
||||
"quaternion": {
|
||||
"W": 0.9659258262890683,
|
||||
"X": 0.0,
|
||||
"Y": 0.25881904510252074,
|
||||
"Z": 0.0
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": 5,
|
||||
"pose": {
|
||||
"translation": {
|
||||
"x": 9.276079999999999,
|
||||
"y": 1.9098259999999998,
|
||||
"z": 1.8679160000000001
|
||||
},
|
||||
"rotation": {
|
||||
"quaternion": {
|
||||
"W": 0.9659258262890683,
|
||||
"X": 0.0,
|
||||
"Y": 0.25881904510252074,
|
||||
"Z": 0.0
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": 6,
|
||||
"pose": {
|
||||
"translation": {
|
||||
"x": 13.474446,
|
||||
"y": 3.3012379999999997,
|
||||
"z": 0.308102
|
||||
},
|
||||
"rotation": {
|
||||
"quaternion": {
|
||||
"W": -0.8660254037844387,
|
||||
"X": -0.0,
|
||||
"Y": 0.0,
|
||||
"Z": 0.49999999999999994
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": 7,
|
||||
"pose": {
|
||||
"translation": {
|
||||
"x": 13.890498,
|
||||
"y": 4.0208200000000005,
|
||||
"z": 0.308102
|
||||
},
|
||||
"rotation": {
|
||||
"quaternion": {
|
||||
"W": 1.0,
|
||||
"X": 0.0,
|
||||
"Y": 0.0,
|
||||
"Z": 0.0
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": 8,
|
||||
"pose": {
|
||||
"translation": {
|
||||
"x": 13.474446,
|
||||
"y": 4.740402,
|
||||
"z": 0.308102
|
||||
},
|
||||
"rotation": {
|
||||
"quaternion": {
|
||||
"W": 0.8660254037844387,
|
||||
"X": 0.0,
|
||||
"Y": 0.0,
|
||||
"Z": 0.49999999999999994
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": 9,
|
||||
"pose": {
|
||||
"translation": {
|
||||
"x": 12.643358,
|
||||
"y": 4.740402,
|
||||
"z": 0.308102
|
||||
},
|
||||
"rotation": {
|
||||
"quaternion": {
|
||||
"W": 0.5000000000000001,
|
||||
"X": 0.0,
|
||||
"Y": 0.0,
|
||||
"Z": 0.8660254037844386
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": 10,
|
||||
"pose": {
|
||||
"translation": {
|
||||
"x": 12.227305999999999,
|
||||
"y": 4.0208200000000005,
|
||||
"z": 0.308102
|
||||
},
|
||||
"rotation": {
|
||||
"quaternion": {
|
||||
"W": 6.123233995736766e-17,
|
||||
"X": 0.0,
|
||||
"Y": 0.0,
|
||||
"Z": 1.0
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": 11,
|
||||
"pose": {
|
||||
"translation": {
|
||||
"x": 12.643358,
|
||||
"y": 3.3012379999999997,
|
||||
"z": 0.308102
|
||||
},
|
||||
"rotation": {
|
||||
"quaternion": {
|
||||
"W": -0.4999999999999998,
|
||||
"X": -0.0,
|
||||
"Y": 0.0,
|
||||
"Z": 0.8660254037844387
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": 12,
|
||||
"pose": {
|
||||
"translation": {
|
||||
"x": 0.8613139999999999,
|
||||
"y": 0.628142,
|
||||
"z": 1.4859
|
||||
},
|
||||
"rotation": {
|
||||
"quaternion": {
|
||||
"W": 0.8910065241883679,
|
||||
"X": 0.0,
|
||||
"Y": 0.0,
|
||||
"Z": 0.45399049973954675
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": 13,
|
||||
"pose": {
|
||||
"translation": {
|
||||
"x": 0.8613139999999999,
|
||||
"y": 7.414259999999999,
|
||||
"z": 1.4859
|
||||
},
|
||||
"rotation": {
|
||||
"quaternion": {
|
||||
"W": -0.8910065241883678,
|
||||
"X": -0.0,
|
||||
"Y": 0.0,
|
||||
"Z": 0.45399049973954686
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": 14,
|
||||
"pose": {
|
||||
"translation": {
|
||||
"x": 8.272272,
|
||||
"y": 6.132575999999999,
|
||||
"z": 1.8679160000000001
|
||||
},
|
||||
"rotation": {
|
||||
"quaternion": {
|
||||
"W": 5.914589856893349e-17,
|
||||
"X": -0.25881904510252074,
|
||||
"Y": 1.5848095757158825e-17,
|
||||
"Z": 0.9659258262890683
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": 15,
|
||||
"pose": {
|
||||
"translation": {
|
||||
"x": 8.272272,
|
||||
"y": 1.9098259999999998,
|
||||
"z": 1.8679160000000001
|
||||
},
|
||||
"rotation": {
|
||||
"quaternion": {
|
||||
"W": 5.914589856893349e-17,
|
||||
"X": -0.25881904510252074,
|
||||
"Y": 1.5848095757158825e-17,
|
||||
"Z": 0.9659258262890683
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": 16,
|
||||
"pose": {
|
||||
"translation": {
|
||||
"x": 6.057646,
|
||||
"y": 0.010667999999999999,
|
||||
"z": 1.30175
|
||||
},
|
||||
"rotation": {
|
||||
"quaternion": {
|
||||
"W": 0.7071067811865476,
|
||||
"X": 0.0,
|
||||
"Y": 0.0,
|
||||
"Z": 0.7071067811865476
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": 17,
|
||||
"pose": {
|
||||
"translation": {
|
||||
"x": 4.073905999999999,
|
||||
"y": 3.3012379999999997,
|
||||
"z": 0.308102
|
||||
},
|
||||
"rotation": {
|
||||
"quaternion": {
|
||||
"W": -0.4999999999999998,
|
||||
"X": -0.0,
|
||||
"Y": 0.0,
|
||||
"Z": 0.8660254037844387
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": 18,
|
||||
"pose": {
|
||||
"translation": {
|
||||
"x": 3.6576,
|
||||
"y": 4.0208200000000005,
|
||||
"z": 0.308102
|
||||
},
|
||||
"rotation": {
|
||||
"quaternion": {
|
||||
"W": 6.123233995736766e-17,
|
||||
"X": 0.0,
|
||||
"Y": 0.0,
|
||||
"Z": 1.0
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": 19,
|
||||
"pose": {
|
||||
"translation": {
|
||||
"x": 4.073905999999999,
|
||||
"y": 4.740402,
|
||||
"z": 0.308102
|
||||
},
|
||||
"rotation": {
|
||||
"quaternion": {
|
||||
"W": 0.5000000000000001,
|
||||
"X": 0.0,
|
||||
"Y": 0.0,
|
||||
"Z": 0.8660254037844386
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": 20,
|
||||
"pose": {
|
||||
"translation": {
|
||||
"x": 4.904739999999999,
|
||||
"y": 4.740402,
|
||||
"z": 0.308102
|
||||
},
|
||||
"rotation": {
|
||||
"quaternion": {
|
||||
"W": 0.8660254037844387,
|
||||
"X": 0.0,
|
||||
"Y": 0.0,
|
||||
"Z": 0.49999999999999994
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": 21,
|
||||
"pose": {
|
||||
"translation": {
|
||||
"x": 5.321046,
|
||||
"y": 4.0208200000000005,
|
||||
"z": 0.308102
|
||||
},
|
||||
"rotation": {
|
||||
"quaternion": {
|
||||
"W": 1.0,
|
||||
"X": 0.0,
|
||||
"Y": 0.0,
|
||||
"Z": 0.0
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": 22,
|
||||
"pose": {
|
||||
"translation": {
|
||||
"x": 4.904739999999999,
|
||||
"y": 3.3012379999999997,
|
||||
"z": 0.308102
|
||||
},
|
||||
"rotation": {
|
||||
"quaternion": {
|
||||
"W": -0.8660254037844387,
|
||||
"X": -0.0,
|
||||
"Y": 0.0,
|
||||
"Z": 0.49999999999999994
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"field": {
|
||||
"length": 17.548,
|
||||
"width": 8.042
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
ID,X,Y,Z,Z-Rotation,X-Rotation
|
||||
1,657.37,25.8,58.5,126,0
|
||||
2,657.37,291.2,58.5,234,0
|
||||
3,455.15,317.15,51.25,270,0
|
||||
4,365.2,241.64,73.54,0,30
|
||||
5,365.2,75.39,73.54,0,30
|
||||
6,530.49,130.17,12.13,300,0
|
||||
7,546.87,158.5,12.13,0,0
|
||||
8,530.49,186.83,12.13,60,0
|
||||
9,497.77,186.83,12.13,120,0
|
||||
10,481.39,158.5,12.13,180,0
|
||||
11,497.77,130.17,12.13,240,0
|
||||
12,33.51,25.8,58.5,54,0
|
||||
13,33.51,291.2,58.5,306,0
|
||||
14,325.68,241.64,73.54,180,30
|
||||
15,325.68,75.39,73.54,180,30
|
||||
16,235.73,-0.15,51.25,90,0
|
||||
17,160.39,130.17,12.13,240,0
|
||||
18,144,158.5,12.13,180,0
|
||||
19,160.39,186.83,12.13,120,0
|
||||
20,193.1,186.83,12.13,60,0
|
||||
21,209.49,158.5,12.13,0,0
|
||||
22,193.1,130.17,12.13,300,0
|
||||
|
@@ -0,0 +1,404 @@
|
||||
{
|
||||
"tags": [
|
||||
{
|
||||
"ID": 1,
|
||||
"pose": {
|
||||
"translation": {
|
||||
"x": 16.697198,
|
||||
"y": 0.65532,
|
||||
"z": 1.4859
|
||||
},
|
||||
"rotation": {
|
||||
"quaternion": {
|
||||
"W": 0.4539904997395468,
|
||||
"X": 0.0,
|
||||
"Y": 0.0,
|
||||
"Z": 0.8910065241883678
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": 2,
|
||||
"pose": {
|
||||
"translation": {
|
||||
"x": 16.697198,
|
||||
"y": 7.3964799999999995,
|
||||
"z": 1.4859
|
||||
},
|
||||
"rotation": {
|
||||
"quaternion": {
|
||||
"W": -0.45399049973954675,
|
||||
"X": -0.0,
|
||||
"Y": 0.0,
|
||||
"Z": 0.8910065241883679
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": 3,
|
||||
"pose": {
|
||||
"translation": {
|
||||
"x": 11.560809999999998,
|
||||
"y": 8.05561,
|
||||
"z": 1.30175
|
||||
},
|
||||
"rotation": {
|
||||
"quaternion": {
|
||||
"W": -0.7071067811865475,
|
||||
"X": -0.0,
|
||||
"Y": 0.0,
|
||||
"Z": 0.7071067811865476
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": 4,
|
||||
"pose": {
|
||||
"translation": {
|
||||
"x": 9.276079999999999,
|
||||
"y": 6.137656,
|
||||
"z": 1.8679160000000001
|
||||
},
|
||||
"rotation": {
|
||||
"quaternion": {
|
||||
"W": 0.9659258262890683,
|
||||
"X": 0.0,
|
||||
"Y": 0.25881904510252074,
|
||||
"Z": 0.0
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": 5,
|
||||
"pose": {
|
||||
"translation": {
|
||||
"x": 9.276079999999999,
|
||||
"y": 1.914906,
|
||||
"z": 1.8679160000000001
|
||||
},
|
||||
"rotation": {
|
||||
"quaternion": {
|
||||
"W": 0.9659258262890683,
|
||||
"X": 0.0,
|
||||
"Y": 0.25881904510252074,
|
||||
"Z": 0.0
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": 6,
|
||||
"pose": {
|
||||
"translation": {
|
||||
"x": 13.474446,
|
||||
"y": 3.3063179999999996,
|
||||
"z": 0.308102
|
||||
},
|
||||
"rotation": {
|
||||
"quaternion": {
|
||||
"W": -0.8660254037844387,
|
||||
"X": -0.0,
|
||||
"Y": 0.0,
|
||||
"Z": 0.49999999999999994
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": 7,
|
||||
"pose": {
|
||||
"translation": {
|
||||
"x": 13.890498,
|
||||
"y": 4.0259,
|
||||
"z": 0.308102
|
||||
},
|
||||
"rotation": {
|
||||
"quaternion": {
|
||||
"W": 1.0,
|
||||
"X": 0.0,
|
||||
"Y": 0.0,
|
||||
"Z": 0.0
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": 8,
|
||||
"pose": {
|
||||
"translation": {
|
||||
"x": 13.474446,
|
||||
"y": 4.745482,
|
||||
"z": 0.308102
|
||||
},
|
||||
"rotation": {
|
||||
"quaternion": {
|
||||
"W": 0.8660254037844387,
|
||||
"X": 0.0,
|
||||
"Y": 0.0,
|
||||
"Z": 0.49999999999999994
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": 9,
|
||||
"pose": {
|
||||
"translation": {
|
||||
"x": 12.643358,
|
||||
"y": 4.745482,
|
||||
"z": 0.308102
|
||||
},
|
||||
"rotation": {
|
||||
"quaternion": {
|
||||
"W": 0.5000000000000001,
|
||||
"X": 0.0,
|
||||
"Y": 0.0,
|
||||
"Z": 0.8660254037844386
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": 10,
|
||||
"pose": {
|
||||
"translation": {
|
||||
"x": 12.227305999999999,
|
||||
"y": 4.0259,
|
||||
"z": 0.308102
|
||||
},
|
||||
"rotation": {
|
||||
"quaternion": {
|
||||
"W": 6.123233995736766e-17,
|
||||
"X": 0.0,
|
||||
"Y": 0.0,
|
||||
"Z": 1.0
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": 11,
|
||||
"pose": {
|
||||
"translation": {
|
||||
"x": 12.643358,
|
||||
"y": 3.3063179999999996,
|
||||
"z": 0.308102
|
||||
},
|
||||
"rotation": {
|
||||
"quaternion": {
|
||||
"W": -0.4999999999999998,
|
||||
"X": -0.0,
|
||||
"Y": 0.0,
|
||||
"Z": 0.8660254037844387
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": 12,
|
||||
"pose": {
|
||||
"translation": {
|
||||
"x": 0.851154,
|
||||
"y": 0.65532,
|
||||
"z": 1.4859
|
||||
},
|
||||
"rotation": {
|
||||
"quaternion": {
|
||||
"W": 0.8910065241883679,
|
||||
"X": 0.0,
|
||||
"Y": 0.0,
|
||||
"Z": 0.45399049973954675
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": 13,
|
||||
"pose": {
|
||||
"translation": {
|
||||
"x": 0.851154,
|
||||
"y": 7.3964799999999995,
|
||||
"z": 1.4859
|
||||
},
|
||||
"rotation": {
|
||||
"quaternion": {
|
||||
"W": -0.8910065241883678,
|
||||
"X": -0.0,
|
||||
"Y": 0.0,
|
||||
"Z": 0.45399049973954686
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": 14,
|
||||
"pose": {
|
||||
"translation": {
|
||||
"x": 8.272272,
|
||||
"y": 6.137656,
|
||||
"z": 1.8679160000000001
|
||||
},
|
||||
"rotation": {
|
||||
"quaternion": {
|
||||
"W": 5.914589856893349e-17,
|
||||
"X": -0.25881904510252074,
|
||||
"Y": 1.5848095757158825e-17,
|
||||
"Z": 0.9659258262890683
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": 15,
|
||||
"pose": {
|
||||
"translation": {
|
||||
"x": 8.272272,
|
||||
"y": 1.914906,
|
||||
"z": 1.8679160000000001
|
||||
},
|
||||
"rotation": {
|
||||
"quaternion": {
|
||||
"W": 5.914589856893349e-17,
|
||||
"X": -0.25881904510252074,
|
||||
"Y": 1.5848095757158825e-17,
|
||||
"Z": 0.9659258262890683
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": 16,
|
||||
"pose": {
|
||||
"translation": {
|
||||
"x": 5.9875419999999995,
|
||||
"y": -0.0038099999999999996,
|
||||
"z": 1.30175
|
||||
},
|
||||
"rotation": {
|
||||
"quaternion": {
|
||||
"W": 0.7071067811865476,
|
||||
"X": 0.0,
|
||||
"Y": 0.0,
|
||||
"Z": 0.7071067811865476
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": 17,
|
||||
"pose": {
|
||||
"translation": {
|
||||
"x": 4.073905999999999,
|
||||
"y": 3.3063179999999996,
|
||||
"z": 0.308102
|
||||
},
|
||||
"rotation": {
|
||||
"quaternion": {
|
||||
"W": -0.4999999999999998,
|
||||
"X": -0.0,
|
||||
"Y": 0.0,
|
||||
"Z": 0.8660254037844387
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": 18,
|
||||
"pose": {
|
||||
"translation": {
|
||||
"x": 3.6576,
|
||||
"y": 4.0259,
|
||||
"z": 0.308102
|
||||
},
|
||||
"rotation": {
|
||||
"quaternion": {
|
||||
"W": 6.123233995736766e-17,
|
||||
"X": 0.0,
|
||||
"Y": 0.0,
|
||||
"Z": 1.0
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": 19,
|
||||
"pose": {
|
||||
"translation": {
|
||||
"x": 4.073905999999999,
|
||||
"y": 4.745482,
|
||||
"z": 0.308102
|
||||
},
|
||||
"rotation": {
|
||||
"quaternion": {
|
||||
"W": 0.5000000000000001,
|
||||
"X": 0.0,
|
||||
"Y": 0.0,
|
||||
"Z": 0.8660254037844386
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": 20,
|
||||
"pose": {
|
||||
"translation": {
|
||||
"x": 4.904739999999999,
|
||||
"y": 4.745482,
|
||||
"z": 0.308102
|
||||
},
|
||||
"rotation": {
|
||||
"quaternion": {
|
||||
"W": 0.8660254037844387,
|
||||
"X": 0.0,
|
||||
"Y": 0.0,
|
||||
"Z": 0.49999999999999994
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": 21,
|
||||
"pose": {
|
||||
"translation": {
|
||||
"x": 5.321046,
|
||||
"y": 4.0259,
|
||||
"z": 0.308102
|
||||
},
|
||||
"rotation": {
|
||||
"quaternion": {
|
||||
"W": 1.0,
|
||||
"X": 0.0,
|
||||
"Y": 0.0,
|
||||
"Z": 0.0
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"ID": 22,
|
||||
"pose": {
|
||||
"translation": {
|
||||
"x": 4.904739999999999,
|
||||
"y": 3.3063179999999996,
|
||||
"z": 0.308102
|
||||
},
|
||||
"rotation": {
|
||||
"quaternion": {
|
||||
"W": -0.8660254037844387,
|
||||
"X": -0.0,
|
||||
"Y": 0.0,
|
||||
"Z": 0.49999999999999994
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"field": {
|
||||
"length": 17.548,
|
||||
"width": 8.052
|
||||
}
|
||||
}
|
||||
4
apriltag/src/main/python/README.md
Normal file
4
apriltag/src/main/python/README.md
Normal file
@@ -0,0 +1,4 @@
|
||||
robotpy-apriltag
|
||||
================
|
||||
|
||||
RobotPy wrappers around WPILib's version of the apriltag library.
|
||||
41
apriltag/src/main/python/native-pyproject.toml
Normal file
41
apriltag/src/main/python/native-pyproject.toml
Normal file
@@ -0,0 +1,41 @@
|
||||
[build-system]
|
||||
build-backend = "hatchling.build"
|
||||
requires = [
|
||||
"hatchling",
|
||||
"hatch-nativelib~=0.2.0",
|
||||
"hatch-robotpy~=0.2.1",
|
||||
"robotpy-native-wpiutil==2027.0.0a2",
|
||||
"robotpy-native-wpimath==2027.0.0a2",
|
||||
]
|
||||
|
||||
[project]
|
||||
name = "robotpy-native-apriltag"
|
||||
version = "2027.0.0a2"
|
||||
description = "WPILib AprilTag Library"
|
||||
license = "BSD-3-Clause"
|
||||
|
||||
dependencies = [
|
||||
"robotpy-native-wpiutil==2027.0.0a2",
|
||||
"robotpy-native-wpimath==2027.0.0a2",
|
||||
]
|
||||
|
||||
[tool.hatch.build.targets.wheel]
|
||||
packages = ["src/native"]
|
||||
|
||||
[[tool.hatch.build.hooks.robotpy.maven_lib_download]]
|
||||
artifact_id = "apriltag-cpp"
|
||||
group_id = "edu.wpi.first.apriltag"
|
||||
repo_url = "https://frcmaven.wpi.edu/artifactory/release-2027"
|
||||
version = "2027.0.0-alpha-2"
|
||||
|
||||
extract_to = "src/native/apriltag"
|
||||
libs = ["apriltag"]
|
||||
|
||||
[[tool.hatch.build.hooks.nativelib.pcfile]]
|
||||
pcfile = "src/native/apriltag/robotpy-native-apriltag.pc"
|
||||
name = "apriltag"
|
||||
|
||||
includedir = "src/native/apriltag/include"
|
||||
libdir = "src/native/apriltag/lib"
|
||||
shared_libraries = ["apriltag"]
|
||||
requires = ["robotpy-native-wpiutil", "robotpy-native-wpimath"]
|
||||
74
apriltag/src/main/python/pyproject.toml
Normal file
74
apriltag/src/main/python/pyproject.toml
Normal file
@@ -0,0 +1,74 @@
|
||||
[build-system]
|
||||
build-backend = "hatchling.build"
|
||||
requires = [
|
||||
"semiwrap~=0.1.7",
|
||||
"hatch-meson~=0.1.0b2",
|
||||
"hatch-robotpy~=0.2.1",
|
||||
"hatchling",
|
||||
"robotpy-native-apriltag==2027.0.0a2",
|
||||
"robotpy-wpiutil==2027.0.0a2",
|
||||
"robotpy-wpimath==2027.0.0a2",
|
||||
]
|
||||
|
||||
[project]
|
||||
name = "robotpy-apriltag"
|
||||
version = "2027.0.0a2"
|
||||
description = "RobotPy bindings for WPILib's AprilTag library"
|
||||
authors = [
|
||||
{name = "RobotPy Development Team", email = "robotpy@googlegroups.com"},
|
||||
]
|
||||
license = "BSD-3-Clause"
|
||||
dependencies = [
|
||||
"robotpy-native-apriltag==2027.0.0a2",
|
||||
"robotpy-wpiutil==2027.0.0a2",
|
||||
"robotpy-wpimath==2027.0.0a2",
|
||||
]
|
||||
|
||||
[project.urls]
|
||||
"Source code" = "https://github.com/robotpy/mostrobotpy"
|
||||
|
||||
|
||||
[tool.hatch.build.hooks.robotpy]
|
||||
version_file = "robotpy_apriltag/version.py"
|
||||
|
||||
[tool.hatch.build.hooks.semiwrap]
|
||||
|
||||
[tool.hatch.build.hooks.meson]
|
||||
|
||||
[tool.hatch.build.targets.wheel]
|
||||
packages = ["robotpy_apriltag"]
|
||||
|
||||
|
||||
[tool.semiwrap]
|
||||
update_init = [
|
||||
"robotpy_apriltag robotpy_apriltag._apriltag"
|
||||
]
|
||||
scan_headers_ignore = [
|
||||
"common/*",
|
||||
"test/*",
|
||||
|
||||
"apriltag.h",
|
||||
"apriltag_math.h",
|
||||
"apriltag_pose.h",
|
||||
|
||||
"frc/apriltag/AprilTagDetector_cv.h",
|
||||
|
||||
"tag16h5.h",
|
||||
"tag36h11.h",
|
||||
]
|
||||
|
||||
[tool.semiwrap.extension_modules."robotpy_apriltag._apriltag"]
|
||||
name = "apriltag"
|
||||
wraps = ["robotpy-native-apriltag"]
|
||||
depends = ["wpiutil", "wpimath"]
|
||||
|
||||
[tool.semiwrap.extension_modules."robotpy_apriltag._apriltag".headers]
|
||||
# frc/apriltag
|
||||
AprilTag = "frc/apriltag/AprilTag.h"
|
||||
AprilTagDetection = "frc/apriltag/AprilTagDetection.h"
|
||||
AprilTagDetector = "frc/apriltag/AprilTagDetector.h"
|
||||
# AprilTagDetector_cv = "frc/apriltag/AprilTagDetector_cv.h"
|
||||
AprilTagFieldLayout = "frc/apriltag/AprilTagFieldLayout.h"
|
||||
AprilTagFields = "frc/apriltag/AprilTagFields.h"
|
||||
AprilTagPoseEstimate = "frc/apriltag/AprilTagPoseEstimate.h"
|
||||
AprilTagPoseEstimator = "frc/apriltag/AprilTagPoseEstimator.h"
|
||||
22
apriltag/src/main/python/robotpy_apriltag/__init__.py
Normal file
22
apriltag/src/main/python/robotpy_apriltag/__init__.py
Normal file
@@ -0,0 +1,22 @@
|
||||
from . import _init__apriltag
|
||||
|
||||
# autogenerated by 'semiwrap create-imports robotpy_apriltag robotpy_apriltag._apriltag'
|
||||
from ._apriltag import (
|
||||
AprilTag,
|
||||
AprilTagDetection,
|
||||
AprilTagDetector,
|
||||
AprilTagField,
|
||||
AprilTagFieldLayout,
|
||||
AprilTagPoseEstimate,
|
||||
AprilTagPoseEstimator,
|
||||
)
|
||||
|
||||
__all__ = [
|
||||
"AprilTag",
|
||||
"AprilTagDetection",
|
||||
"AprilTagDetector",
|
||||
"AprilTagField",
|
||||
"AprilTagFieldLayout",
|
||||
"AprilTagPoseEstimate",
|
||||
"AprilTagPoseEstimator",
|
||||
]
|
||||
0
apriltag/src/main/python/robotpy_apriltag/py.typed
Normal file
0
apriltag/src/main/python/robotpy_apriltag/py.typed
Normal file
4
apriltag/src/main/python/robotpy_apriltag/src/main.cpp
Normal file
4
apriltag/src/main/python/robotpy_apriltag/src/main.cpp
Normal file
@@ -0,0 +1,4 @@
|
||||
|
||||
#include "semiwrap_init.robotpy_apriltag._apriltag.hpp"
|
||||
|
||||
SEMIWRAP_PYBIND11_MODULE(m) { initWrapper(m); }
|
||||
16
apriltag/src/main/python/semiwrap/AprilTag.yml
Normal file
16
apriltag/src/main/python/semiwrap/AprilTag.yml
Normal file
@@ -0,0 +1,16 @@
|
||||
functions:
|
||||
to_json:
|
||||
ignore: true
|
||||
from_json:
|
||||
ignore: true
|
||||
classes:
|
||||
frc::AprilTag:
|
||||
attributes:
|
||||
ID:
|
||||
pose:
|
||||
methods:
|
||||
Generate36h11AprilTagImage:
|
||||
ignore: true
|
||||
Generate16h5AprilTagImage:
|
||||
ignore: true
|
||||
operator==:
|
||||
43
apriltag/src/main/python/semiwrap/AprilTagDetection.yml
Normal file
43
apriltag/src/main/python/semiwrap/AprilTagDetection.yml
Normal file
@@ -0,0 +1,43 @@
|
||||
extra_includes:
|
||||
- pybind11/eigen.h
|
||||
|
||||
classes:
|
||||
frc::AprilTagDetection:
|
||||
methods:
|
||||
GetFamily:
|
||||
GetId:
|
||||
GetHamming:
|
||||
GetDecisionMargin:
|
||||
GetHomography:
|
||||
GetHomographyMatrix:
|
||||
GetCenter:
|
||||
GetCorner:
|
||||
GetCorners:
|
||||
inline_code: |
|
||||
.def("__repr__", [](const AprilTagDetection &self) {
|
||||
return py::str("<AprilTagDetection tag_family={} tag_id={} hamming={} decision_margin={} center={}>")
|
||||
.format(self.GetFamily(), self.GetId(), self.GetHamming(), self.GetDecisionMargin(), self.GetCenter());
|
||||
})
|
||||
frc::AprilTagDetection::Point:
|
||||
attributes:
|
||||
x:
|
||||
y:
|
||||
inline_code: |
|
||||
.def(py::init([](double x, double y) {
|
||||
AprilTagDetection::Point pt{x, y};
|
||||
return std::make_unique<AprilTagDetection::Point>(std::move(pt));
|
||||
}), py::arg("x"), py::arg("y"))
|
||||
.def("__len__", [](const AprilTagDetection::Point &self) { return 2; })
|
||||
.def("__getitem__", [](const AprilTagDetection::Point &self, int index) {
|
||||
switch (index) {
|
||||
case 0:
|
||||
return self.x;
|
||||
case 1:
|
||||
return self.y;
|
||||
default:
|
||||
throw std::out_of_range("AprilTagDetection.Point index out of range");
|
||||
}
|
||||
})
|
||||
.def("__repr__", [](const AprilTagDetection::Point &self) {
|
||||
return py::str("AprilTagDetection.Point(x={}, y={})").format(self.x, self.y);
|
||||
})
|
||||
99
apriltag/src/main/python/semiwrap/AprilTagDetector.yml
Normal file
99
apriltag/src/main/python/semiwrap/AprilTagDetector.yml
Normal file
@@ -0,0 +1,99 @@
|
||||
extra_includes:
|
||||
- pybind11_typing.h
|
||||
|
||||
classes:
|
||||
frc::AprilTagDetector:
|
||||
methods:
|
||||
AprilTagDetector:
|
||||
SetConfig:
|
||||
GetConfig:
|
||||
SetQuadThresholdParameters:
|
||||
GetQuadThresholdParameters:
|
||||
AddFamily:
|
||||
RemoveFamily:
|
||||
ClearFamilies:
|
||||
Detect:
|
||||
overloads:
|
||||
int, int, int, uint8_t*:
|
||||
ignore: true
|
||||
int, int, uint8_t*:
|
||||
ignore: true
|
||||
inline_code: |
|
||||
.def("detect", [](AprilTagDetector *self, py::buffer img) {
|
||||
|
||||
// validate the input image buffer
|
||||
auto buf = img.request();
|
||||
if (buf.ndim != 2) {
|
||||
throw py::value_error("buffer must only have two dimensions");
|
||||
} else if (buf.itemsize != 1) {
|
||||
throw py::value_error("buffer elements must be bytes");
|
||||
}
|
||||
|
||||
// We are going to move the detection result into this shared_ptr
|
||||
// so that python can keep it alive. We don't expose the result directly
|
||||
// to the user because we'd have to pretend it's a list, and that would
|
||||
// be annoying.
|
||||
std::shared_ptr<AprilTagDetector::Results> c_result;
|
||||
{
|
||||
py::gil_scoped_release unlock;
|
||||
c_result = std::make_shared<AprilTagDetector::Results>(std::move(self->Detect(buf.shape[1], buf.shape[0], (uint8_t*)buf.ptr)));
|
||||
}
|
||||
|
||||
// This tells python about the shared_ptr, and it'll keep it alive as
|
||||
// long as the python reference is alive. When we call get(), we marked
|
||||
// the return value as reference_internal so python will keep the python
|
||||
// reference for the results object alive for as long as all of its
|
||||
// results that we put into the list are alive
|
||||
py::object py_result = py::cast(c_result);
|
||||
auto len = c_result->size();
|
||||
auto get = py_result.attr("get");
|
||||
py::typing::List<AprilTagDetection> l(len);
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
l[i] = get(i);
|
||||
}
|
||||
return l;
|
||||
}, py::arg("image"),
|
||||
R"doc(
|
||||
Detect tags from an 8-bit grayscale image with shape (height, width)
|
||||
|
||||
:return: list of results
|
||||
)doc"
|
||||
)
|
||||
frc::AprilTagDetector::Config:
|
||||
attributes:
|
||||
numThreads:
|
||||
quadDecimate:
|
||||
quadSigma:
|
||||
refineEdges:
|
||||
decodeSharpening:
|
||||
debug:
|
||||
methods:
|
||||
operator==:
|
||||
frc::AprilTagDetector::QuadThresholdParameters:
|
||||
attributes:
|
||||
minClusterPixels:
|
||||
maxNumMaxima:
|
||||
criticalAngle:
|
||||
maxLineFitMSE:
|
||||
minWhiteBlackDiff:
|
||||
deglitch:
|
||||
methods:
|
||||
operator==:
|
||||
frc::AprilTagDetector::Results:
|
||||
rename: _Results
|
||||
ignored_bases:
|
||||
- std::span<const AprilTagDetection* const>
|
||||
force_no_trampoline: true
|
||||
methods:
|
||||
Results:
|
||||
overloads:
|
||||
'':
|
||||
ignore: true
|
||||
void*, const private_init&:
|
||||
ignore: true
|
||||
inline_code: |
|
||||
// use the keepalive to keep the array of results around until
|
||||
// the user deletes them
|
||||
.def("get", [](const AprilTagDetector::Results &self, int i) {
|
||||
return self[i];
|
||||
}, py::return_value_policy::reference_internal)
|
||||
29
apriltag/src/main/python/semiwrap/AprilTagFieldLayout.yml
Normal file
29
apriltag/src/main/python/semiwrap/AprilTagFieldLayout.yml
Normal file
@@ -0,0 +1,29 @@
|
||||
functions:
|
||||
to_json:
|
||||
ignore: true
|
||||
from_json:
|
||||
ignore: true
|
||||
LoadAprilTagLayoutField:
|
||||
ignore: true
|
||||
classes:
|
||||
frc::AprilTagFieldLayout:
|
||||
enums:
|
||||
OriginPosition:
|
||||
methods:
|
||||
AprilTagFieldLayout:
|
||||
overloads:
|
||||
'':
|
||||
std::string_view:
|
||||
std::vector<AprilTag>, units::meter_t, units::meter_t:
|
||||
LoadField:
|
||||
GetFieldLength:
|
||||
GetFieldWidth:
|
||||
GetTags:
|
||||
SetOrigin:
|
||||
overloads:
|
||||
OriginPosition:
|
||||
const Pose3d&:
|
||||
GetOrigin:
|
||||
GetTagPose:
|
||||
Serialize:
|
||||
operator==:
|
||||
2
apriltag/src/main/python/semiwrap/AprilTagFields.yml
Normal file
2
apriltag/src/main/python/semiwrap/AprilTagFields.yml
Normal file
@@ -0,0 +1,2 @@
|
||||
enums:
|
||||
AprilTagField:
|
||||
@@ -0,0 +1,9 @@
|
||||
classes:
|
||||
frc::AprilTagPoseEstimate:
|
||||
attributes:
|
||||
pose1:
|
||||
pose2:
|
||||
error1:
|
||||
error2:
|
||||
methods:
|
||||
GetAmbiguity:
|
||||
36
apriltag/src/main/python/semiwrap/AprilTagPoseEstimator.yml
Normal file
36
apriltag/src/main/python/semiwrap/AprilTagPoseEstimator.yml
Normal file
@@ -0,0 +1,36 @@
|
||||
extra_includes:
|
||||
- frc/apriltag/AprilTagDetection.h
|
||||
|
||||
classes:
|
||||
frc::AprilTagPoseEstimator:
|
||||
methods:
|
||||
AprilTagPoseEstimator:
|
||||
SetConfig:
|
||||
GetConfig:
|
||||
EstimateHomography:
|
||||
overloads:
|
||||
const AprilTagDetection& [const]:
|
||||
std::span<const double, 9> [const]:
|
||||
EstimateOrthogonalIteration:
|
||||
overloads:
|
||||
const AprilTagDetection&, int [const]:
|
||||
std::span<const double, 9>, std::span<const double, 8>, int [const]:
|
||||
Estimate:
|
||||
overloads:
|
||||
const AprilTagDetection& [const]:
|
||||
std::span<const double, 9>, std::span<const double, 8> [const]:
|
||||
frc::AprilTagPoseEstimator::Config:
|
||||
force_no_default_constructor: true
|
||||
attributes:
|
||||
tagSize:
|
||||
fx:
|
||||
fy:
|
||||
cx:
|
||||
cy:
|
||||
methods:
|
||||
operator==:
|
||||
inline_code: |
|
||||
.def(py::init([](units::meter_t tagSize, double fx, double fy, double cx, double cy) {
|
||||
AprilTagPoseEstimator::Config cfg{tagSize, fx, fy, cx, cy};
|
||||
return std::make_unique<AprilTagPoseEstimator::Config>(std::move(cfg));
|
||||
}), py::arg("tagSize"), py::arg("fx"), py::arg("fy"), py::arg("cx"), py::arg("cy"))
|
||||
@@ -24,7 +24,6 @@ import org.opencv.core.Mat;
|
||||
import org.opencv.imgcodecs.Imgcodecs;
|
||||
import org.opencv.imgproc.Imgproc;
|
||||
|
||||
@SuppressWarnings("PMD.MutableStaticState")
|
||||
class AprilTagDetectorTest {
|
||||
@SuppressWarnings("MemberName")
|
||||
AprilTagDetector detector;
|
||||
@@ -131,6 +130,34 @@ class AprilTagDetectorTest {
|
||||
return image;
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDecodeCropped() {
|
||||
detector.addFamily("tag16h5");
|
||||
detector.addFamily("tag36h11");
|
||||
|
||||
Mat image;
|
||||
try {
|
||||
image = loadImage("tag1_640_480.jpg");
|
||||
} catch (IOException ex) {
|
||||
fail(ex);
|
||||
return;
|
||||
}
|
||||
|
||||
// Pre-knowledge -- the tag is within this ROI of this particular test image
|
||||
var cropped = image.submat(100, 400, 220, 570);
|
||||
|
||||
try {
|
||||
AprilTagDetection[] results = detector.detect(cropped);
|
||||
assertEquals(1, results.length);
|
||||
assertEquals("tag36h11", results[0].getFamily());
|
||||
assertEquals(1, results[0].getId());
|
||||
assertEquals(0, results[0].getHamming());
|
||||
} finally {
|
||||
cropped.release();
|
||||
image.release();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDecodeAndPose() {
|
||||
detector.addFamily("tag16h5");
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "frc/apriltag/AprilTagFieldLayout.h"
|
||||
|
||||
BIN
apriltag/src/test/python/tag1_640_480.jpg
Normal file
BIN
apriltag/src/test/python/tag1_640_480.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 26 KiB |
BIN
apriltag/src/test/python/tag2_16h5_straight.png
Normal file
BIN
apriltag/src/test/python/tag2_16h5_straight.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.8 KiB |
BIN
apriltag/src/test/python/tag2_45deg_X.png
Normal file
BIN
apriltag/src/test/python/tag2_45deg_X.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
BIN
apriltag/src/test/python/tag2_45deg_y.png
Normal file
BIN
apriltag/src/test/python/tag2_45deg_y.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
119
apriltag/src/test/python/test_detection.py
Normal file
119
apriltag/src/test/python/test_detection.py
Normal file
@@ -0,0 +1,119 @@
|
||||
import cv2
|
||||
import robotpy_apriltag
|
||||
from wpimath.geometry import Transform3d
|
||||
|
||||
import math
|
||||
import pathlib
|
||||
import pytest
|
||||
|
||||
|
||||
def test_point():
|
||||
point = robotpy_apriltag.AprilTagDetection.Point()
|
||||
|
||||
x, y = point
|
||||
|
||||
assert x == 0
|
||||
assert y == 0
|
||||
|
||||
|
||||
def _load_grayscale_image(fname):
|
||||
full_path = pathlib.Path(__file__).parent / fname
|
||||
img = cv2.imread(str(full_path))
|
||||
return cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
|
||||
|
||||
|
||||
def test_1():
|
||||
detector = robotpy_apriltag.AprilTagDetector()
|
||||
assert detector.addFamily("tag16h5")
|
||||
assert detector.addFamily("tag36h11")
|
||||
|
||||
img = _load_grayscale_image("tag1_640_480.jpg")
|
||||
results = detector.detect(img)
|
||||
|
||||
assert len(results) == 1
|
||||
assert results[0].getFamily() == "tag36h11"
|
||||
assert results[0].getId() == 1
|
||||
assert results[0].getHamming() == 0
|
||||
|
||||
estimator = robotpy_apriltag.AprilTagPoseEstimator(
|
||||
robotpy_apriltag.AprilTagPoseEstimator.Config(0.2, 500, 500, 320, 240)
|
||||
)
|
||||
|
||||
est = estimator.estimateOrthogonalIteration(results[0], 50)
|
||||
assert est.pose2 == Transform3d()
|
||||
pose = estimator.estimate(results[0])
|
||||
assert est.pose1 == pose
|
||||
|
||||
|
||||
def test_pose_rotated_x():
|
||||
"""
|
||||
This tag is rotated such that the top is closer to the camera than the bottom. In the camera
|
||||
frame, with +x to the right, this is a rotation about +X by 45 degrees.
|
||||
"""
|
||||
|
||||
detector = robotpy_apriltag.AprilTagDetector()
|
||||
assert detector.addFamily("tag16h5")
|
||||
|
||||
img = _load_grayscale_image("tag2_45deg_X.png")
|
||||
results = detector.detect(img)
|
||||
|
||||
assert len(results) == 1
|
||||
|
||||
estimator = robotpy_apriltag.AprilTagPoseEstimator(
|
||||
robotpy_apriltag.AprilTagPoseEstimator.Config(
|
||||
0.2, 500, 500, img.shape[1] / 2.0, img.shape[0] / 2.0
|
||||
)
|
||||
)
|
||||
est = estimator.estimateOrthogonalIteration(results[0], 50)
|
||||
assert pytest.approx(est.pose1.rotation().x, abs=0.1) == math.radians(45)
|
||||
assert pytest.approx(est.pose1.rotation().y, abs=0.1) == math.radians(0)
|
||||
assert pytest.approx(est.pose1.rotation().z, abs=0.1) == math.radians(0)
|
||||
|
||||
|
||||
def test_pose_rotated_y():
|
||||
"""
|
||||
This tag is rotated such that the right is closer to the camera than the left. In the camera
|
||||
frame, with +y down, this is a rotation of 45 degrees about +y.
|
||||
"""
|
||||
|
||||
detector = robotpy_apriltag.AprilTagDetector()
|
||||
assert detector.addFamily("tag16h5")
|
||||
|
||||
img = _load_grayscale_image("tag2_45deg_y.png")
|
||||
results = detector.detect(img)
|
||||
|
||||
assert len(results) == 1
|
||||
|
||||
estimator = robotpy_apriltag.AprilTagPoseEstimator(
|
||||
robotpy_apriltag.AprilTagPoseEstimator.Config(
|
||||
0.2, 500, 500, img.shape[1] / 2.0, img.shape[0] / 2.0
|
||||
)
|
||||
)
|
||||
est = estimator.estimateOrthogonalIteration(results[0], 50)
|
||||
assert pytest.approx(est.pose1.rotation().x, abs=0.1) == math.radians(0)
|
||||
assert pytest.approx(est.pose1.rotation().y, abs=0.1) == math.radians(45)
|
||||
assert pytest.approx(est.pose1.rotation().z, abs=0.1) == math.radians(0)
|
||||
|
||||
|
||||
def test_pose_straight_on():
|
||||
"""
|
||||
This tag is facing right at the camera -- no rotation should be observed.
|
||||
"""
|
||||
|
||||
detector = robotpy_apriltag.AprilTagDetector()
|
||||
assert detector.addFamily("tag16h5")
|
||||
|
||||
img = _load_grayscale_image("tag2_16h5_straight.png")
|
||||
results = detector.detect(img)
|
||||
|
||||
assert len(results) == 1
|
||||
|
||||
estimator = robotpy_apriltag.AprilTagPoseEstimator(
|
||||
robotpy_apriltag.AprilTagPoseEstimator.Config(
|
||||
0.2, 500, 500, img.shape[1] / 2.0, img.shape[0] / 2.0
|
||||
)
|
||||
)
|
||||
est = estimator.estimateOrthogonalIteration(results[0], 50)
|
||||
assert pytest.approx(est.pose1.rotation().x, abs=0.1) == math.radians(0)
|
||||
assert pytest.approx(est.pose1.rotation().y, abs=0.1) == math.radians(0)
|
||||
assert pytest.approx(est.pose1.rotation().z, abs=0.1) == math.radians(0)
|
||||
@@ -1,92 +0,0 @@
|
||||
# Testing steps for real hardware
|
||||
|
||||
trigger:
|
||||
batch: true
|
||||
branches:
|
||||
include:
|
||||
- master
|
||||
|
||||
stages:
|
||||
- stage: Build
|
||||
jobs:
|
||||
- job: IntegrationTests
|
||||
displayName: Integration Tests
|
||||
pool:
|
||||
vmImage: 'ubuntu-latest'
|
||||
|
||||
container:
|
||||
image: wpilib/roborio-cross-ubuntu:2023-22.04
|
||||
|
||||
timeoutInMinutes: 0
|
||||
|
||||
steps:
|
||||
- task: Gradle@2
|
||||
condition: and(succeeded(), not(startsWith(variables['Build.SourceBranch'], 'refs/tags/v')))
|
||||
inputs:
|
||||
workingDirectory: ""
|
||||
gradleWrapperFile: "gradlew"
|
||||
gradleOptions: "-Xmx3072m"
|
||||
publishJUnitResults: false
|
||||
testResultsFiles: "**/TEST-*.xml"
|
||||
tasks: "copyWpilibJIntegrationTestJarToOutput copyWpilibCTestLibrariesToOutput"
|
||||
options: "-Ponlylinuxathena -PbuildServer -PskipJavaFormat"
|
||||
|
||||
- task: PublishPipelineArtifact@0
|
||||
inputs:
|
||||
artifactName: "Integration Tests"
|
||||
targetPath: "build/integrationTestFiles"
|
||||
|
||||
- stage: TestBench
|
||||
displayName: Test Bench
|
||||
condition: false
|
||||
jobs:
|
||||
- job: Cpp
|
||||
displayName: C++
|
||||
pool: RoboRioConnections
|
||||
timeoutInMinutes: 30
|
||||
workspace:
|
||||
clean: all
|
||||
steps:
|
||||
- task: DownloadPipelineArtifact@0
|
||||
inputs:
|
||||
artifactName: "Integration Tests"
|
||||
targetPath: "build/integrationTestFiles"
|
||||
|
||||
- task: ShellScript@2
|
||||
displayName: Run C++ Tests
|
||||
inputs:
|
||||
scriptPath: test-scripts/deploy-and-run-test-on-robot.sh
|
||||
args: 'cpp -A "--gtest_output=xml:/home/admin/testResults/cppreport.xml"'
|
||||
|
||||
- task: PublishTestResults@2
|
||||
displayName: Publish C++ Test Results
|
||||
inputs:
|
||||
testResultsFormat: "JUnit"
|
||||
testResultsFiles: "*.xml"
|
||||
testRunTitle: "C++ Test Report"
|
||||
searchFolder: "$(System.DefaultWorkingDirectory)/test-reports"
|
||||
|
||||
- job: Java
|
||||
pool: RoboRioConnections
|
||||
timeoutInMinutes: 30
|
||||
workspace:
|
||||
clean: all
|
||||
steps:
|
||||
- task: DownloadPipelineArtifact@0
|
||||
inputs:
|
||||
artifactName: "Integration Tests"
|
||||
targetPath: "build/integrationTestFiles"
|
||||
|
||||
- task: ShellScript@2
|
||||
displayName: Run Java Tests
|
||||
inputs:
|
||||
scriptPath: test-scripts/deploy-and-run-test-on-robot.sh
|
||||
args: "java"
|
||||
|
||||
- task: PublishTestResults@2
|
||||
displayName: Publish Java Test Results
|
||||
inputs:
|
||||
testResultsFormat: "JUnit"
|
||||
testResultsFiles: "*.xml"
|
||||
testRunTitle: "Java Test Report"
|
||||
searchFolder: "$(System.DefaultWorkingDirectory)/test-reports"
|
||||
44
benchmark/CMakeLists.txt
Normal file
44
benchmark/CMakeLists.txt
Normal file
@@ -0,0 +1,44 @@
|
||||
project(benchmark)
|
||||
|
||||
include(CompileWarnings)
|
||||
|
||||
file(GLOB benchmarkCpp_src src/main/native/cpp/*.cpp src/main/native/thirdparty/benchmark/src/*.cpp)
|
||||
|
||||
add_executable(benchmarkCpp ${benchmarkCpp_src})
|
||||
|
||||
target_compile_features(benchmarkCpp PUBLIC cxx_std_20)
|
||||
|
||||
wpilib_target_warnings(benchmarkCpp)
|
||||
|
||||
target_link_libraries(
|
||||
benchmarkCpp
|
||||
PUBLIC
|
||||
$<TARGET_NAME_IF_EXISTS:apriltag>
|
||||
$<TARGET_NAME_IF_EXISTS:wpilibc>
|
||||
$<TARGET_NAME_IF_EXISTS:wpilibNewCommands>
|
||||
$<TARGET_NAME_IF_EXISTS:wpimath>
|
||||
$<TARGET_NAME_IF_EXISTS:wpiutil>
|
||||
)
|
||||
|
||||
# benchmark library setup
|
||||
target_compile_definitions(benchmarkCpp PRIVATE benchmark_EXPORTS)
|
||||
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
|
||||
target_link_libraries(benchmarkCpp PRIVATE shlwapi)
|
||||
endif()
|
||||
|
||||
if(NOT BUILD_SHARED_LIBS)
|
||||
target_compile_definitions(benchmarkCpp PUBLIC -DBENCHMARK_STATIC_DEFINE)
|
||||
endif()
|
||||
|
||||
install(
|
||||
DIRECTORY src/main/native/thirdparty/benchmark/include/
|
||||
DESTINATION "${include_dest}/benchmark"
|
||||
)
|
||||
target_include_directories(
|
||||
benchmarkCpp
|
||||
SYSTEM
|
||||
PRIVATE
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src/main/native/thirdparty/benchmark/include>
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src/main/native/thirdparty/benchmark/src>
|
||||
)
|
||||
49
benchmark/README.md
Normal file
49
benchmark/README.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# Benchmark
|
||||
|
||||
This is a benchmark project built directly against this repo's sources.
|
||||
|
||||
## Desktop benchmarking
|
||||
|
||||
This command runs the Java benchmarks on desktop.
|
||||
|
||||
```bash
|
||||
./gradlew benchmark:run
|
||||
```
|
||||
|
||||
This command runs the C++ benchmarks on desktop.
|
||||
|
||||
```
|
||||
./gradlew benchmark:runCpp
|
||||
```
|
||||
|
||||
## Deploy to a roboRIO
|
||||
|
||||
This project can only deploy over USB. If an alternate IP address is preferred, the `address` block in benchmark/build.gradle can be changed to point to another address.
|
||||
|
||||
This command deploys the C++ project using shared dependencies. Prefer this one for most C++ development.
|
||||
```bash
|
||||
./gradlew benchmark:deployShared
|
||||
```
|
||||
|
||||
This command deploys the C++ project with all dependencies statically linked.
|
||||
```bash
|
||||
./gradlew benchmark:deployStatic
|
||||
```
|
||||
|
||||
This command deploys the Java project and all required dependencies. It also installs the JRE if it's not currently installed.
|
||||
```bash
|
||||
./gradlew benchmark:deployJava
|
||||
```
|
||||
|
||||
Those commands won't start the robot executable, so you have to manually ssh in and start it. The following command will do that.
|
||||
```bash
|
||||
ssh lvuser@172.22.11.2 frcRunRobot.sh
|
||||
```
|
||||
|
||||
Console log prints will appear in the terminal.
|
||||
|
||||
Deploying any of these to the roboRIO will disable the current startup project until it is redeployed.
|
||||
|
||||
## Faster builds
|
||||
|
||||
If your benchmarks only need some projects, you can comment out or delete unnecessary subprojects from the dependencies, benchmarkCpp, and benchmarkCppStatic blocks in benchmark/build.gradle (Java or C++) and from `target_link_libraries()` in benchmark/CMakeLists.txt (C++ only).
|
||||
343
benchmark/build.gradle
Normal file
343
benchmark/build.gradle
Normal file
@@ -0,0 +1,343 @@
|
||||
import edu.wpi.first.deployutils.deploy.target.RemoteTarget
|
||||
import edu.wpi.first.deployutils.deploy.target.location.SshDeployLocation
|
||||
import edu.wpi.first.deployutils.deploy.artifact.*
|
||||
import org.gradle.internal.os.OperatingSystem
|
||||
|
||||
plugins {
|
||||
id 'java'
|
||||
id 'application'
|
||||
id 'cpp'
|
||||
id 'visual-studio'
|
||||
}
|
||||
|
||||
apply plugin: 'edu.wpi.first.NativeUtils'
|
||||
apply plugin: 'edu.wpi.first.DeployUtils'
|
||||
|
||||
apply from: "${rootDir}/shared/config.gradle"
|
||||
|
||||
application {
|
||||
if (OperatingSystem.current().isMacOsX()) {
|
||||
applicationDefaultJvmArgs = ['-XstartOnFirstThread']
|
||||
}
|
||||
}
|
||||
|
||||
ext {
|
||||
sharedCvConfigs = [benchmarkCpp: []]
|
||||
staticCvConfigs = [benchmarkCppStatic: []]
|
||||
useJava = true
|
||||
useCpp = true
|
||||
skipDev = true
|
||||
}
|
||||
|
||||
apply from: "${rootDir}/shared/opencv.gradle"
|
||||
|
||||
application {
|
||||
mainClass = 'frc.robot.Main'
|
||||
}
|
||||
|
||||
apply plugin: 'com.gradleup.shadow'
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
url = 'https://frcmaven.wpi.edu/artifactory/ex-mvn'
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation project(':apriltag')
|
||||
implementation project(':cameraserver')
|
||||
implementation project(':cscore')
|
||||
implementation project(':epilogue-runtime')
|
||||
implementation project(':hal')
|
||||
implementation project(':ntcore')
|
||||
implementation project(':wpilibj')
|
||||
implementation project(':wpilibNewCommands')
|
||||
implementation project(':wpimath')
|
||||
implementation project(':wpinet')
|
||||
implementation project(':wpiunits')
|
||||
implementation project(':wpiutil')
|
||||
annotationProcessor project(':epilogue-processor')
|
||||
implementation "org.openjdk.jmh:jmh-core:1.37"
|
||||
annotationProcessor "org.openjdk.jmh:jmh-generator-annprocess:1.37"
|
||||
}
|
||||
|
||||
tasks.withType(com.github.spotbugs.snom.SpotBugsTask).configureEach {
|
||||
onlyIf { false }
|
||||
}
|
||||
|
||||
deploy {
|
||||
targets {
|
||||
roborio(RemoteTarget) {
|
||||
directory = '/home/lvuser'
|
||||
maxChannels = 4
|
||||
locations {
|
||||
ssh(SshDeployLocation) {
|
||||
address = "172.22.11.2"
|
||||
user = 'admin'
|
||||
password = ''
|
||||
ipv6 = false
|
||||
}
|
||||
}
|
||||
|
||||
def remote = it
|
||||
|
||||
artifacts.registerFactory(WPIJREArtifact) {
|
||||
return objects.newInstance(WPIJREArtifact, it, remote)
|
||||
}
|
||||
|
||||
artifacts {
|
||||
all {
|
||||
predeploy << { ctx ->
|
||||
ctx.execute('. /etc/profile.d/natinst-path.sh; /usr/local/frc/bin/frcKillRobot.sh -t 2> /dev/null')
|
||||
ctx.execute("sed -i -e 's/\"exec /\"/' /usr/local/frc/bin/frcRunRobot.sh")
|
||||
}
|
||||
postdeploy << { ctx ->
|
||||
ctx.execute("sync")
|
||||
ctx.execute("ldconfig")
|
||||
}
|
||||
}
|
||||
|
||||
benchmarkCpp(NativeExecutableArtifact) {
|
||||
libraryDirectory = '/usr/local/frc/third-party/lib'
|
||||
def excludes = getLibraryFilter().getExcludes()
|
||||
excludes.add('**/*.so.debug')
|
||||
excludes.add('**/*.so.*.debug')
|
||||
postdeploy << { ctx ->
|
||||
ctx.execute("echo '/home/lvuser/benchmarkCpp' > /home/lvuser/robotCommand")
|
||||
ctx.execute("chmod +x /home/lvuser/robotCommand; chown lvuser /home/lvuser/robotCommand")
|
||||
ctx.execute("setcap cap_sys_nice+eip \"/home/lvuser/benchmarkCpp\"")
|
||||
ctx.execute('chmod +x benchmarkCpp')
|
||||
}
|
||||
}
|
||||
|
||||
benchmarkCppStatic(NativeExecutableArtifact) {
|
||||
libraryDirectory = '/usr/local/frc/third-party/lib'
|
||||
postdeploy << { ctx ->
|
||||
ctx.execute("echo '/home/lvuser/benchmarkCppStatic' > /home/lvuser/robotCommand")
|
||||
ctx.execute("chmod +x /home/lvuser/robotCommand; chown lvuser /home/lvuser/robotCommand")
|
||||
ctx.execute("setcap cap_sys_nice+eip \"/home/lvuser/benchmarkCppStatic\"")
|
||||
ctx.execute('chmod +x benchmarkCppStatic')
|
||||
}
|
||||
}
|
||||
|
||||
benchmarkCppJava(NativeExecutableArtifact) {
|
||||
libraryDirectory = '/usr/local/frc/third-party/lib'
|
||||
def excludes = getLibraryFilter().getExcludes()
|
||||
excludes.add('**/*.so.debug')
|
||||
excludes.add('**/*.so.*.debug')
|
||||
}
|
||||
|
||||
jre(WPIJREArtifact) {
|
||||
}
|
||||
|
||||
benchmarkJava(JavaArtifact) {
|
||||
jarTask = shadowJar
|
||||
postdeploy << { ctx ->
|
||||
ctx.execute("echo '/usr/local/frc/JRE/bin/java -XX:+UseSerialGC -Djava.library.path=/usr/local/frc/third-party/lib -Djava.lang.invoke.stringConcat=BC_SB -jar /home/lvuser/benchmark-all.jar' > /home/lvuser/robotCommand")
|
||||
ctx.execute("chmod +x /home/lvuser/robotCommand; chown lvuser /home/lvuser/robotCommand")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Prevent the eclipse compiler (used by the VS Code extension for intellisense and debugging)
|
||||
// from generating bad class files from annotation processors like Epilogue
|
||||
eclipse {
|
||||
classpath {
|
||||
containers 'org.eclipse.buildship.core.gradleclasspathcontainer'
|
||||
file.whenMerged { cp ->
|
||||
def entries = cp.entries;
|
||||
def src = new org.gradle.plugins.ide.eclipse.model.SourceFolder('build/generated/sources/annotationProcessor/java/main/', null)
|
||||
entries.add(src)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.register('deployJava') {
|
||||
try {
|
||||
dependsOn tasks.named('deployjreroborio')
|
||||
dependsOn tasks.named('deploybenchmarkJavaroborio')
|
||||
dependsOn tasks.named('deploybenchmarkCppJavaroborio') // Deploying shared C++ is how to get the Java shared libraries.
|
||||
} catch (ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
tasks.register('deployShared') {
|
||||
try {
|
||||
dependsOn tasks.named('deploybenchmarkCpproborio')
|
||||
} catch (ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
tasks.register('deployStatic') {
|
||||
try {
|
||||
dependsOn tasks.named('deploybenchmarkCppStaticroborio')
|
||||
} catch (ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
model {
|
||||
components {
|
||||
benchmarkCpp(NativeExecutableSpec) {
|
||||
if (project.hasProperty('ciDebugOnly')) {
|
||||
targetBuildTypes 'debug'
|
||||
} else {
|
||||
targetBuildTypes 'release'
|
||||
}
|
||||
sources {
|
||||
cpp {
|
||||
source {
|
||||
srcDirs = [
|
||||
'src/main/native/cpp',
|
||||
'src/main/native/thirdparty/benchmark/src'
|
||||
]
|
||||
includes = ['**/*.cpp']
|
||||
}
|
||||
exportedHeaders {
|
||||
srcDirs = [
|
||||
'src/main/native/include',
|
||||
'src/main/native/thirdparty/benchmark/include',
|
||||
'src/main/native/thirdparty/benchmark/src'
|
||||
]
|
||||
includes = ['**/*.h']
|
||||
}
|
||||
}
|
||||
}
|
||||
binaries.all { binary ->
|
||||
if (binary.targetPlatform.name == nativeUtils.wpi.platforms.roborio) {
|
||||
if (binary.buildType.name == 'debug') {
|
||||
deploy.targets.roborio.artifacts.benchmarkCpp.binary = binary
|
||||
deploy.targets.roborio.artifacts.benchmarkCppJava.binary = binary
|
||||
}
|
||||
}
|
||||
lib project: ':apriltag', library: 'apriltag', linkage: 'shared'
|
||||
lib project: ':cameraserver', library: 'cameraserver', linkage: 'shared'
|
||||
lib project: ':cscore', library: 'cscore', linkage: 'shared'
|
||||
lib project: ':cscore', library: 'cscoreJNIShared', linkage: 'shared'
|
||||
project(':hal').addHalDependency(binary, 'shared')
|
||||
project(':hal').addHalJniDependency(binary)
|
||||
project(':ntcore').addNtcoreDependency(binary, 'shared')
|
||||
project(':ntcore').addNtcoreJniDependency(binary)
|
||||
lib project: ':wpilibc', library: 'wpilibc', linkage: 'shared'
|
||||
lib project: ':wpilibNewCommands', library: 'wpilibNewCommands', linkage: 'shared'
|
||||
lib project: ':wpimath', library: 'wpimath', linkage: 'shared'
|
||||
lib project: ':wpimath', library: 'wpimathJNIShared', linkage: 'shared'
|
||||
lib project: ':wpinet', library: 'wpinet', linkage: 'shared'
|
||||
lib project: ':wpinet', library: 'wpinetJNIShared', linkage: 'shared'
|
||||
lib project: ':wpiutil', library: 'wpiutil', linkage: 'shared'
|
||||
lib project: ':wpiutil', library: 'wpiutilJNIShared', linkage: 'shared'
|
||||
if (binary.targetPlatform.name == nativeUtils.wpi.platforms.roborio) {
|
||||
nativeUtils.useRequiredLibrary(binary, 'ni_link_libraries', 'ni_runtime_libraries')
|
||||
}
|
||||
if (binary.targetPlatform.operatingSystem.isWindows()) {
|
||||
// Shlwapi.lib is needed for SHGetValueA() inside thirdparty benchmark
|
||||
binary.linker.args << "Shlwapi.lib"
|
||||
}
|
||||
binary.cppCompiler.define 'benchmark_EXPORTS'
|
||||
}
|
||||
}
|
||||
benchmarkCppStatic(NativeExecutableSpec) {
|
||||
if (project.hasProperty('ciDebugOnly')) {
|
||||
targetBuildTypes 'debug'
|
||||
} else {
|
||||
targetBuildTypes 'release'
|
||||
}
|
||||
nativeUtils.excludeBinariesFromStrip(it)
|
||||
sources {
|
||||
cpp {
|
||||
source {
|
||||
srcDirs = [
|
||||
'src/main/native/cpp',
|
||||
'src/main/native/thirdparty/benchmark/src'
|
||||
]
|
||||
includes = ['**/*.cpp']
|
||||
}
|
||||
exportedHeaders {
|
||||
srcDirs = [
|
||||
'src/main/native/include',
|
||||
'src/main/native/thirdparty/benchmark/include',
|
||||
'src/main/native/thirdparty/benchmark/src'
|
||||
]
|
||||
includes = ['**/*.h']
|
||||
}
|
||||
}
|
||||
}
|
||||
binaries.all { binary ->
|
||||
if (binary.targetPlatform.name == nativeUtils.wpi.platforms.roborio) {
|
||||
if (binary.buildType.name == 'debug') {
|
||||
deploy.targets.roborio.artifacts.benchmarkCppStatic.binary = binary
|
||||
}
|
||||
}
|
||||
lib project: ':apriltag', library: 'apriltag', linkage: 'static'
|
||||
lib project: ':cameraserver', library: 'cameraserver', linkage: 'static'
|
||||
lib project: ':cscore', library: 'cscore', linkage: 'static'
|
||||
project(':hal').addHalDependency(binary, 'static')
|
||||
project(':ntcore').addNtcoreDependency(binary, 'static')
|
||||
lib project: ':wpilibc', library: 'wpilibc', linkage: 'static'
|
||||
lib project: ':wpilibNewCommands', library: 'wpilibNewCommands', linkage: 'static'
|
||||
lib project: ':wpimath', library: 'wpimath', linkage: 'static'
|
||||
lib project: ':wpinet', library: 'wpinet', linkage: 'static'
|
||||
lib project: ':wpiutil', library: 'wpiutil', linkage: 'static'
|
||||
if (binary.targetPlatform.name == nativeUtils.wpi.platforms.roborio) {
|
||||
nativeUtils.useRequiredLibrary(binary, 'ni_link_libraries', 'ni_runtime_libraries')
|
||||
}
|
||||
if (binary.targetPlatform.operatingSystem.isWindows()) {
|
||||
// Shlwapi.lib is needed for SHGetValueA() inside thirdparty benchmark
|
||||
binary.linker.args << "Shlwapi.lib"
|
||||
}
|
||||
binary.cppCompiler.define 'benchmark_EXPORTS'
|
||||
binary.cppCompiler.define 'BENCHMARK_STATIC_DEFINE'
|
||||
}
|
||||
}
|
||||
all {
|
||||
it.sources.each {
|
||||
it.exportedHeaders {
|
||||
srcDirs 'src/main/native/thirdparty/benchmark/include'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
tasks {
|
||||
def c = $.components
|
||||
project.tasks.create('runCpp', Exec) {
|
||||
group = 'WPILib'
|
||||
description = "Run the benchmarkCpp executable"
|
||||
def found = false
|
||||
def systemArch = getCurrentArch()
|
||||
c.each {
|
||||
if (it in NativeExecutableSpec && it.name == "benchmarkCpp") {
|
||||
it.binaries.each {
|
||||
if (!found) {
|
||||
def arch = it.targetPlatform.name
|
||||
if (arch == systemArch) {
|
||||
dependsOn it.tasks.install
|
||||
commandLine it.tasks.install.runScriptFile.get().asFile.toString()
|
||||
def filePath = it.tasks.install.installDirectory.get().toString() + File.separatorChar + 'lib'
|
||||
run.dependsOn it.tasks.install
|
||||
run.systemProperty 'java.library.path', filePath
|
||||
|
||||
found = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
installAthena(Task) {
|
||||
$.binaries.each {
|
||||
if (it in NativeExecutableBinarySpec && it.targetPlatform.name == nativeUtils.wpi.platforms.roborio && it.component.name == 'benchmarkCpp') {
|
||||
dependsOn it.tasks.install
|
||||
}
|
||||
}
|
||||
}
|
||||
installAthenaStatic(Task) {
|
||||
$.binaries.each {
|
||||
if (it in NativeExecutableBinarySpec && it.targetPlatform.name == nativeUtils.wpi.platforms.roborio && it.component.name == 'benchmarkCppStatic') {
|
||||
dependsOn it.tasks.install
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
79
benchmark/src/main/java/frc/robot/Main.java
Normal file
79
benchmark/src/main/java/frc/robot/Main.java
Normal file
@@ -0,0 +1,79 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
package frc.robot;
|
||||
|
||||
import edu.wpi.first.math.geometry.Pose2d;
|
||||
import edu.wpi.first.math.geometry.Rotation2d;
|
||||
import edu.wpi.first.math.path.TravelingSalesman;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import org.openjdk.jmh.annotations.Benchmark;
|
||||
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||
import org.openjdk.jmh.annotations.Mode;
|
||||
import org.openjdk.jmh.annotations.OutputTimeUnit;
|
||||
import org.openjdk.jmh.profile.GCProfiler;
|
||||
import org.openjdk.jmh.runner.Runner;
|
||||
import org.openjdk.jmh.runner.RunnerException;
|
||||
import org.openjdk.jmh.runner.options.Options;
|
||||
import org.openjdk.jmh.runner.options.OptionsBuilder;
|
||||
import org.openjdk.jmh.runner.options.TimeValue;
|
||||
|
||||
public class Main {
|
||||
private static final Pose2d[] poses = {
|
||||
new Pose2d(-1, 1, Rotation2d.kCW_90deg),
|
||||
new Pose2d(-1, 2, Rotation2d.kCCW_90deg),
|
||||
new Pose2d(0, 0, Rotation2d.kZero),
|
||||
new Pose2d(0, 3, Rotation2d.kCW_90deg),
|
||||
new Pose2d(1, 1, Rotation2d.kCCW_90deg),
|
||||
new Pose2d(1, 2, Rotation2d.kCCW_90deg),
|
||||
};
|
||||
private static final int iterations = 100;
|
||||
|
||||
private static final TravelingSalesman transformTraveler =
|
||||
new TravelingSalesman(
|
||||
(pose1, pose2) -> {
|
||||
var transform = pose2.minus(pose1);
|
||||
return Math.hypot(transform.getX(), transform.getY());
|
||||
});
|
||||
private static final TravelingSalesman twistTraveler =
|
||||
new TravelingSalesman(
|
||||
(pose1, pose2) -> {
|
||||
var twist = pose2.minus(pose1).log();
|
||||
return Math.hypot(twist.dx, twist.dy);
|
||||
});
|
||||
|
||||
/**
|
||||
* Main function.
|
||||
*
|
||||
* @param args The (unused) arguments to the program.
|
||||
*/
|
||||
public static void main(String... args) throws RunnerException {
|
||||
Options opt =
|
||||
new OptionsBuilder()
|
||||
.include(Main.class.getSimpleName())
|
||||
.addProfiler(GCProfiler.class)
|
||||
.forks(1)
|
||||
.warmupIterations(2)
|
||||
.warmupTime(TimeValue.seconds(3))
|
||||
.measurementIterations(3)
|
||||
.measurementTime(TimeValue.seconds(3))
|
||||
.build();
|
||||
|
||||
new Runner(opt).run();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
@BenchmarkMode(Mode.AverageTime)
|
||||
@OutputTimeUnit(TimeUnit.MICROSECONDS)
|
||||
public Pose2d[] transform() {
|
||||
return transformTraveler.solve(poses, iterations);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
@BenchmarkMode(Mode.AverageTime)
|
||||
@OutputTimeUnit(TimeUnit.MICROSECONDS)
|
||||
public Pose2d[] twist() {
|
||||
return twistTraveler.solve(poses, iterations);
|
||||
}
|
||||
}
|
||||
44
benchmark/src/main/native/cpp/Main.cpp
Normal file
44
benchmark/src/main/native/cpp/Main.cpp
Normal file
@@ -0,0 +1,44 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
#include <benchmark/benchmark.h>
|
||||
#include <frc/geometry/Pose2d.h>
|
||||
#include <frc/path/TravelingSalesman.h>
|
||||
|
||||
#include <units/angle.h>
|
||||
#include <units/length.h>
|
||||
#include <wpi/array.h>
|
||||
|
||||
static constexpr wpi::array<frc::Pose2d, 6> poses{
|
||||
frc::Pose2d{-1_m, 1_m, -90_deg}, frc::Pose2d{-1_m, 2_m, 90_deg},
|
||||
frc::Pose2d{0_m, 0_m, 0_deg}, frc::Pose2d{0_m, 3_m, -90_deg},
|
||||
frc::Pose2d{1_m, 1_m, 90_deg}, frc::Pose2d{1_m, 2_m, 90_deg},
|
||||
};
|
||||
static constexpr int iterations = 100;
|
||||
|
||||
void BM_Transform(benchmark::State& state) {
|
||||
frc::TravelingSalesman traveler{[](auto pose1, auto pose2) {
|
||||
auto transform = pose2 - pose1;
|
||||
return units::math::hypot(transform.X(), transform.Y()).value();
|
||||
}};
|
||||
// NOLINTNEXTLINE(clang-analyzer-deadcode.DeadStores)
|
||||
for (auto _ : state) {
|
||||
traveler.Solve(poses, iterations);
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Transform);
|
||||
|
||||
void BM_Twist(benchmark::State& state) {
|
||||
frc::TravelingSalesman traveler{[](auto pose1, auto pose2) {
|
||||
auto twist = (pose2 - pose1).Log();
|
||||
return units::math::hypot(twist.dx, twist.dy).value();
|
||||
}};
|
||||
// NOLINTNEXTLINE(clang-analyzer-deadcode.DeadStores)
|
||||
for (auto _ : state) {
|
||||
traveler.Solve(poses, iterations);
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_Twist);
|
||||
|
||||
BENCHMARK_MAIN();
|
||||
2041
benchmark/src/main/native/thirdparty/benchmark/include/benchmark/benchmark.h
vendored
Normal file
2041
benchmark/src/main/native/thirdparty/benchmark/include/benchmark/benchmark.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
47
benchmark/src/main/native/thirdparty/benchmark/include/benchmark/export.h
vendored
Normal file
47
benchmark/src/main/native/thirdparty/benchmark/include/benchmark/export.h
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
#ifndef BENCHMARK_EXPORT_H
|
||||
#define BENCHMARK_EXPORT_H
|
||||
|
||||
#if defined(_WIN32)
|
||||
#define EXPORT_ATTR __declspec(dllexport)
|
||||
#define IMPORT_ATTR __declspec(dllimport)
|
||||
#define NO_EXPORT_ATTR
|
||||
#define DEPRECATED_ATTR __declspec(deprecated)
|
||||
#else // _WIN32
|
||||
#define EXPORT_ATTR __attribute__((visibility("default")))
|
||||
#define IMPORT_ATTR __attribute__((visibility("default")))
|
||||
#define NO_EXPORT_ATTR __attribute__((visibility("hidden")))
|
||||
#define DEPRECATE_ATTR __attribute__((__deprecated__))
|
||||
#endif // _WIN32
|
||||
|
||||
#ifdef BENCHMARK_STATIC_DEFINE
|
||||
#define BENCHMARK_EXPORT
|
||||
#define BENCHMARK_NO_EXPORT
|
||||
#else // BENCHMARK_STATIC_DEFINE
|
||||
#ifndef BENCHMARK_EXPORT
|
||||
#ifdef benchmark_EXPORTS
|
||||
/* We are building this library */
|
||||
#define BENCHMARK_EXPORT EXPORT_ATTR
|
||||
#else // benchmark_EXPORTS
|
||||
/* We are using this library */
|
||||
#define BENCHMARK_EXPORT IMPORT_ATTR
|
||||
#endif // benchmark_EXPORTS
|
||||
#endif // !BENCHMARK_EXPORT
|
||||
|
||||
#ifndef BENCHMARK_NO_EXPORT
|
||||
#define BENCHMARK_NO_EXPORT NO_EXPORT_ATTR
|
||||
#endif // !BENCHMARK_NO_EXPORT
|
||||
#endif // BENCHMARK_STATIC_DEFINE
|
||||
|
||||
#ifndef BENCHMARK_DEPRECATED
|
||||
#define BENCHMARK_DEPRECATED DEPRECATE_ATTR
|
||||
#endif // BENCHMARK_DEPRECATED
|
||||
|
||||
#ifndef BENCHMARK_DEPRECATED_EXPORT
|
||||
#define BENCHMARK_DEPRECATED_EXPORT BENCHMARK_EXPORT BENCHMARK_DEPRECATED
|
||||
#endif // BENCHMARK_DEPRECATED_EXPORT
|
||||
|
||||
#ifndef BENCHMARK_DEPRECATED_NO_EXPORT
|
||||
#define BENCHMARK_DEPRECATED_NO_EXPORT BENCHMARK_NO_EXPORT BENCHMARK_DEPRECATED
|
||||
#endif // BENCHMARK_DEPRECATED_EXPORT
|
||||
|
||||
#endif /* BENCHMARK_EXPORT_H */
|
||||
33
benchmark/src/main/native/thirdparty/benchmark/src/arraysize.h
vendored
Normal file
33
benchmark/src/main/native/thirdparty/benchmark/src/arraysize.h
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
#ifndef BENCHMARK_ARRAYSIZE_H_
|
||||
#define BENCHMARK_ARRAYSIZE_H_
|
||||
|
||||
#include "internal_macros.h"
|
||||
|
||||
namespace benchmark {
|
||||
namespace internal {
|
||||
// The arraysize(arr) macro returns the # of elements in an array arr.
|
||||
// The expression is a compile-time constant, and therefore can be
|
||||
// used in defining new arrays, for example. If you use arraysize on
|
||||
// a pointer by mistake, you will get a compile-time error.
|
||||
//
|
||||
|
||||
// This template function declaration is used in defining arraysize.
|
||||
// Note that the function doesn't need an implementation, as we only
|
||||
// use its type.
|
||||
template <typename T, size_t N>
|
||||
char (&ArraySizeHelper(T (&array)[N]))[N];
|
||||
|
||||
// That gcc wants both of these prototypes seems mysterious. VC, for
|
||||
// its part, can't decide which to use (another mystery). Matching of
|
||||
// template overloads: the final frontier.
|
||||
#ifndef COMPILER_MSVC
|
||||
template <typename T, size_t N>
|
||||
char (&ArraySizeHelper(const T (&array)[N]))[N];
|
||||
#endif
|
||||
|
||||
#define arraysize(array) (sizeof(::benchmark::internal::ArraySizeHelper(array)))
|
||||
|
||||
} // end namespace internal
|
||||
} // end namespace benchmark
|
||||
|
||||
#endif // BENCHMARK_ARRAYSIZE_H_
|
||||
912
benchmark/src/main/native/thirdparty/benchmark/src/benchmark.cpp
vendored
Normal file
912
benchmark/src/main/native/thirdparty/benchmark/src/benchmark.cpp
vendored
Normal file
@@ -0,0 +1,912 @@
|
||||
// Copyright 2015 Google Inc. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "benchmark/benchmark.h"
|
||||
|
||||
#include "benchmark_api_internal.h"
|
||||
#include "benchmark_runner.h"
|
||||
#include "internal_macros.h"
|
||||
|
||||
#ifndef BENCHMARK_OS_WINDOWS
|
||||
#if !defined(BENCHMARK_OS_FUCHSIA) && !defined(BENCHMARK_OS_QURT)
|
||||
#include <sys/resource.h>
|
||||
#endif
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef BENCHMARK_OS_LINUX
|
||||
#include <sys/personality.h>
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
#include <atomic>
|
||||
#include <condition_variable>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <limits>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <random>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <utility>
|
||||
|
||||
#include "check.h"
|
||||
#include "colorprint.h"
|
||||
#include "commandlineflags.h"
|
||||
#include "complexity.h"
|
||||
#include "counter.h"
|
||||
#include "log.h"
|
||||
#include "mutex.h"
|
||||
#include "perf_counters.h"
|
||||
#include "re.h"
|
||||
#include "statistics.h"
|
||||
#include "string_util.h"
|
||||
#include "thread_manager.h"
|
||||
#include "thread_timer.h"
|
||||
|
||||
namespace benchmark {
|
||||
// Print a list of benchmarks. This option overrides all other options.
|
||||
BM_DEFINE_bool(benchmark_list_tests, false);
|
||||
|
||||
// A regular expression that specifies the set of benchmarks to execute. If
|
||||
// this flag is empty, or if this flag is the string \"all\", all benchmarks
|
||||
// linked into the binary are run.
|
||||
BM_DEFINE_string(benchmark_filter, "");
|
||||
|
||||
// Specification of how long to run the benchmark.
|
||||
//
|
||||
// It can be either an exact number of iterations (specified as `<integer>x`),
|
||||
// or a minimum number of seconds (specified as `<float>s`). If the latter
|
||||
// format (ie., min seconds) is used, the system may run the benchmark longer
|
||||
// until the results are considered significant.
|
||||
//
|
||||
// For backward compatibility, the `s` suffix may be omitted, in which case,
|
||||
// the specified number is interpreted as the number of seconds.
|
||||
//
|
||||
// For cpu-time based tests, this is the lower bound
|
||||
// on the total cpu time used by all threads that make up the test. For
|
||||
// real-time based tests, this is the lower bound on the elapsed time of the
|
||||
// benchmark execution, regardless of number of threads.
|
||||
BM_DEFINE_string(benchmark_min_time, kDefaultMinTimeStr);
|
||||
|
||||
// Minimum number of seconds a benchmark should be run before results should be
|
||||
// taken into account. This e.g can be necessary for benchmarks of code which
|
||||
// needs to fill some form of cache before performance is of interest.
|
||||
// Note: results gathered within this period are discarded and not used for
|
||||
// reported result.
|
||||
BM_DEFINE_double(benchmark_min_warmup_time, 0.0);
|
||||
|
||||
// The number of runs of each benchmark. If greater than 1, the mean and
|
||||
// standard deviation of the runs will be reported.
|
||||
BM_DEFINE_int32(benchmark_repetitions, 1);
|
||||
|
||||
// If enabled, forces each benchmark to execute exactly one iteration and one
|
||||
// repetition, bypassing any configured
|
||||
// MinTime()/MinWarmUpTime()/Iterations()/Repetitions()
|
||||
BM_DEFINE_bool(benchmark_dry_run, false);
|
||||
|
||||
// If set, enable random interleaving of repetitions of all benchmarks.
|
||||
// See http://github.com/google/benchmark/issues/1051 for details.
|
||||
BM_DEFINE_bool(benchmark_enable_random_interleaving, false);
|
||||
|
||||
// Report the result of each benchmark repetitions. When 'true' is specified
|
||||
// only the mean, standard deviation, and other statistics are reported for
|
||||
// repeated benchmarks. Affects all reporters.
|
||||
BM_DEFINE_bool(benchmark_report_aggregates_only, false);
|
||||
|
||||
// Display the result of each benchmark repetitions. When 'true' is specified
|
||||
// only the mean, standard deviation, and other statistics are displayed for
|
||||
// repeated benchmarks. Unlike benchmark_report_aggregates_only, only affects
|
||||
// the display reporter, but *NOT* file reporter, which will still contain
|
||||
// all the output.
|
||||
BM_DEFINE_bool(benchmark_display_aggregates_only, false);
|
||||
|
||||
// The format to use for console output.
|
||||
// Valid values are 'console', 'json', or 'csv'.
|
||||
BM_DEFINE_string(benchmark_format, "console");
|
||||
|
||||
// The format to use for file output.
|
||||
// Valid values are 'console', 'json', or 'csv'.
|
||||
BM_DEFINE_string(benchmark_out_format, "json");
|
||||
|
||||
// The file to write additional output to.
|
||||
BM_DEFINE_string(benchmark_out, "");
|
||||
|
||||
// Whether to use colors in the output. Valid values:
|
||||
// 'true'/'yes'/1, 'false'/'no'/0, and 'auto'. 'auto' means to use colors if
|
||||
// the output is being sent to a terminal and the TERM environment variable is
|
||||
// set to a terminal type that supports colors.
|
||||
BM_DEFINE_string(benchmark_color, "auto");
|
||||
|
||||
// Whether to use tabular format when printing user counters to the console.
|
||||
// Valid values: 'true'/'yes'/1, 'false'/'no'/0. Defaults to false.
|
||||
BM_DEFINE_bool(benchmark_counters_tabular, false);
|
||||
|
||||
// List of additional perf counters to collect, in libpfm format. For more
|
||||
// information about libpfm: https://man7.org/linux/man-pages/man3/libpfm.3.html
|
||||
BM_DEFINE_string(benchmark_perf_counters, "");
|
||||
|
||||
// Extra context to include in the output formatted as comma-separated key-value
|
||||
// pairs. Kept internal as it's only used for parsing from env/command line.
|
||||
BM_DEFINE_kvpairs(benchmark_context, {});
|
||||
|
||||
// Set the default time unit to use for reports
|
||||
// Valid values are 'ns', 'us', 'ms' or 's'
|
||||
BM_DEFINE_string(benchmark_time_unit, "");
|
||||
|
||||
// The level of verbose logging to output
|
||||
BM_DEFINE_int32(v, 0);
|
||||
|
||||
namespace internal {
|
||||
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
|
||||
std::map<std::string, std::string>* global_context = nullptr;
|
||||
|
||||
BENCHMARK_EXPORT std::map<std::string, std::string>*& GetGlobalContext() {
|
||||
return global_context;
|
||||
}
|
||||
|
||||
namespace {
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
|
||||
void const volatile* volatile global_force_escape_pointer;
|
||||
} // namespace
|
||||
|
||||
// FIXME: Verify if LTO still messes this up?
|
||||
void UseCharPointer(char const volatile* const v) {
|
||||
// We want to escape the pointer `v` so that the compiler can not eliminate
|
||||
// computations that produced it. To do that, we escape the pointer by storing
|
||||
// it into a volatile variable, since generally, volatile store, is not
|
||||
// something the compiler is allowed to elide.
|
||||
global_force_escape_pointer = reinterpret_cast<void const volatile*>(v);
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
State::State(std::string name, IterationCount max_iters,
|
||||
const std::vector<int64_t>& ranges, int thread_i, int n_threads,
|
||||
internal::ThreadTimer* timer, internal::ThreadManager* manager,
|
||||
internal::PerfCountersMeasurement* perf_counters_measurement,
|
||||
ProfilerManager* profiler_manager)
|
||||
: total_iterations_(0),
|
||||
batch_leftover_(0),
|
||||
max_iterations(max_iters),
|
||||
started_(false),
|
||||
finished_(false),
|
||||
skipped_(internal::NotSkipped),
|
||||
range_(ranges),
|
||||
complexity_n_(0),
|
||||
name_(std::move(name)),
|
||||
thread_index_(thread_i),
|
||||
threads_(n_threads),
|
||||
timer_(timer),
|
||||
manager_(manager),
|
||||
perf_counters_measurement_(perf_counters_measurement),
|
||||
profiler_manager_(profiler_manager) {
|
||||
BM_CHECK(max_iterations != 0) << "At least one iteration must be run";
|
||||
BM_CHECK_LT(thread_index_, threads_)
|
||||
<< "thread_index must be less than threads";
|
||||
|
||||
// Add counters with correct flag now. If added with `counters[name]` in
|
||||
// `PauseTiming`, a new `Counter` will be inserted the first time, which
|
||||
// won't have the flag. Inserting them now also reduces the allocations
|
||||
// during the benchmark.
|
||||
if (perf_counters_measurement_ != nullptr) {
|
||||
for (const std::string& counter_name :
|
||||
perf_counters_measurement_->names()) {
|
||||
counters[counter_name] = Counter(0.0, Counter::kAvgIterations);
|
||||
}
|
||||
}
|
||||
|
||||
// Note: The use of offsetof below is technically undefined until C++17
|
||||
// because State is not a standard layout type. However, all compilers
|
||||
// currently provide well-defined behavior as an extension (which is
|
||||
// demonstrated since constexpr evaluation must diagnose all undefined
|
||||
// behavior). However, GCC and Clang also warn about this use of offsetof,
|
||||
// which must be suppressed.
|
||||
#if defined(__INTEL_COMPILER)
|
||||
#pragma warning push
|
||||
#pragma warning(disable : 1875)
|
||||
#elif defined(__GNUC__) || defined(__clang__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Winvalid-offsetof"
|
||||
#endif
|
||||
#if defined(__NVCC__)
|
||||
#pragma nv_diagnostic push
|
||||
#pragma nv_diag_suppress 1427
|
||||
#endif
|
||||
#if defined(__NVCOMPILER)
|
||||
#pragma diagnostic push
|
||||
#pragma diag_suppress offset_in_non_POD_nonstandard
|
||||
#endif
|
||||
// Offset tests to ensure commonly accessed data is on the first cache line.
|
||||
const int cache_line_size = 64;
|
||||
static_assert(
|
||||
offsetof(State, skipped_) <= (cache_line_size - sizeof(skipped_)), "");
|
||||
#if defined(__INTEL_COMPILER)
|
||||
#pragma warning pop
|
||||
#elif defined(__GNUC__) || defined(__clang__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
#if defined(__NVCC__)
|
||||
#pragma nv_diagnostic pop
|
||||
#endif
|
||||
#if defined(__NVCOMPILER)
|
||||
#pragma diagnostic pop
|
||||
#endif
|
||||
}
|
||||
|
||||
void State::PauseTiming() {
|
||||
// Add in time accumulated so far
|
||||
BM_CHECK(started_ && !finished_ && !skipped());
|
||||
timer_->StopTimer();
|
||||
if (perf_counters_measurement_ != nullptr) {
|
||||
std::vector<std::pair<std::string, double>> measurements;
|
||||
if (!perf_counters_measurement_->Stop(measurements)) {
|
||||
BM_CHECK(false) << "Perf counters read the value failed.";
|
||||
}
|
||||
for (const auto& name_and_measurement : measurements) {
|
||||
const std::string& name = name_and_measurement.first;
|
||||
const double measurement = name_and_measurement.second;
|
||||
// Counter was inserted with `kAvgIterations` flag by the constructor.
|
||||
assert(counters.find(name) != counters.end());
|
||||
counters[name].value += measurement;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void State::ResumeTiming() {
|
||||
BM_CHECK(started_ && !finished_ && !skipped());
|
||||
timer_->StartTimer();
|
||||
if (perf_counters_measurement_ != nullptr) {
|
||||
perf_counters_measurement_->Start();
|
||||
}
|
||||
}
|
||||
|
||||
void State::SkipWithMessage(const std::string& msg) {
|
||||
skipped_ = internal::SkippedWithMessage;
|
||||
{
|
||||
MutexLock l(manager_->GetBenchmarkMutex());
|
||||
if (internal::NotSkipped == manager_->results.skipped_) {
|
||||
manager_->results.skip_message_ = msg;
|
||||
manager_->results.skipped_ = skipped_;
|
||||
}
|
||||
}
|
||||
total_iterations_ = 0;
|
||||
if (timer_->running()) {
|
||||
timer_->StopTimer();
|
||||
}
|
||||
}
|
||||
|
||||
void State::SkipWithError(const std::string& msg) {
|
||||
skipped_ = internal::SkippedWithError;
|
||||
{
|
||||
MutexLock l(manager_->GetBenchmarkMutex());
|
||||
if (internal::NotSkipped == manager_->results.skipped_) {
|
||||
manager_->results.skip_message_ = msg;
|
||||
manager_->results.skipped_ = skipped_;
|
||||
}
|
||||
}
|
||||
total_iterations_ = 0;
|
||||
if (timer_->running()) {
|
||||
timer_->StopTimer();
|
||||
}
|
||||
}
|
||||
|
||||
void State::SetIterationTime(double seconds) {
|
||||
timer_->SetIterationTime(seconds);
|
||||
}
|
||||
|
||||
void State::SetLabel(const std::string& label) {
|
||||
MutexLock l(manager_->GetBenchmarkMutex());
|
||||
manager_->results.report_label_ = label;
|
||||
}
|
||||
|
||||
void State::StartKeepRunning() {
|
||||
BM_CHECK(!started_ && !finished_);
|
||||
started_ = true;
|
||||
total_iterations_ = skipped() ? 0 : max_iterations;
|
||||
if (BENCHMARK_BUILTIN_EXPECT(profiler_manager_ != nullptr, false)) {
|
||||
profiler_manager_->AfterSetupStart();
|
||||
}
|
||||
manager_->StartStopBarrier();
|
||||
if (!skipped()) {
|
||||
ResumeTiming();
|
||||
}
|
||||
}
|
||||
|
||||
void State::FinishKeepRunning() {
|
||||
BM_CHECK(started_ && (!finished_ || skipped()));
|
||||
if (!skipped()) {
|
||||
PauseTiming();
|
||||
}
|
||||
// Total iterations has now wrapped around past 0. Fix this.
|
||||
total_iterations_ = 0;
|
||||
finished_ = true;
|
||||
manager_->StartStopBarrier();
|
||||
if (BENCHMARK_BUILTIN_EXPECT(profiler_manager_ != nullptr, false)) {
|
||||
profiler_manager_->BeforeTeardownStop();
|
||||
}
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
namespace {
|
||||
|
||||
// Flushes streams after invoking reporter methods that write to them. This
|
||||
// ensures users get timely updates even when streams are not line-buffered.
|
||||
void FlushStreams(BenchmarkReporter* reporter) {
|
||||
if (reporter == nullptr) {
|
||||
return;
|
||||
}
|
||||
std::flush(reporter->GetOutputStream());
|
||||
std::flush(reporter->GetErrorStream());
|
||||
}
|
||||
|
||||
// Reports in both display and file reporters.
|
||||
void Report(BenchmarkReporter* display_reporter,
|
||||
BenchmarkReporter* file_reporter, const RunResults& run_results) {
|
||||
auto report_one = [](BenchmarkReporter* reporter, bool aggregates_only,
|
||||
const RunResults& results) {
|
||||
assert(reporter);
|
||||
// If there are no aggregates, do output non-aggregates.
|
||||
aggregates_only &= !results.aggregates_only.empty();
|
||||
if (!aggregates_only) {
|
||||
reporter->ReportRuns(results.non_aggregates);
|
||||
}
|
||||
if (!results.aggregates_only.empty()) {
|
||||
reporter->ReportRuns(results.aggregates_only);
|
||||
}
|
||||
};
|
||||
|
||||
report_one(display_reporter, run_results.display_report_aggregates_only,
|
||||
run_results);
|
||||
if (file_reporter != nullptr) {
|
||||
report_one(file_reporter, run_results.file_report_aggregates_only,
|
||||
run_results);
|
||||
}
|
||||
|
||||
FlushStreams(display_reporter);
|
||||
FlushStreams(file_reporter);
|
||||
}
|
||||
|
||||
void RunBenchmarks(const std::vector<BenchmarkInstance>& benchmarks,
|
||||
BenchmarkReporter* display_reporter,
|
||||
BenchmarkReporter* file_reporter) {
|
||||
// Note the file_reporter can be null.
|
||||
BM_CHECK(display_reporter != nullptr);
|
||||
|
||||
// Determine the width of the name field using a minimum width of 10.
|
||||
bool might_have_aggregates = FLAGS_benchmark_repetitions > 1;
|
||||
size_t name_field_width = 10;
|
||||
size_t stat_field_width = 0;
|
||||
for (const BenchmarkInstance& benchmark : benchmarks) {
|
||||
name_field_width =
|
||||
std::max<size_t>(name_field_width, benchmark.name().str().size());
|
||||
might_have_aggregates |= benchmark.repetitions() > 1;
|
||||
|
||||
for (const auto& Stat : benchmark.statistics()) {
|
||||
stat_field_width = std::max<size_t>(stat_field_width, Stat.name_.size());
|
||||
}
|
||||
}
|
||||
if (might_have_aggregates) {
|
||||
name_field_width += 1 + stat_field_width;
|
||||
}
|
||||
|
||||
// Print header here
|
||||
BenchmarkReporter::Context context;
|
||||
context.name_field_width = name_field_width;
|
||||
|
||||
// Keep track of running times of all instances of each benchmark family.
|
||||
std::map<int /*family_index*/, BenchmarkReporter::PerFamilyRunReports>
|
||||
per_family_reports;
|
||||
|
||||
if (display_reporter->ReportContext(context) &&
|
||||
((file_reporter == nullptr) || file_reporter->ReportContext(context))) {
|
||||
FlushStreams(display_reporter);
|
||||
FlushStreams(file_reporter);
|
||||
|
||||
size_t num_repetitions_total = 0;
|
||||
|
||||
// This perfcounters object needs to be created before the runners vector
|
||||
// below so it outlasts their lifetime.
|
||||
PerfCountersMeasurement perfcounters(
|
||||
StrSplit(FLAGS_benchmark_perf_counters, ','));
|
||||
|
||||
// Vector of benchmarks to run
|
||||
std::vector<internal::BenchmarkRunner> runners;
|
||||
runners.reserve(benchmarks.size());
|
||||
|
||||
// Count the number of benchmarks with threads to warn the user in case
|
||||
// performance counters are used.
|
||||
int benchmarks_with_threads = 0;
|
||||
|
||||
// Loop through all benchmarks
|
||||
for (const BenchmarkInstance& benchmark : benchmarks) {
|
||||
BenchmarkReporter::PerFamilyRunReports* reports_for_family = nullptr;
|
||||
if (benchmark.complexity() != oNone) {
|
||||
reports_for_family = &per_family_reports[benchmark.family_index()];
|
||||
}
|
||||
benchmarks_with_threads += static_cast<int>(benchmark.threads() > 1);
|
||||
runners.emplace_back(benchmark, &perfcounters, reports_for_family);
|
||||
int num_repeats_of_this_instance = runners.back().GetNumRepeats();
|
||||
num_repetitions_total +=
|
||||
static_cast<size_t>(num_repeats_of_this_instance);
|
||||
if (reports_for_family != nullptr) {
|
||||
reports_for_family->num_runs_total += num_repeats_of_this_instance;
|
||||
}
|
||||
}
|
||||
assert(runners.size() == benchmarks.size() && "Unexpected runner count.");
|
||||
|
||||
// The use of performance counters with threads would be unintuitive for
|
||||
// the average user so we need to warn them about this case
|
||||
if ((benchmarks_with_threads > 0) && (perfcounters.num_counters() > 0)) {
|
||||
GetErrorLogInstance()
|
||||
<< "***WARNING*** There are " << benchmarks_with_threads
|
||||
<< " benchmarks with threads and " << perfcounters.num_counters()
|
||||
<< " performance counters were requested. Beware counters will "
|
||||
"reflect the combined usage across all "
|
||||
"threads.\n";
|
||||
}
|
||||
|
||||
std::vector<size_t> repetition_indices;
|
||||
repetition_indices.reserve(num_repetitions_total);
|
||||
for (size_t runner_index = 0, num_runners = runners.size();
|
||||
runner_index != num_runners; ++runner_index) {
|
||||
const internal::BenchmarkRunner& runner = runners[runner_index];
|
||||
std::fill_n(std::back_inserter(repetition_indices),
|
||||
runner.GetNumRepeats(), runner_index);
|
||||
}
|
||||
assert(repetition_indices.size() == num_repetitions_total &&
|
||||
"Unexpected number of repetition indexes.");
|
||||
|
||||
if (FLAGS_benchmark_enable_random_interleaving) {
|
||||
std::random_device rd;
|
||||
std::mt19937 g(rd());
|
||||
std::shuffle(repetition_indices.begin(), repetition_indices.end(), g);
|
||||
}
|
||||
|
||||
for (size_t repetition_index : repetition_indices) {
|
||||
internal::BenchmarkRunner& runner = runners[repetition_index];
|
||||
runner.DoOneRepetition();
|
||||
if (runner.HasRepeatsRemaining()) {
|
||||
continue;
|
||||
}
|
||||
// FIXME: report each repetition separately, not all of them in bulk.
|
||||
|
||||
display_reporter->ReportRunsConfig(
|
||||
runner.GetMinTime(), runner.HasExplicitIters(), runner.GetIters());
|
||||
if (file_reporter != nullptr) {
|
||||
file_reporter->ReportRunsConfig(
|
||||
runner.GetMinTime(), runner.HasExplicitIters(), runner.GetIters());
|
||||
}
|
||||
|
||||
RunResults run_results = runner.GetResults();
|
||||
|
||||
// Maybe calculate complexity report
|
||||
if (const auto* reports_for_family = runner.GetReportsForFamily()) {
|
||||
if (reports_for_family->num_runs_done ==
|
||||
reports_for_family->num_runs_total) {
|
||||
auto additional_run_stats = ComputeBigO(reports_for_family->Runs);
|
||||
run_results.aggregates_only.insert(run_results.aggregates_only.end(),
|
||||
additional_run_stats.begin(),
|
||||
additional_run_stats.end());
|
||||
per_family_reports.erase(
|
||||
static_cast<int>(reports_for_family->Runs.front().family_index));
|
||||
}
|
||||
}
|
||||
|
||||
Report(display_reporter, file_reporter, run_results);
|
||||
}
|
||||
}
|
||||
display_reporter->Finalize();
|
||||
if (file_reporter != nullptr) {
|
||||
file_reporter->Finalize();
|
||||
}
|
||||
FlushStreams(display_reporter);
|
||||
FlushStreams(file_reporter);
|
||||
}
|
||||
|
||||
// Disable deprecated warnings temporarily because we need to reference
|
||||
// CSVReporter but don't want to trigger -Werror=-Wdeprecated-declarations
|
||||
BENCHMARK_DISABLE_DEPRECATED_WARNING
|
||||
|
||||
std::unique_ptr<BenchmarkReporter> CreateReporter(
|
||||
std::string const& name, ConsoleReporter::OutputOptions output_opts) {
|
||||
typedef std::unique_ptr<BenchmarkReporter> PtrType;
|
||||
if (name == "console") {
|
||||
return PtrType(new ConsoleReporter(output_opts));
|
||||
}
|
||||
if (name == "json") {
|
||||
return PtrType(new JSONReporter());
|
||||
}
|
||||
if (name == "csv") {
|
||||
return PtrType(new CSVReporter());
|
||||
}
|
||||
std::cerr << "Unexpected format: '" << name << "'\n";
|
||||
std::flush(std::cerr);
|
||||
std::exit(1);
|
||||
}
|
||||
|
||||
BENCHMARK_RESTORE_DEPRECATED_WARNING
|
||||
|
||||
} // end namespace
|
||||
|
||||
bool IsZero(double n) {
|
||||
return std::abs(n) < std::numeric_limits<double>::epsilon();
|
||||
}
|
||||
|
||||
ConsoleReporter::OutputOptions GetOutputOptions(bool force_no_color) {
|
||||
int output_opts = ConsoleReporter::OO_Defaults;
|
||||
auto is_benchmark_color = [force_no_color]() -> bool {
|
||||
if (force_no_color) {
|
||||
return false;
|
||||
}
|
||||
if (FLAGS_benchmark_color == "auto") {
|
||||
return IsColorTerminal();
|
||||
}
|
||||
return IsTruthyFlagValue(FLAGS_benchmark_color);
|
||||
};
|
||||
if (is_benchmark_color()) {
|
||||
output_opts |= ConsoleReporter::OO_Color;
|
||||
} else {
|
||||
output_opts &= ~ConsoleReporter::OO_Color;
|
||||
}
|
||||
if (FLAGS_benchmark_counters_tabular) {
|
||||
output_opts |= ConsoleReporter::OO_Tabular;
|
||||
} else {
|
||||
output_opts &= ~ConsoleReporter::OO_Tabular;
|
||||
}
|
||||
return static_cast<ConsoleReporter::OutputOptions>(output_opts);
|
||||
}
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
BenchmarkReporter* CreateDefaultDisplayReporter() {
|
||||
static auto* default_display_reporter =
|
||||
internal::CreateReporter(FLAGS_benchmark_format,
|
||||
internal::GetOutputOptions())
|
||||
.release();
|
||||
return default_display_reporter;
|
||||
}
|
||||
|
||||
size_t RunSpecifiedBenchmarks() {
|
||||
return RunSpecifiedBenchmarks(nullptr, nullptr, FLAGS_benchmark_filter);
|
||||
}
|
||||
|
||||
size_t RunSpecifiedBenchmarks(std::string spec) {
|
||||
return RunSpecifiedBenchmarks(nullptr, nullptr, std::move(spec));
|
||||
}
|
||||
|
||||
size_t RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter) {
|
||||
return RunSpecifiedBenchmarks(display_reporter, nullptr,
|
||||
FLAGS_benchmark_filter);
|
||||
}
|
||||
|
||||
size_t RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter,
|
||||
std::string spec) {
|
||||
return RunSpecifiedBenchmarks(display_reporter, nullptr, std::move(spec));
|
||||
}
|
||||
|
||||
size_t RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter,
|
||||
BenchmarkReporter* file_reporter) {
|
||||
return RunSpecifiedBenchmarks(display_reporter, file_reporter,
|
||||
FLAGS_benchmark_filter);
|
||||
}
|
||||
|
||||
size_t RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter,
|
||||
BenchmarkReporter* file_reporter,
|
||||
std::string spec) {
|
||||
if (spec.empty() || spec == "all") {
|
||||
spec = "."; // Regexp that matches all benchmarks
|
||||
}
|
||||
|
||||
// Setup the reporters
|
||||
std::ofstream output_file;
|
||||
std::unique_ptr<BenchmarkReporter> default_display_reporter;
|
||||
std::unique_ptr<BenchmarkReporter> default_file_reporter;
|
||||
if (display_reporter == nullptr) {
|
||||
default_display_reporter.reset(CreateDefaultDisplayReporter());
|
||||
display_reporter = default_display_reporter.get();
|
||||
}
|
||||
auto& Out = display_reporter->GetOutputStream();
|
||||
auto& Err = display_reporter->GetErrorStream();
|
||||
|
||||
std::string const& fname = FLAGS_benchmark_out;
|
||||
if (fname.empty() && (file_reporter != nullptr)) {
|
||||
Err << "A custom file reporter was provided but "
|
||||
"--benchmark_out=<file> was not specified.\n";
|
||||
Out.flush();
|
||||
Err.flush();
|
||||
std::exit(1);
|
||||
}
|
||||
if (!fname.empty()) {
|
||||
output_file.open(fname);
|
||||
if (!output_file.is_open()) {
|
||||
Err << "invalid file name: '" << fname << "'\n";
|
||||
Out.flush();
|
||||
Err.flush();
|
||||
std::exit(1);
|
||||
}
|
||||
if (file_reporter == nullptr) {
|
||||
default_file_reporter = internal::CreateReporter(
|
||||
FLAGS_benchmark_out_format, FLAGS_benchmark_counters_tabular
|
||||
? ConsoleReporter::OO_Tabular
|
||||
: ConsoleReporter::OO_None);
|
||||
file_reporter = default_file_reporter.get();
|
||||
}
|
||||
file_reporter->SetOutputStream(&output_file);
|
||||
file_reporter->SetErrorStream(&output_file);
|
||||
}
|
||||
|
||||
std::vector<internal::BenchmarkInstance> benchmarks;
|
||||
if (!FindBenchmarksInternal(spec, &benchmarks, &Err)) {
|
||||
Out.flush();
|
||||
Err.flush();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (benchmarks.empty()) {
|
||||
Err << "Failed to match any benchmarks against regex: " << spec << "\n";
|
||||
Out.flush();
|
||||
Err.flush();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (FLAGS_benchmark_list_tests) {
|
||||
for (auto const& benchmark : benchmarks) {
|
||||
Out << benchmark.name().str() << "\n";
|
||||
}
|
||||
} else {
|
||||
internal::RunBenchmarks(benchmarks, display_reporter, file_reporter);
|
||||
}
|
||||
|
||||
Out.flush();
|
||||
Err.flush();
|
||||
return benchmarks.size();
|
||||
}
|
||||
|
||||
namespace {
|
||||
// stores the time unit benchmarks use by default
|
||||
TimeUnit default_time_unit = kNanosecond;
|
||||
} // namespace
|
||||
|
||||
TimeUnit GetDefaultTimeUnit() { return default_time_unit; }
|
||||
|
||||
void SetDefaultTimeUnit(TimeUnit unit) { default_time_unit = unit; }
|
||||
|
||||
std::string GetBenchmarkFilter() { return FLAGS_benchmark_filter; }
|
||||
|
||||
void SetBenchmarkFilter(std::string value) {
|
||||
FLAGS_benchmark_filter = std::move(value);
|
||||
}
|
||||
|
||||
int32_t GetBenchmarkVerbosity() { return FLAGS_v; }
|
||||
|
||||
void RegisterMemoryManager(MemoryManager* manager) {
|
||||
internal::memory_manager = manager;
|
||||
}
|
||||
|
||||
void RegisterProfilerManager(ProfilerManager* manager) {
|
||||
// Don't allow overwriting an existing manager.
|
||||
if (manager != nullptr) {
|
||||
BM_CHECK_EQ(internal::profiler_manager, nullptr);
|
||||
}
|
||||
internal::profiler_manager = manager;
|
||||
}
|
||||
|
||||
void AddCustomContext(const std::string& key, const std::string& value) {
|
||||
if (internal::global_context == nullptr) {
|
||||
internal::global_context = new std::map<std::string, std::string>();
|
||||
}
|
||||
if (!internal::global_context->emplace(key, value).second) {
|
||||
std::cerr << "Failed to add custom context \"" << key << "\" as it already "
|
||||
<< "exists with value \"" << value << "\"\n";
|
||||
}
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
|
||||
void (*HelperPrintf)();
|
||||
|
||||
void PrintUsageAndExit() {
|
||||
HelperPrintf();
|
||||
std::flush(std::cout);
|
||||
std::flush(std::cerr);
|
||||
std::exit(0);
|
||||
}
|
||||
|
||||
void SetDefaultTimeUnitFromFlag(const std::string& time_unit_flag) {
|
||||
if (time_unit_flag == "s") {
|
||||
return SetDefaultTimeUnit(kSecond);
|
||||
}
|
||||
if (time_unit_flag == "ms") {
|
||||
return SetDefaultTimeUnit(kMillisecond);
|
||||
}
|
||||
if (time_unit_flag == "us") {
|
||||
return SetDefaultTimeUnit(kMicrosecond);
|
||||
}
|
||||
if (time_unit_flag == "ns") {
|
||||
return SetDefaultTimeUnit(kNanosecond);
|
||||
}
|
||||
if (!time_unit_flag.empty()) {
|
||||
PrintUsageAndExit();
|
||||
}
|
||||
}
|
||||
|
||||
void ParseCommandLineFlags(int* argc, char** argv) {
|
||||
using namespace benchmark;
|
||||
BenchmarkReporter::Context::executable_name =
|
||||
((argc != nullptr) && *argc > 0) ? argv[0] : "unknown";
|
||||
for (int i = 1; (argc != nullptr) && i < *argc; ++i) {
|
||||
if (ParseBoolFlag(argv[i], "benchmark_list_tests",
|
||||
&FLAGS_benchmark_list_tests) ||
|
||||
ParseStringFlag(argv[i], "benchmark_filter", &FLAGS_benchmark_filter) ||
|
||||
ParseStringFlag(argv[i], "benchmark_min_time",
|
||||
&FLAGS_benchmark_min_time) ||
|
||||
ParseDoubleFlag(argv[i], "benchmark_min_warmup_time",
|
||||
&FLAGS_benchmark_min_warmup_time) ||
|
||||
ParseInt32Flag(argv[i], "benchmark_repetitions",
|
||||
&FLAGS_benchmark_repetitions) ||
|
||||
ParseBoolFlag(argv[i], "benchmark_dry_run", &FLAGS_benchmark_dry_run) ||
|
||||
ParseBoolFlag(argv[i], "benchmark_enable_random_interleaving",
|
||||
&FLAGS_benchmark_enable_random_interleaving) ||
|
||||
ParseBoolFlag(argv[i], "benchmark_report_aggregates_only",
|
||||
&FLAGS_benchmark_report_aggregates_only) ||
|
||||
ParseBoolFlag(argv[i], "benchmark_display_aggregates_only",
|
||||
&FLAGS_benchmark_display_aggregates_only) ||
|
||||
ParseStringFlag(argv[i], "benchmark_format", &FLAGS_benchmark_format) ||
|
||||
ParseStringFlag(argv[i], "benchmark_out", &FLAGS_benchmark_out) ||
|
||||
ParseStringFlag(argv[i], "benchmark_out_format",
|
||||
&FLAGS_benchmark_out_format) ||
|
||||
ParseStringFlag(argv[i], "benchmark_color", &FLAGS_benchmark_color) ||
|
||||
ParseBoolFlag(argv[i], "benchmark_counters_tabular",
|
||||
&FLAGS_benchmark_counters_tabular) ||
|
||||
ParseStringFlag(argv[i], "benchmark_perf_counters",
|
||||
&FLAGS_benchmark_perf_counters) ||
|
||||
ParseKeyValueFlag(argv[i], "benchmark_context",
|
||||
&FLAGS_benchmark_context) ||
|
||||
ParseStringFlag(argv[i], "benchmark_time_unit",
|
||||
&FLAGS_benchmark_time_unit) ||
|
||||
ParseInt32Flag(argv[i], "v", &FLAGS_v)) {
|
||||
for (int j = i; j != *argc - 1; ++j) {
|
||||
argv[j] = argv[j + 1];
|
||||
}
|
||||
|
||||
--(*argc);
|
||||
--i;
|
||||
} else if (IsFlag(argv[i], "help")) {
|
||||
PrintUsageAndExit();
|
||||
}
|
||||
}
|
||||
for (auto const* flag :
|
||||
{&FLAGS_benchmark_format, &FLAGS_benchmark_out_format}) {
|
||||
if (*flag != "console" && *flag != "json" && *flag != "csv") {
|
||||
PrintUsageAndExit();
|
||||
}
|
||||
}
|
||||
SetDefaultTimeUnitFromFlag(FLAGS_benchmark_time_unit);
|
||||
if (FLAGS_benchmark_color.empty()) {
|
||||
PrintUsageAndExit();
|
||||
}
|
||||
if (FLAGS_benchmark_dry_run) {
|
||||
AddCustomContext("dry_run", "true");
|
||||
}
|
||||
for (const auto& kv : FLAGS_benchmark_context) {
|
||||
AddCustomContext(kv.first, kv.second);
|
||||
}
|
||||
}
|
||||
|
||||
int InitializeStreams() {
|
||||
static std::ios_base::Init init;
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::make_unsigned_t<T> get_as_unsigned(T v) {
|
||||
using UnsignedT = std::make_unsigned_t<T>;
|
||||
return static_cast<UnsignedT>(v);
|
||||
}
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
void MaybeReenterWithoutASLR(int /*argc*/, char** argv) {
|
||||
// On e.g. Hexagon simulator, argv may be NULL.
|
||||
if (!argv) return;
|
||||
|
||||
#ifdef BENCHMARK_OS_LINUX
|
||||
const auto curr_personality = personality(0xffffffff);
|
||||
|
||||
// We should never fail to read-only query the current personality,
|
||||
// but let's be cautious.
|
||||
if (curr_personality == -1) return;
|
||||
|
||||
// If ASLR is already disabled, we have nothing more to do.
|
||||
if (internal::get_as_unsigned(curr_personality) & ADDR_NO_RANDOMIZE) return;
|
||||
|
||||
// Try to change the personality to disable ASLR.
|
||||
const auto proposed_personality =
|
||||
internal::get_as_unsigned(curr_personality) | ADDR_NO_RANDOMIZE;
|
||||
const auto prev_personality = personality(proposed_personality);
|
||||
|
||||
// Have we failed to change the personality? That may happen.
|
||||
if (prev_personality == -1) return;
|
||||
|
||||
// Make sure the parsona has been updated with the no-ASLR flag,
|
||||
// otherwise we will try to reenter infinitely.
|
||||
// This seems impossible, but can happen in some docker configurations.
|
||||
const auto new_personality = personality(0xffffffff);
|
||||
if ((internal::get_as_unsigned(new_personality) & ADDR_NO_RANDOMIZE) == 0)
|
||||
return;
|
||||
|
||||
execv(argv[0], argv);
|
||||
// The exec() functions return only if an error has occurred,
|
||||
// in which case we want to just continue as-is.
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string GetBenchmarkVersion() {
|
||||
#ifdef BENCHMARK_VERSION
|
||||
return {BENCHMARK_VERSION};
|
||||
#else
|
||||
return {""};
|
||||
#endif
|
||||
}
|
||||
|
||||
void PrintDefaultHelp() {
|
||||
fprintf(stdout,
|
||||
"benchmark"
|
||||
" [--benchmark_list_tests={true|false}]\n"
|
||||
" [--benchmark_filter=<regex>]\n"
|
||||
" [--benchmark_min_time=`<integer>x` OR `<float>s` ]\n"
|
||||
" [--benchmark_min_warmup_time=<min_warmup_time>]\n"
|
||||
" [--benchmark_repetitions=<num_repetitions>]\n"
|
||||
" [--benchmark_dry_run={true|false}]\n"
|
||||
" [--benchmark_enable_random_interleaving={true|false}]\n"
|
||||
" [--benchmark_report_aggregates_only={true|false}]\n"
|
||||
" [--benchmark_display_aggregates_only={true|false}]\n"
|
||||
" [--benchmark_format=<console|json|csv>]\n"
|
||||
" [--benchmark_out=<filename>]\n"
|
||||
" [--benchmark_out_format=<json|console|csv>]\n"
|
||||
" [--benchmark_color={auto|true|false}]\n"
|
||||
" [--benchmark_counters_tabular={true|false}]\n"
|
||||
#if defined HAVE_LIBPFM
|
||||
" [--benchmark_perf_counters=<counter>,...]\n"
|
||||
#endif
|
||||
" [--benchmark_context=<key>=<value>,...]\n"
|
||||
" [--benchmark_time_unit={ns|us|ms|s}]\n"
|
||||
" [--v=<verbosity>]\n");
|
||||
}
|
||||
|
||||
void Initialize(int* argc, char** argv, void (*HelperPrintf)()) {
|
||||
internal::HelperPrintf = HelperPrintf;
|
||||
internal::ParseCommandLineFlags(argc, argv);
|
||||
internal::LogLevel() = FLAGS_v;
|
||||
}
|
||||
|
||||
void Shutdown() { delete internal::global_context; }
|
||||
|
||||
bool ReportUnrecognizedArguments(int argc, char** argv) {
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
fprintf(stderr, "%s: error: unrecognized command-line flag: %s\n", argv[0],
|
||||
argv[i]);
|
||||
}
|
||||
return argc > 1;
|
||||
}
|
||||
|
||||
} // end namespace benchmark
|
||||
118
benchmark/src/main/native/thirdparty/benchmark/src/benchmark_api_internal.cpp
vendored
Normal file
118
benchmark/src/main/native/thirdparty/benchmark/src/benchmark_api_internal.cpp
vendored
Normal file
@@ -0,0 +1,118 @@
|
||||
#include "benchmark_api_internal.h"
|
||||
|
||||
#include <cinttypes>
|
||||
|
||||
#include "string_util.h"
|
||||
|
||||
namespace benchmark {
|
||||
namespace internal {
|
||||
|
||||
BenchmarkInstance::BenchmarkInstance(Benchmark* benchmark, int family_idx,
|
||||
int per_family_instance_idx,
|
||||
const std::vector<int64_t>& args,
|
||||
int thread_count)
|
||||
: benchmark_(*benchmark),
|
||||
family_index_(family_idx),
|
||||
per_family_instance_index_(per_family_instance_idx),
|
||||
aggregation_report_mode_(benchmark_.aggregation_report_mode_),
|
||||
args_(args),
|
||||
time_unit_(benchmark_.GetTimeUnit()),
|
||||
measure_process_cpu_time_(benchmark_.measure_process_cpu_time_),
|
||||
use_real_time_(benchmark_.use_real_time_),
|
||||
use_manual_time_(benchmark_.use_manual_time_),
|
||||
complexity_(benchmark_.complexity_),
|
||||
complexity_lambda_(benchmark_.complexity_lambda_),
|
||||
statistics_(benchmark_.statistics_),
|
||||
repetitions_(benchmark_.repetitions_),
|
||||
min_time_(benchmark_.min_time_),
|
||||
min_warmup_time_(benchmark_.min_warmup_time_),
|
||||
iterations_(benchmark_.iterations_),
|
||||
threads_(thread_count),
|
||||
setup_(benchmark_.setup_),
|
||||
teardown_(benchmark_.teardown_) {
|
||||
name_.function_name = benchmark_.name_;
|
||||
|
||||
size_t arg_i = 0;
|
||||
for (const auto& arg : args) {
|
||||
if (!name_.args.empty()) {
|
||||
name_.args += '/';
|
||||
}
|
||||
|
||||
if (arg_i < benchmark->arg_names_.size()) {
|
||||
const auto& arg_name = benchmark_.arg_names_[arg_i];
|
||||
if (!arg_name.empty()) {
|
||||
name_.args += StrFormat("%s:", arg_name.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
name_.args += StrFormat("%" PRId64, arg);
|
||||
++arg_i;
|
||||
}
|
||||
|
||||
if (!IsZero(benchmark->min_time_)) {
|
||||
name_.min_time = StrFormat("min_time:%0.3f", benchmark_.min_time_);
|
||||
}
|
||||
|
||||
if (!IsZero(benchmark->min_warmup_time_)) {
|
||||
name_.min_warmup_time =
|
||||
StrFormat("min_warmup_time:%0.3f", benchmark_.min_warmup_time_);
|
||||
}
|
||||
|
||||
if (benchmark_.iterations_ != 0) {
|
||||
name_.iterations = StrFormat(
|
||||
"iterations:%lu", static_cast<unsigned long>(benchmark_.iterations_));
|
||||
}
|
||||
|
||||
if (benchmark_.repetitions_ != 0) {
|
||||
name_.repetitions = StrFormat("repeats:%d", benchmark_.repetitions_);
|
||||
}
|
||||
|
||||
if (benchmark_.measure_process_cpu_time_) {
|
||||
name_.time_type = "process_time";
|
||||
}
|
||||
|
||||
if (benchmark_.use_manual_time_) {
|
||||
if (!name_.time_type.empty()) {
|
||||
name_.time_type += '/';
|
||||
}
|
||||
name_.time_type += "manual_time";
|
||||
} else if (benchmark_.use_real_time_) {
|
||||
if (!name_.time_type.empty()) {
|
||||
name_.time_type += '/';
|
||||
}
|
||||
name_.time_type += "real_time";
|
||||
}
|
||||
|
||||
if (!benchmark_.thread_counts_.empty()) {
|
||||
name_.threads = StrFormat("threads:%d", threads_);
|
||||
}
|
||||
}
|
||||
|
||||
State BenchmarkInstance::Run(
|
||||
IterationCount iters, int thread_id, internal::ThreadTimer* timer,
|
||||
internal::ThreadManager* manager,
|
||||
internal::PerfCountersMeasurement* perf_counters_measurement,
|
||||
ProfilerManager* profiler_manager) const {
|
||||
State st(name_.function_name, iters, args_, thread_id, threads_, timer,
|
||||
manager, perf_counters_measurement, profiler_manager);
|
||||
benchmark_.Run(st);
|
||||
return st;
|
||||
}
|
||||
|
||||
void BenchmarkInstance::Setup() const {
|
||||
if (setup_ != nullptr) {
|
||||
State st(name_.function_name, /*iters*/ 1, args_, /*thread_id*/ 0, threads_,
|
||||
nullptr, nullptr, nullptr, nullptr);
|
||||
setup_(st);
|
||||
}
|
||||
}
|
||||
|
||||
void BenchmarkInstance::Teardown() const {
|
||||
if (teardown_ != nullptr) {
|
||||
State st(name_.function_name, /*iters*/ 1, args_, /*thread_id*/ 0, threads_,
|
||||
nullptr, nullptr, nullptr, nullptr);
|
||||
teardown_(st);
|
||||
}
|
||||
}
|
||||
} // namespace internal
|
||||
} // namespace benchmark
|
||||
90
benchmark/src/main/native/thirdparty/benchmark/src/benchmark_api_internal.h
vendored
Normal file
90
benchmark/src/main/native/thirdparty/benchmark/src/benchmark_api_internal.h
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
#ifndef BENCHMARK_API_INTERNAL_H
|
||||
#define BENCHMARK_API_INTERNAL_H
|
||||
|
||||
#include <cmath>
|
||||
#include <iosfwd>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "benchmark/benchmark.h"
|
||||
#include "commandlineflags.h"
|
||||
|
||||
namespace benchmark {
|
||||
namespace internal {
|
||||
|
||||
// Information kept per benchmark we may want to run
|
||||
class BenchmarkInstance {
|
||||
public:
|
||||
BenchmarkInstance(Benchmark* benchmark, int family_idx,
|
||||
int per_family_instance_idx,
|
||||
const std::vector<int64_t>& args, int thread_count);
|
||||
|
||||
const BenchmarkName& name() const { return name_; }
|
||||
int family_index() const { return family_index_; }
|
||||
int per_family_instance_index() const { return per_family_instance_index_; }
|
||||
AggregationReportMode aggregation_report_mode() const {
|
||||
return aggregation_report_mode_;
|
||||
}
|
||||
TimeUnit time_unit() const { return time_unit_; }
|
||||
bool measure_process_cpu_time() const { return measure_process_cpu_time_; }
|
||||
bool use_real_time() const { return use_real_time_; }
|
||||
bool use_manual_time() const { return use_manual_time_; }
|
||||
BigO complexity() const { return complexity_; }
|
||||
BigOFunc* complexity_lambda() const { return complexity_lambda_; }
|
||||
const std::vector<Statistics>& statistics() const { return statistics_; }
|
||||
int repetitions() const { return repetitions_; }
|
||||
double min_time() const { return min_time_; }
|
||||
double min_warmup_time() const { return min_warmup_time_; }
|
||||
IterationCount iterations() const { return iterations_; }
|
||||
int threads() const { return threads_; }
|
||||
void Setup() const;
|
||||
void Teardown() const;
|
||||
const auto& GetUserThreadRunnerFactory() const {
|
||||
return benchmark_.threadrunner_;
|
||||
}
|
||||
|
||||
State Run(IterationCount iters, int thread_id, internal::ThreadTimer* timer,
|
||||
internal::ThreadManager* manager,
|
||||
internal::PerfCountersMeasurement* perf_counters_measurement,
|
||||
ProfilerManager* profiler_manager) const;
|
||||
|
||||
private:
|
||||
BenchmarkName name_;
|
||||
Benchmark& benchmark_;
|
||||
const int family_index_;
|
||||
const int per_family_instance_index_;
|
||||
AggregationReportMode aggregation_report_mode_;
|
||||
const std::vector<int64_t>& args_;
|
||||
TimeUnit time_unit_;
|
||||
bool measure_process_cpu_time_;
|
||||
bool use_real_time_;
|
||||
bool use_manual_time_;
|
||||
BigO complexity_;
|
||||
BigOFunc* complexity_lambda_;
|
||||
UserCounters counters_;
|
||||
const std::vector<Statistics>& statistics_;
|
||||
int repetitions_;
|
||||
double min_time_;
|
||||
double min_warmup_time_;
|
||||
IterationCount iterations_;
|
||||
int threads_; // Number of concurrent threads to us
|
||||
|
||||
callback_function setup_;
|
||||
callback_function teardown_;
|
||||
};
|
||||
|
||||
bool FindBenchmarksInternal(const std::string& re,
|
||||
std::vector<BenchmarkInstance>* benchmarks,
|
||||
std::ostream* Err);
|
||||
|
||||
bool IsZero(double n);
|
||||
|
||||
BENCHMARK_EXPORT
|
||||
ConsoleReporter::OutputOptions GetOutputOptions(bool force_no_color = false);
|
||||
|
||||
} // end namespace internal
|
||||
} // end namespace benchmark
|
||||
|
||||
#endif // BENCHMARK_API_INTERNAL_H
|
||||
59
benchmark/src/main/native/thirdparty/benchmark/src/benchmark_name.cpp
vendored
Normal file
59
benchmark/src/main/native/thirdparty/benchmark/src/benchmark_name.cpp
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
// Copyright 2015 Google Inc. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <benchmark/benchmark.h>
|
||||
|
||||
namespace benchmark {
|
||||
|
||||
namespace {
|
||||
|
||||
// Compute the total size of a pack of std::strings
|
||||
size_t size_impl() { return 0; }
|
||||
|
||||
template <typename Head, typename... Tail>
|
||||
size_t size_impl(const Head& head, const Tail&... tail) {
|
||||
return head.size() + size_impl(tail...);
|
||||
}
|
||||
|
||||
// Join a pack of std::strings using a delimiter
|
||||
// TODO(dominic): use absl::StrJoin
|
||||
void join_impl(std::string& /*unused*/, char /*unused*/) {}
|
||||
|
||||
template <typename Head, typename... Tail>
|
||||
void join_impl(std::string& s, const char delimiter, const Head& head,
|
||||
const Tail&... tail) {
|
||||
if (!s.empty() && !head.empty()) {
|
||||
s += delimiter;
|
||||
}
|
||||
|
||||
s += head;
|
||||
|
||||
join_impl(s, delimiter, tail...);
|
||||
}
|
||||
|
||||
template <typename... Ts>
|
||||
std::string join(char delimiter, const Ts&... ts) {
|
||||
std::string s;
|
||||
s.reserve(sizeof...(Ts) + size_impl(ts...));
|
||||
join_impl(s, delimiter, ts...);
|
||||
return s;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
BENCHMARK_EXPORT
|
||||
std::string BenchmarkName::str() const {
|
||||
return join('/', function_name, args, min_time, min_warmup_time, iterations,
|
||||
repetitions, time_type, threads);
|
||||
}
|
||||
} // namespace benchmark
|
||||
544
benchmark/src/main/native/thirdparty/benchmark/src/benchmark_register.cpp
vendored
Normal file
544
benchmark/src/main/native/thirdparty/benchmark/src/benchmark_register.cpp
vendored
Normal file
@@ -0,0 +1,544 @@
|
||||
// Copyright 2015 Google Inc. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "benchmark_register.h"
|
||||
|
||||
#ifndef BENCHMARK_OS_WINDOWS
|
||||
#if !defined(BENCHMARK_OS_FUCHSIA) && !defined(BENCHMARK_OS_QURT)
|
||||
#include <sys/resource.h>
|
||||
#endif
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
#include <atomic>
|
||||
#include <cinttypes>
|
||||
#include <condition_variable>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <numeric>
|
||||
#include <sstream>
|
||||
#include <thread>
|
||||
|
||||
#include "benchmark/benchmark.h"
|
||||
#include "benchmark_api_internal.h"
|
||||
#include "check.h"
|
||||
#include "commandlineflags.h"
|
||||
#include "complexity.h"
|
||||
#include "internal_macros.h"
|
||||
#include "log.h"
|
||||
#include "mutex.h"
|
||||
#include "re.h"
|
||||
#include "statistics.h"
|
||||
#include "string_util.h"
|
||||
#include "timers.h"
|
||||
|
||||
namespace benchmark {
|
||||
|
||||
namespace {
|
||||
// For non-dense Range, intermediate values are powers of kRangeMultiplier.
|
||||
constexpr int kRangeMultiplier = 8;
|
||||
|
||||
// The size of a benchmark family determines is the number of inputs to repeat
|
||||
// the benchmark on. If this is "large" then warn the user during configuration.
|
||||
constexpr size_t kMaxFamilySize = 100;
|
||||
|
||||
constexpr char kDisabledPrefix[] = "DISABLED_";
|
||||
} // end namespace
|
||||
|
||||
namespace internal {
|
||||
|
||||
//=============================================================================//
|
||||
// BenchmarkFamilies
|
||||
//=============================================================================//
|
||||
|
||||
// Class for managing registered benchmarks. Note that each registered
|
||||
// benchmark identifies a family of related benchmarks to run.
|
||||
class BenchmarkFamilies {
|
||||
public:
|
||||
static BenchmarkFamilies* GetInstance();
|
||||
|
||||
// Registers a benchmark family and returns the index assigned to it.
|
||||
size_t AddBenchmark(std::unique_ptr<Benchmark> family);
|
||||
|
||||
// Clear all registered benchmark families.
|
||||
void ClearBenchmarks();
|
||||
|
||||
// Extract the list of benchmark instances that match the specified
|
||||
// regular expression.
|
||||
bool FindBenchmarks(std::string spec,
|
||||
std::vector<BenchmarkInstance>* benchmarks,
|
||||
std::ostream* Err);
|
||||
|
||||
private:
|
||||
BenchmarkFamilies() {}
|
||||
|
||||
std::vector<std::unique_ptr<Benchmark>> families_;
|
||||
Mutex mutex_;
|
||||
};
|
||||
|
||||
BenchmarkFamilies* BenchmarkFamilies::GetInstance() {
|
||||
static BenchmarkFamilies instance;
|
||||
return &instance;
|
||||
}
|
||||
|
||||
size_t BenchmarkFamilies::AddBenchmark(std::unique_ptr<Benchmark> family) {
|
||||
MutexLock l(mutex_);
|
||||
size_t index = families_.size();
|
||||
families_.push_back(std::move(family));
|
||||
return index;
|
||||
}
|
||||
|
||||
void BenchmarkFamilies::ClearBenchmarks() {
|
||||
MutexLock l(mutex_);
|
||||
families_.clear();
|
||||
families_.shrink_to_fit();
|
||||
}
|
||||
|
||||
bool BenchmarkFamilies::FindBenchmarks(
|
||||
std::string spec, std::vector<BenchmarkInstance>* benchmarks,
|
||||
std::ostream* ErrStream) {
|
||||
BM_CHECK(ErrStream);
|
||||
auto& Err = *ErrStream;
|
||||
// Make regular expression out of command-line flag
|
||||
std::string error_msg;
|
||||
Regex re;
|
||||
bool is_negative_filter = false;
|
||||
if (spec[0] == '-') {
|
||||
spec.replace(0, 1, "");
|
||||
is_negative_filter = true;
|
||||
}
|
||||
if (!re.Init(spec, &error_msg)) {
|
||||
Err << "Could not compile benchmark re: " << error_msg << '\n';
|
||||
return false;
|
||||
}
|
||||
|
||||
// Special list of thread counts to use when none are specified
|
||||
const std::vector<int> one_thread = {1};
|
||||
|
||||
int next_family_index = 0;
|
||||
|
||||
MutexLock l(mutex_);
|
||||
for (std::unique_ptr<Benchmark>& family : families_) {
|
||||
int family_index = next_family_index;
|
||||
int per_family_instance_index = 0;
|
||||
|
||||
// Family was deleted or benchmark doesn't match
|
||||
if (!family) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (family->ArgsCnt() == -1) {
|
||||
family->Args({});
|
||||
}
|
||||
const std::vector<int>* thread_counts =
|
||||
(family->thread_counts_.empty()
|
||||
? &one_thread
|
||||
: &static_cast<const std::vector<int>&>(family->thread_counts_));
|
||||
const size_t family_size = family->args_.size() * thread_counts->size();
|
||||
// The benchmark will be run at least 'family_size' different inputs.
|
||||
// If 'family_size' is very large warn the user.
|
||||
if (family_size > kMaxFamilySize) {
|
||||
Err << "The number of inputs is very large. " << family->name_
|
||||
<< " will be repeated at least " << family_size << " times.\n";
|
||||
}
|
||||
// reserve in the special case the regex ".", since we know the final
|
||||
// family size. this doesn't take into account any disabled benchmarks
|
||||
// so worst case we reserve more than we need.
|
||||
if (spec == ".") {
|
||||
benchmarks->reserve(benchmarks->size() + family_size);
|
||||
}
|
||||
|
||||
for (auto const& args : family->args_) {
|
||||
for (int num_threads : *thread_counts) {
|
||||
BenchmarkInstance instance(family.get(), family_index,
|
||||
per_family_instance_index, args,
|
||||
num_threads);
|
||||
|
||||
const auto full_name = instance.name().str();
|
||||
if (full_name.rfind(kDisabledPrefix, 0) != 0 &&
|
||||
((re.Match(full_name) && !is_negative_filter) ||
|
||||
(!re.Match(full_name) && is_negative_filter))) {
|
||||
benchmarks->push_back(std::move(instance));
|
||||
|
||||
++per_family_instance_index;
|
||||
|
||||
// Only bump the next family index once we've estabilished that
|
||||
// at least one instance of this family will be run.
|
||||
if (next_family_index == family_index) {
|
||||
++next_family_index;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Benchmark* RegisterBenchmarkInternal(std::unique_ptr<Benchmark> bench) {
|
||||
Benchmark* bench_ptr = bench.get();
|
||||
BenchmarkFamilies* families = BenchmarkFamilies::GetInstance();
|
||||
families->AddBenchmark(std::move(bench));
|
||||
return bench_ptr;
|
||||
}
|
||||
|
||||
// FIXME: This function is a hack so that benchmark.cc can access
|
||||
// `BenchmarkFamilies`
|
||||
bool FindBenchmarksInternal(const std::string& re,
|
||||
std::vector<BenchmarkInstance>* benchmarks,
|
||||
std::ostream* Err) {
|
||||
return BenchmarkFamilies::GetInstance()->FindBenchmarks(re, benchmarks, Err);
|
||||
}
|
||||
|
||||
//=============================================================================//
|
||||
// Benchmark
|
||||
//=============================================================================//
|
||||
|
||||
Benchmark::Benchmark(const std::string& name)
|
||||
: name_(name),
|
||||
aggregation_report_mode_(ARM_Unspecified),
|
||||
time_unit_(GetDefaultTimeUnit()),
|
||||
use_default_time_unit_(true),
|
||||
range_multiplier_(kRangeMultiplier),
|
||||
min_time_(0),
|
||||
min_warmup_time_(0),
|
||||
iterations_(0),
|
||||
repetitions_(0),
|
||||
measure_process_cpu_time_(false),
|
||||
use_real_time_(false),
|
||||
use_manual_time_(false),
|
||||
complexity_(oNone),
|
||||
complexity_lambda_(nullptr) {
|
||||
ComputeStatistics("mean", StatisticsMean);
|
||||
ComputeStatistics("median", StatisticsMedian);
|
||||
ComputeStatistics("stddev", StatisticsStdDev);
|
||||
ComputeStatistics("cv", StatisticsCV, kPercentage);
|
||||
}
|
||||
|
||||
Benchmark::~Benchmark() {}
|
||||
|
||||
Benchmark* Benchmark::Name(const std::string& name) {
|
||||
SetName(name);
|
||||
return this;
|
||||
}
|
||||
|
||||
Benchmark* Benchmark::Arg(int64_t x) {
|
||||
BM_CHECK(ArgsCnt() == -1 || ArgsCnt() == 1);
|
||||
args_.push_back({x});
|
||||
return this;
|
||||
}
|
||||
|
||||
Benchmark* Benchmark::Unit(TimeUnit unit) {
|
||||
time_unit_ = unit;
|
||||
use_default_time_unit_ = false;
|
||||
return this;
|
||||
}
|
||||
|
||||
Benchmark* Benchmark::Range(int64_t start, int64_t limit) {
|
||||
BM_CHECK(ArgsCnt() == -1 || ArgsCnt() == 1);
|
||||
std::vector<int64_t> arglist;
|
||||
AddRange(&arglist, start, limit, range_multiplier_);
|
||||
|
||||
for (int64_t i : arglist) {
|
||||
args_.push_back({i});
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
Benchmark* Benchmark::Ranges(
|
||||
const std::vector<std::pair<int64_t, int64_t>>& ranges) {
|
||||
BM_CHECK(ArgsCnt() == -1 || ArgsCnt() == static_cast<int>(ranges.size()));
|
||||
std::vector<std::vector<int64_t>> arglists(ranges.size());
|
||||
for (std::size_t i = 0; i < ranges.size(); i++) {
|
||||
AddRange(&arglists[i], ranges[i].first, ranges[i].second,
|
||||
range_multiplier_);
|
||||
}
|
||||
|
||||
ArgsProduct(arglists);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
Benchmark* Benchmark::ArgsProduct(
|
||||
const std::vector<std::vector<int64_t>>& arglists) {
|
||||
BM_CHECK(ArgsCnt() == -1 || ArgsCnt() == static_cast<int>(arglists.size()));
|
||||
|
||||
std::vector<std::size_t> indices(arglists.size());
|
||||
const std::size_t total = std::accumulate(
|
||||
std::begin(arglists), std::end(arglists), std::size_t{1},
|
||||
[](const std::size_t res, const std::vector<int64_t>& arglist) {
|
||||
return res * arglist.size();
|
||||
});
|
||||
std::vector<int64_t> args;
|
||||
args.reserve(arglists.size());
|
||||
for (std::size_t i = 0; i < total; i++) {
|
||||
for (std::size_t arg = 0; arg < arglists.size(); arg++) {
|
||||
args.push_back(arglists[arg][indices[arg]]);
|
||||
}
|
||||
args_.push_back(args);
|
||||
args.clear();
|
||||
|
||||
std::size_t arg = 0;
|
||||
do {
|
||||
indices[arg] = (indices[arg] + 1) % arglists[arg].size();
|
||||
} while (indices[arg++] == 0 && arg < arglists.size());
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
Benchmark* Benchmark::ArgName(const std::string& name) {
|
||||
BM_CHECK(ArgsCnt() == -1 || ArgsCnt() == 1);
|
||||
arg_names_ = {name};
|
||||
return this;
|
||||
}
|
||||
|
||||
Benchmark* Benchmark::ArgNames(const std::vector<std::string>& names) {
|
||||
BM_CHECK(ArgsCnt() == -1 || ArgsCnt() == static_cast<int>(names.size()));
|
||||
arg_names_ = names;
|
||||
return this;
|
||||
}
|
||||
|
||||
Benchmark* Benchmark::DenseRange(int64_t start, int64_t limit, int step) {
|
||||
BM_CHECK(ArgsCnt() == -1 || ArgsCnt() == 1);
|
||||
BM_CHECK_LE(start, limit);
|
||||
for (int64_t arg = start; arg <= limit; arg += step) {
|
||||
args_.push_back({arg});
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
Benchmark* Benchmark::Args(const std::vector<int64_t>& args) {
|
||||
BM_CHECK(ArgsCnt() == -1 || ArgsCnt() == static_cast<int>(args.size()));
|
||||
args_.push_back(args);
|
||||
return this;
|
||||
}
|
||||
|
||||
Benchmark* Benchmark::Apply(void (*custom_arguments)(Benchmark* benchmark)) {
|
||||
custom_arguments(this);
|
||||
return this;
|
||||
}
|
||||
|
||||
Benchmark* Benchmark::Setup(callback_function&& setup) {
|
||||
BM_CHECK(setup != nullptr);
|
||||
setup_ = std::forward<callback_function>(setup);
|
||||
return this;
|
||||
}
|
||||
|
||||
Benchmark* Benchmark::Setup(const callback_function& setup) {
|
||||
BM_CHECK(setup != nullptr);
|
||||
setup_ = setup;
|
||||
return this;
|
||||
}
|
||||
|
||||
Benchmark* Benchmark::Teardown(callback_function&& teardown) {
|
||||
BM_CHECK(teardown != nullptr);
|
||||
teardown_ = std::forward<callback_function>(teardown);
|
||||
return this;
|
||||
}
|
||||
|
||||
Benchmark* Benchmark::Teardown(const callback_function& teardown) {
|
||||
BM_CHECK(teardown != nullptr);
|
||||
teardown_ = teardown;
|
||||
return this;
|
||||
}
|
||||
|
||||
Benchmark* Benchmark::RangeMultiplier(int multiplier) {
|
||||
BM_CHECK(multiplier > 1);
|
||||
range_multiplier_ = multiplier;
|
||||
return this;
|
||||
}
|
||||
|
||||
Benchmark* Benchmark::MinTime(double t) {
|
||||
BM_CHECK(t > 0.0);
|
||||
BM_CHECK(iterations_ == 0);
|
||||
min_time_ = t;
|
||||
return this;
|
||||
}
|
||||
|
||||
Benchmark* Benchmark::MinWarmUpTime(double t) {
|
||||
BM_CHECK(t >= 0.0);
|
||||
BM_CHECK(iterations_ == 0);
|
||||
min_warmup_time_ = t;
|
||||
return this;
|
||||
}
|
||||
|
||||
Benchmark* Benchmark::Iterations(IterationCount n) {
|
||||
BM_CHECK(n > 0);
|
||||
BM_CHECK(IsZero(min_time_));
|
||||
BM_CHECK(IsZero(min_warmup_time_));
|
||||
iterations_ = n;
|
||||
return this;
|
||||
}
|
||||
|
||||
Benchmark* Benchmark::Repetitions(int n) {
|
||||
BM_CHECK(n > 0);
|
||||
repetitions_ = n;
|
||||
return this;
|
||||
}
|
||||
|
||||
Benchmark* Benchmark::ReportAggregatesOnly(bool value) {
|
||||
aggregation_report_mode_ = value ? ARM_ReportAggregatesOnly : ARM_Default;
|
||||
return this;
|
||||
}
|
||||
|
||||
Benchmark* Benchmark::DisplayAggregatesOnly(bool value) {
|
||||
// If we were called, the report mode is no longer 'unspecified', in any case.
|
||||
aggregation_report_mode_ = static_cast<AggregationReportMode>(
|
||||
aggregation_report_mode_ | ARM_Default);
|
||||
|
||||
if (value) {
|
||||
aggregation_report_mode_ = static_cast<AggregationReportMode>(
|
||||
aggregation_report_mode_ | ARM_DisplayReportAggregatesOnly);
|
||||
} else {
|
||||
aggregation_report_mode_ = static_cast<AggregationReportMode>(
|
||||
aggregation_report_mode_ & ~ARM_DisplayReportAggregatesOnly);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
Benchmark* Benchmark::MeasureProcessCPUTime() {
|
||||
// Can be used together with UseRealTime() / UseManualTime().
|
||||
measure_process_cpu_time_ = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
Benchmark* Benchmark::UseRealTime() {
|
||||
BM_CHECK(!use_manual_time_)
|
||||
<< "Cannot set UseRealTime and UseManualTime simultaneously.";
|
||||
use_real_time_ = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
Benchmark* Benchmark::UseManualTime() {
|
||||
BM_CHECK(!use_real_time_)
|
||||
<< "Cannot set UseRealTime and UseManualTime simultaneously.";
|
||||
use_manual_time_ = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
Benchmark* Benchmark::Complexity(BigO complexity) {
|
||||
complexity_ = complexity;
|
||||
return this;
|
||||
}
|
||||
|
||||
Benchmark* Benchmark::Complexity(BigOFunc* complexity) {
|
||||
complexity_lambda_ = complexity;
|
||||
complexity_ = oLambda;
|
||||
return this;
|
||||
}
|
||||
|
||||
Benchmark* Benchmark::ComputeStatistics(const std::string& name,
|
||||
StatisticsFunc* statistics,
|
||||
StatisticUnit unit) {
|
||||
statistics_.emplace_back(name, statistics, unit);
|
||||
return this;
|
||||
}
|
||||
|
||||
Benchmark* Benchmark::Threads(int t) {
|
||||
BM_CHECK_GT(t, 0);
|
||||
thread_counts_.push_back(t);
|
||||
return this;
|
||||
}
|
||||
|
||||
Benchmark* Benchmark::ThreadRange(int min_threads, int max_threads) {
|
||||
BM_CHECK_GT(min_threads, 0);
|
||||
BM_CHECK_GE(max_threads, min_threads);
|
||||
|
||||
AddRange(&thread_counts_, min_threads, max_threads, 2);
|
||||
return this;
|
||||
}
|
||||
|
||||
Benchmark* Benchmark::DenseThreadRange(int min_threads, int max_threads,
|
||||
int stride) {
|
||||
BM_CHECK_GT(min_threads, 0);
|
||||
BM_CHECK_GE(max_threads, min_threads);
|
||||
BM_CHECK_GE(stride, 1);
|
||||
|
||||
for (auto i = min_threads; i < max_threads; i += stride) {
|
||||
thread_counts_.push_back(i);
|
||||
}
|
||||
thread_counts_.push_back(max_threads);
|
||||
return this;
|
||||
}
|
||||
|
||||
Benchmark* Benchmark::ThreadPerCpu() {
|
||||
thread_counts_.push_back(CPUInfo::Get().num_cpus);
|
||||
return this;
|
||||
}
|
||||
|
||||
Benchmark* Benchmark::ThreadRunner(threadrunner_factory&& factory) {
|
||||
threadrunner_ = std::move(factory);
|
||||
return this;
|
||||
}
|
||||
|
||||
void Benchmark::SetName(const std::string& name) { name_ = name; }
|
||||
|
||||
const char* Benchmark::GetName() const { return name_.c_str(); }
|
||||
|
||||
int Benchmark::ArgsCnt() const {
|
||||
if (args_.empty()) {
|
||||
if (arg_names_.empty()) {
|
||||
return -1;
|
||||
}
|
||||
return static_cast<int>(arg_names_.size());
|
||||
}
|
||||
return static_cast<int>(args_.front().size());
|
||||
}
|
||||
|
||||
const char* Benchmark::GetArgName(int arg) const {
|
||||
BM_CHECK_GE(arg, 0);
|
||||
size_t uarg = static_cast<size_t>(arg);
|
||||
BM_CHECK_LT(uarg, arg_names_.size());
|
||||
return arg_names_[uarg].c_str();
|
||||
}
|
||||
|
||||
TimeUnit Benchmark::GetTimeUnit() const {
|
||||
return use_default_time_unit_ ? GetDefaultTimeUnit() : time_unit_;
|
||||
}
|
||||
|
||||
//=============================================================================//
|
||||
// FunctionBenchmark
|
||||
//=============================================================================//
|
||||
|
||||
void FunctionBenchmark::Run(State& st) { func_(st); }
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
void ClearRegisteredBenchmarks() {
|
||||
internal::BenchmarkFamilies::GetInstance()->ClearBenchmarks();
|
||||
}
|
||||
|
||||
std::vector<int64_t> CreateRange(int64_t lo, int64_t hi, int multi) {
|
||||
std::vector<int64_t> args;
|
||||
internal::AddRange(&args, lo, hi, multi);
|
||||
return args;
|
||||
}
|
||||
|
||||
std::vector<int64_t> CreateDenseRange(int64_t start, int64_t limit, int step) {
|
||||
BM_CHECK_LE(start, limit);
|
||||
std::vector<int64_t> args;
|
||||
for (int64_t arg = start; arg <= limit; arg += step) {
|
||||
args.push_back(arg);
|
||||
}
|
||||
return args;
|
||||
}
|
||||
|
||||
} // end namespace benchmark
|
||||
109
benchmark/src/main/native/thirdparty/benchmark/src/benchmark_register.h
vendored
Normal file
109
benchmark/src/main/native/thirdparty/benchmark/src/benchmark_register.h
vendored
Normal file
@@ -0,0 +1,109 @@
|
||||
#ifndef BENCHMARK_REGISTER_H
|
||||
#define BENCHMARK_REGISTER_H
|
||||
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
#include <vector>
|
||||
|
||||
#include "check.h"
|
||||
|
||||
namespace benchmark {
|
||||
namespace internal {
|
||||
|
||||
// Append the powers of 'mult' in the closed interval [lo, hi].
|
||||
// Returns iterator to the start of the inserted range.
|
||||
template <typename T>
|
||||
typename std::vector<T>::iterator AddPowers(std::vector<T>* dst, T lo, T hi,
|
||||
int mult) {
|
||||
BM_CHECK_GE(lo, 0);
|
||||
BM_CHECK_GE(hi, lo);
|
||||
BM_CHECK_GE(mult, 2);
|
||||
|
||||
const size_t start_offset = dst->size();
|
||||
|
||||
static const T kmax = std::numeric_limits<T>::max();
|
||||
|
||||
// Space out the values in multiples of "mult"
|
||||
for (T i = static_cast<T>(1); i <= hi; i = static_cast<T>(i * mult)) {
|
||||
if (i >= lo) {
|
||||
dst->push_back(i);
|
||||
}
|
||||
// Break the loop here since multiplying by
|
||||
// 'mult' would move outside of the range of T
|
||||
if (i > kmax / mult) break;
|
||||
}
|
||||
|
||||
return dst->begin() + static_cast<int>(start_offset);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void AddNegatedPowers(std::vector<T>* dst, T lo, T hi, int mult) {
|
||||
// We negate lo and hi so we require that they cannot be equal to 'min'.
|
||||
BM_CHECK_GT(lo, std::numeric_limits<T>::min());
|
||||
BM_CHECK_GT(hi, std::numeric_limits<T>::min());
|
||||
BM_CHECK_GE(hi, lo);
|
||||
BM_CHECK_LE(hi, 0);
|
||||
|
||||
// Add positive powers, then negate and reverse.
|
||||
// Casts necessary since small integers get promoted
|
||||
// to 'int' when negating.
|
||||
const auto lo_complement = static_cast<T>(-lo);
|
||||
const auto hi_complement = static_cast<T>(-hi);
|
||||
|
||||
const auto it = AddPowers(dst, hi_complement, lo_complement, mult);
|
||||
|
||||
std::for_each(it, dst->end(), [](T& t) { t = static_cast<T>(t * -1); });
|
||||
std::reverse(it, dst->end());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void AddRange(std::vector<T>* dst, T lo, T hi, int mult) {
|
||||
static_assert(std::is_integral<T>::value && std::is_signed<T>::value,
|
||||
"Args type must be a signed integer");
|
||||
|
||||
BM_CHECK_GE(hi, lo);
|
||||
BM_CHECK_GE(mult, 2);
|
||||
|
||||
// Add "lo"
|
||||
dst->push_back(lo);
|
||||
|
||||
// Handle lo == hi as a special case, so we then know
|
||||
// lo < hi and so it is safe to add 1 to lo and subtract 1
|
||||
// from hi without falling outside of the range of T.
|
||||
if (lo == hi) return;
|
||||
|
||||
// Ensure that lo_inner <= hi_inner below.
|
||||
if (lo + 1 == hi) {
|
||||
dst->push_back(hi);
|
||||
return;
|
||||
}
|
||||
|
||||
// Add all powers of 'mult' in the range [lo+1, hi-1] (inclusive).
|
||||
const auto lo_inner = static_cast<T>(lo + 1);
|
||||
const auto hi_inner = static_cast<T>(hi - 1);
|
||||
|
||||
// Insert negative values
|
||||
if (lo_inner < 0) {
|
||||
AddNegatedPowers(dst, lo_inner, std::min(hi_inner, T{-1}), mult);
|
||||
}
|
||||
|
||||
// Treat 0 as a special case (see discussion on #762).
|
||||
if (lo < 0 && hi >= 0) {
|
||||
dst->push_back(0);
|
||||
}
|
||||
|
||||
// Insert positive values
|
||||
if (hi_inner > 0) {
|
||||
AddPowers(dst, std::max(lo_inner, T{1}), hi_inner, mult);
|
||||
}
|
||||
|
||||
// Add "hi" (if different from last value).
|
||||
if (hi != dst->back()) {
|
||||
dst->push_back(hi);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace benchmark
|
||||
|
||||
#endif // BENCHMARK_REGISTER_H
|
||||
573
benchmark/src/main/native/thirdparty/benchmark/src/benchmark_runner.cpp
vendored
Normal file
573
benchmark/src/main/native/thirdparty/benchmark/src/benchmark_runner.cpp
vendored
Normal file
@@ -0,0 +1,573 @@
|
||||
// Copyright 2015 Google Inc. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "benchmark_runner.h"
|
||||
|
||||
#include "benchmark/benchmark.h"
|
||||
#include "benchmark_api_internal.h"
|
||||
#include "internal_macros.h"
|
||||
|
||||
#ifndef BENCHMARK_OS_WINDOWS
|
||||
#if !defined(BENCHMARK_OS_FUCHSIA) && !defined(BENCHMARK_OS_QURT)
|
||||
#include <sys/resource.h>
|
||||
#endif
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
#include <atomic>
|
||||
#include <climits>
|
||||
#include <cmath>
|
||||
#include <condition_variable>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <fstream>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <utility>
|
||||
|
||||
#include "check.h"
|
||||
#include "colorprint.h"
|
||||
#include "commandlineflags.h"
|
||||
#include "complexity.h"
|
||||
#include "counter.h"
|
||||
#include "log.h"
|
||||
#include "mutex.h"
|
||||
#include "perf_counters.h"
|
||||
#include "re.h"
|
||||
#include "statistics.h"
|
||||
#include "string_util.h"
|
||||
#include "thread_manager.h"
|
||||
#include "thread_timer.h"
|
||||
|
||||
namespace benchmark {
|
||||
|
||||
BM_DECLARE_bool(benchmark_dry_run);
|
||||
BM_DECLARE_string(benchmark_min_time);
|
||||
BM_DECLARE_double(benchmark_min_warmup_time);
|
||||
BM_DECLARE_int32(benchmark_repetitions);
|
||||
BM_DECLARE_bool(benchmark_report_aggregates_only);
|
||||
BM_DECLARE_bool(benchmark_display_aggregates_only);
|
||||
BM_DECLARE_string(benchmark_perf_counters);
|
||||
|
||||
namespace internal {
|
||||
|
||||
MemoryManager* memory_manager = nullptr;
|
||||
|
||||
ProfilerManager* profiler_manager = nullptr;
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr IterationCount kMaxIterations = 1000000000000;
|
||||
const double kDefaultMinTime =
|
||||
std::strtod(::benchmark::kDefaultMinTimeStr, /*p_end*/ nullptr);
|
||||
|
||||
BenchmarkReporter::Run CreateRunReport(
|
||||
const benchmark::internal::BenchmarkInstance& b,
|
||||
const internal::ThreadManager::Result& results,
|
||||
IterationCount memory_iterations,
|
||||
const MemoryManager::Result& memory_result, double seconds,
|
||||
int64_t repetition_index, int64_t repeats) {
|
||||
// Create report about this benchmark run.
|
||||
BenchmarkReporter::Run report;
|
||||
|
||||
report.run_name = b.name();
|
||||
report.family_index = b.family_index();
|
||||
report.per_family_instance_index = b.per_family_instance_index();
|
||||
report.skipped = results.skipped_;
|
||||
report.skip_message = results.skip_message_;
|
||||
report.report_label = results.report_label_;
|
||||
// This is the total iterations across all threads.
|
||||
report.iterations = results.iterations;
|
||||
report.time_unit = b.time_unit();
|
||||
report.threads = b.threads();
|
||||
report.repetition_index = repetition_index;
|
||||
report.repetitions = repeats;
|
||||
|
||||
if (report.skipped == 0u) {
|
||||
if (b.use_manual_time()) {
|
||||
report.real_accumulated_time = results.manual_time_used;
|
||||
} else {
|
||||
report.real_accumulated_time = results.real_time_used;
|
||||
}
|
||||
report.use_real_time_for_initial_big_o = b.use_manual_time();
|
||||
report.cpu_accumulated_time = results.cpu_time_used;
|
||||
report.complexity_n = results.complexity_n;
|
||||
report.complexity = b.complexity();
|
||||
report.complexity_lambda = b.complexity_lambda();
|
||||
report.statistics = &b.statistics();
|
||||
report.counters = results.counters;
|
||||
|
||||
if (memory_iterations > 0) {
|
||||
report.memory_result = memory_result;
|
||||
report.allocs_per_iter =
|
||||
memory_iterations != 0
|
||||
? static_cast<double>(memory_result.num_allocs) /
|
||||
static_cast<double>(memory_iterations)
|
||||
: 0;
|
||||
}
|
||||
|
||||
internal::Finish(&report.counters, results.iterations, seconds,
|
||||
b.threads());
|
||||
}
|
||||
return report;
|
||||
}
|
||||
|
||||
// Execute one thread of benchmark b for the specified number of iterations.
|
||||
// Adds the stats collected for the thread into manager->results.
|
||||
void RunInThread(const BenchmarkInstance* b, IterationCount iters,
|
||||
int thread_id, ThreadManager* manager,
|
||||
PerfCountersMeasurement* perf_counters_measurement,
|
||||
ProfilerManager* profiler_manager_) {
|
||||
internal::ThreadTimer timer(
|
||||
b->measure_process_cpu_time()
|
||||
? internal::ThreadTimer::CreateProcessCpuTime()
|
||||
: internal::ThreadTimer::Create());
|
||||
|
||||
State st = b->Run(iters, thread_id, &timer, manager,
|
||||
perf_counters_measurement, profiler_manager_);
|
||||
if (!(st.skipped() || st.iterations() >= st.max_iterations)) {
|
||||
st.SkipWithError(
|
||||
"The benchmark didn't run, nor was it explicitly skipped. Please call "
|
||||
"'SkipWithXXX` in your benchmark as appropriate.");
|
||||
}
|
||||
{
|
||||
MutexLock l(manager->GetBenchmarkMutex());
|
||||
internal::ThreadManager::Result& results = manager->results;
|
||||
results.iterations += st.iterations();
|
||||
results.cpu_time_used += timer.cpu_time_used();
|
||||
results.real_time_used += timer.real_time_used();
|
||||
results.manual_time_used += timer.manual_time_used();
|
||||
results.complexity_n += st.complexity_length_n();
|
||||
internal::Increment(&results.counters, st.counters);
|
||||
}
|
||||
manager->NotifyThreadComplete();
|
||||
}
|
||||
|
||||
double ComputeMinTime(const benchmark::internal::BenchmarkInstance& b,
|
||||
const BenchTimeType& iters_or_time) {
|
||||
if (!IsZero(b.min_time())) {
|
||||
return b.min_time();
|
||||
}
|
||||
// If the flag was used to specify number of iters, then return the default
|
||||
// min_time.
|
||||
if (iters_or_time.tag == BenchTimeType::ITERS) {
|
||||
return kDefaultMinTime;
|
||||
}
|
||||
|
||||
return iters_or_time.time;
|
||||
}
|
||||
|
||||
IterationCount ComputeIters(const benchmark::internal::BenchmarkInstance& b,
|
||||
const BenchTimeType& iters_or_time) {
|
||||
if (b.iterations() != 0) {
|
||||
return b.iterations();
|
||||
}
|
||||
|
||||
// We've already concluded that this flag is currently used to pass
|
||||
// iters but do a check here again anyway.
|
||||
BM_CHECK(iters_or_time.tag == BenchTimeType::ITERS);
|
||||
return iters_or_time.iters;
|
||||
}
|
||||
|
||||
class ThreadRunnerDefault : public ThreadRunnerBase {
|
||||
public:
|
||||
explicit ThreadRunnerDefault(int num_threads)
|
||||
: pool(static_cast<size_t>(num_threads - 1)) {}
|
||||
|
||||
void RunThreads(const std::function<void(int)>& fn) final {
|
||||
// Run all but one thread in separate threads
|
||||
for (std::size_t ti = 0; ti < pool.size(); ++ti) {
|
||||
pool[ti] = std::thread(fn, static_cast<int>(ti + 1));
|
||||
}
|
||||
// And run one thread here directly.
|
||||
// (If we were asked to run just one thread, we don't create new threads.)
|
||||
// Yes, we need to do this here *after* we start the separate threads.
|
||||
fn(0);
|
||||
|
||||
// The main thread has finished. Now let's wait for the other threads.
|
||||
for (std::thread& thread : pool) {
|
||||
thread.join();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<std::thread> pool;
|
||||
};
|
||||
|
||||
std::unique_ptr<ThreadRunnerBase> GetThreadRunner(
|
||||
const threadrunner_factory& userThreadRunnerFactory, int num_threads) {
|
||||
return userThreadRunnerFactory
|
||||
? userThreadRunnerFactory(num_threads)
|
||||
: std::make_unique<ThreadRunnerDefault>(num_threads);
|
||||
}
|
||||
|
||||
} // end namespace
|
||||
|
||||
BenchTimeType ParseBenchMinTime(const std::string& value) {
|
||||
BenchTimeType ret = {};
|
||||
|
||||
if (value.empty()) {
|
||||
ret.tag = BenchTimeType::TIME;
|
||||
ret.time = 0.0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (value.back() == 'x') {
|
||||
char* p_end = nullptr;
|
||||
// Reset errno before it's changed by strtol.
|
||||
errno = 0;
|
||||
IterationCount num_iters = std::strtol(value.c_str(), &p_end, 10);
|
||||
|
||||
// After a valid parse, p_end should have been set to
|
||||
// point to the 'x' suffix.
|
||||
BM_CHECK(errno == 0 && p_end != nullptr && *p_end == 'x')
|
||||
<< "Malformed iters value passed to --benchmark_min_time: `" << value
|
||||
<< "`. Expected --benchmark_min_time=<integer>x.";
|
||||
|
||||
ret.tag = BenchTimeType::ITERS;
|
||||
ret.iters = num_iters;
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool has_suffix = value.back() == 's';
|
||||
if (!has_suffix) {
|
||||
BM_VLOG(0) << "Value passed to --benchmark_min_time should have a suffix. "
|
||||
"Eg., `30s` for 30-seconds.";
|
||||
}
|
||||
|
||||
char* p_end = nullptr;
|
||||
// Reset errno before it's changed by strtod.
|
||||
errno = 0;
|
||||
double min_time = std::strtod(value.c_str(), &p_end);
|
||||
|
||||
// After a successful parse, p_end should point to the suffix 's',
|
||||
// or the end of the string if the suffix was omitted.
|
||||
BM_CHECK(errno == 0 && p_end != nullptr &&
|
||||
((has_suffix && *p_end == 's') || *p_end == '\0'))
|
||||
<< "Malformed seconds value passed to --benchmark_min_time: `" << value
|
||||
<< "`. Expected --benchmark_min_time=<float>x.";
|
||||
|
||||
ret.tag = BenchTimeType::TIME;
|
||||
ret.time = min_time;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
BenchmarkRunner::BenchmarkRunner(
|
||||
const benchmark::internal::BenchmarkInstance& b_,
|
||||
PerfCountersMeasurement* pcm_,
|
||||
BenchmarkReporter::PerFamilyRunReports* reports_for_family_)
|
||||
: b(b_),
|
||||
reports_for_family(reports_for_family_),
|
||||
parsed_benchtime_flag(ParseBenchMinTime(FLAGS_benchmark_min_time)),
|
||||
min_time(FLAGS_benchmark_dry_run
|
||||
? 0
|
||||
: ComputeMinTime(b_, parsed_benchtime_flag)),
|
||||
min_warmup_time(
|
||||
FLAGS_benchmark_dry_run
|
||||
? 0
|
||||
: ((!IsZero(b.min_time()) && b.min_warmup_time() > 0.0)
|
||||
? b.min_warmup_time()
|
||||
: FLAGS_benchmark_min_warmup_time)),
|
||||
warmup_done(FLAGS_benchmark_dry_run ? true : !(min_warmup_time > 0.0)),
|
||||
repeats(FLAGS_benchmark_dry_run
|
||||
? 1
|
||||
: (b.repetitions() != 0 ? b.repetitions()
|
||||
: FLAGS_benchmark_repetitions)),
|
||||
has_explicit_iteration_count(b.iterations() != 0 ||
|
||||
parsed_benchtime_flag.tag ==
|
||||
BenchTimeType::ITERS),
|
||||
thread_runner(
|
||||
GetThreadRunner(b.GetUserThreadRunnerFactory(), b.threads())),
|
||||
iters(FLAGS_benchmark_dry_run
|
||||
? 1
|
||||
: (has_explicit_iteration_count
|
||||
? ComputeIters(b_, parsed_benchtime_flag)
|
||||
: 1)),
|
||||
perf_counters_measurement_ptr(pcm_) {
|
||||
run_results.display_report_aggregates_only =
|
||||
(FLAGS_benchmark_report_aggregates_only ||
|
||||
FLAGS_benchmark_display_aggregates_only);
|
||||
run_results.file_report_aggregates_only =
|
||||
FLAGS_benchmark_report_aggregates_only;
|
||||
if (b.aggregation_report_mode() != internal::ARM_Unspecified) {
|
||||
run_results.display_report_aggregates_only =
|
||||
((b.aggregation_report_mode() &
|
||||
internal::ARM_DisplayReportAggregatesOnly) != 0u);
|
||||
run_results.file_report_aggregates_only =
|
||||
((b.aggregation_report_mode() &
|
||||
internal::ARM_FileReportAggregatesOnly) != 0u);
|
||||
BM_CHECK(FLAGS_benchmark_perf_counters.empty() ||
|
||||
(perf_counters_measurement_ptr->num_counters() == 0))
|
||||
<< "Perf counters were requested but could not be set up.";
|
||||
}
|
||||
}
|
||||
|
||||
BenchmarkRunner::IterationResults BenchmarkRunner::DoNIterations() {
|
||||
BM_VLOG(2) << "Running " << b.name().str() << " for " << iters << "\n";
|
||||
|
||||
std::unique_ptr<internal::ThreadManager> manager;
|
||||
manager.reset(new internal::ThreadManager(b.threads()));
|
||||
|
||||
thread_runner->RunThreads([&](int thread_idx) {
|
||||
RunInThread(&b, iters, thread_idx, manager.get(),
|
||||
perf_counters_measurement_ptr, /*profiler_manager=*/nullptr);
|
||||
});
|
||||
|
||||
IterationResults i;
|
||||
// Acquire the measurements/counters from the manager, UNDER THE LOCK!
|
||||
{
|
||||
MutexLock l(manager->GetBenchmarkMutex());
|
||||
i.results = manager->results;
|
||||
}
|
||||
|
||||
// And get rid of the manager.
|
||||
manager.reset();
|
||||
|
||||
BM_VLOG(2) << "Ran in " << i.results.cpu_time_used << "/"
|
||||
<< i.results.real_time_used << "\n";
|
||||
|
||||
// By using KeepRunningBatch a benchmark can iterate more times than
|
||||
// requested, so take the iteration count from i.results.
|
||||
i.iters = i.results.iterations / b.threads();
|
||||
|
||||
// Base decisions off of real time if requested by this benchmark.
|
||||
i.seconds = i.results.cpu_time_used;
|
||||
if (b.use_manual_time()) {
|
||||
i.seconds = i.results.manual_time_used;
|
||||
} else if (b.use_real_time()) {
|
||||
i.seconds = i.results.real_time_used;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
IterationCount BenchmarkRunner::PredictNumItersNeeded(
|
||||
const IterationResults& i) const {
|
||||
// See how much iterations should be increased by.
|
||||
// Note: Avoid division by zero with max(seconds, 1ns).
|
||||
double multiplier = GetMinTimeToApply() * 1.4 / std::max(i.seconds, 1e-9);
|
||||
// If our last run was at least 10% of FLAGS_benchmark_min_time then we
|
||||
// use the multiplier directly.
|
||||
// Otherwise we use at most 10 times expansion.
|
||||
// NOTE: When the last run was at least 10% of the min time the max
|
||||
// expansion should be 14x.
|
||||
const bool is_significant = (i.seconds / GetMinTimeToApply()) > 0.1;
|
||||
multiplier = is_significant ? multiplier : 10.0;
|
||||
|
||||
// So what seems to be the sufficiently-large iteration count? Round up.
|
||||
const IterationCount max_next_iters = static_cast<IterationCount>(
|
||||
std::llround(std::max(multiplier * static_cast<double>(i.iters),
|
||||
static_cast<double>(i.iters) + 1.0)));
|
||||
// But we do have *some* limits though..
|
||||
const IterationCount next_iters = std::min(max_next_iters, kMaxIterations);
|
||||
|
||||
BM_VLOG(3) << "Next iters: " << next_iters << ", " << multiplier << "\n";
|
||||
return next_iters; // round up before conversion to integer.
|
||||
}
|
||||
|
||||
bool BenchmarkRunner::ShouldReportIterationResults(
|
||||
const IterationResults& i) const {
|
||||
// Determine if this run should be reported;
|
||||
// Either it has run for a sufficient amount of time
|
||||
// or because an error was reported.
|
||||
return (i.results.skipped_ != 0u) || FLAGS_benchmark_dry_run ||
|
||||
i.iters >= kMaxIterations || // Too many iterations already.
|
||||
i.seconds >=
|
||||
GetMinTimeToApply() || // The elapsed time is large enough.
|
||||
// CPU time is specified but the elapsed real time greatly exceeds
|
||||
// the minimum time.
|
||||
// Note that user provided timers are except from this test.
|
||||
((i.results.real_time_used >= 5 * GetMinTimeToApply()) &&
|
||||
!b.use_manual_time());
|
||||
}
|
||||
|
||||
double BenchmarkRunner::GetMinTimeToApply() const {
|
||||
// In order to re-use functionality to run and measure benchmarks for running
|
||||
// a warmup phase of the benchmark, we need a way of telling whether to apply
|
||||
// min_time or min_warmup_time. This function will figure out if we are in the
|
||||
// warmup phase and therefore need to apply min_warmup_time or if we already
|
||||
// in the benchmarking phase and min_time needs to be applied.
|
||||
return warmup_done ? min_time : min_warmup_time;
|
||||
}
|
||||
|
||||
void BenchmarkRunner::FinishWarmUp(const IterationCount& i) {
|
||||
warmup_done = true;
|
||||
iters = i;
|
||||
}
|
||||
|
||||
void BenchmarkRunner::RunWarmUp() {
|
||||
// Use the same mechanisms for warming up the benchmark as used for actually
|
||||
// running and measuring the benchmark.
|
||||
IterationResults i_warmup;
|
||||
// Dont use the iterations determined in the warmup phase for the actual
|
||||
// measured benchmark phase. While this may be a good starting point for the
|
||||
// benchmark and it would therefore get rid of the need to figure out how many
|
||||
// iterations are needed if min_time is set again, this may also be a complete
|
||||
// wrong guess since the warmup loops might be considerably slower (e.g
|
||||
// because of caching effects).
|
||||
const IterationCount i_backup = iters;
|
||||
|
||||
for (;;) {
|
||||
b.Setup();
|
||||
i_warmup = DoNIterations();
|
||||
b.Teardown();
|
||||
|
||||
const bool finish = ShouldReportIterationResults(i_warmup);
|
||||
|
||||
if (finish) {
|
||||
FinishWarmUp(i_backup);
|
||||
break;
|
||||
}
|
||||
|
||||
// Although we are running "only" a warmup phase where running enough
|
||||
// iterations at once without measuring time isn't as important as it is for
|
||||
// the benchmarking phase, we still do it the same way as otherwise it is
|
||||
// very confusing for the user to know how to choose a proper value for
|
||||
// min_warmup_time if a different approach on running it is used.
|
||||
iters = PredictNumItersNeeded(i_warmup);
|
||||
assert(iters > i_warmup.iters &&
|
||||
"if we did more iterations than we want to do the next time, "
|
||||
"then we should have accepted the current iteration run.");
|
||||
}
|
||||
}
|
||||
|
||||
MemoryManager::Result BenchmarkRunner::RunMemoryManager(
|
||||
IterationCount memory_iterations) {
|
||||
memory_manager->Start();
|
||||
std::unique_ptr<internal::ThreadManager> manager;
|
||||
manager.reset(new internal::ThreadManager(1));
|
||||
b.Setup();
|
||||
RunInThread(&b, memory_iterations, 0, manager.get(),
|
||||
perf_counters_measurement_ptr,
|
||||
/*profiler_manager=*/nullptr);
|
||||
manager.reset();
|
||||
b.Teardown();
|
||||
MemoryManager::Result memory_result;
|
||||
memory_manager->Stop(memory_result);
|
||||
memory_result.memory_iterations = memory_iterations;
|
||||
return memory_result;
|
||||
}
|
||||
|
||||
void BenchmarkRunner::RunProfilerManager(IterationCount profile_iterations) {
|
||||
std::unique_ptr<internal::ThreadManager> manager;
|
||||
manager.reset(new internal::ThreadManager(1));
|
||||
b.Setup();
|
||||
RunInThread(&b, profile_iterations, 0, manager.get(),
|
||||
/*perf_counters_measurement_ptr=*/nullptr,
|
||||
/*profiler_manager=*/profiler_manager);
|
||||
manager.reset();
|
||||
b.Teardown();
|
||||
}
|
||||
|
||||
void BenchmarkRunner::DoOneRepetition() {
|
||||
assert(HasRepeatsRemaining() && "Already done all repetitions?");
|
||||
|
||||
const bool is_the_first_repetition = num_repetitions_done == 0;
|
||||
|
||||
// In case a warmup phase is requested by the benchmark, run it now.
|
||||
// After running the warmup phase the BenchmarkRunner should be in a state as
|
||||
// this warmup never happened except the fact that warmup_done is set. Every
|
||||
// other manipulation of the BenchmarkRunner instance would be a bug! Please
|
||||
// fix it.
|
||||
if (!warmup_done) {
|
||||
RunWarmUp();
|
||||
}
|
||||
|
||||
IterationResults i;
|
||||
// We *may* be gradually increasing the length (iteration count)
|
||||
// of the benchmark until we decide the results are significant.
|
||||
// And once we do, we report those last results and exit.
|
||||
// Please do note that the if there are repetitions, the iteration count
|
||||
// is *only* calculated for the *first* repetition, and other repetitions
|
||||
// simply use that precomputed iteration count.
|
||||
for (;;) {
|
||||
b.Setup();
|
||||
i = DoNIterations();
|
||||
b.Teardown();
|
||||
|
||||
// Do we consider the results to be significant?
|
||||
// If we are doing repetitions, and the first repetition was already done,
|
||||
// it has calculated the correct iteration time, so we have run that very
|
||||
// iteration count just now. No need to calculate anything. Just report.
|
||||
// Else, the normal rules apply.
|
||||
const bool results_are_significant = !is_the_first_repetition ||
|
||||
has_explicit_iteration_count ||
|
||||
ShouldReportIterationResults(i);
|
||||
// Good, let's report them!
|
||||
if (results_are_significant) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Nope, bad iteration. Let's re-estimate the hopefully-sufficient
|
||||
// iteration count, and run the benchmark again...
|
||||
|
||||
iters = PredictNumItersNeeded(i);
|
||||
assert(iters > i.iters &&
|
||||
"if we did more iterations than we want to do the next time, "
|
||||
"then we should have accepted the current iteration run.");
|
||||
}
|
||||
|
||||
// Produce memory measurements if requested.
|
||||
MemoryManager::Result memory_result;
|
||||
IterationCount memory_iterations = 0;
|
||||
if (memory_manager != nullptr) {
|
||||
// Only run a few iterations to reduce the impact of one-time
|
||||
// allocations in benchmarks that are not properly managed.
|
||||
memory_iterations = std::min<IterationCount>(16, iters);
|
||||
memory_result = RunMemoryManager(memory_iterations);
|
||||
}
|
||||
|
||||
if (profiler_manager != nullptr) {
|
||||
// We want to externally profile the benchmark for the same number of
|
||||
// iterations because, for example, if we're tracing the benchmark then we
|
||||
// want trace data to reasonably match PMU data.
|
||||
RunProfilerManager(iters);
|
||||
}
|
||||
|
||||
// Ok, now actually report.
|
||||
BenchmarkReporter::Run report =
|
||||
CreateRunReport(b, i.results, memory_iterations, memory_result, i.seconds,
|
||||
num_repetitions_done, repeats);
|
||||
|
||||
if (reports_for_family != nullptr) {
|
||||
++reports_for_family->num_runs_done;
|
||||
if (report.skipped == 0u) {
|
||||
reports_for_family->Runs.push_back(report);
|
||||
}
|
||||
}
|
||||
|
||||
run_results.non_aggregates.push_back(report);
|
||||
|
||||
++num_repetitions_done;
|
||||
}
|
||||
|
||||
RunResults&& BenchmarkRunner::GetResults() {
|
||||
assert(!HasRepeatsRemaining() && "Did not run all repetitions yet?");
|
||||
|
||||
// Calculate additional statistics over the repetitions of this instance.
|
||||
run_results.aggregates_only = ComputeStats(run_results.non_aggregates);
|
||||
|
||||
return std::move(run_results);
|
||||
}
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
} // end namespace benchmark
|
||||
127
benchmark/src/main/native/thirdparty/benchmark/src/benchmark_runner.h
vendored
Normal file
127
benchmark/src/main/native/thirdparty/benchmark/src/benchmark_runner.h
vendored
Normal file
@@ -0,0 +1,127 @@
|
||||
// Copyright 2015 Google Inc. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef BENCHMARK_RUNNER_H_
|
||||
#define BENCHMARK_RUNNER_H_
|
||||
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
#include "benchmark_api_internal.h"
|
||||
#include "perf_counters.h"
|
||||
#include "thread_manager.h"
|
||||
|
||||
namespace benchmark {
|
||||
|
||||
namespace internal {
|
||||
|
||||
extern MemoryManager* memory_manager;
|
||||
extern ProfilerManager* profiler_manager;
|
||||
|
||||
struct RunResults {
|
||||
std::vector<BenchmarkReporter::Run> non_aggregates;
|
||||
std::vector<BenchmarkReporter::Run> aggregates_only;
|
||||
|
||||
bool display_report_aggregates_only = false;
|
||||
bool file_report_aggregates_only = false;
|
||||
};
|
||||
|
||||
struct BENCHMARK_EXPORT BenchTimeType {
|
||||
enum { UNSPECIFIED, ITERS, TIME } tag;
|
||||
union {
|
||||
IterationCount iters;
|
||||
double time;
|
||||
};
|
||||
};
|
||||
|
||||
BENCHMARK_EXPORT
|
||||
BenchTimeType ParseBenchMinTime(const std::string& value);
|
||||
|
||||
class BenchmarkRunner {
|
||||
public:
|
||||
BenchmarkRunner(const benchmark::internal::BenchmarkInstance& b_,
|
||||
benchmark::internal::PerfCountersMeasurement* pcm_,
|
||||
BenchmarkReporter::PerFamilyRunReports* reports_for_family);
|
||||
|
||||
int GetNumRepeats() const { return repeats; }
|
||||
|
||||
bool HasRepeatsRemaining() const {
|
||||
return GetNumRepeats() != num_repetitions_done;
|
||||
}
|
||||
|
||||
void DoOneRepetition();
|
||||
|
||||
RunResults&& GetResults();
|
||||
|
||||
BenchmarkReporter::PerFamilyRunReports* GetReportsForFamily() const {
|
||||
return reports_for_family;
|
||||
}
|
||||
|
||||
double GetMinTime() const { return min_time; }
|
||||
|
||||
bool HasExplicitIters() const { return has_explicit_iteration_count; }
|
||||
|
||||
IterationCount GetIters() const { return iters; }
|
||||
|
||||
private:
|
||||
RunResults run_results;
|
||||
|
||||
const benchmark::internal::BenchmarkInstance& b;
|
||||
BenchmarkReporter::PerFamilyRunReports* reports_for_family;
|
||||
|
||||
BenchTimeType parsed_benchtime_flag;
|
||||
const double min_time;
|
||||
const double min_warmup_time;
|
||||
bool warmup_done;
|
||||
const int repeats;
|
||||
const bool has_explicit_iteration_count;
|
||||
|
||||
int num_repetitions_done = 0;
|
||||
|
||||
std::unique_ptr<ThreadRunnerBase> thread_runner;
|
||||
|
||||
IterationCount iters; // preserved between repetitions!
|
||||
// So only the first repetition has to find/calculate it,
|
||||
// the other repetitions will just use that precomputed iteration count.
|
||||
|
||||
PerfCountersMeasurement* const perf_counters_measurement_ptr = nullptr;
|
||||
|
||||
struct IterationResults {
|
||||
internal::ThreadManager::Result results;
|
||||
IterationCount iters;
|
||||
double seconds;
|
||||
};
|
||||
IterationResults DoNIterations();
|
||||
|
||||
MemoryManager::Result RunMemoryManager(IterationCount memory_iterations);
|
||||
|
||||
void RunProfilerManager(IterationCount profile_iterations);
|
||||
|
||||
IterationCount PredictNumItersNeeded(const IterationResults& i) const;
|
||||
|
||||
bool ShouldReportIterationResults(const IterationResults& i) const;
|
||||
|
||||
double GetMinTimeToApply() const;
|
||||
|
||||
void FinishWarmUp(const IterationCount& i);
|
||||
|
||||
void RunWarmUp();
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
} // end namespace benchmark
|
||||
|
||||
#endif // BENCHMARK_RUNNER_H_
|
||||
14
benchmark/src/main/native/thirdparty/benchmark/src/check.cpp
vendored
Normal file
14
benchmark/src/main/native/thirdparty/benchmark/src/check.cpp
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
#include "check.h"
|
||||
|
||||
namespace benchmark {
|
||||
namespace internal {
|
||||
|
||||
namespace {
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
|
||||
AbortHandlerT* handler = &std::abort;
|
||||
} // namespace
|
||||
|
||||
BENCHMARK_EXPORT AbortHandlerT*& GetAbortHandler() { return handler; }
|
||||
|
||||
} // namespace internal
|
||||
} // namespace benchmark
|
||||
112
benchmark/src/main/native/thirdparty/benchmark/src/check.h
vendored
Normal file
112
benchmark/src/main/native/thirdparty/benchmark/src/check.h
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
#ifndef CHECK_H_
|
||||
#define CHECK_H_
|
||||
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
#include <ostream>
|
||||
#include <string_view>
|
||||
|
||||
#include "benchmark/export.h"
|
||||
#include "internal_macros.h"
|
||||
#include "log.h"
|
||||
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
#define BENCHMARK_NOEXCEPT noexcept
|
||||
#define BENCHMARK_NOEXCEPT_OP(x) noexcept(x)
|
||||
#elif defined(_MSC_VER) && !defined(__clang__)
|
||||
#if _MSC_VER >= 1900
|
||||
#define BENCHMARK_NOEXCEPT noexcept
|
||||
#define BENCHMARK_NOEXCEPT_OP(x) noexcept(x)
|
||||
#else
|
||||
#define BENCHMARK_NOEXCEPT
|
||||
#define BENCHMARK_NOEXCEPT_OP(x)
|
||||
#endif
|
||||
#define __func__ __FUNCTION__
|
||||
#else
|
||||
#define BENCHMARK_NOEXCEPT
|
||||
#define BENCHMARK_NOEXCEPT_OP(x)
|
||||
#endif
|
||||
|
||||
namespace benchmark {
|
||||
namespace internal {
|
||||
|
||||
typedef void(AbortHandlerT)();
|
||||
|
||||
BENCHMARK_EXPORT
|
||||
AbortHandlerT*& GetAbortHandler();
|
||||
|
||||
BENCHMARK_NORETURN inline void CallAbortHandler() {
|
||||
GetAbortHandler()();
|
||||
std::flush(std::cout);
|
||||
std::flush(std::cerr);
|
||||
std::abort(); // fallback to enforce noreturn
|
||||
}
|
||||
|
||||
// CheckHandler is the class constructed by failing BM_CHECK macros.
|
||||
// CheckHandler will log information about the failures and abort when it is
|
||||
// destructed.
|
||||
class CheckHandler {
|
||||
public:
|
||||
CheckHandler(std::string_view check, std::string_view file,
|
||||
std::string_view func, int line)
|
||||
: log_(GetErrorLogInstance()) {
|
||||
log_ << file << ":" << line << ": " << func << ": Check `" << check
|
||||
<< "' failed. ";
|
||||
}
|
||||
|
||||
LogType& GetLog() { return log_; }
|
||||
|
||||
#if defined(COMPILER_MSVC)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4722)
|
||||
#endif
|
||||
BENCHMARK_NORETURN ~CheckHandler() BENCHMARK_NOEXCEPT_OP(false) {
|
||||
log_ << '\n';
|
||||
CallAbortHandler();
|
||||
}
|
||||
#if defined(COMPILER_MSVC)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
CheckHandler& operator=(const CheckHandler&) = delete;
|
||||
CheckHandler(const CheckHandler&) = delete;
|
||||
CheckHandler() = delete;
|
||||
|
||||
private:
|
||||
LogType& log_;
|
||||
};
|
||||
|
||||
} // end namespace internal
|
||||
} // end namespace benchmark
|
||||
|
||||
// The BM_CHECK macro returns a std::ostream object that can have extra
|
||||
// information written to it.
|
||||
#ifndef NDEBUG
|
||||
#define BM_CHECK(b) \
|
||||
(b ? ::benchmark::internal::GetNullLogInstance() \
|
||||
: ::benchmark::internal::CheckHandler( \
|
||||
std::string_view(#b), std::string_view(__FILE__), \
|
||||
std::string_view(__func__), __LINE__) \
|
||||
.GetLog())
|
||||
#else
|
||||
#define BM_CHECK(b) ::benchmark::internal::GetNullLogInstance()
|
||||
#endif
|
||||
|
||||
// clang-format off
|
||||
// preserve whitespacing between operators for alignment
|
||||
#define BM_CHECK_EQ(a, b) BM_CHECK((a) == (b))
|
||||
#define BM_CHECK_NE(a, b) BM_CHECK((a) != (b))
|
||||
#define BM_CHECK_GE(a, b) BM_CHECK((a) >= (b))
|
||||
#define BM_CHECK_LE(a, b) BM_CHECK((a) <= (b))
|
||||
#define BM_CHECK_GT(a, b) BM_CHECK((a) > (b))
|
||||
#define BM_CHECK_LT(a, b) BM_CHECK((a) < (b))
|
||||
|
||||
#define BM_CHECK_FLOAT_EQ(a, b, eps) BM_CHECK(std::fabs((a) - (b)) < (eps))
|
||||
#define BM_CHECK_FLOAT_NE(a, b, eps) BM_CHECK(std::fabs((a) - (b)) >= (eps))
|
||||
#define BM_CHECK_FLOAT_GE(a, b, eps) BM_CHECK((a) - (b) > -(eps))
|
||||
#define BM_CHECK_FLOAT_LE(a, b, eps) BM_CHECK((b) - (a) > -(eps))
|
||||
#define BM_CHECK_FLOAT_GT(a, b, eps) BM_CHECK((a) - (b) > (eps))
|
||||
#define BM_CHECK_FLOAT_LT(a, b, eps) BM_CHECK((b) - (a) > (eps))
|
||||
//clang-format on
|
||||
|
||||
#endif // CHECK_H_
|
||||
222
benchmark/src/main/native/thirdparty/benchmark/src/colorprint.cpp
vendored
Normal file
222
benchmark/src/main/native/thirdparty/benchmark/src/colorprint.cpp
vendored
Normal file
@@ -0,0 +1,222 @@
|
||||
// Copyright 2015 Google Inc. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "colorprint.h"
|
||||
|
||||
#include <cstdarg>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "check.h"
|
||||
#include "internal_macros.h"
|
||||
|
||||
#ifdef BENCHMARK_OS_WINDOWS
|
||||
#include <io.h>
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif // BENCHMARK_OS_WINDOWS
|
||||
|
||||
namespace benchmark {
|
||||
namespace {
|
||||
#ifdef BENCHMARK_OS_WINDOWS
|
||||
typedef WORD PlatformColorCode;
|
||||
#else
|
||||
typedef const char* PlatformColorCode;
|
||||
#endif
|
||||
|
||||
PlatformColorCode GetPlatformColorCode(LogColor color) {
|
||||
#ifdef BENCHMARK_OS_WINDOWS
|
||||
switch (color) {
|
||||
case COLOR_RED:
|
||||
return FOREGROUND_RED;
|
||||
case COLOR_GREEN:
|
||||
return FOREGROUND_GREEN;
|
||||
case COLOR_YELLOW:
|
||||
return FOREGROUND_RED | FOREGROUND_GREEN;
|
||||
case COLOR_BLUE:
|
||||
return FOREGROUND_BLUE;
|
||||
case COLOR_MAGENTA:
|
||||
return FOREGROUND_BLUE | FOREGROUND_RED;
|
||||
case COLOR_CYAN:
|
||||
return FOREGROUND_BLUE | FOREGROUND_GREEN;
|
||||
case COLOR_WHITE: // fall through to default
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
switch (color) {
|
||||
case COLOR_RED:
|
||||
return "1";
|
||||
case COLOR_GREEN:
|
||||
return "2";
|
||||
case COLOR_YELLOW:
|
||||
return "3";
|
||||
case COLOR_BLUE:
|
||||
return "4";
|
||||
case COLOR_MAGENTA:
|
||||
return "5";
|
||||
case COLOR_CYAN:
|
||||
return "6";
|
||||
case COLOR_WHITE:
|
||||
return "7";
|
||||
default:
|
||||
return nullptr;
|
||||
};
|
||||
#endif
|
||||
}
|
||||
|
||||
} // end namespace
|
||||
|
||||
std::string FormatString(const char* msg, va_list args) {
|
||||
// we might need a second shot at this, so pre-emptivly make a copy
|
||||
va_list args_cp;
|
||||
va_copy(args_cp, args);
|
||||
|
||||
std::size_t size = 256;
|
||||
char local_buff[256];
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
|
||||
#endif // __GNUC__
|
||||
auto ret = vsnprintf(local_buff, size, msg, args_cp);
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif // __GNUC__
|
||||
|
||||
va_end(args_cp);
|
||||
|
||||
// currently there is no error handling for failure, so this is hack.
|
||||
BM_CHECK(ret >= 0);
|
||||
|
||||
if (ret == 0) { // handle empty expansion
|
||||
return {};
|
||||
}
|
||||
if (static_cast<size_t>(ret) < size) {
|
||||
return local_buff;
|
||||
}
|
||||
// we did not provide a long enough buffer on our first attempt.
|
||||
size = static_cast<size_t>(ret) + 1; // + 1 for the null byte
|
||||
std::unique_ptr<char[]> buff(new char[size]);
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
|
||||
#endif // __GNUC__
|
||||
ret = vsnprintf(buff.get(), size, msg, args);
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif // __GNUC__
|
||||
BM_CHECK(ret > 0 && (static_cast<size_t>(ret)) < size);
|
||||
return buff.get();
|
||||
}
|
||||
|
||||
std::string FormatString(const char* msg, ...) {
|
||||
va_list args;
|
||||
va_start(args, msg);
|
||||
auto tmp = FormatString(msg, args);
|
||||
va_end(args);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
void ColorPrintf(std::ostream& out, LogColor color, const char* fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
ColorPrintf(out, color, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void ColorPrintf(std::ostream& out, LogColor color, const char* fmt,
|
||||
va_list args) {
|
||||
#ifdef BENCHMARK_OS_WINDOWS
|
||||
((void)out); // suppress unused warning
|
||||
|
||||
const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
|
||||
// Gets the current text color.
|
||||
CONSOLE_SCREEN_BUFFER_INFO buffer_info;
|
||||
GetConsoleScreenBufferInfo(stdout_handle, &buffer_info);
|
||||
const WORD original_color_attrs = buffer_info.wAttributes;
|
||||
|
||||
// We need to flush the stream buffers into the console before each
|
||||
// SetConsoleTextAttribute call lest it affect the text that is already
|
||||
// printed but has not yet reached the console.
|
||||
out.flush();
|
||||
|
||||
const WORD original_background_attrs =
|
||||
original_color_attrs & (BACKGROUND_RED | BACKGROUND_GREEN |
|
||||
BACKGROUND_BLUE | BACKGROUND_INTENSITY);
|
||||
|
||||
SetConsoleTextAttribute(stdout_handle, GetPlatformColorCode(color) |
|
||||
FOREGROUND_INTENSITY |
|
||||
original_background_attrs);
|
||||
out << FormatString(fmt, args);
|
||||
|
||||
out.flush();
|
||||
// Restores the text and background color.
|
||||
SetConsoleTextAttribute(stdout_handle, original_color_attrs);
|
||||
#else
|
||||
const char* color_code = GetPlatformColorCode(color);
|
||||
if (color_code != nullptr) {
|
||||
out << FormatString("\033[0;3%sm", color_code);
|
||||
}
|
||||
out << FormatString(fmt, args) << "\033[m";
|
||||
#endif
|
||||
}
|
||||
|
||||
bool IsColorTerminal() {
|
||||
#if BENCHMARK_OS_WINDOWS
|
||||
// On Windows the TERM variable is usually not set, but the
|
||||
// console there does support colors.
|
||||
return 0 != _isatty(_fileno(stdout));
|
||||
#else
|
||||
// On non-Windows platforms, we rely on the TERM variable. This list of
|
||||
// supported TERM values is copied from Google Test:
|
||||
// <https://github.com/google/googletest/blob/v1.13.0/googletest/src/gtest.cc#L3225-L3259>.
|
||||
const char* const SUPPORTED_TERM_VALUES[] = {
|
||||
"xterm",
|
||||
"xterm-color",
|
||||
"xterm-256color",
|
||||
"screen",
|
||||
"screen-256color",
|
||||
"tmux",
|
||||
"tmux-256color",
|
||||
"rxvt-unicode",
|
||||
"rxvt-unicode-256color",
|
||||
"linux",
|
||||
"cygwin",
|
||||
"xterm-kitty",
|
||||
"alacritty",
|
||||
"foot",
|
||||
"foot-extra",
|
||||
"wezterm",
|
||||
};
|
||||
|
||||
const char* const term = getenv("TERM");
|
||||
|
||||
bool term_supports_color = false;
|
||||
for (const char* candidate : SUPPORTED_TERM_VALUES) {
|
||||
if ((term != nullptr) && 0 == strcmp(term, candidate)) {
|
||||
term_supports_color = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0 != isatty(fileno(stdout)) && term_supports_color;
|
||||
#endif // BENCHMARK_OS_WINDOWS
|
||||
}
|
||||
|
||||
} // end namespace benchmark
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user