mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-22 01:11:42 +00:00
Compare commits
258 Commits
v2027.0.0-
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d4f89c11c3 | ||
|
|
7298d9eafb | ||
|
|
7dcb70cfcd | ||
|
|
3d6df4a50e | ||
|
|
50eab65b07 | ||
|
|
f1c9d82d50 | ||
|
|
481a586009 | ||
|
|
396b553069 | ||
|
|
cfab47e871 | ||
|
|
637f006f9b | ||
|
|
608f024f82 | ||
|
|
8d2f3212e7 | ||
|
|
0b950ea6d9 | ||
|
|
ad797456f5 | ||
|
|
e92478c212 | ||
|
|
0662a78892 | ||
|
|
c35df58a81 | ||
|
|
5a7d7d50ee | ||
|
|
d6fb871a26 | ||
|
|
489b993e60 | ||
|
|
97381549e6 | ||
|
|
025732093f | ||
|
|
c647e67de0 | ||
|
|
fe499ede4c | ||
|
|
3f966aa7c6 | ||
|
|
72d85be0c2 | ||
|
|
111130d8bb | ||
|
|
0213ecf382 | ||
|
|
bdd45c7365 | ||
|
|
44501bf5eb | ||
|
|
1be5da5bde | ||
|
|
06fb36ba8e | ||
|
|
71ed28f768 | ||
|
|
edf77fa007 | ||
|
|
6e5171cd8f | ||
|
|
ddf9306264 | ||
|
|
88d8369751 | ||
|
|
96fb033deb | ||
|
|
d941be905e | ||
|
|
e085c3e8b3 | ||
|
|
98c03baf54 | ||
|
|
8353b95507 | ||
|
|
a41679854b | ||
|
|
fdc6fd9cb1 | ||
|
|
dca59147e1 | ||
|
|
a734275cc5 | ||
|
|
3f0d7bc2c4 | ||
|
|
3d982f81dd | ||
|
|
a3c18d24a7 | ||
|
|
c597116f02 | ||
|
|
9adffd356d | ||
|
|
635e971a02 | ||
|
|
40fdb779d8 | ||
|
|
e728ee27f2 | ||
|
|
50fd29e697 | ||
|
|
4fa5dacfc4 | ||
|
|
1e12408a7d | ||
|
|
14db070c2c | ||
|
|
5c3a474a58 | ||
|
|
f1d95ee5f8 | ||
|
|
7ff32d7756 | ||
|
|
aedee56e22 | ||
|
|
ac7a9524f8 | ||
|
|
b100586cab | ||
|
|
254ca64106 | ||
|
|
1392db4529 | ||
|
|
40f9a87e70 | ||
|
|
94fda36e04 | ||
|
|
f217dfe747 | ||
|
|
d86378d353 | ||
|
|
ac41523eb4 | ||
|
|
d48f1cd0e5 | ||
|
|
e88729c67e | ||
|
|
e35ca772fd | ||
|
|
fa24446ce3 | ||
|
|
67b795057b | ||
|
|
e4ae671b49 | ||
|
|
f751ca88eb | ||
|
|
6ba5734a94 | ||
|
|
68d24bb29e | ||
|
|
3f1cf3cabe | ||
|
|
b91001f504 | ||
|
|
ffd36eb091 | ||
|
|
97c0b0c40a | ||
|
|
16fcf016de | ||
|
|
878da3d54c | ||
|
|
1021ff88a9 | ||
|
|
0af65ea787 | ||
|
|
8832d6a7c2 | ||
|
|
62e0bc515c | ||
|
|
5964443038 | ||
|
|
8c5c535e1b | ||
|
|
4c07aedd91 | ||
|
|
3d4cabfbc9 | ||
|
|
63a82dccb2 | ||
|
|
b10bc0a674 | ||
|
|
e40ca392c3 | ||
|
|
f97571fb1f | ||
|
|
d23c732d79 | ||
|
|
063ac7002f | ||
|
|
e76074d381 | ||
|
|
6f88066170 | ||
|
|
3fddf71c47 | ||
|
|
668124e0fd | ||
|
|
433c7f00ad | ||
|
|
94443c8e84 | ||
|
|
3bf67edc34 | ||
|
|
29beacbefe | ||
|
|
8d30131fce | ||
|
|
657d4d9b58 | ||
|
|
97d0b15f7d | ||
|
|
a695865781 | ||
|
|
c511fcc160 | ||
|
|
e5980b46ef | ||
|
|
af7d68e993 | ||
|
|
880cfd60c4 | ||
|
|
a3968faa57 | ||
|
|
6aa1611959 | ||
|
|
35e8abedeb | ||
|
|
e7e51c9c05 | ||
|
|
2edef821f9 | ||
|
|
3bf3060ff5 | ||
|
|
ded1937fcf | ||
|
|
a6425d3e1e | ||
|
|
68a8ebfc81 | ||
|
|
d539e06b4f | ||
|
|
163cfaa027 | ||
|
|
40188d9cc6 | ||
|
|
a8b827af54 | ||
|
|
5703f608d7 | ||
|
|
d893d44e37 | ||
|
|
1586dcf385 | ||
|
|
930340e8f0 | ||
|
|
7fc8845424 | ||
|
|
44b9545f30 | ||
|
|
ab00aac960 | ||
|
|
14d14e4ebc | ||
|
|
b7df267687 | ||
|
|
3eaeac6150 | ||
|
|
ab2aef2c29 | ||
|
|
58ad633ae2 | ||
|
|
a97214df43 | ||
|
|
6cb6903780 | ||
|
|
fdb454a6b1 | ||
|
|
056d7bcbbe | ||
|
|
8c80cdcf28 | ||
|
|
628ba1458f | ||
|
|
f96ded6909 | ||
|
|
613c86d1d7 | ||
|
|
f89cf297e4 | ||
|
|
7af3ac579b | ||
|
|
476b9641c1 | ||
|
|
d76486d885 | ||
|
|
7e9138f8c1 | ||
|
|
042567d0ba | ||
|
|
c6f54e963c | ||
|
|
9ea63c7fd6 | ||
|
|
8e72d17770 | ||
|
|
2102a543d1 | ||
|
|
346cd9ed9c | ||
|
|
aedff82286 | ||
|
|
d8df358e6a | ||
|
|
a8c7f3e3c6 | ||
|
|
84295180cd | ||
|
|
bc984234e9 | ||
|
|
ea06f0b257 | ||
|
|
3728bc3b5c | ||
|
|
1671150521 | ||
|
|
b7fe3dad46 | ||
|
|
7e86c10a28 | ||
|
|
21f6bdbc1a | ||
|
|
ce77e6022f | ||
|
|
b6849a8da3 | ||
|
|
a4e035ba64 | ||
|
|
ece8001b1e | ||
|
|
02c6030251 | ||
|
|
5a96685c86 | ||
|
|
9ca93fa190 | ||
|
|
de3e211fdb | ||
|
|
bfea2b7e1f | ||
|
|
3ac168f9d2 | ||
|
|
44dcf9a3ca | ||
|
|
5b4769ea0a | ||
|
|
719e9dddc0 | ||
|
|
e4ef8a2515 | ||
|
|
173ecd3d02 | ||
|
|
cc56c42d4c | ||
|
|
dfc8098b9c | ||
|
|
bf218113db | ||
|
|
d248c040bf | ||
|
|
3e821b9448 | ||
|
|
db42c6cbba | ||
|
|
ceb712b089 | ||
|
|
d74644283b | ||
|
|
f3757bdeae | ||
|
|
962168acf1 | ||
|
|
dc4a8d572d | ||
|
|
1925cf0e1f | ||
|
|
d05d3b1c78 | ||
|
|
f2929af00f | ||
|
|
ea32c247db | ||
|
|
f060c98992 | ||
|
|
a57d658ef1 | ||
|
|
d86a745328 | ||
|
|
c5738fcbad | ||
|
|
87e677d4af | ||
|
|
3776f8a1ef | ||
|
|
e73e2e99f7 | ||
|
|
49065aa07f | ||
|
|
38b9214e38 | ||
|
|
09be21c319 | ||
|
|
48868020a9 | ||
|
|
7815248d62 | ||
|
|
6559d78658 | ||
|
|
8fa6976cb2 | ||
|
|
5ec92df137 | ||
|
|
8a802fd670 | ||
|
|
b7122f0fda | ||
|
|
4e4ad9c498 | ||
|
|
0fc1f45324 | ||
|
|
dba033eaee | ||
|
|
f1aa84aecf | ||
|
|
fb4bcefabc | ||
|
|
b86204bf45 | ||
|
|
410c11994e | ||
|
|
c5e32652f9 | ||
|
|
4059797635 | ||
|
|
aa88fa0fcf | ||
|
|
c913b27a27 | ||
|
|
9ce9918763 | ||
|
|
e5107e7e00 | ||
|
|
8af6bd354e | ||
|
|
0665aed66b | ||
|
|
e81d47fb46 | ||
|
|
58e112480a | ||
|
|
aad08b9ad1 | ||
|
|
70f77a1f8e | ||
|
|
68ca74c129 | ||
|
|
c18f811ea7 | ||
|
|
261a0ebbd7 | ||
|
|
b68fbb1adc | ||
|
|
f6fdae3212 | ||
|
|
227f01f3bd | ||
|
|
614eb1db18 | ||
|
|
fc3be46e6c | ||
|
|
ab7e4766f6 | ||
|
|
86dd3ca2b7 | ||
|
|
14e2c1c4cf | ||
|
|
e944ae9aca | ||
|
|
1a5b023235 | ||
|
|
d1fba06851 | ||
|
|
f1adce4cf7 | ||
|
|
62ce8944aa | ||
|
|
b2b111dc11 | ||
|
|
6830c65a15 | ||
|
|
ab4700854c | ||
|
|
80647654c3 | ||
|
|
907bf05607 |
10
.bazelrc
10
.bazelrc
@@ -9,10 +9,10 @@ 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
|
||||
build --java_language_version=25
|
||||
build --java_runtime_version=remotejdk_25
|
||||
build --tool_java_language_version=25
|
||||
build --tool_java_runtime_version=remotejdk_25
|
||||
|
||||
test --test_output=errors
|
||||
test --test_verbose_timeout_warnings
|
||||
@@ -67,7 +67,7 @@ build:remote_user --config=remote_cache
|
||||
build:remote_user --config=remote_cache_readonly
|
||||
build:remote_user --remote_download_toplevel
|
||||
|
||||
build:ci --config=remote_cache
|
||||
common:ci --color=yes
|
||||
build:ci --remote_download_minimal
|
||||
build:ci --progress_report_interval=60 --show_progress_rate_limit=60
|
||||
|
||||
|
||||
@@ -72,3 +72,4 @@ CheckOptions:
|
||||
- key: modernize-use-using.IgnoreExternC
|
||||
value: 'true'
|
||||
FormatStyle: file
|
||||
HeaderFilterRegex: '^((?!thirdparty/).)*$'
|
||||
|
||||
38
.github/actions/setup-bazel-cache/action.yml
vendored
Normal file
38
.github/actions/setup-bazel-cache/action.yml
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
name: 'Setup Bazel Cache'
|
||||
description: 'Configures the Bazel remote cache. Prefers WPI bazel-remote (R/W), falls back to BuildBuddy, then readonly WPI cache.'
|
||||
|
||||
inputs:
|
||||
bazel_remote_username:
|
||||
description: 'WPI Bazel remote cache username'
|
||||
bazel_remote_password:
|
||||
description: 'WPI Bazel remote cache password'
|
||||
bazel_remote_url:
|
||||
description: 'WPI Bazel remote cache base URL (no credentials or protocol, e.g. gitlib-bazel.wpi.edu)'
|
||||
default: 'gitlib-bazel.wpi.edu'
|
||||
buildbuddy_token:
|
||||
description: 'BuildBuddy API token'
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- name: Resolve Bazel cache configuration
|
||||
env:
|
||||
CACHE_USER: ${{ inputs.bazel_remote_username }}
|
||||
CACHE_PASS: ${{ inputs.bazel_remote_password }}
|
||||
REMOTE_URL: ${{ inputs.bazel_remote_url }}
|
||||
BB_TOKEN: ${{ inputs.buildbuddy_token }}
|
||||
shell: bash
|
||||
run: |
|
||||
if [ -n "${CACHE_USER}" ] && [ -n "${CACHE_PASS}" ]; then
|
||||
echo "WPI bazel-remote credentials detected; configuring R/W access"
|
||||
echo "build:remote_cache --remote_cache=grpcs://${CACHE_USER}:${CACHE_PASS}@${REMOTE_URL}" > bazel_auth.rc
|
||||
echo "build:ci --config=remote_cache" >> bazel_auth.rc
|
||||
elif [ -n "${BB_TOKEN}" ]; then
|
||||
echo "BuildBuddy token detected; configuring BuildBuddy cache"
|
||||
echo "build:build_buddy --remote_header=x-buildbuddy-api-key=${BB_TOKEN}" > bazel_auth.rc
|
||||
echo "build:ci --config=build_buddy" >> bazel_auth.rc
|
||||
else
|
||||
echo "No cache credentials detected; falling back to readonly WPI cache"
|
||||
echo "build:ci --config=remote_cache" > bazel_auth.rc
|
||||
echo "build:ci --config=remote_cache_readonly" >> bazel_auth.rc
|
||||
fi
|
||||
37
.github/actions/setup-bazel-remote/action.yml
vendored
37
.github/actions/setup-bazel-remote/action.yml
vendored
@@ -1,37 +0,0 @@
|
||||
name: 'Setup Bazel Remote cache'
|
||||
description: 'Sets up bazel-remote cache using basic auth from GitHub secrets'
|
||||
|
||||
inputs:
|
||||
username:
|
||||
description: 'Bazel remote cache username'
|
||||
password:
|
||||
description: 'Bazel remote cache password'
|
||||
remote_url:
|
||||
description: 'Bazel remote cache base URL (no credentials or protocol, e.g. gitlib-bazel.wpi.edu)'
|
||||
default: 'gitlib-bazel.wpi.edu'
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- name: Setup bazel-remote (skip when no creds)
|
||||
env:
|
||||
CACHE_USER: ${{ inputs.username }}
|
||||
CACHE_PASS: ${{ inputs.password }}
|
||||
REMOTE_URL: ${{ inputs.remote_url }}
|
||||
if: ${{ env.CACHE_USER == '' || env.CACHE_PASS == '' }}
|
||||
shell: bash
|
||||
run: |
|
||||
echo "No bazel-remote credentials detected; leaving caching as previously configured"
|
||||
echo "build:ci --config=remote_cache_readonly" >> bazel_auth.rc
|
||||
|
||||
- name: Setup bazel-remote (with creds)
|
||||
env:
|
||||
CACHE_USER: ${{ inputs.username }}
|
||||
CACHE_PASS: ${{ inputs.password }}
|
||||
REMOTE_URL: ${{ inputs.remote_url }}
|
||||
if: ${{ env.CACHE_USER != '' && env.CACHE_PASS != '' }}
|
||||
shell: bash
|
||||
run: |
|
||||
echo "Bazel-remote credentials detected; configuring bazel_auth.rc"
|
||||
URL_WITH_CREDS="grpcs://${CACHE_USER}:${CACHE_PASS}@${REMOTE_URL}"
|
||||
echo "build:remote_cache --remote_cache=${URL_WITH_CREDS}" >> bazel_auth.rc
|
||||
38
.github/actions/setup-build-buddy/action.yml
vendored
38
.github/actions/setup-build-buddy/action.yml
vendored
@@ -1,38 +0,0 @@
|
||||
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
|
||||
158
.github/labeler.yml
vendored
158
.github/labeler.yml
vendored
@@ -1,62 +1,96 @@
|
||||
'2027':
|
||||
- base-branch: '2027'
|
||||
'component: apriltag':
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: apriltag/**
|
||||
'component: command-based':
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: commandsv2/**
|
||||
'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/**
|
||||
"build":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
[
|
||||
.github/actions/**,
|
||||
.github/workflows/**,
|
||||
cmake/*,
|
||||
shared/**,
|
||||
upstream_utils/**,
|
||||
"**/*.bzl",
|
||||
"**/*.cmake",
|
||||
"**/*.gradle",
|
||||
"**/CMakeLists.txt",
|
||||
"**/BUILD.bazel",
|
||||
]
|
||||
"component: apriltag":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: apriltag/**
|
||||
"component: command-based":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: commandsv2/**
|
||||
"component: commands v3":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: commandsv3/**
|
||||
"component: cscore":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: cscore/**
|
||||
"component: datalogtool":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: tools/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: javac plugin":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: javacPlugin/**
|
||||
"component: ntcore":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: ntcore/**
|
||||
"component: outlineviewer":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: tools/outlineviewer/**
|
||||
"component: romi":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: romiVendordep/**
|
||||
"component: sysid":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: tools/sysid/**
|
||||
"component: wpiannotations":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: wpiannotations/**
|
||||
"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: tools/wpical/**
|
||||
"component: xrp":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: xrpVendordep/**
|
||||
"component: usage reporting":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: hal/src/generate/**
|
||||
"os: simulation":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: "**/simulation/**"
|
||||
"robotpy":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: "**python/**"
|
||||
"type: testing":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: "**/test/**"
|
||||
|
||||
132
.github/workflows/bazel.yml
vendored
132
.github/workflows/bazel.yml
vendored
@@ -12,33 +12,35 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- { name: "Linux System Core", classifier: "linuxsystemcore", os: ubuntu-24.04, action: "build" }
|
||||
- { name: "Linux System Core Debug", classifier: "linuxsystemcoredebug", os: ubuntu-24.04, action: "build" }
|
||||
- { name: "Linux System Core Static", classifier: "linuxsystemcorestatic", os: ubuntu-24.04, action: "build" }
|
||||
- { name: "Linux System Core Static Debug", classifier: "linuxsystemcorestaticdebug", os: ubuntu-24.04, action: "build" }
|
||||
- { name: "Linux x86-64", classifier: "linuxx86-64,headers,sources", os: ubuntu-24.04, action: "test" }
|
||||
- { name: "Linux x86-64 Debug", classifier: "linuxx86-64debug", os: ubuntu-24.04, action: "test" }
|
||||
- { name: "Linux x86-64 Static", classifier: "linuxx86-64static", os: ubuntu-24.04, action: "test" }
|
||||
- { name: "Linux x86-64 Static Debug", classifier: "linuxx86-64staticdebug", os: ubuntu-24.04, action: "test" }
|
||||
- { name: "Linux System Core", classifier: "linuxsystemcore", os: ubuntu-24.04, container: wpilib/debian-base:trixie, action: "build" }
|
||||
- { name: "Linux System Core Debug", classifier: "linuxsystemcoredebug", os: ubuntu-24.04, container: wpilib/debian-base:trixie, action: "build" }
|
||||
- { name: "Linux System Core Static", classifier: "linuxsystemcorestatic", os: ubuntu-24.04, container: wpilib/debian-base:trixie, action: "build" }
|
||||
- { name: "Linux System Core Static Debug", classifier: "linuxsystemcorestaticdebug", os: ubuntu-24.04, container: wpilib/debian-base:trixie, action: "build" }
|
||||
- { name: "Linux x86-64", classifier: "linuxx86-64,headers,sources", os: ubuntu-24.04, container: wpilib/debian-base:trixie, action: "test" }
|
||||
- { name: "Linux x86-64 Debug", classifier: "linuxx86-64debug", os: ubuntu-24.04, container: wpilib/debian-base:trixie, action: "test" }
|
||||
- { name: "Linux x86-64 Static", classifier: "linuxx86-64static", os: ubuntu-24.04, container: wpilib/debian-base:trixie, action: "test" }
|
||||
- { name: "Linux x86-64 Static Debug", classifier: "linuxx86-64staticdebug", os: ubuntu-24.04, container: wpilib/debian-base:trixie, action: "test" }
|
||||
|
||||
- { name: "macOS", classifier: "osxuniversal,osxuniversaldebug,headers,sources,osxuniversalstatic,osxuniversalstaticdebug,linuxsystemcore,linuxsystemcoredebug,linuxsystemcorestatic,linuxsystemcorestaticdebug", os: macOS-15, action: "test" }
|
||||
- { name: "macOS", classifier: "osxuniversal,osxuniversaldebug,headers,sources,osxuniversalstatic,osxuniversalstaticdebug,linuxsystemcore,linuxsystemcoredebug,linuxsystemcorestatic,linuxsystemcorestaticdebug", os: macOS-15, container: "", action: "test" }
|
||||
|
||||
- { name: "Windows x86-64", classifier: "windowsx86-64,windowsx86-64debug,headers,sources", os: windows-2022, action: "test" }
|
||||
- { name: "Windows x86-64 Static", classifier: "windowsx86-64static,windowsx86-64staticdebug", os: windows-2022, action: "test" }
|
||||
- { name: "Windows x86-64", classifier: "windowsx86-64,windowsx86-64static,headers,sources", os: windows-2022, container: "", action: "test" }
|
||||
- { name: "Windows x86-64 Debug", classifier: "windowsx86-64debug,windowsx86-64staticdebug", os: windows-2022, container: "", action: "test" }
|
||||
|
||||
- { name: "Windows ARM64", classifier: "windowsarm64,windowsarm64debug", os: windows-2022, action: "build" }
|
||||
- { name: "Windows ARM64 Static", classifier: "windowsarm64static,windowsarm64staticdebug", os: windows-2022, action: "build" }
|
||||
- { name: "Windows ARM64", classifier: "windowsarm64,windowsarm64static", os: windows-2022, container: "", action: "build" }
|
||||
- { name: "Windows ARM64 Debug", classifier: "windowsarm64debug,windowsarm64staticdebug", os: windows-2022, container: "", action: "build" }
|
||||
|
||||
- { name: "Windows System Core", classifier: "linuxsystemcore,linuxsystemcoredebug", os: windows-2022, action: "build" }
|
||||
- { name: "Windows System Core Static", classifier: "linuxsystemcorestatic,linuxsystemcorestaticdebug", os: windows-2022, action: "build" }
|
||||
- { name: "Windows System Core", classifier: "linuxsystemcore,linuxsystemcorestatic", os: windows-2022, container: "", action: "build" }
|
||||
- { name: "Windows System Core Debug", classifier: "linuxsystemcoredebug,linuxsystemcorestaticdebug", os: windows-2022, container: "", action: "build" }
|
||||
|
||||
name: "${{ matrix.action == 'test' && 'Test' || 'Build' }} ${{ matrix.name }}"
|
||||
runs-on: ${{ matrix.os }}
|
||||
container: ${{ matrix.container }}
|
||||
steps:
|
||||
- name: Check disk free space pre-cleanup
|
||||
run: df -h
|
||||
|
||||
- name: Free disk space (Linux)
|
||||
if: runner.os == 'Linux'
|
||||
uses: jlumbroso/free-disk-space@main
|
||||
with:
|
||||
tool-cache: false
|
||||
@@ -48,8 +50,9 @@ jobs:
|
||||
large-packages: false
|
||||
docker-images: false
|
||||
swap-storage: false
|
||||
if: startsWith(matrix.os, 'ubuntu')
|
||||
|
||||
- name: Free disk space (macOS)
|
||||
if: runner.os == 'macOS'
|
||||
# CodeQL: 5G
|
||||
# go: 748M
|
||||
# Android: 12G
|
||||
@@ -57,7 +60,6 @@ jobs:
|
||||
rm -rf /Users/runner/hostedtoolcache/CodeQL
|
||||
rm -rf /Users/runner/hostedtoolcache/go
|
||||
rm -rf /Users/runner/Library/Android
|
||||
if: startsWith(matrix.os, 'macOS')
|
||||
|
||||
- name: Check disk free space post-cleanup
|
||||
run: df -h
|
||||
@@ -65,17 +67,24 @@ jobs:
|
||||
- uses: actions/checkout@v6
|
||||
with: { fetch-depth: 0 }
|
||||
|
||||
- id: Setup_bazel_remote
|
||||
uses: ./.github/actions/setup-bazel-remote
|
||||
- id: Setup_bazel_cache
|
||||
uses: ./.github/actions/setup-bazel-cache
|
||||
with:
|
||||
username: ${{ secrets.BAZEL_CACHE_USERNAME }}
|
||||
password: ${{ secrets.BAZEL_CACHE_PASSWORD }}
|
||||
bazel_remote_username: ${{ secrets.BAZEL_CACHE_USERNAME }}
|
||||
bazel_remote_password: ${{ secrets.BAZEL_CACHE_PASSWORD }}
|
||||
buildbuddy_token: ${{ secrets.BUILDBUDDY_API_KEY }}
|
||||
|
||||
- name: Install apt dependencies
|
||||
if: matrix.os == 'ubuntu-24.04'
|
||||
run: sudo apt-get update && sudo apt-get install -y libgl1-mesa-dev libx11-dev libxcursor-dev libxi-dev libxinerama-dev libxrandr-dev
|
||||
if: runner.os == 'Linux'
|
||||
run: sudo apt-get update && sudo apt-get install -y libgl1-mesa-dev libx11-dev libxcursor-dev libxi-dev libxinerama-dev libxrandr-dev avahi-daemon
|
||||
|
||||
- if: matrix.os == 'ubuntu-24.04'
|
||||
- name: Setup avahi-daemon
|
||||
if: runner.os == 'Linux'
|
||||
run: |
|
||||
sudo service dbus start
|
||||
sudo avahi-daemon -D
|
||||
|
||||
- if: runner.os == 'Linux'
|
||||
uses: bazel-contrib/setup-bazel@0.15.0
|
||||
with:
|
||||
bazelisk-cache: true
|
||||
@@ -85,12 +94,12 @@ jobs:
|
||||
- name: bazel ${{ matrix.action }}
|
||||
run: |
|
||||
ACTION='${{ matrix.action }}'
|
||||
if [[ "${ACTION}" == "build" ]]; then
|
||||
if [ "${ACTION}" = "build" ]; then
|
||||
TARGETS=:publish
|
||||
else
|
||||
TARGETS=...
|
||||
fi
|
||||
if [[ "${{ matrix.os }}" == "windows-2022" ]]; then
|
||||
if [ "${{ runner.os }}" = "Windows" ]; then
|
||||
bazel --output_user_root=C:\\bazelroot ${ACTION} ${TARGETS} --config=ci -c opt --repo_env=WPI_PUBLISH_CLASSIFIER_FILTER='${{ matrix.classifier }}'
|
||||
else
|
||||
bazel ${ACTION} ${TARGETS} --config=ci -c opt --repo_env=WPI_PUBLISH_CLASSIFIER_FILTER='${{ matrix.classifier }}'
|
||||
@@ -127,13 +136,64 @@ jobs:
|
||||
run: git --no-pager diff --exit-code HEAD
|
||||
|
||||
- name: Generate diff
|
||||
run: git diff HEAD > bazel-lint-fixes.patch
|
||||
run: git diff HEAD > ${{ matrix.platform }}-bazel-lint-fixes.patch
|
||||
if: ${{ failure() }}
|
||||
|
||||
- uses: actions/upload-artifact@v7
|
||||
with:
|
||||
archive: false
|
||||
path: "*-bazel-lint-fixes.patch"
|
||||
if: ${{ failure() }}
|
||||
|
||||
mod-lock:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Check lockfile
|
||||
run: bazel mod deps --lockfile_mode=error
|
||||
|
||||
- run: bazel mod deps --lockfile_mode=update
|
||||
if: ${{ failure() }}
|
||||
|
||||
- name: Generate diff
|
||||
run: git diff HEAD > bazel-mod-lock-fixes.patch
|
||||
if: ${{ failure() }}
|
||||
|
||||
- uses: actions/upload-artifact@v7
|
||||
with:
|
||||
archive: false
|
||||
path: "bazel-mod-lock-fixes.patch"
|
||||
if: ${{ failure() }}
|
||||
|
||||
non_robotpy_pregeneration:
|
||||
name: "Non-RobotPy Pregen"
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
with: { fetch-depth: 0 }
|
||||
|
||||
- id: Setup_bazel_cache
|
||||
uses: ./.github/actions/setup-bazel-cache
|
||||
with:
|
||||
bazel_remote_username: ${{ secrets.BAZEL_CACHE_USERNAME }}
|
||||
bazel_remote_password: ${{ secrets.BAZEL_CACHE_PASSWORD }}
|
||||
buildbuddy_token: ${{ secrets.BUILDBUDDY_API_KEY }}
|
||||
|
||||
- name: Run Non-RobotPy pregeneration
|
||||
run: bazel run --config=ci //:write_pregenerated_files
|
||||
|
||||
- name: Check Output
|
||||
run: git --no-pager diff --exit-code HEAD
|
||||
|
||||
- name: Generate diff
|
||||
run: git diff HEAD > non-robotpy-pregeneration.patch
|
||||
if: ${{ failure() }}
|
||||
|
||||
- uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: ${{ matrix.platform }}-bazel-lint-fixes
|
||||
path: bazel-lint-fixes.patch
|
||||
name: non-robotpy-pregeneration-fixes
|
||||
path: non-robotpy-pregeneration.patch
|
||||
if: ${{ failure() }}
|
||||
|
||||
robotpy_pregeneration:
|
||||
@@ -143,21 +203,23 @@ jobs:
|
||||
- uses: actions/checkout@v6
|
||||
with: { fetch-depth: 0 }
|
||||
|
||||
- id: Setup_build_buddy
|
||||
uses: ./.github/actions/setup-build-buddy
|
||||
- id: Setup_bazel_cache
|
||||
uses: ./.github/actions/setup-bazel-cache
|
||||
with:
|
||||
token: ${{ secrets.BUILDBUDDY_API_KEY }}
|
||||
bazel_remote_username: ${{ secrets.BAZEL_CACHE_USERNAME }}
|
||||
bazel_remote_password: ${{ secrets.BAZEL_CACHE_PASSWORD }}
|
||||
buildbuddy_token: ${{ secrets.BUILDBUDDY_API_KEY }}
|
||||
|
||||
# You should ensure the headers are correct before trying to pregen files
|
||||
- name: Test Scan Headers
|
||||
run: bazel test //... -k --test_tag_filters=robotpy_scan_headers --build_tests_only
|
||||
run: bazel test --config=ci //... -k --test_tag_filters=robotpy_scan_headers --build_tests_only
|
||||
shell: bash
|
||||
|
||||
- name: Run yaml file generation
|
||||
run: bazel run //:write_robotpy_update_yaml_files
|
||||
run: bazel run --config=ci //:write_robotpy_update_yaml_files
|
||||
|
||||
- name: Run build file generation
|
||||
run: bazel run //:write_robotpy_generated_pybind_files
|
||||
run: bazel run --config=ci //:write_robotpy_generated_pybind_files
|
||||
|
||||
- name: Check Output
|
||||
run: git --no-pager diff --exit-code HEAD
|
||||
|
||||
7
.github/workflows/cmake-android.yml
vendored
7
.github/workflows/cmake-android.yml
vendored
@@ -33,11 +33,6 @@ jobs:
|
||||
ndk-version: r27d
|
||||
add-to-path: false
|
||||
|
||||
- uses: actions/setup-java@v5
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: 21
|
||||
|
||||
- name: Install sccache
|
||||
uses: mozilla-actions/sccache-action@v0.0.9
|
||||
|
||||
@@ -45,7 +40,7 @@ jobs:
|
||||
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
|
||||
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 -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 }}
|
||||
|
||||
14
.github/workflows/cmake.yml
vendored
14
.github/workflows/cmake.yml
vendored
@@ -18,8 +18,8 @@ jobs:
|
||||
include:
|
||||
- os: ubuntu-24.04
|
||||
name: Linux
|
||||
container: wpilib/systemcore-cross-ubuntu:2027-24.04
|
||||
flags: "--preset with-java-and-sccache -DCMAKE_BUILD_TYPE=Release -DWITH_EXAMPLES=ON"
|
||||
container: wpilib/systemcore-cross-debian:trixie
|
||||
flags: "--preset with-sccache -DCMAKE_BUILD_TYPE=Release -DWITH_EXAMPLES=ON"
|
||||
- os: macOS-15
|
||||
name: macOS
|
||||
container: ""
|
||||
@@ -35,7 +35,13 @@ jobs:
|
||||
steps:
|
||||
- name: Install dependencies (Linux)
|
||||
if: runner.os == 'Linux'
|
||||
run: sudo apt-get update && sudo apt-get install -y libopencv-dev libopencv-java ninja-build
|
||||
run: sudo apt-get update && sudo apt-get install -y libopencv-dev ninja-build
|
||||
|
||||
- name: Setup avahi-daemon
|
||||
if: runner.os == 'Linux'
|
||||
run: |
|
||||
sudo service dbus start
|
||||
sudo avahi-daemon -D
|
||||
|
||||
- name: Install dependencies (macOS)
|
||||
if: runner.os == 'macOS'
|
||||
@@ -49,7 +55,7 @@ jobs:
|
||||
uses: lukka/get-cmake@v3.29.3
|
||||
|
||||
- name: Install sccache
|
||||
uses: mozilla-actions/sccache-action@v0.0.9
|
||||
uses: mozilla-actions/sccache-action@v0.0.10
|
||||
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
|
||||
71
.github/workflows/gradle.yml
vendored
71
.github/workflows/gradle.yml
vendored
@@ -19,13 +19,13 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- container: wpilib/systemcore-cross-ubuntu:2027-24.04
|
||||
- container: wpilib/systemcore-cross-debian:trixie
|
||||
artifact-name: Systemcore
|
||||
build-options: "-Ponlylinuxsystemcore"
|
||||
- container: wpilib/aarch64-cross-ubuntu:2027-bookworm-24.04
|
||||
- container: wpilib/aarch64-cross-debian:trixie
|
||||
artifact-name: Arm64
|
||||
build-options: "-Ponlylinuxarm64"
|
||||
- container: wpilib/systemcore-cross-ubuntu:2027-24.04
|
||||
- container: wpilib/systemcore-cross-debian:trixie
|
||||
artifact-name: Linux
|
||||
build-options: "-Ponlylinuxx86-64"
|
||||
name: "Build - ${{ matrix.artifact-name }}"
|
||||
@@ -54,17 +54,21 @@ jobs:
|
||||
fetch-depth: 0
|
||||
- name: Set release environment variable
|
||||
run: echo "EXTRA_GRADLE_ARGS=-PreleaseMode" >> $GITHUB_ENV
|
||||
if: startsWith(github.ref, 'refs/tags/v2027')
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
- name: Build with Gradle
|
||||
uses: wpilibsuite/docker-run-action@v4
|
||||
with:
|
||||
image: ${{ matrix.container }}
|
||||
options: -v ${{ github.workspace }}:/work -w /work -e ARTIFACTORY_PUBLISH_USERNAME -e ARTIFACTORY_PUBLISH_PASSWORD -e GITHUB_REF -e CI
|
||||
run: ./gradlew build --build-cache -PbuildServer -PskipJavaFormat ${{ matrix.build-options }} ${{ env.EXTRA_GRADLE_ARGS }}
|
||||
# Start avahi-daemon and build
|
||||
run: |
|
||||
service dbus start
|
||||
avahi-daemon -D
|
||||
./gradlew build --build-cache -PbuildServer -PskipJavaFormat ${{ matrix.build-options }} ${{ env.EXTRA_GRADLE_ARGS }}
|
||||
env:
|
||||
ARTIFACTORY_PUBLISH_USERNAME: ${{ secrets.ARTIFACTORY_USERNAME }}
|
||||
ARTIFACTORY_PUBLISH_PASSWORD: ${{ secrets.ARTIFACTORY_PASSWORD }}
|
||||
- uses: actions/upload-artifact@v6
|
||||
- uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: ${{ matrix.artifact-name }}
|
||||
path: build/allOutputs
|
||||
@@ -123,6 +127,7 @@ jobs:
|
||||
run: df -h
|
||||
|
||||
- name: Free disk space (macOS)
|
||||
if: runner.os == 'macOS'
|
||||
# CodeQL: 5G
|
||||
# go: 748M
|
||||
# Android: 12G
|
||||
@@ -130,7 +135,6 @@ jobs:
|
||||
rm -rf /Users/runner/hostedtoolcache/CodeQL
|
||||
rm -rf /Users/runner/hostedtoolcache/go
|
||||
rm -rf /Users/runner/Library/Android
|
||||
if: startsWith(matrix.os, 'macOS')
|
||||
|
||||
- name: Check disk free space post-cleanup
|
||||
run: df -h
|
||||
@@ -141,7 +145,7 @@ jobs:
|
||||
- uses: actions/setup-java@v5
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: 21
|
||||
java-version: 25
|
||||
architecture: ${{ matrix.architecture }}
|
||||
- name: Import Developer ID Certificate
|
||||
uses: wpilibsuite/import-signing-certificate@v3
|
||||
@@ -151,16 +155,16 @@ jobs:
|
||||
keychain-password: ${{ secrets.APPLE_KEYCHAIN_PASSWORD }}
|
||||
if: |
|
||||
matrix.artifact-name == 'macOS' && (github.repository == 'wpilibsuite/allwpilib' &&
|
||||
(github.ref == 'refs/heads/2027' || startsWith(github.ref, 'refs/tags/v2027')))
|
||||
(github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v')))
|
||||
- name: Set Keychain Lock Timeout
|
||||
run: security set-keychain-settings -lut 21600
|
||||
if: |
|
||||
matrix.artifact-name == 'macOS' && (github.repository == 'wpilibsuite/allwpilib' &&
|
||||
(github.ref == 'refs/heads/2027' || startsWith(github.ref, 'refs/tags/v2027')))
|
||||
(github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v')))
|
||||
- name: Set release environment variable
|
||||
run: echo "EXTRA_GRADLE_ARGS=-PreleaseMode" >> $GITHUB_ENV
|
||||
shell: bash
|
||||
if: startsWith(github.ref, 'refs/tags/v2027')
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
- name: Build with Gradle
|
||||
run: ./gradlew ${{ matrix.task }} --build-cache -PbuildServer -PskipJavaFormat ${{ matrix.build-options }} ${{ env.EXTRA_GRADLE_ARGS }}
|
||||
env:
|
||||
@@ -170,8 +174,8 @@ 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/2027' || startsWith(github.ref, 'refs/tags/v2027')))
|
||||
- uses: actions/upload-artifact@v6
|
||||
(github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v')))
|
||||
- uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: ${{ matrix.artifact-name }}
|
||||
path: ${{ matrix.outputs }}
|
||||
@@ -191,16 +195,16 @@ jobs:
|
||||
- uses: actions/setup-java@v5
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: 25
|
||||
java-version: 26
|
||||
- name: Set release environment variable
|
||||
run: echo "EXTRA_GRADLE_ARGS=-PreleaseMode" >> $GITHUB_ENV
|
||||
if: startsWith(github.ref, 'refs/tags/v2027')
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
- name: Build with Gradle
|
||||
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 }}
|
||||
- uses: actions/upload-artifact@v6
|
||||
- uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: Documentation
|
||||
path: docs/build/outputs
|
||||
@@ -236,17 +240,12 @@ jobs:
|
||||
run: |
|
||||
echo "EXTRA_GRADLE_ARGS=-PreleaseMode" >> $GITHUB_ENV
|
||||
echo "BRANCH=beta" >> $GITHUB_ENV
|
||||
if: startsWith(github.ref, 'refs/tags/v') && !contains(github.ref, '2027')
|
||||
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') && !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')
|
||||
if: startsWith(github.ref, 'refs/tags/v') && !contains(github.ref, 'alpha') && !contains(github.ref, 'beta')
|
||||
- name: Install SSH Client 🔑
|
||||
uses: webfactory/ssh-agent@v0.9.1
|
||||
with:
|
||||
@@ -280,7 +279,7 @@ jobs:
|
||||
- name: Free disk space
|
||||
if: |
|
||||
github.repository == 'wpilibsuite/allwpilib' &&
|
||||
(github.ref == 'refs/heads/2027' || startsWith(github.ref, 'refs/tags/v2027'))
|
||||
(github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v'))
|
||||
uses: jlumbroso/free-disk-space@main
|
||||
with:
|
||||
tool-cache: false
|
||||
@@ -294,56 +293,56 @@ jobs:
|
||||
- uses: actions/checkout@v6
|
||||
if: |
|
||||
github.repository == 'wpilibsuite/allwpilib' &&
|
||||
(github.ref == 'refs/heads/2027' || startsWith(github.ref, 'refs/tags/v2027'))
|
||||
(github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v'))
|
||||
with:
|
||||
repository: wpilibsuite/build-tools
|
||||
- uses: actions/download-artifact@v7
|
||||
if: |
|
||||
github.repository == 'wpilibsuite/allwpilib' &&
|
||||
(github.ref == 'refs/heads/2027' || startsWith(github.ref, 'refs/tags/v2027'))
|
||||
(github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v'))
|
||||
with:
|
||||
path: combiner/products/build/allOutputs
|
||||
- name: Flatten Artifacts
|
||||
if: |
|
||||
github.repository == 'wpilibsuite/allwpilib' &&
|
||||
(github.ref == 'refs/heads/2027' || startsWith(github.ref, 'refs/tags/v2027'))
|
||||
(github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v'))
|
||||
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/2027' || startsWith(github.ref, 'refs/tags/v2027'))
|
||||
(github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v'))
|
||||
run: |
|
||||
cat combiner/products/build/allOutputs/version.txt
|
||||
test -s combiner/products/build/allOutputs/version.txt
|
||||
- uses: actions/setup-java@v5
|
||||
if: |
|
||||
github.repository == 'wpilibsuite/allwpilib' &&
|
||||
(github.ref == 'refs/heads/2027' || startsWith(github.ref, 'refs/tags/v2027'))
|
||||
(github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v'))
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: 21
|
||||
- name: Combine (2027)
|
||||
java-version: 25
|
||||
- name: Combine
|
||||
if: |
|
||||
github.repository == 'wpilibsuite/allwpilib' &&
|
||||
github.ref == 'refs/heads/2027'
|
||||
github.ref == 'refs/heads/main'
|
||||
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 (2027 Release)
|
||||
- name: Combine (Release)
|
||||
if: |
|
||||
github.repository == 'wpilibsuite/allwpilib' &&
|
||||
startsWith(github.ref, 'refs/tags/v2027')
|
||||
startsWith(github.ref, 'refs/tags/v')
|
||||
run: cd combiner && ./gradlew publish -Pallwpilib -PreleaseRepoPublish -Pbuild2027
|
||||
env:
|
||||
RUN_AZURE_ARTIFACTORY_RELEASE: "TRUE"
|
||||
ARTIFACTORY_PUBLISH_USERNAME: ${{ secrets.ARTIFACTORY_USERNAME }}
|
||||
ARTIFACTORY_PUBLISH_PASSWORD: ${{ secrets.ARTIFACTORY_PASSWORD }}
|
||||
- uses: actions/upload-artifact@v6
|
||||
- uses: actions/upload-artifact@v7
|
||||
if: |
|
||||
github.repository == 'wpilibsuite/allwpilib' &&
|
||||
(github.ref == 'refs/heads/2027' || startsWith(github.ref, 'refs/tags/v2027'))
|
||||
(github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v'))
|
||||
with:
|
||||
name: Maven
|
||||
path: ~/releases
|
||||
|
||||
54
.github/workflows/lint-format.yml
vendored
54
.github/workflows/lint-format.yml
vendored
@@ -28,7 +28,7 @@ jobs:
|
||||
- name: Fetch all history and metadata
|
||||
run: |
|
||||
git checkout -b pr
|
||||
git branch -f 2027 origin/2027
|
||||
git branch -f main origin/main
|
||||
- name: Set up Python 3.12
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
@@ -36,17 +36,17 @@ jobs:
|
||||
- name: Install wpiformat
|
||||
run: |
|
||||
python -m venv ${{ runner.temp }}/wpiformat
|
||||
${{ runner.temp }}/wpiformat/bin/pip3 install wpiformat==2025.79
|
||||
${{ runner.temp }}/wpiformat/bin/pip3 install wpiformat==2026.64
|
||||
- name: Run
|
||||
run: ${{ runner.temp }}/wpiformat/bin/wpiformat -default-branch 2027
|
||||
run: ${{ runner.temp }}/wpiformat/bin/wpiformat
|
||||
- name: Check output
|
||||
run: git --no-pager diff --exit-code HEAD
|
||||
- name: Generate diff
|
||||
run: git diff HEAD > wpiformat-fixes.patch
|
||||
if: ${{ failure() }}
|
||||
- uses: actions/upload-artifact@v6
|
||||
- uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: wpiformat fixes
|
||||
archive: false
|
||||
path: wpiformat-fixes.patch
|
||||
if: ${{ failure() }}
|
||||
- name: Write to job summary
|
||||
@@ -61,7 +61,7 @@ jobs:
|
||||
name: "clang-tidy"
|
||||
runs-on: ubuntu-24.04
|
||||
needs: [validation]
|
||||
container: wpilib/ubuntu-base:24.04
|
||||
container: wpilib/debian-base:trixie
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
@@ -70,7 +70,7 @@ jobs:
|
||||
run: |
|
||||
git config --global --add safe.directory /__w/allwpilib/allwpilib
|
||||
git checkout -b pr
|
||||
git branch -f 2027 origin/2027
|
||||
git branch -f main origin/main
|
||||
- name: Set up Python 3.12
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
@@ -78,23 +78,23 @@ jobs:
|
||||
- name: Install wpiformat
|
||||
run: |
|
||||
python -m venv ${{ runner.temp }}/wpiformat
|
||||
${{ runner.temp }}/wpiformat/bin/pip3 install wpiformat==2025.79
|
||||
${{ runner.temp }}/wpiformat/bin/pip3 install wpiformat==2026.64
|
||||
- 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: ${{ runner.temp }}/wpiformat/bin/wpiformat -default-branch 2027 -list-changed-files
|
||||
run: ${{ runner.temp }}/wpiformat/bin/wpiformat -list-changed-files
|
||||
- name: Run clang-tidy release
|
||||
run: ${{ runner.temp }}/wpiformat/bin/wpiformat -default-branch 2027 -no-format -tidy-changed -compile-commands=build/TargetedCompileCommands/linuxx86-64release
|
||||
run: ${{ runner.temp }}/wpiformat/bin/wpiformat -no-format -tidy-changed -compile-commands=build/TargetedCompileCommands/linuxx86-64release
|
||||
- name: Run clang-tidy debug
|
||||
run: ${{ runner.temp }}/wpiformat/bin/wpiformat -default-branch 2027 -no-format -tidy-changed -compile-commands=build/TargetedCompileCommands/linuxx86-64debug
|
||||
run: ${{ runner.temp }}/wpiformat/bin/wpiformat -no-format -tidy-changed -compile-commands=build/TargetedCompileCommands/linuxx86-64debug
|
||||
javaformat:
|
||||
name: "Java format"
|
||||
runs-on: ubuntu-24.04
|
||||
needs: [validation]
|
||||
container: wpilib/systemcore-cross-ubuntu:2027-24.04
|
||||
container: wpilib/debian-base:trixie
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
@@ -103,7 +103,7 @@ jobs:
|
||||
run: |
|
||||
git config --global --add safe.directory /__w/allwpilib/allwpilib
|
||||
git checkout -b pr
|
||||
git branch -f 2027 origin/2027
|
||||
git branch -f main origin/main
|
||||
- name: Run Java format
|
||||
run: ./gradlew javaFormat spotbugsMain spotbugsTest spotbugsDev
|
||||
- name: Check output
|
||||
@@ -111,9 +111,9 @@ jobs:
|
||||
- name: Generate diff
|
||||
run: git diff HEAD > javaformat-fixes.patch
|
||||
if: ${{ failure() }}
|
||||
- uses: actions/upload-artifact@v6
|
||||
- uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: javaformat fixes
|
||||
archive: false
|
||||
path: javaformat-fixes.patch
|
||||
if: ${{ failure() }}
|
||||
- name: Write to job summary
|
||||
@@ -123,3 +123,27 @@ jobs:
|
||||
echo '' >> $GITHUB_STEP_SUMMARY
|
||||
echo '```' >> $GITHUB_STEP_SUMMARY
|
||||
if: ${{ failure() }}
|
||||
|
||||
check-spelling:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- name: misspell
|
||||
uses: reviewdog/action-misspell@v1
|
||||
with:
|
||||
reporter: "github-check"
|
||||
fail_level: "error"
|
||||
exclude: |
|
||||
**/*.svg
|
||||
**/thirdparty/**
|
||||
**/upstream_utils/**
|
||||
**/generated/**
|
||||
./wpigui/src/main/native/cpp/portable-file-dialogs.*
|
||||
./wpimath/src/main/native/include/wpi/units/base.hpp
|
||||
./wpinet/src/main/native/linux/AvahiClient.*
|
||||
./wpinet/src/main/native/cpp/http_parser.cpp
|
||||
./wpinet/src/main/native/include/wpi/net/http_parser.hpp
|
||||
./wpiutil/src/main/native/include/wpi/util/FastQueue.hpp
|
||||
./wpiutil/src/test/native/cpp/json/**
|
||||
./wpiutil/src/test/native/cpp/llvm/**
|
||||
./wpiutil/src/test/native/cpp/span/**
|
||||
|
||||
4
.github/workflows/pregenerate.yml
vendored
4
.github/workflows/pregenerate.yml
vendored
@@ -27,8 +27,8 @@ jobs:
|
||||
- name: Generate diff
|
||||
run: git diff HEAD > pregenerated-files-fixes.patch
|
||||
if: ${{ failure() }}
|
||||
- uses: actions/upload-artifact@v6
|
||||
- uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: pregenerated-files-fixes
|
||||
archive: false
|
||||
path: pregenerated-files-fixes.patch
|
||||
if: ${{ failure() }}
|
||||
|
||||
17
.github/workflows/sanitizers.yml
vendored
17
.github/workflows/sanitizers.yml
vendored
@@ -19,10 +19,10 @@ jobs:
|
||||
- name: asan
|
||||
cmake-flags: "-DCMAKE_BUILD_TYPE=Asan"
|
||||
ctest-env: ""
|
||||
ctest-flags: "-E 'wpilibc'"
|
||||
ctest-flags: ""
|
||||
- name: tsan
|
||||
cmake-flags: "-DCMAKE_BUILD_TYPE=Tsan"
|
||||
ctest-env: "TSAN_OPTIONS=second_deadlock_stack=1"
|
||||
ctest-env: "TSAN_OPTIONS=second_deadlock_stack=1:suppressions=$GITHUB_WORKSPACE/tsan_suppressions.txt"
|
||||
ctest-flags: "-E 'cscore|cameraserver'"
|
||||
- name: ubsan
|
||||
cmake-flags: "-DCMAKE_BUILD_TYPE=Ubsan"
|
||||
@@ -30,22 +30,27 @@ jobs:
|
||||
ctest-flags: ""
|
||||
name: "${{ matrix.name }}"
|
||||
runs-on: ubuntu-24.04
|
||||
container: wpilib/roborio-cross-ubuntu:2025-24.04
|
||||
container: wpilib/debian-base:trixie
|
||||
steps:
|
||||
- name: Install Dependencies
|
||||
run: sudo apt-get update && sudo apt-get install -y libopencv-dev libopencv-java clang-18 ninja-build
|
||||
run: sudo apt-get update && sudo apt-get install -y libopencv-dev clang-18 ninja-build avahi-daemon
|
||||
|
||||
- name: Install sccache
|
||||
uses: mozilla-actions/sccache-action@v0.0.9
|
||||
uses: mozilla-actions/sccache-action@v0.0.10
|
||||
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- 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-18 -DCMAKE_CXX_COMPILER:FILEPATH=/usr/bin/clang++-18 -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 ${{ matrix.cmake-flags }} ..
|
||||
env:
|
||||
SCCACHE_WEBDAV_USERNAME: ${{ secrets.ARTIFACTORY_USERNAME }}
|
||||
SCCACHE_WEBDAV_PASSWORD: ${{ secrets.ARTIFACTORY_PASSWORD }}
|
||||
|
||||
- name: Setup avahi-daemon
|
||||
run: |
|
||||
sudo service dbus start
|
||||
sudo avahi-daemon -D
|
||||
|
||||
- name: build
|
||||
working-directory: build
|
||||
run: cmake --build . --parallel $(nproc)
|
||||
|
||||
30
.github/workflows/sentinel-build.yml
vendored
30
.github/workflows/sentinel-build.yml
vendored
@@ -23,13 +23,13 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- container: wpilib/systemcore-cross-ubuntu:2027-24.04
|
||||
- container: wpilib/systemcore-cross-debian:trixie
|
||||
artifact-name: Systemcore
|
||||
build-options: "-Ponlylinuxsystemcore"
|
||||
- container: wpilib/aarch64-cross-ubuntu:2027-bookworm-24.04
|
||||
- container: wpilib/aarch64-cross-debian:trixie
|
||||
artifact-name: Arm64
|
||||
build-options: "-Ponlylinuxarm64"
|
||||
- container: wpilib/systemcore-cross-ubuntu:2027-24.04
|
||||
- container: wpilib/systemcore-cross-debian:trixie
|
||||
artifact-name: Linux
|
||||
build-options: "-Ponlylinuxx86-64"
|
||||
name: "Build - ${{ matrix.artifact-name }}"
|
||||
@@ -54,10 +54,14 @@ jobs:
|
||||
with:
|
||||
image: ${{ matrix.container }}
|
||||
options: -v ${{ github.workspace }}:/work -w /work -e GITHUB_REF -e CI
|
||||
run: ./gradlew build -PbuildServer -PskipJavaFormat ${{ matrix.build-options }}
|
||||
# Start avahi-daemon and build
|
||||
run: |
|
||||
service dbus start
|
||||
avahi-daemon -D
|
||||
./gradlew build -PbuildServer -PskipJavaFormat ${{ matrix.build-options }}
|
||||
- name: Check free disk space
|
||||
run: df .
|
||||
- uses: actions/upload-artifact@v6
|
||||
- uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: ${{ matrix.artifact-name }}
|
||||
path: build/allOutputs
|
||||
@@ -115,7 +119,7 @@ jobs:
|
||||
- uses: actions/setup-java@v5
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: 21
|
||||
java-version: 25
|
||||
architecture: ${{ matrix.architecture }}
|
||||
- name: Import Developer ID Certificate
|
||||
uses: wpilibsuite/import-signing-certificate@v3
|
||||
@@ -130,12 +134,13 @@ jobs:
|
||||
if: |
|
||||
matrix.artifact-name == 'macOS' && (github.repository_owner == 'wpilibsuite' && github.ref == 'refs/heads/main')
|
||||
- name: Check disk free space (Windows)
|
||||
if: runner.os == 'Windows'
|
||||
run: wmic logicaldisk get caption, freespace
|
||||
if: matrix.os == 'windows-2022'
|
||||
- name: Check disk free space pre-cleanup (macOS)
|
||||
if: runner.os == 'macOS'
|
||||
run: df -h .
|
||||
if: matrix.os == 'macOS-15'
|
||||
- name: Cleanup disk space
|
||||
if: runner.os == 'macOS'
|
||||
# CodeQL: 5G
|
||||
# go: 748M
|
||||
# Android: 12G
|
||||
@@ -143,10 +148,9 @@ jobs:
|
||||
rm -rf /Users/runner/hostedtoolcache/CodeQL
|
||||
rm -rf /Users/runner/hostedtoolcache/go
|
||||
rm -rf /Users/runner/Library/Android
|
||||
if: matrix.os == 'macOS-15'
|
||||
- name: Check disk free space post-cleanup (macOS)
|
||||
if: runner.os == 'macOS'
|
||||
run: df -h .
|
||||
if: matrix.os == 'macOS-15'
|
||||
- name: Build with Gradle
|
||||
run: ./gradlew ${{ matrix.task }} -PbuildServer -PskipJavaFormat ${{ matrix.build-options }}
|
||||
- name: Sign Libraries with Developer ID
|
||||
@@ -154,12 +158,12 @@ jobs:
|
||||
if: |
|
||||
matrix.artifact-name == 'macOS' && (github.repository_owner == 'wpilibsuite' && github.ref == 'refs/heads/main')
|
||||
- name: Check disk free space (Windows)
|
||||
if: runner.os == 'Windows'
|
||||
run: wmic logicaldisk get caption, freespace
|
||||
if: matrix.os == 'windows-2022'
|
||||
- name: Check disk free space (macOS)
|
||||
if: runner.os == 'macOS'
|
||||
run: df -h .
|
||||
if: matrix.os == 'macOS-15'
|
||||
- uses: actions/upload-artifact@v6
|
||||
- uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: ${{ matrix.artifact-name }}
|
||||
path: ${{ matrix.outputs }}
|
||||
|
||||
12
.github/workflows/upstream-utils.yml
vendored
12
.github/workflows/upstream-utils.yml
vendored
@@ -42,6 +42,18 @@ jobs:
|
||||
./argparse_lib.py clone
|
||||
./argparse_lib.py copy-src
|
||||
./argparse_lib.py format-patch
|
||||
- name: Run benchmark.py
|
||||
run: |
|
||||
cd upstream_utils
|
||||
./benchmark.py clone
|
||||
./benchmark.py copy-src
|
||||
./benchmark.py format-patch
|
||||
- name: Run double-conversion.py
|
||||
run: |
|
||||
cd upstream_utils
|
||||
./double-conversion.py clone
|
||||
./double-conversion.py copy-src
|
||||
./double-conversion.py format-patch
|
||||
- name: Run eigen.py
|
||||
run: |
|
||||
cd upstream_utils
|
||||
|
||||
5
.gitignore
vendored
5
.gitignore
vendored
@@ -261,3 +261,8 @@ bazel_auth.rc
|
||||
|
||||
# Copybara user config
|
||||
shared/bazel/copybara/.copybara.json
|
||||
|
||||
# Nix files
|
||||
shell.nix
|
||||
flake.nix
|
||||
flake.lock
|
||||
|
||||
@@ -40,4 +40,5 @@ licenseUpdateExclude {
|
||||
wpiutil/src/main/native/cpp/Base64\.cpp$
|
||||
wpiutil/src/main/native/cpp/sha1\.cpp$
|
||||
wpiutil/src/main/native/include/wpi/util/sha1\.hpp$
|
||||
wpinet/src/main/native/linux/AvahiClient\.hpp$
|
||||
}
|
||||
|
||||
27
BUILD.bazel
27
BUILD.bazel
@@ -1,10 +1,20 @@
|
||||
load("@aspect_bazel_lib//lib:write_source_files.bzl", "write_source_files")
|
||||
load("@rules_java//java:java_binary.bzl", "java_binary")
|
||||
load("@rules_java//java:java_plugin.bzl", "java_plugin")
|
||||
load("@rules_pkg//:mappings.bzl", "pkg_files")
|
||||
load("@rules_python//python:pip.bzl", "compile_pip_requirements")
|
||||
load("//shared/bazel/rules:publishing.bzl", "publish_all")
|
||||
load("//shared/bazel/rules/robotpy:compatibility_select.bzl", "robotpy_compatibility_select")
|
||||
|
||||
java_plugin(
|
||||
name = "avaje_jsonb_generator",
|
||||
processor_class = "io.avaje.jsonb.generator.JsonbProcessor",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"@maven//:io_avaje_avaje_jsonb_generator",
|
||||
],
|
||||
)
|
||||
|
||||
exports_files([
|
||||
"LICENSE.md",
|
||||
"ThirdPartyNotices.txt",
|
||||
@@ -75,12 +85,14 @@ publish_all(
|
||||
"//apriltag:apriltag-java_publish.publish",
|
||||
"//cameraserver:cameraserver-cpp_publish.publish",
|
||||
"//cameraserver:cameraserver-java_publish.publish",
|
||||
"//commandsv2:commandsv2-cpp_publish.publish",
|
||||
"//commandsv2:commandsv2-java_publish.publish",
|
||||
"//commandsv3:commandsv3-java_publish.publish",
|
||||
"//cscore:cscore-cpp_publish.publish",
|
||||
"//cscore:cscore-java_publish.publish",
|
||||
"//cscore:cscorejnicvstatic-cpp_publish.publish",
|
||||
"//datalog:datalog-cpp_publish.publish",
|
||||
"//datalog:datalog-java_publish.publish",
|
||||
"//tools/datalogtool:datalogtool_publish.publish",
|
||||
"//docs:wpilibj_publish.publish",
|
||||
"//epilogue-processor:processor-java_publish.publish",
|
||||
"//epilogue-runtime:epilogue-java_publish.publish",
|
||||
@@ -91,11 +103,10 @@ publish_all(
|
||||
"//glass:glassnt-cpp_publish.publish",
|
||||
"//hal:hal-java_publish.publish",
|
||||
"//hal:wpiHal-cpp_publish.publish",
|
||||
"//javacPlugin:javacPlugin_publish.publish",
|
||||
"//ntcore:ntcore-cpp_publish.publish",
|
||||
"//ntcore:ntcore-java_publish.publish",
|
||||
"//ntcoreffi:ntcoreffi-cpp_publish.publish",
|
||||
"//tools/outlineviewer:outlineviewer_publish.publish",
|
||||
"//tools/processstarter:processstarter_publish.publish",
|
||||
"//romiVendordep:romiVendordep-cpp_publish.publish",
|
||||
"//romiVendordep:romiVendordep-java_publish.publish",
|
||||
"//simulation/halsim_ds_socket:halsim_ds_socket-cpp_publish.publish",
|
||||
@@ -104,14 +115,16 @@ publish_all(
|
||||
"//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",
|
||||
"//tools/sysid:sysid_publish.publish",
|
||||
"//thirdparty/catch2:catch2-cpp_publish.publish",
|
||||
"//thirdparty/googletest:googletest-cpp_publish.publish",
|
||||
"//thirdparty/imgui_suite:imguiSuite-cpp_publish.publish",
|
||||
"//tools/datalogtool:datalogtool_publish.publish",
|
||||
"//tools/outlineviewer:outlineviewer_publish.publish",
|
||||
"//tools/processstarter:processstarter_publish.publish",
|
||||
"//tools/sysid:sysid_publish.publish",
|
||||
"//tools/wpical:wpical_publish.publish",
|
||||
"//wpiannotations:wpiannotations_publish.publish",
|
||||
"//wpigui:wpigui-cpp_publish.publish",
|
||||
"//commandsv2:commandsv2-cpp_publish.publish",
|
||||
"//commandsv2:commandsv2-java_publish.publish",
|
||||
"//commandsv3:commandsv3-java_publish.publish",
|
||||
"//wpilibc:wpilibc-cpp_publish.publish",
|
||||
"//wpilibcExamples:commands_publish.publish",
|
||||
"//wpilibcExamples:examples_publish.publish",
|
||||
|
||||
@@ -63,9 +63,7 @@ set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
|
||||
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
|
||||
|
||||
# Options for building certain parts of the repo. Everything is built by default.
|
||||
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(BUILD_SHARED_LIBS "Build with shared libs" ON)
|
||||
option(WITH_DOCS "Build Doxygen docs (needs Git for versioning)" OFF)
|
||||
cmake_dependent_option(
|
||||
DOCS_WARNINGS_AS_ERRORS
|
||||
@@ -78,13 +76,6 @@ 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
|
||||
"Build wpiunits"
|
||||
ON
|
||||
WITH_JAVA
|
||||
OFF
|
||||
)
|
||||
option(WITH_WPILIB "Build hal, wpilibc/j, and developerRobot (needs OpenCV)" ON)
|
||||
option(WITH_EXAMPLES "Build examples" OFF)
|
||||
option(WITH_TESTS "Build unit tests (requires internet connection)" ON)
|
||||
@@ -98,26 +89,9 @@ option(USE_SYSTEM_LIBUV "Use system libuv" OFF)
|
||||
option(USE_SYSTEM_EIGEN "Use system eigen" OFF)
|
||||
option(USE_LINKED_AVAHI "Use directly linked Avahi instead of loading at runtime" OFF)
|
||||
|
||||
# Options for location of OpenCV Java.
|
||||
set(OPENCV_JAVA_INSTALL_DIR "" CACHE PATH "Location to search for the OpenCV jar file")
|
||||
|
||||
# Options for compilation flags.
|
||||
option(NO_WERROR "Disable -Werror flag during compilation" OFF)
|
||||
|
||||
if(NOT WITH_JAVA OR NOT WITH_CSCORE)
|
||||
if(NOT "${OPENCV_JAVA_INSTALL_DIR}" STREQUAL "")
|
||||
message(
|
||||
WARNING
|
||||
"
|
||||
WARNING: OpenCV Java dir set but java is not enabled!
|
||||
It will be ignored.
|
||||
"
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
wpilib_config(OPTIONS WITH_JAVA REQUIRES BUILD_SHARED_LIBS)
|
||||
|
||||
wpilib_config(OPTIONS WITH_SIMULATION_MODULES REQUIRES BUILD_SHARED_LIBS WITH_WPILIB WITH_NTCORE)
|
||||
|
||||
wpilib_config(OPTIONS WITH_CSCORE REQUIRES WITH_NTCORE)
|
||||
@@ -126,17 +100,7 @@ wpilib_config(OPTIONS WITH_GUI REQUIRES WITH_NTCORE WITH_WPIMATH)
|
||||
|
||||
wpilib_config(OPTIONS WITH_WPILIB REQUIRES WITH_NTCORE WITH_WPIMATH)
|
||||
|
||||
wpilib_config(OPTIONS WITH_WPIMATH WITH_JAVA REQUIRES WITH_WPIUNITS)
|
||||
|
||||
set(include_dest include)
|
||||
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)
|
||||
if(NOT ANDROID)
|
||||
find_package(JNI REQUIRED COMPONENTS JVM)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WITH_DOCS)
|
||||
find_package(Doxygen REQUIRED)
|
||||
@@ -283,10 +247,9 @@ 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)
|
||||
@@ -299,24 +262,10 @@ if(WITH_NTCORE)
|
||||
endif()
|
||||
|
||||
if(WITH_WPIMATH)
|
||||
if(WITH_JAVA)
|
||||
set(WPIUNITS_DEP_REPLACE ${WPIUNITS_DEP_REPLACE_IMPL})
|
||||
add_subdirectory(wpiunits)
|
||||
endif()
|
||||
set(WPIMATH_DEP_REPLACE "find_dependency(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})
|
||||
add_subdirectory(wpiunits)
|
||||
endif()
|
||||
|
||||
if(WITH_GUI)
|
||||
add_subdirectory(fields)
|
||||
add_subdirectory(thirdparty/imgui_suite)
|
||||
@@ -347,16 +296,10 @@ 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)")
|
||||
if(WITH_JAVA)
|
||||
set(WPILIBJ_DEP_REPLACE "find_dependency(wpilibj)")
|
||||
endif()
|
||||
set(COMMAND_DEP_REPLACE "find_dependency(commandsv2)")
|
||||
add_subdirectory(apriltag)
|
||||
add_subdirectory(wpilibj)
|
||||
add_subdirectory(wpilibc)
|
||||
add_subdirectory(commandsv3) # must be after wpilibj
|
||||
add_subdirectory(commandsv2)
|
||||
add_subdirectory(romiVendordep)
|
||||
add_subdirectory(xrpVendordep)
|
||||
|
||||
@@ -24,27 +24,6 @@
|
||||
"CMAKE_C_COMPILER_LAUNCHER": "sccache",
|
||||
"CMAKE_CXX_COMPILER_LAUNCHER": "sccache"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "with-java",
|
||||
"displayName": "",
|
||||
"description": "Ninja config with Java",
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "build-cmake",
|
||||
"cacheVariables": {
|
||||
"WITH_JAVA": "ON"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "with-java-and-sccache",
|
||||
"displayName": "",
|
||||
"description": "Ninja config with Java and sccache",
|
||||
"generator": "Ninja",
|
||||
"inherits": "with-sccache",
|
||||
"binaryDir": "build-cmake",
|
||||
"cacheVariables": {
|
||||
"WITH_JAVA": "ON"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
- [Design Philosophy](#design-philosophy)
|
||||
- [Contribution Process](#contribution-process)
|
||||
- [Coding Guidelines](#coding-guidelines)
|
||||
- [Submitting Changes](#submitting-changes)
|
||||
@@ -13,29 +14,41 @@ So you want to contribute your changes back to WPILib. Great! We have a few cont
|
||||
|
||||
## General Contribution Rules
|
||||
|
||||
- Everything in the library must work for the 4000+ teams that will be using it.
|
||||
- Everything in the library must work for the 14000+ teams that will be using it.
|
||||
- We need to be able to maintain submitted changes, even if you are no longer working on the project.
|
||||
- Tool suite changes must be generally useful to a broad range of teams
|
||||
- Excluding bug fixes, changes in one language generally need to have corresponding changes in other languages.
|
||||
- Some features, such the addition of C++23 for WPILibC or Functional Interfaces for WPILibJ, are specific to that version of WPILib only. New language features added to C++ must be wrappable in Python for [RobotPy](https://github.com/robotpy).
|
||||
- Substantial changes often need to have corresponding LabVIEW changes. To do this, we will work with NI on these large changes.
|
||||
- Some features, such the addition of C++26 for WPILibC or Functional Interfaces for WPILibJ, are specific to that version of WPILib only. New language features added to C++ must be wrappable in Python for [RobotPy](https://github.com/robotpy).
|
||||
- Changes should have tests.
|
||||
- Code should be well documented.
|
||||
- This involves writing tutorials and/or usage guides for your submitted feature. These articles are then hosted on the [WPILib](https://docs.wpilib.org/) documentation website. See the [frc-docs repository](https://github.com/wpilibsuite/frc-docs) for more information.
|
||||
- This involves writing tutorials and/or usage guides for your submitted feature. These articles are then hosted on the [WPILib](https://docs.wpilib.org/) documentation website. See the [wpilib-docs repository](https://github.com/wpilibsuite/wpilib-docs) for more information.
|
||||
|
||||
## What to Contribute
|
||||
|
||||
- Bug reports and fixes
|
||||
- We will generally accept bug fixes without too much question. If they are only implemented for one language, we will implement them for any other necessary languages. Bug reports are also welcome, please submit them to our GitHub issue tracker.
|
||||
- While we do welcome improvements to the API, there are a few important rules to consider:
|
||||
- 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.
|
||||
- Features must be added to Java (WPILibJ), C++ (WPILibC), and Python with rare exceptions.
|
||||
- Most of Python (RobotPy) is created by wrapping WPILibC with pybind11 via semiwrap. In general, new user-facing functions or classes should have the proper wrapper configs updated, typically located in a YAML file with the same name as the header. See the [in-repo RobotPy README](./README-RobotPy.md) for more info and how to partially auto-update the configs. However, the command framework is reimplemented in Python, and requires code to be ported instead of being wrapped via semiwrap.
|
||||
- During competition season, we will not merge any new feature additions or removals. 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! 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.
|
||||
- While the library may contain support for specific sensors, these are typically items contained in the FIRST Robotics Competition Kit of Parts or commonly used hardware identified by FIRST or core WPILib Developers. If you think a certain sensor should be supported in WPILib, you may submit an issue justifying the reasons why it should be supported and approval will be determined by FIRST or core WPILib Developers. If you are a company interested in getting a sensor into the Kit of Parts, please contact FIRST directly at frcparts@firstinspires.org.
|
||||
|
||||
## Design Philosophy
|
||||
|
||||
WPILib's general design philosophy strays far away from the traditional Object-Oriented Programming architectures dominant in enterprise codebases. The general points to follow for WPILib are as follows:
|
||||
|
||||
- Prefer functions and composition over inheritance. Inheritance is rigid and often prevents evolution, as adding or removing methods from an inherited class risks breakage. For similar reasons, functional interfaces (`std::function` in C++) are preferred over actual interfaces.
|
||||
- Avoid opaque black-boxes of functionality. Classes like RamseteCommand or HolonomicDriveController (both removed in 2027) are good examples of this. While they look like a good abstraction that helps beginners, the black-box nature means they are [difficult to debug](https://github.com/wpilibsuite/allwpilib/issues/3350) and it's impossible to instrument the internals to figure out what's going on, or they are extremely clunky to use compared to composing the individual components (thus defeating the point of abstracting it away; SwerveControllerCommand construction was [a huge pile of opaque arguments glued together](https://github.com/wpilibsuite/allwpilib/blob/v2026.2.2/wpilibjExamples/src/main/java/edu/wpi/first/wpilibj/examples/swervecontrollercommand/RobotContainer.java#L104-L114)). Composition is strongly preferred, with strong documentation and examples describing how to do that composition.
|
||||
- Error at compile time, not runtime. Despite our best efforts, there will always be people who don't read stack traces (understandable for beginner programmers). Compile time errors show up in builds and in an IDE, which is much easier and faster for people to pinpoint and debug. Use language features to make invalid code impossible to build.
|
||||
- The Matrix class in Java is an example of this. While clunky due to Java's weak generics system, it enforces correct Matrix dimensions at compile time, with the MatBuilder factory method throwing if the array passed in is the wrong size, which leads to the next point:
|
||||
- Try to only throw exceptions at code startup, and only for things that are obviously incorrect. Robots shouldn't quit, and it's a real "feels bad" moment when yours does, especially in a match. It's oftentimes better to have a robot continue running when it sees nonsensical state as opposed to outright crashing, since other components are often still functional. If you can't make invalid code a compile time error, throwing at the start of the robot program is the next best solution, but avoid throwing in functions likely to be called throughout a robot's runtime.
|
||||
- Sometimes the behavior of functions are just incorrect if invalid data is passed in, and throwing is one of the only options. This is a judgement call, but if there are no other options, throwing can be okay.
|
||||
- An alternative to throwing is logging an error, typically with [the Alerts framework](https://docs.wpilib.org/en/latest/docs/software/telemetry/persistent-alerts.html); this is a good choice for runtime errors. Also see https://github.com/wpilibsuite/allwpilib/issues/6766 for an example of not throwing exceptions, but simply logging an error on invalid data.
|
||||
- Note that hardware configuration issues such as a sensor not existing isn't necessarily obviously incorrect; it could be that the wrong port was specified, but it could also be unplugged due to external factors. Throwing just because it's unplugged can make for a "feels bad" moment, and should be avoided.
|
||||
|
||||
## Contribution 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 2027 GradleRIO version, ie `2027.0.0-alpha-3`
|
||||
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 2027 GradleRIO version, ie `2027.0.0-alpha-5`
|
||||
|
||||
```groovy
|
||||
wpi.maven.useLocal = false
|
||||
@@ -27,7 +27,7 @@ Java
|
||||
```groovy
|
||||
plugins {
|
||||
id "java"
|
||||
id "edu.wpi.first.GradleRIO" version "2027.0.0-alpha-3"
|
||||
id "org.wpilib.GradleRIO" version "2027.0.0-alpha-5"
|
||||
}
|
||||
|
||||
wpi.maven.useLocal = false
|
||||
@@ -40,7 +40,7 @@ C++
|
||||
plugins {
|
||||
id "cpp"
|
||||
id "google-test-test-suite"
|
||||
id "edu.wpi.first.GradleRIO" version "2027.0.0-alpha-3"
|
||||
id "org.wpilib.GradleRIO" version "2027.0.0-alpha-5"
|
||||
}
|
||||
|
||||
wpi.maven.useLocal = false
|
||||
@@ -61,11 +61,11 @@ Java
|
||||
```groovy
|
||||
plugins {
|
||||
id "java"
|
||||
id "edu.wpi.first.GradleRIO" version "2027.0.0-alpha-3"
|
||||
id "org.wpilib.GradleRIO" version "2027.0.0-alpha-5"
|
||||
}
|
||||
|
||||
wpi.maven.useLocal = false
|
||||
wpi.maven.useFrcMavenLocalDevelopment = true
|
||||
wpi.maven.useWpilibMavenLocalDevelopment = true
|
||||
wpi.versions.wpilibVersion = 'YEAR.424242.+'
|
||||
```
|
||||
|
||||
@@ -74,11 +74,11 @@ C++
|
||||
plugins {
|
||||
id "cpp"
|
||||
id "google-test-test-suite"
|
||||
id "edu.wpi.first.GradleRIO" version "2027.0.0-alpha-3"
|
||||
id "org.wpilib.GradleRIO" version "2027.0.0-alpha-5"
|
||||
}
|
||||
|
||||
wpi.maven.useLocal = false
|
||||
wpi.maven.useFrcMavenLocalDevelopment = true
|
||||
wpi.maven.useWpilibMavenLocalDevelopment = true
|
||||
wpi.versions.wpilibVersion = 'YEAR.424242.+'
|
||||
```
|
||||
|
||||
|
||||
@@ -23,3 +23,6 @@ To maintain consistency with other Python scripts, copy an existing `generate_*.
|
||||
|
||||
### (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.
|
||||
|
||||
#### (Re)Generating QuickBuffers files
|
||||
Regenerating QuickBuffers files requires the Protocol Buffers compiler (protoc), and the QuickBuffers plugin, which can be found on [their releases page](https://github.com/HebiRobotics/QuickBuffers/releases). Once you have both, you can pass their paths into the generation scripts with `--protoc` and `--quickbuf_plugin` and regenerate the files.
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
## Publishing Third Party Dependencies
|
||||
Currently the 3rd party deps are imgui, opencv, google test, libssh, and apriltaglib
|
||||
Currently the 3rd party external deps are opencv, libssh, ceres, and gtsam.
|
||||
|
||||
For publishing these dependencies, the version needs to be manually updated in the publish.gradle file of their respective repository.
|
||||
Then, in the azure build for the dependency you want to build for, manually start a pipeline build (As of current, this is the `Run Pipeline` button).
|
||||
A variable needs to be added called `RUN_AZURE_ARTIFACTORY_RELEASE`, with a value of `true`. Then when the pipeline gets started, the final build outputs will be updated to artifactory.
|
||||
Then, upload a new tag for the dependency you want to build for, which will automatically start a build.
|
||||
The CI workflow should set `RUN_AZURE_ARTIFACTORY_RELEASE` to `true` on tagged runs. Then when the pipeline gets started, the final build outputs will be uploaded to artifactory.
|
||||
|
||||
To use newer versions of C++ dependencies, in `shared/config.gradle`, update the version related to the specific dependency.
|
||||
For Java dependencies, there is likely a file related to the specific dependency in the shared folder. Update the version in there.
|
||||
|
||||
Note, changing artifact locations (This includes changing the artifact year currently, I have an issue open to change this) requires updating the `native-utils` plugin
|
||||
Note, changing artifact locations requires updating the `native-utils` plugin; specifically, the `configureDependencies` method in the `WPINativeUtilsExtension` class.
|
||||
|
||||
## Publishing allwpilib
|
||||
allwpilib publishes to the development repo on every push to main. To publish a release build, upload a new tag, and a release will automatically be built and published.
|
||||
|
||||
## Publishing desktop tools
|
||||
Desktop tools publish to the development repo on every push to main. To publish a release build, upload a new tag, and a release will automatically be built and published.
|
||||
### Adding a new robot code dependency/subproject
|
||||
If a new subproject has been added that is meant for use from robot code, both GradleRIO and the `native-utils` plugin need to be updated. `native-utils` is updated in the same way as 3rd party dependencies. For GradleRIO, update the `WPIJavaDepsExtension` to contain your new subproject's artifacts.
|
||||
|
||||
## Publishing VS Code
|
||||
Before publishing, make sure to update the gradlerio version in `vscode-wpilib/resources/gradle/version.txt` Also make sure the gradle wrapper version matches the wrapper required by gradlerio.
|
||||
Before publishing, make sure to update the GradleRIO version in `vscode-wpilib/resources/gradle/version.txt`. Also make sure the Gradle Wrapper version matches the wrapper required by GradleRIO.
|
||||
Upon pushing a tag, a release will be built, and the files will be uploaded to the releases on GitHub.
|
||||
|
||||
## Publishing GradleRIO
|
||||
|
||||
72
MODULE.bazel
72
MODULE.bazel
@@ -3,25 +3,22 @@ module(
|
||||
version = "0.0.0",
|
||||
)
|
||||
|
||||
include("//docs:doxygen.MODULE.bazel")
|
||||
|
||||
include("//shared/bazel/thirdparty/ceres:ceres.MODULE.bazel")
|
||||
|
||||
include("//shared/bazel/thirdparty/libssh:libssh.MODULE.bazel")
|
||||
|
||||
include("//shared/bazel/thirdparty/mrclib:mrclib.MODULE.bazel")
|
||||
|
||||
bazel_dep(name = "apple_support", version = "2.0.0", repo_name = "build_bazel_apple_support")
|
||||
|
||||
# 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
|
||||
bazel_dep(name = "rules_cc", version = "0.2.13")
|
||||
single_version_override(
|
||||
module_name = "rules_cc",
|
||||
patch_strip = 1,
|
||||
patches = ["//:shared/bazel/patches/rules_cc_windows.patch"],
|
||||
)
|
||||
|
||||
bazel_dep(name = "rules_cc", version = "0.2.17")
|
||||
bazel_dep(name = "rules_pkg", version = "1.1.0")
|
||||
bazel_dep(name = "bazel_features", version = "1.33.0")
|
||||
bazel_dep(name = "aspect_bazel_lib", version = "2.14.0")
|
||||
bazel_dep(name = "bazel_skylib", version = "1.8.2")
|
||||
bazel_dep(name = "platforms", version = "1.0.0")
|
||||
bazel_dep(name = "rules_java", version = "8.14.0")
|
||||
bazel_dep(name = "rules_java", version = "8.16.1")
|
||||
bazel_dep(name = "rules_python", version = "1.7.0")
|
||||
bazel_dep(name = "rules_pycross", version = "0.8.1")
|
||||
|
||||
@@ -51,12 +48,11 @@ maven.install(
|
||||
name = "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",
|
||||
"io.avaje:avaje-jsonb:3.14",
|
||||
"io.avaje:avaje-jsonb-generator:3.14",
|
||||
"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",
|
||||
"org.wpilib.thirdparty.opencv:opencv-java:2027-4.13.0-1",
|
||||
"org.junit.jupiter:junit-jupiter:5.10.1",
|
||||
"org.junit.platform:junit-platform-console:1.10.1",
|
||||
"org.junit.platform:junit-platform-launcher:1.10.1",
|
||||
@@ -77,32 +73,6 @@ maven.install(
|
||||
use_repo(maven, "maven", "unpinned_maven")
|
||||
|
||||
bazel_dep(name = "caseyduquettesc_rules_python_pytest", version = "1.1.1", repo_name = "rules_python_pytest")
|
||||
bazel_dep(name = "rules_doxygen", version = "2.5.0")
|
||||
archive_override(
|
||||
module_name = "rules_doxygen",
|
||||
integrity = "sha256-qxfKreTkQnV4tUX6KJDFXuOJj4p6VZdBYjAie77I5ho=",
|
||||
strip_prefix = "rules_doxygen-2.5.0",
|
||||
urls = ["https://github.com/TendTo/rules_doxygen/releases/download/2.5.0/rules_doxygen-2.5.0.tar.gz"],
|
||||
)
|
||||
|
||||
doxygen_extension = use_extension("@rules_doxygen//:extensions.bzl", "doxygen_extension")
|
||||
doxygen_extension.configuration(
|
||||
platform = "windows",
|
||||
sha256 = "44658b9cc5c91749e6e3cc426ba63e2550b4a4a7619065acd77029aa234719c6",
|
||||
version = "1.15.0",
|
||||
)
|
||||
doxygen_extension.configuration(
|
||||
platform = "mac",
|
||||
sha256 = "b7630eaa0d97bb50b0333929ef5dc1c18f9e38faf1e22dca3166189a9718faf0",
|
||||
version = "1.15.0",
|
||||
)
|
||||
doxygen_extension.configuration(
|
||||
platform = "linux",
|
||||
sha256 = "0ec2e5b2c3cd82b7106d19cb42d8466450730b8cb7a9e85af712be38bf4523a1",
|
||||
version = "1.15.0",
|
||||
)
|
||||
use_repo(doxygen_extension, "doxygen")
|
||||
|
||||
bazel_dep(name = "eigen", version = "5.0.1")
|
||||
local_path_override(
|
||||
module_name = "eigen",
|
||||
@@ -116,29 +86,29 @@ http_file = use_repo_rule("@bazel_tools//tools/build_defs/repo:http.bzl", "http_
|
||||
http_file(
|
||||
name = "quickbuffer_protoc_linux",
|
||||
executable = True,
|
||||
sha256 = "f9a041bccaa7040db523666ef1b5fe9f6f94e70a82c88951f18f58aadd9c50b5",
|
||||
urls = ["https://repo1.maven.org/maven2/us/hebi/quickbuf/protoc-gen-quickbuf/1.3.2/protoc-gen-quickbuf-1.3.2-linux-x86_64.exe"],
|
||||
sha256 = "02767f5f662720c121dfaaa9109aefa9b0b1e2415cbe1af9e4713a7b00663696",
|
||||
urls = ["https://repo1.maven.org/maven2/us/hebi/quickbuf/protoc-gen-quickbuf/1.3.3/protoc-gen-quickbuf-1.3.3-linux-x86_64.exe"],
|
||||
)
|
||||
|
||||
http_file(
|
||||
name = "quickbuffer_protoc_osx_x86-64",
|
||||
executable = True,
|
||||
sha256 = "ea307c2b69664ae7e7c69db4cddf5803187e5a34bceffd09a21652f0f16044f7",
|
||||
urls = ["https://repo1.maven.org/maven2/us/hebi/quickbuf/protoc-gen-quickbuf/1.3.2/protoc-gen-quickbuf-1.3.2-osx-x86_64.exe"],
|
||||
sha256 = "cdc0b4b188f944dddd4430bcd6f6266ca1aaf8c33940d7bee1ed63fc962d8525",
|
||||
urls = ["https://repo1.maven.org/maven2/us/hebi/quickbuf/protoc-gen-quickbuf/1.3.3/protoc-gen-quickbuf-1.3.3-osx-x86_64.exe"],
|
||||
)
|
||||
|
||||
http_file(
|
||||
name = "quickbuffer_protoc_osx_aarch64",
|
||||
executable = True,
|
||||
sha256 = "a9abdee09d8b5ef0aa954b238536917313511deec11e1901994af26ade033e28",
|
||||
urls = ["https://repo1.maven.org/maven2/us/hebi/quickbuf/protoc-gen-quickbuf/1.3.2/protoc-gen-quickbuf-1.3.2-osx-aarch_64.exe"],
|
||||
sha256 = "95fa0a22ad2d9fa8f84a31cf3a0670b18c0ad954f73035f60cfb77c2814fb41c",
|
||||
urls = ["https://repo1.maven.org/maven2/us/hebi/quickbuf/protoc-gen-quickbuf/1.3.3/protoc-gen-quickbuf-1.3.3-osx-aarch_64.exe"],
|
||||
)
|
||||
|
||||
http_file(
|
||||
name = "quickbuffer_protoc_windows",
|
||||
executable = True,
|
||||
sha256 = "27dc1f29764a62b5e6a813a4bcd63e81bbdc3394da760a44acae1025b4a89f1d",
|
||||
urls = ["https://repo1.maven.org/maven2/us/hebi/quickbuf/protoc-gen-quickbuf/1.3.2/protoc-gen-quickbuf-1.3.2-windows-x86_64.exe"],
|
||||
sha256 = "8a30b2eaebefbedc3b592118670de1ab6ea1aa19dcf8cdab220e25485ccd4a0a",
|
||||
urls = ["https://repo1.maven.org/maven2/us/hebi/quickbuf/protoc-gen-quickbuf/1.3.3/protoc-gen-quickbuf-1.3.3-windows-x86_64.exe"],
|
||||
)
|
||||
|
||||
bazel_dep(name = "rules_bzlmodrio_toolchains", version = "2025-1.bcr6")
|
||||
|
||||
323
MODULE.bazel.lock
generated
323
MODULE.bazel.lock
generated
@@ -12,7 +12,8 @@
|
||||
"https://bcr.bazel.build/modules/abseil-cpp/20240116.2/MODULE.bazel": "73939767a4686cd9a520d16af5ab440071ed75cec1a876bf2fcfaf1f71987a16",
|
||||
"https://bcr.bazel.build/modules/abseil-cpp/20250127.1/MODULE.bazel": "c4a89e7ceb9bf1e25cf84a9f830ff6b817b72874088bf5141b314726e46a57c1",
|
||||
"https://bcr.bazel.build/modules/abseil-cpp/20250512.1/MODULE.bazel": "d209fdb6f36ffaf61c509fcc81b19e81b411a999a934a032e10cd009a0226215",
|
||||
"https://bcr.bazel.build/modules/abseil-cpp/20250512.1/source.json": "d725d73707d01bb46ab3ca59ba408b8e9bd336642ca77a2269d4bfb8bbfd413d",
|
||||
"https://bcr.bazel.build/modules/abseil-cpp/20250814.0/MODULE.bazel": "c43c16ca2c432566cdb78913964497259903ebe8fb7d9b57b38e9f1425b427b8",
|
||||
"https://bcr.bazel.build/modules/abseil-cpp/20250814.0/source.json": "b88bff599ceaf0f56c264c749b1606f8485cec3b8c38ba30f88a4df9af142861",
|
||||
"https://bcr.bazel.build/modules/apple_support/1.11.1/MODULE.bazel": "1843d7cd8a58369a444fc6000e7304425fba600ff641592161d9f15b179fb896",
|
||||
"https://bcr.bazel.build/modules/apple_support/1.15.1/MODULE.bazel": "a0556fefca0b1bb2de8567b8827518f94db6a6e7e7d632b4c48dc5f865bc7c85",
|
||||
"https://bcr.bazel.build/modules/apple_support/1.23.1/MODULE.bazel": "53763fed456a968cf919b3240427cf3a9d5481ec5466abc9d5dc51bc70087442",
|
||||
@@ -49,6 +50,7 @@
|
||||
"https://bcr.bazel.build/modules/bazel_skylib/1.6.1/MODULE.bazel": "8fdee2dbaace6c252131c00e1de4b165dc65af02ea278476187765e1a617b917",
|
||||
"https://bcr.bazel.build/modules/bazel_skylib/1.7.0/MODULE.bazel": "0db596f4563de7938de764cc8deeabec291f55e8ec15299718b93c4423e9796d",
|
||||
"https://bcr.bazel.build/modules/bazel_skylib/1.7.1/MODULE.bazel": "3120d80c5861aa616222ec015332e5f8d3171e062e3e804a2a0253e1be26e59b",
|
||||
"https://bcr.bazel.build/modules/bazel_skylib/1.8.1/MODULE.bazel": "88ade7293becda963e0e3ea33e7d54d3425127e0a326e0d17da085a5f1f03ff6",
|
||||
"https://bcr.bazel.build/modules/bazel_skylib/1.8.2/MODULE.bazel": "69ad6927098316848b34a9142bcc975e018ba27f08c4ff403f50c1b6e646ca67",
|
||||
"https://bcr.bazel.build/modules/bazel_skylib/1.8.2/source.json": "34a3c8bcf233b835eb74be9d628899bb32999d3e0eadef1947a0a562a2b16ffb",
|
||||
"https://bcr.bazel.build/modules/buildozer/7.1.2/MODULE.bazel": "2e8dd40ede9c454042645fd8d8d0cd1527966aa5c919de86661e62953cd73d84",
|
||||
@@ -112,9 +114,12 @@
|
||||
"https://bcr.bazel.build/modules/rules_cc/0.0.9/MODULE.bazel": "836e76439f354b89afe6a911a7adf59a6b2518fafb174483ad78a2a2fde7b1c5",
|
||||
"https://bcr.bazel.build/modules/rules_cc/0.1.1/MODULE.bazel": "2f0222a6f229f0bf44cd711dc13c858dad98c62d52bd51d8fc3a764a83125513",
|
||||
"https://bcr.bazel.build/modules/rules_cc/0.1.5/MODULE.bazel": "88dfc9361e8b5ae1008ac38f7cdfd45ad738e4fa676a3ad67d19204f045a1fd8",
|
||||
"https://bcr.bazel.build/modules/rules_cc/0.2.0/MODULE.bazel": "b5c17f90458caae90d2ccd114c81970062946f49f355610ed89bebf954f5783c",
|
||||
"https://bcr.bazel.build/modules/rules_cc/0.2.13/MODULE.bazel": "eecdd666eda6be16a8d9dc15e44b5c75133405e820f620a234acc4b1fdc5aa37",
|
||||
"https://bcr.bazel.build/modules/rules_cc/0.2.14/MODULE.bazel": "353c99ed148887ee89c54a17d4100ae7e7e436593d104b668476019023b58df8",
|
||||
"https://bcr.bazel.build/modules/rules_cc/0.2.14/source.json": "55d0a4587c5592fad350f6e698530f4faf0e7dd15e69d43f8d87e220c78bea54",
|
||||
"https://bcr.bazel.build/modules/rules_cc/0.2.17/MODULE.bazel": "1849602c86cb60da8613d2de887f9566a6d354a6df6d7009f9d04a14402f9a84",
|
||||
"https://bcr.bazel.build/modules/rules_cc/0.2.17/source.json": "3832f45d145354049137c0090df04629d9c2b5493dc5c2bf46f1834040133a07",
|
||||
"https://bcr.bazel.build/modules/rules_cc/0.2.8/MODULE.bazel": "f1df20f0bf22c28192a794f29b501ee2018fa37a3862a1a2132ae2940a23a642",
|
||||
"https://bcr.bazel.build/modules/rules_foreign_cc/0.9.0/MODULE.bazel": "c9e8c682bf75b0e7c704166d79b599f93b72cfca5ad7477df596947891feeef6",
|
||||
"https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/MODULE.bazel": "40c97d1144356f52905566c55811f13b299453a14ac7769dfba2ac38192337a8",
|
||||
"https://bcr.bazel.build/modules/rules_java/4.0.0/MODULE.bazel": "5a78a7ae82cd1a33cef56dc578c7d2a46ed0dca12643ee45edbb8417899e6f74",
|
||||
@@ -129,7 +134,8 @@
|
||||
"https://bcr.bazel.build/modules/rules_java/7.3.2/MODULE.bazel": "50dece891cfdf1741ea230d001aa9c14398062f2b7c066470accace78e412bc2",
|
||||
"https://bcr.bazel.build/modules/rules_java/7.6.1/MODULE.bazel": "2f14b7e8a1aa2f67ae92bc69d1ec0fa8d9f827c4e17ff5e5f02e91caa3b2d0fe",
|
||||
"https://bcr.bazel.build/modules/rules_java/8.14.0/MODULE.bazel": "717717ed40cc69994596a45aec6ea78135ea434b8402fb91b009b9151dd65615",
|
||||
"https://bcr.bazel.build/modules/rules_java/8.14.0/source.json": "8a88c4ca9e8759da53cddc88123880565c520503321e2566b4e33d0287a3d4bc",
|
||||
"https://bcr.bazel.build/modules/rules_java/8.16.1/MODULE.bazel": "0f20b1cecaa8e52f60a8f071e59a20b4e3b9a67f6c56c802ea256f6face692d3",
|
||||
"https://bcr.bazel.build/modules/rules_java/8.16.1/source.json": "072f8d11264edc499621be2dc9ea01d6395db5aa6f8799c034ae01a3e857f2e4",
|
||||
"https://bcr.bazel.build/modules/rules_java/8.3.2/MODULE.bazel": "7336d5511ad5af0b8615fdc7477535a2e4e723a357b6713af439fe8cf0195017",
|
||||
"https://bcr.bazel.build/modules/rules_java/8.5.1/MODULE.bazel": "d8a9e38cc5228881f7055a6079f6f7821a073df3744d441978e7a43e20226939",
|
||||
"https://bcr.bazel.build/modules/rules_java/8.6.1/MODULE.bazel": "f4808e2ab5b0197f094cabce9f4b006a27766beb6a9975931da07099560ca9c2",
|
||||
@@ -199,6 +205,156 @@
|
||||
},
|
||||
"selectedYankedVersions": {},
|
||||
"moduleExtensions": {
|
||||
"@@pybind11_bazel+//:internal_configure.bzl%internal_configure_extension": {
|
||||
"general": {
|
||||
"bzlTransitiveDigest": "uxP2cZuW027Q8wpZbeJeuW5MXcNBO8GcOK/LNN2sPvQ=",
|
||||
"usagesDigest": "D1r3lfzMuUBFxgG8V6o0bQTLMk3GkaGOaPzw53wrwyw=",
|
||||
"recordedFileInputs": {
|
||||
"@@pybind11_bazel+//MODULE.bazel": "e6f4c20442eaa7c90d7190d8dc539d0ab422f95c65a57cc59562170c58ae3d34"
|
||||
},
|
||||
"recordedDirentsInputs": {},
|
||||
"envVariables": {},
|
||||
"generatedRepoSpecs": {
|
||||
"pybind11": {
|
||||
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
|
||||
"attributes": {
|
||||
"build_file": "@@pybind11_bazel+//:pybind11-BUILD.bazel",
|
||||
"strip_prefix": "pybind11-2.12.0",
|
||||
"urls": [
|
||||
"https://github.com/pybind/pybind11/archive/v2.12.0.zip"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"recordedRepoMappingEntries": [
|
||||
[
|
||||
"pybind11_bazel+",
|
||||
"bazel_tools",
|
||||
"bazel_tools"
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"@@rules_apple+//apple:apple.bzl%provisioning_profile_repository_extension": {
|
||||
"general": {
|
||||
"bzlTransitiveDigest": "JNyWptXQtF/Vu+dUIk3wLLXiS47h7sDP2eYWSsD28xU=",
|
||||
"usagesDigest": "vsJl8Rw5NL+5Ag2wdUDoTeRF/5klkXO8545Iy7U1Q08=",
|
||||
"recordedFileInputs": {},
|
||||
"recordedDirentsInputs": {},
|
||||
"envVariables": {},
|
||||
"generatedRepoSpecs": {
|
||||
"local_provisioning_profiles": {
|
||||
"repoRuleId": "@@rules_apple+//apple/internal:local_provisioning_profiles.bzl%provisioning_profile_repository",
|
||||
"attributes": {}
|
||||
}
|
||||
},
|
||||
"recordedRepoMappingEntries": [
|
||||
[
|
||||
"apple_support+",
|
||||
"bazel_skylib",
|
||||
"bazel_skylib+"
|
||||
],
|
||||
[
|
||||
"bazel_tools",
|
||||
"rules_cc",
|
||||
"rules_cc+"
|
||||
],
|
||||
[
|
||||
"rules_apple+",
|
||||
"bazel_skylib",
|
||||
"bazel_skylib+"
|
||||
],
|
||||
[
|
||||
"rules_apple+",
|
||||
"bazel_tools",
|
||||
"bazel_tools"
|
||||
],
|
||||
[
|
||||
"rules_apple+",
|
||||
"build_bazel_apple_support",
|
||||
"apple_support+"
|
||||
],
|
||||
[
|
||||
"rules_apple+",
|
||||
"build_bazel_rules_swift",
|
||||
"rules_swift+"
|
||||
],
|
||||
[
|
||||
"rules_cc+",
|
||||
"bazel_tools",
|
||||
"bazel_tools"
|
||||
],
|
||||
[
|
||||
"rules_cc+",
|
||||
"cc_compatibility_proxy",
|
||||
"rules_cc++compatibility_proxy+cc_compatibility_proxy"
|
||||
],
|
||||
[
|
||||
"rules_cc+",
|
||||
"rules_cc",
|
||||
"rules_cc+"
|
||||
],
|
||||
[
|
||||
"rules_cc++compatibility_proxy+cc_compatibility_proxy",
|
||||
"rules_cc",
|
||||
"rules_cc+"
|
||||
],
|
||||
[
|
||||
"rules_swift+",
|
||||
"bazel_skylib",
|
||||
"bazel_skylib+"
|
||||
],
|
||||
[
|
||||
"rules_swift+",
|
||||
"bazel_tools",
|
||||
"bazel_tools"
|
||||
],
|
||||
[
|
||||
"rules_swift+",
|
||||
"build_bazel_apple_support",
|
||||
"apple_support+"
|
||||
],
|
||||
[
|
||||
"rules_swift+",
|
||||
"build_bazel_rules_swift",
|
||||
"rules_swift+"
|
||||
],
|
||||
[
|
||||
"rules_swift+",
|
||||
"build_bazel_rules_swift_local_config",
|
||||
"rules_swift++non_module_deps+build_bazel_rules_swift_local_config"
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"@@rules_apple+//apple:extensions.bzl%non_module_deps": {
|
||||
"general": {
|
||||
"bzlTransitiveDigest": "UsflLeiazyu2v5pvibcvOeIdDV95S25rT96h4XU1nhY=",
|
||||
"usagesDigest": "M3VqFpeTCo4qmrNKGZw0dxBHvTYDrfV3cscGzlSAhQ4=",
|
||||
"recordedFileInputs": {},
|
||||
"recordedDirentsInputs": {},
|
||||
"envVariables": {},
|
||||
"generatedRepoSpecs": {
|
||||
"xctestrunner": {
|
||||
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
|
||||
"attributes": {
|
||||
"urls": [
|
||||
"https://github.com/google/xctestrunner/archive/b7698df3d435b6491b4b4c0f9fc7a63fbed5e3a6.tar.gz"
|
||||
],
|
||||
"strip_prefix": "xctestrunner-b7698df3d435b6491b4b4c0f9fc7a63fbed5e3a6",
|
||||
"sha256": "ae3a063c985a8633cb7eb566db21656f8db8eb9a0edb8c182312c7f0db53730d"
|
||||
}
|
||||
}
|
||||
},
|
||||
"recordedRepoMappingEntries": [
|
||||
[
|
||||
"rules_apple+",
|
||||
"bazel_tools",
|
||||
"bazel_tools"
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"@@rules_bzlmodrio_toolchains+//:extensions.bzl%sh_configure": {
|
||||
"general": {
|
||||
"bzlTransitiveDigest": "q+0LgnvjpZ9Y2r2JYzNeYCKGLphbczG73lZ3rBg+XhM=",
|
||||
@@ -263,7 +419,7 @@
|
||||
"repoRuleId": "@@rules_bzlmodrio_toolchains+//toolchains:configure_cross_compiler.bzl%configure_cross_compiler",
|
||||
"attributes": {
|
||||
"extra_defines": [
|
||||
"-D__FRC_SYSTEMCORE__=1"
|
||||
"-D__FIRST_SYSTEMCORE__=1"
|
||||
],
|
||||
"bin_subfolder": "bookworm/bin",
|
||||
"bin_prefix": "aarch64-bookworm-linux-gnu-",
|
||||
@@ -847,6 +1003,165 @@
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"@@rules_swift+//swift:extensions.bzl%non_module_deps": {
|
||||
"general": {
|
||||
"bzlTransitiveDigest": "WQxCEBSXJEaQYe860JXZvAQug2B6+/VbBtRIDMF0pOc=",
|
||||
"usagesDigest": "mhACFnrdMv9Wi0Mt67bxocJqviRkDSV+Ee5Mqdj5akA=",
|
||||
"recordedFileInputs": {},
|
||||
"recordedDirentsInputs": {},
|
||||
"envVariables": {},
|
||||
"generatedRepoSpecs": {
|
||||
"com_github_apple_swift_protobuf": {
|
||||
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
|
||||
"attributes": {
|
||||
"urls": [
|
||||
"https://github.com/apple/swift-protobuf/archive/1.20.2.tar.gz"
|
||||
],
|
||||
"sha256": "3fb50bd4d293337f202d917b6ada22f9548a0a0aed9d9a4d791e6fbd8a246ebb",
|
||||
"strip_prefix": "swift-protobuf-1.20.2/",
|
||||
"build_file": "@@rules_swift+//third_party:com_github_apple_swift_protobuf/BUILD.overlay"
|
||||
}
|
||||
},
|
||||
"com_github_grpc_grpc_swift": {
|
||||
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
|
||||
"attributes": {
|
||||
"urls": [
|
||||
"https://github.com/grpc/grpc-swift/archive/1.16.0.tar.gz"
|
||||
],
|
||||
"sha256": "58b60431d0064969f9679411264b82e40a217ae6bd34e17096d92cc4e47556a5",
|
||||
"strip_prefix": "grpc-swift-1.16.0/",
|
||||
"build_file": "@@rules_swift+//third_party:com_github_grpc_grpc_swift/BUILD.overlay"
|
||||
}
|
||||
},
|
||||
"com_github_apple_swift_docc_symbolkit": {
|
||||
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
|
||||
"attributes": {
|
||||
"urls": [
|
||||
"https://github.com/apple/swift-docc-symbolkit/archive/refs/tags/swift-5.10-RELEASE.tar.gz"
|
||||
],
|
||||
"sha256": "de1d4b6940468ddb53b89df7aa1a81323b9712775b0e33e8254fa0f6f7469a97",
|
||||
"strip_prefix": "swift-docc-symbolkit-swift-5.10-RELEASE",
|
||||
"build_file": "@@rules_swift+//third_party:com_github_apple_swift_docc_symbolkit/BUILD.overlay"
|
||||
}
|
||||
},
|
||||
"com_github_apple_swift_nio": {
|
||||
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
|
||||
"attributes": {
|
||||
"urls": [
|
||||
"https://github.com/apple/swift-nio/archive/2.42.0.tar.gz"
|
||||
],
|
||||
"sha256": "e3304bc3fb53aea74a3e54bd005ede11f6dc357117d9b1db642d03aea87194a0",
|
||||
"strip_prefix": "swift-nio-2.42.0/",
|
||||
"build_file": "@@rules_swift+//third_party:com_github_apple_swift_nio/BUILD.overlay"
|
||||
}
|
||||
},
|
||||
"com_github_apple_swift_nio_http2": {
|
||||
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
|
||||
"attributes": {
|
||||
"urls": [
|
||||
"https://github.com/apple/swift-nio-http2/archive/1.26.0.tar.gz"
|
||||
],
|
||||
"sha256": "f0edfc9d6a7be1d587e5b403f2d04264bdfae59aac1d74f7d974a9022c6d2b25",
|
||||
"strip_prefix": "swift-nio-http2-1.26.0/",
|
||||
"build_file": "@@rules_swift+//third_party:com_github_apple_swift_nio_http2/BUILD.overlay"
|
||||
}
|
||||
},
|
||||
"com_github_apple_swift_nio_transport_services": {
|
||||
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
|
||||
"attributes": {
|
||||
"urls": [
|
||||
"https://github.com/apple/swift-nio-transport-services/archive/1.15.0.tar.gz"
|
||||
],
|
||||
"sha256": "f3498dafa633751a52b9b7f741f7ac30c42bcbeb3b9edca6d447e0da8e693262",
|
||||
"strip_prefix": "swift-nio-transport-services-1.15.0/",
|
||||
"build_file": "@@rules_swift+//third_party:com_github_apple_swift_nio_transport_services/BUILD.overlay"
|
||||
}
|
||||
},
|
||||
"com_github_apple_swift_nio_extras": {
|
||||
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
|
||||
"attributes": {
|
||||
"urls": [
|
||||
"https://github.com/apple/swift-nio-extras/archive/1.4.0.tar.gz"
|
||||
],
|
||||
"sha256": "4684b52951d9d9937bb3e8ccd6b5daedd777021ef2519ea2f18c4c922843b52b",
|
||||
"strip_prefix": "swift-nio-extras-1.4.0/",
|
||||
"build_file": "@@rules_swift+//third_party:com_github_apple_swift_nio_extras/BUILD.overlay"
|
||||
}
|
||||
},
|
||||
"com_github_apple_swift_log": {
|
||||
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
|
||||
"attributes": {
|
||||
"urls": [
|
||||
"https://github.com/apple/swift-log/archive/1.4.4.tar.gz"
|
||||
],
|
||||
"sha256": "48fe66426c784c0c20031f15dc17faf9f4c9037c192bfac2f643f65cb2321ba0",
|
||||
"strip_prefix": "swift-log-1.4.4/",
|
||||
"build_file": "@@rules_swift+//third_party:com_github_apple_swift_log/BUILD.overlay"
|
||||
}
|
||||
},
|
||||
"com_github_apple_swift_nio_ssl": {
|
||||
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
|
||||
"attributes": {
|
||||
"urls": [
|
||||
"https://github.com/apple/swift-nio-ssl/archive/2.23.0.tar.gz"
|
||||
],
|
||||
"sha256": "4787c63f61dd04d99e498adc3d1a628193387e41efddf8de19b8db04544d016d",
|
||||
"strip_prefix": "swift-nio-ssl-2.23.0/",
|
||||
"build_file": "@@rules_swift+//third_party:com_github_apple_swift_nio_ssl/BUILD.overlay"
|
||||
}
|
||||
},
|
||||
"com_github_apple_swift_collections": {
|
||||
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
|
||||
"attributes": {
|
||||
"urls": [
|
||||
"https://github.com/apple/swift-collections/archive/1.0.4.tar.gz"
|
||||
],
|
||||
"sha256": "d9e4c8a91c60fb9c92a04caccbb10ded42f4cb47b26a212bc6b39cc390a4b096",
|
||||
"strip_prefix": "swift-collections-1.0.4/",
|
||||
"build_file": "@@rules_swift+//third_party:com_github_apple_swift_collections/BUILD.overlay"
|
||||
}
|
||||
},
|
||||
"com_github_apple_swift_atomics": {
|
||||
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
|
||||
"attributes": {
|
||||
"urls": [
|
||||
"https://github.com/apple/swift-atomics/archive/1.1.0.tar.gz"
|
||||
],
|
||||
"sha256": "1bee7f469f7e8dc49f11cfa4da07182fbc79eab000ec2c17bfdce468c5d276fb",
|
||||
"strip_prefix": "swift-atomics-1.1.0/",
|
||||
"build_file": "@@rules_swift+//third_party:com_github_apple_swift_atomics/BUILD.overlay"
|
||||
}
|
||||
},
|
||||
"build_bazel_rules_swift_index_import": {
|
||||
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
|
||||
"attributes": {
|
||||
"build_file": "@@rules_swift+//third_party:build_bazel_rules_swift_index_import/BUILD.overlay",
|
||||
"canonical_id": "index-import-5.8",
|
||||
"urls": [
|
||||
"https://github.com/MobileNativeFoundation/index-import/releases/download/5.8.0.1/index-import.tar.gz"
|
||||
],
|
||||
"sha256": "28c1ffa39d99e74ed70623899b207b41f79214c498c603915aef55972a851a15"
|
||||
}
|
||||
},
|
||||
"build_bazel_rules_swift_local_config": {
|
||||
"repoRuleId": "@@rules_swift+//swift/internal:swift_autoconfiguration.bzl%swift_autoconfiguration",
|
||||
"attributes": {}
|
||||
}
|
||||
},
|
||||
"recordedRepoMappingEntries": [
|
||||
[
|
||||
"rules_swift+",
|
||||
"bazel_tools",
|
||||
"bazel_tools"
|
||||
],
|
||||
[
|
||||
"rules_swift+",
|
||||
"build_bazel_rules_swift",
|
||||
"rules_swift+"
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"facts": {}
|
||||
|
||||
@@ -18,10 +18,10 @@ The first types are Java artifacts. These are usually published as `jar` files.
|
||||
|
||||
Example:
|
||||
```
|
||||
edu.wpi.first.wpilibj:wpilibj-java:version
|
||||
org.wpilib.wpilibj:wpilibj-java:version
|
||||
```
|
||||
|
||||
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.
|
||||
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 in the Platforms nested class](https://github.com/wpilibsuite/native-utils/blob/main/src/main/java/org/wpilib/nativeutils/WPINativeUtilsExtension.java). 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.
|
||||
|
||||
@@ -29,8 +29,8 @@ Native artifacts are published with the base artifact name as their artifact ID,
|
||||
|
||||
Example:
|
||||
```
|
||||
edu.wpi.first.wpimath:wpimath-cpp:version:classifier@zip
|
||||
edu.wpi.first.wpimath:wpimath-cpp:version:windowsx86-64staticdebug@zip
|
||||
org.wpilib.wpimath:wpimath-cpp:version:classifier@zip
|
||||
org.wpilib.wpimath:wpimath-cpp:version:windowsx86-64staticdebug@zip
|
||||
```
|
||||
|
||||
## Provided Artifacts
|
||||
@@ -38,7 +38,7 @@ This repository provides the following artifacts. Below each artifact is its dep
|
||||
|
||||
For C++, if building with static dependencies, the listed order should be the link order in your linker.
|
||||
|
||||
All artifacts are based at `edu.wpi.first.artifactname` in the repository.
|
||||
All artifacts are based at `org.wpilib.artifactname` in the repository.
|
||||
|
||||
* wpiutil
|
||||
|
||||
@@ -52,32 +52,33 @@ All artifacts are based at `edu.wpi.first.artifactname` in the repository.
|
||||
* wpiutil
|
||||
|
||||
* ntcore
|
||||
* wpiutil
|
||||
* wpinet
|
||||
* wpiutil
|
||||
|
||||
* glass/libglass
|
||||
* wpiutil
|
||||
* wpimath
|
||||
* wpigui
|
||||
* wpimath
|
||||
* wpiutil
|
||||
|
||||
* glass/libglassnt
|
||||
* wpiutil
|
||||
* wpinet
|
||||
* ntcore
|
||||
* wpimath
|
||||
* wpigui
|
||||
* ntcore
|
||||
* wpinet
|
||||
* wpimath
|
||||
* wpiutil
|
||||
|
||||
* hal
|
||||
* ntcore
|
||||
* wpiutil
|
||||
|
||||
* halsim
|
||||
* wpiutil
|
||||
* wpinet
|
||||
* libglassnt
|
||||
* libglass
|
||||
* ntcore
|
||||
* wpimath
|
||||
* wpigui
|
||||
* libglass
|
||||
* libglassnt
|
||||
* wpinet
|
||||
* wpiutil
|
||||
|
||||
* cscore
|
||||
* opencv
|
||||
@@ -126,12 +127,16 @@ All artifacts are based at `edu.wpi.first.artifactname` in the repository.
|
||||
|
||||
### Third Party Artifacts
|
||||
|
||||
This repository provides the builds of the following third party software.
|
||||
This repository provides the builds of the following third party software:
|
||||
|
||||
All artifacts are based at `edu.wpi.first.thirdparty.frcYEAR` in the repository.
|
||||
|
||||
* apriltaglib
|
||||
* googletest
|
||||
* imgui
|
||||
* opencv
|
||||
* libssh
|
||||
|
||||
Other software can be found in their corresponding GitHub repositories:
|
||||
|
||||
* ceres: https://github.com/wpilibsuite/thirdparty-ceres
|
||||
* gtsam: https://github.com/wpilibsuite/thirdparty-gtsam
|
||||
* opencv: https://github.com/wpilibsuite/thirdparty-opencv
|
||||
* libssh: https://github.com/wpilibsuite/thirdparty-libssh
|
||||
|
||||
All artifacts are based at `org.wpilib.thirdparty` in the repository.
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# 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)
|
||||
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.
|
||||
- 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 //...`
|
||||
@@ -14,7 +14,7 @@ Other examples:
|
||||
- `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.
|
||||
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 builds in 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
|
||||
@@ -36,12 +36,12 @@ 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
|
||||
these pre-generation scripts use some configuration file to create multiple 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.
|
||||
adding new features those libraries. Therefore, 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.
|
||||
One of the huge benefits of Bazel is its remote caching ability. However, due to Bazel's 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 fork's 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.
|
||||
|
||||
|
||||
@@ -1,23 +1,22 @@
|
||||
# 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.
|
||||
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. The CMake build does not build Java or Python, only C++.
|
||||
|
||||
## Libraries that get built
|
||||
* apriltag
|
||||
* cameraserver
|
||||
* commandsv3
|
||||
* commandsv2
|
||||
* cscore
|
||||
* datalog
|
||||
* fields
|
||||
* hal (simulation HAL only)
|
||||
* ntcore
|
||||
* romiVendordep
|
||||
* simulation extensions
|
||||
* wpigui
|
||||
* wpilib (wpilibc, wpilibj, and myRobot)
|
||||
* commandsv2
|
||||
* wpilib (wpilibc, wpilibj, and developerRobot)
|
||||
* wpimath
|
||||
* wpinet
|
||||
* wpiunits
|
||||
* wpiutil
|
||||
* xrpVendordep
|
||||
|
||||
@@ -26,34 +25,27 @@ WPILib is normally built with Gradle, however for some systems, such as Linux ba
|
||||
* glass
|
||||
* outlineviewer
|
||||
* sysid
|
||||
* wpical
|
||||
* 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.
|
||||
By default, all libraries get built with a default CMake setup. The libraries are built as shared libraries. Data Log Tool is 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.
|
||||
* This option will cause CMake to build static libraries instead of shared libraries.
|
||||
* `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)
|
||||
@@ -61,13 +53,9 @@ The following build options are available:
|
||||
* `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.
|
||||
* This option will build the HAL and wpilibc 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 Systemcore.
|
||||
* `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`
|
||||
@@ -89,11 +77,11 @@ If you want, you can also use `ccmake` in order to visually set these properties
|
||||
|
||||
## 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`.
|
||||
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 preset is `sccache` (sets the C/C++ compiler launcher to 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.
|
||||
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 multi-job build, run the following command with x being the number of jobs you want.
|
||||
|
||||
```
|
||||
cmake --build . --parallel x
|
||||
@@ -115,7 +103,7 @@ sudo cmake --build . --target install
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
## Using the installed libraries for C++.
|
||||
|
||||
@@ -143,40 +131,9 @@ 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 commandsv2_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 commandsv2, 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.
|
||||
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 commandsv2, 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 (using `target_link_libraries`).
|
||||
|
||||
## Troubleshooting
|
||||
Below are some common issues that are run into when building.
|
||||
@@ -204,31 +161,3 @@ CMake Error at cscore/CMakeLists.txt:3 (find_package):
|
||||
```
|
||||
|
||||
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`.
|
||||
|
||||
@@ -1,23 +1,22 @@
|
||||
# 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.
|
||||
# robotpy in allwpilib
|
||||
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.
|
||||
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 native wrapper 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`
|
||||
## 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
|
||||
[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.
|
||||
# Syncing with RobotPy
|
||||
[Copybara](https://github.com/google/copybara) is used to maintain 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 adjustments 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 in this direction.
|
||||
|
||||
## Creating a user config
|
||||
The copybara scripts needs to know information about what repositories it will be pushing the sync'd changes. These can be specified on the command line, or you can create a `shared/bazel/copybara/.copybara.json` config file to save your personalized settings to avoid having to type things out every time. To run the full suite of migrations, you need a fork of [allwpilib](https://github.com/wpilibsuite/allwpilib), a fork of [mostrobotpy](https://github.com/robotpy/mostrobotpy), and a fork of robotpy's [commands-v2](https://github.com/robotpy/robotpy-commands-v2). If you only wish to run a subset of commands (i.e. not sync the commands project), you do not need to include that in your user config.
|
||||
The Copybara scripts needs to know information about what repositories it will be pushing the synced changes to. These can be specified on the command line, or you can create a `shared/bazel/copybara/.copybara.json` config file to save your personalized settings to avoid having to type things out every time. To run the full suite of migrations, you need a fork of [allwpilib](https://github.com/wpilibsuite/allwpilib), a fork of [mostrobotpy](https://github.com/robotpy/mostrobotpy), and a fork of RobotPy's [commands-v2](https://github.com/robotpy/robotpy-commands-v2). If you only wish to run a subset of commands (i.e. not sync the commands project), you do not need to include that in your user config.
|
||||
|
||||
Example config:
|
||||
```
|
||||
```json
|
||||
{
|
||||
"mostrobotpy_local_repo_path": "/home/<username>/git/robotpy/robotpy_monorepo/mostrobotpy",
|
||||
|
||||
"mostrobotpy_fork_repo": "https://github.com/<username>/mostrobotpy.git",
|
||||
"allwpilib_fork_repo": "https://github.com/<username>/allwpilib.git",
|
||||
"robotpy_commandsv2_fork_repo": "https://github.com/<username>/robotpy-commands-v2.git"
|
||||
@@ -40,24 +39,24 @@ Example config:
|
||||
|
||||
- **Pushing changes to mostrobotpy**:
|
||||
|
||||
This process is slightly more complicated, because you will almost certainly also need to update the maven artifacts that mostrobopy is using. Because of this, you must also specify the version number that has been published to wpilibs maven repository. If you are trying to get an early, non-released development build pushed over, you can also add the `--development_build` flag
|
||||
This process is slightly more complicated, because you will almost certainly also need to update the Maven artifacts that mostrobopy is using. Because of this, you must also specify the version number that has been published to WPILib's Maven repository. If you are trying to get an early, non-released development build pushed over, you can also add the `--development_build` flag:
|
||||
|
||||
`python3 shared/bazel/copybara/run_copybara.py allwpilib_to_mostrobotpy --wpilib_bin_version=2027.0.0-alpha-3-86-g418b381 --development_build -y`
|
||||
|
||||
|
||||
# Debugging Build Errors
|
||||
The build process is highly automated and automatically parses C++ header files to generate pybind11 bindings. Some of these steps here are considered "pregeneration" steps, and the bazel build system will update build files as necessary. If a new header is added, or if the contents of a header file has changed, some of the pregeneration scripts might need to be run. If you encounter an error building `robotpy` code, it is recommended that you go through these steps to make sure everything is set up correctly. The examples are for `wpilibc`, but similar build tasks and tests exist for each wrapped project
|
||||
The build process is highly automated and automatically parses C++ header files to generate pybind11 bindings. Some of these steps here are considered "pregeneration" steps, and the Bazel build system will update build files as necessary. If a new header is added, or if the contents of a header file has changed, some of the pregeneration scripts might need to be run. If you encounter an error building `robotpy` code, it is recommended that you go through these steps to make sure everything is set up correctly. The examples are for `wpilibc`, but similar build tasks and tests exist for each wrapped project.
|
||||
|
||||
## 1. scan-headers
|
||||
This can be the first source of problems if a new header file has been added. `semiwrap` will look through all of the headers for a library and notify you if a file is not covered by the projects `pyproject.toml` file. Bazel has a test case to ensure the files are up to date.
|
||||
|
||||
An example test failure when a new header being introduced. You can run the test with the following command
|
||||
An example test failure when a new header being introduced. You can run the test with the following command:
|
||||
|
||||
bazel run //wpilibc:robotpy-wpilib-scan-headers
|
||||
|
||||
```
|
||||
# wpi
|
||||
ExpansionHub = "wpi/ExpansionHub.hpp"
|
||||
ExpansionHubCRServo = "wpi/ExpansionHubCRServo.hpp"
|
||||
ExpansionHubMotor = "wpi/ExpansionHubMotor.hpp"
|
||||
ExpansionHubPidConstants = "wpi/ExpansionHubPidConstants.hpp"
|
||||
ExpansionHubServo = "wpi/ExpansionHubServo.hpp"
|
||||
@@ -67,22 +66,22 @@ ExpansionHubServo = "wpi/ExpansionHubServo.hpp"
|
||||
To fix this, you can copy the lines from the console, and add them to the pyproject.toml file, located here `wpilibc/src/main/python/pyproject.toml`
|
||||
|
||||
## 2. update-yaml
|
||||
This process parses all of the header files, and creates a representation of the classes / enums / etc in yaml. Occasionally some functions might be ignored or need custom pybind code, which can be added to these files by the user.
|
||||
This process parses all of the header files, and creates a representation of the classes / enums / etc in YAML. Occasionally, some functions might be ignored or need custom pybind code, which can be added to these files by the user.
|
||||
|
||||
There is a bazel task that you can run to automatically update the files:
|
||||
There is a Bazel task that you can run to automatically update the files:
|
||||
|
||||
`bazel run //wpilibc:write_robotpy-wpilib-update-yaml`
|
||||
|
||||
|
||||
## 3. generate-build-info
|
||||
This step takes the yaml files, and auto generates a bazel build script for the library.
|
||||
This step takes the yaml files, and auto-generates a Bazel build script for the library.
|
||||
|
||||
There is a bazel task that you can run to automatically update the files:
|
||||
There is a Bazel task that you can run to automatically update the files:
|
||||
|
||||
`bazel run //wpilibc:robotpy-wpilib-generator.generate_build_info`
|
||||
|
||||
## semiwrap errors
|
||||
If all of these steps above go smoothly and have their tests pass, but the generated cpp files still won't compile, it is possible that either an update needs to be made to the semiwrap tool to handle the new complex functionality, the new functionality can be ignored, or the new functionality might be better handled with a custom pybind11 implementation. In any case, it is best to reach out to the robotpy team for guidance.
|
||||
If all of the above steps go smoothly and have their tests pass, but the generated cpp files still won't compile, it is possible that either an update needs to be made to the semiwrap tool to handle the new complex functionality, the new functionality can be ignored, or the new functionality might be better handled with a custom pybind11 implementation. In any case, it is best to reach out to the RobotPy team for guidance.
|
||||
|
||||
## Running multiple projects at once
|
||||
Each project has its own `scan-headers` and various pregeneration tools, but you can run all of them at once with the following commands. Note: Sometimes if something in the dependency chain for a library fails, these amalgamation commands will also fail. If that happens, fix your way up the dependency chain project by project.
|
||||
|
||||
34
README.md
34
README.md
@@ -3,8 +3,9 @@
|
||||
[](https://github.com/wpilibsuite/allwpilib/actions/workflows/gradle.yml)
|
||||
[](https://github.wpilib.org/allwpilib/docs/development/cpp/)
|
||||
[](https://github.wpilib.org/allwpilib/docs/development/java/)
|
||||
[](https://robotpy.readthedocs.io/projects/robotpy/en/latest/)
|
||||
|
||||
Welcome to the WPILib project. This repository contains the HAL, WPILibJ, and WPILibC projects. These are the core libraries for creating robot programs for the roboRIO.
|
||||
Welcome to the WPILib project. This repository contains the HAL, CameraServer, Commands (v2 and v3), NTCore, WPIMath, and WPILib projects. These are the core libraries for creating robot programs for Systemcore.
|
||||
|
||||
- [WPILib Project](#wpilib-project)
|
||||
- [WPILib Mission](#wpilib-mission)
|
||||
@@ -25,7 +26,7 @@ Welcome to the WPILib project. This repository contains the HAL, WPILibJ, and WP
|
||||
|
||||
## WPILib Mission
|
||||
|
||||
The WPILib Mission is to enable FIRST Robotics teams to focus on writing game-specific software rather than focusing on hardware details - "raise the floor, don't lower the ceiling". We work to enable teams with limited programming knowledge and/or mentor experience to be as successful as possible, while not hampering the abilities of teams with more advanced programming capabilities. We support Kit of Parts control system components directly in the library. We also strive to keep parity between major features of each language (Java, C++, Python, and NI's LabVIEW), so that teams aren't at a disadvantage for choosing a specific programming language. WPILib is an open source project, licensed under the BSD 3-clause license. You can find a copy of the license [here](LICENSE.md).
|
||||
The WPILib Mission is to enable FIRST Robotics Competition (FRC) and FIRST Tech Challenge (FTC) teams to focus on writing game-specific software rather than focusing on hardware details - "raise the floor, don't lower the ceiling". We work to enable teams with limited programming knowledge and/or mentor experience to be as successful as possible, while not hampering the abilities of teams with more advanced programming capabilities. We support the FRC Kit of Parts/FTC control system components directly in the library. We also strive to keep parity between major features of each language (Java, C++, and Python), so that teams aren't at a disadvantage for choosing a specific programming language. WPILib is an open source project, licensed under the BSD 3-clause license. You can find a copy of the license [here](LICENSE.md).
|
||||
|
||||
# Quick Start
|
||||
|
||||
@@ -38,29 +39,26 @@ Below is a list of instructions that guide you through cloning, building, publis
|
||||
|
||||
# Building WPILib
|
||||
|
||||
Using Gradle makes building WPILib very straightforward. It only has a few dependencies on outside tools, such as the ARM cross compiler for creating roboRIO binaries.
|
||||
Using Gradle makes building WPILib very straightforward. It only has a few dependencies on outside tools, such as the ARM cross compiler for creating Systemcore binaries.
|
||||
|
||||
## Requirements
|
||||
|
||||
- [JDK 21](https://adoptium.net/temurin/releases/?version=21)
|
||||
- [JDK 25](https://adoptium.net/temurin/releases/?version=25)
|
||||
- Note that the JRE is insufficient; the full JDK is required
|
||||
- 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
|
||||
- On Ubuntu, run `sudo apt install openjdk-25-jdk`
|
||||
- On Windows, install the JDK 25 .msi from the link above
|
||||
- On macOS, install the JDK 25 .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 14 or later is required.
|
||||
- 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
|
||||
- Run `./gradlew installArm64Toolchain` 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 macOS ARM, run `softwareupdate --install-rosetta`. This is necessary to be able to use the macOS x86 Systemcore toolchain on ARM.
|
||||
|
||||
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.
|
||||
|
||||
@@ -129,10 +127,10 @@ Please read the documentation available [here](DevelopmentBuilds.md)
|
||||
|
||||
### Custom toolchain location
|
||||
|
||||
If you have installed the FRC Toolchain to a directory other than the default, or if the Toolchain location is not on your System PATH, you can pass the `toolChainPath` property to specify where it is located. Example:
|
||||
If you have installed the WPILib Toolchain to a directory other than the default, or if the Toolchain location is not on your System PATH, you can pass the `toolChainPath` property to specify where it is located. Example:
|
||||
|
||||
```bash
|
||||
./gradlew build -PtoolChainPath=some/path/to/frc/toolchain/bin
|
||||
./gradlew build -PtoolChainPath=some/path/to/wpilib/toolchain/bin
|
||||
```
|
||||
|
||||
### Formatting/linting
|
||||
@@ -183,15 +181,15 @@ If you are building to test with other dependencies or just want to export the b
|
||||
- stable - Publishes to ~/releases/maven/stable.
|
||||
- release - Publishes to ~/releases/maven/release.
|
||||
|
||||
The maven artifacts are described in [MavenArtifacts.md](MavenArtifacts.md)
|
||||
The Maven artifacts are described in [MavenArtifacts.md](MavenArtifacts.md)
|
||||
|
||||
## Structure and Organization
|
||||
|
||||
The main WPILib code you're probably looking for is in WPILibJ and WPILibC. Those directories are split into shared, sim, and athena. Athena contains the WPILib code meant to run on your roboRIO. Sim is WPILib code meant to run on your computer, and shared is code shared between the two. Shared code must be platform-independent, since it will be compiled with both the ARM cross-compiler and whatever desktop compiler you are using (g++, msvc, etc...).
|
||||
The main WPILib code you're probably looking for is in WPILibJ and WPILibC. Those directories contain the high-level hardware/robot classes used for interacting with hardware, the Driver Station, and contain the core framework that almost all robot projects use.
|
||||
|
||||
The integration test directories for C++ and Java contain test code that runs on our test-system. When you submit code for review, it is tested by those programs. If you add new functionality you should make sure to write tests for it so we don't break it in the future.
|
||||
The src/test directories under each subproject for C++ and Java contain test code that runs on GitHub Actions. When you submit code for review, it is tested by GitHub Actions' runners. If you add new functionality you should make sure to write tests for it so we don't break it in the future.
|
||||
|
||||
The hal directory contains more C++ code meant to run on the roboRIO. HAL is an acronym for "Hardware Abstraction Layer", and it interfaces with the NI Libraries. The NI Libraries contain the low-level code for controlling devices on your robot. The NI Libraries are found in the [ni-libraries](https://github.com/wpilibsuite/ni-libraries) project.
|
||||
The hal directory contains more C++ code meant to run on Systemcore. HAL is an acronym for "Hardware Abstraction Layer", and it interfaces with the robot controller to enable hardware interactions. The HAL is split into cpp, sim, and systemcore. The systemcore directory contains the WPILib code meant to run on your Systemcore. Sim is WPILib code meant to run on your computer, and cpp is code shared between the two. Code in the cpp directory must be platform-independent, since it will be compiled with both the ARM cross-compiler and whatever desktop compiler you are using (g++, MSVC, etc...).
|
||||
|
||||
The upstream_utils directory contains scripts for updating copies of thirdparty code in the repository.
|
||||
|
||||
|
||||
@@ -19,18 +19,12 @@ 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
|
||||
wpiutil/src/test/native/cpp/json/
|
||||
JSON for Classic C++ wpiutil/src/main/native/thirdparty/json
|
||||
libuv wpinet/src/main/native/thirdparty/libuv/
|
||||
fmtlib wpiutil/src/main/native/thirdparty/fmtlib/
|
||||
sigslot wpiutil/src/main/native/thirdparty/sigslot
|
||||
tcpsockets wpinet/src/main/native/thirdparty/tcpsockets
|
||||
MPack wpiutil/src/main/native/thirdparty/mpack
|
||||
Bootstrap wpinet/src/main/native/resources/bootstrap-*
|
||||
CoreUI wpinet/src/main/native/resources/coreui-*
|
||||
Feather Icons wpinet/src/main/native/resources/feather-*
|
||||
jQuery wpinet/src/main/native/resources/jquery-*
|
||||
popper.js wpinet/src/main/native/resources/popper-*
|
||||
units wpimath/src/main/native/include/wpi/units/
|
||||
Eigen wpimath/src/main/native/thirdparty/eigen/include/
|
||||
Team 254 Library wpimath/src/main/java/org/wpilib/math/spline/SplineParameterizer.java
|
||||
@@ -43,6 +37,7 @@ V8 export-template wpiutil/src/main/native/include/wpi/SymbolExports.hpp
|
||||
GCEM wpimath/src/main/native/thirdparty/gcem/include/
|
||||
Sleipnir wpimath/src/main/native/thirdparty/sleipnir
|
||||
Debugging wpiutil/src/main/native/thirdparty/debugging
|
||||
double-conversion wpiutil/src/main/native/thirdparty/double-conversion
|
||||
argparse wpiutil/src/main/native/thirdparty/argparse/include/wpi/util/argparse.hpp
|
||||
apriltag apriltag/src/main/native/thirdparty/apriltag
|
||||
glfw thirdparty/imgui_suite/glfw
|
||||
@@ -53,6 +48,8 @@ upb wpiutil/src/main/native/thirdparty/upb
|
||||
mrcal tools/wpical/src/main/native/thirdparty/mrcal
|
||||
libdogleg tools/wpical/src/main/native/thirdparty/libdogleg
|
||||
Simd hal/src/main/native/systemcore/simd
|
||||
AdvantageScope fields/src/main/native/resources/org/wpilib/fields/ftc
|
||||
Avahi wpinet/src/main/native/linux/AvahiClient.hpp
|
||||
|
||||
Additionally, glfw and nanopb were modified for use in WPILib.
|
||||
|
||||
@@ -369,35 +366,22 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
|
||||
SOFTWARE.
|
||||
|
||||
|
||||
==============================================================================
|
||||
JSON for Modern C++ License
|
||||
==============================================================================
|
||||
============================
|
||||
JSON for Classic C++ License
|
||||
============================
|
||||
Copyright 2024 Mozilla Foundation
|
||||
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++
|
||||
| | |__ | | | | | | version 2.1.1
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
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
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
Copyright (c) 2013-2017 Niels Lohmann <http://nlohmann.me>.
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
|
||||
==============================================================================
|
||||
@@ -498,128 +482,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
|
||||
==============================================================================
|
||||
Bootstrap License
|
||||
==============================================================================
|
||||
Copyright (c) 2011-2018 Twitter, Inc.
|
||||
Copyright (c) 2011-2018 The Bootstrap Authors
|
||||
|
||||
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.
|
||||
|
||||
|
||||
==============================================================================
|
||||
CoreUI License
|
||||
==============================================================================
|
||||
Copyright (c) 2018 creativeLabs tukasz Holeczek.
|
||||
|
||||
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.
|
||||
|
||||
|
||||
==============================================================================
|
||||
Feather Icons License
|
||||
==============================================================================
|
||||
Copyright (c) 2013-2017 Cole Bemis
|
||||
|
||||
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.
|
||||
|
||||
|
||||
==============================================================================
|
||||
jQuery License
|
||||
==============================================================================
|
||||
Copyright JS Foundation and other contributors, https://js.foundation/
|
||||
|
||||
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.
|
||||
|
||||
|
||||
==============================================================================
|
||||
popper.js License
|
||||
==============================================================================
|
||||
Copyright (c) 2016 Federico Zivolo and contributors
|
||||
|
||||
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.
|
||||
|
||||
|
||||
=============
|
||||
units License
|
||||
=============
|
||||
@@ -1184,6 +1046,36 @@ 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.
|
||||
|
||||
=========================
|
||||
double-conversion License
|
||||
=========================
|
||||
Copyright 2006-2011, the V8 project authors. 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.
|
||||
|
||||
================
|
||||
argparse License
|
||||
================
|
||||
@@ -1673,3 +1565,540 @@ 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.
|
||||
|
||||
============
|
||||
AdvantageScope License
|
||||
============
|
||||
|
||||
Copyright (c) 2021-2026 Littleton Robotics. 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 Littleton Robotics, FRC 6328 ("Mechanical Advantage"),
|
||||
AdvantageScope, nor the names of other AdvantageScope contributors may be
|
||||
used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY LITTLETON ROBOTICS AND OTHER ADVANTAGESCOPE
|
||||
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
|
||||
NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY NONINFRINGEMENT
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
LITTLETON ROBOTICS 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.
|
||||
|
||||
=============
|
||||
Avahi License
|
||||
=============
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
<https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library 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 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Moe Ghoul>, 1 April 1990
|
||||
Moe Ghoul, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
|
||||
|
||||
load("//thirdparty/ceres:repositories.bzl", "ceres_repositories")
|
||||
|
||||
ceres_repositories()
|
||||
|
||||
http_archive(
|
||||
name = "pybind11_bazel",
|
||||
integrity = "sha256-iwRj1wuX2pDS6t6DqiCfhIXisv4y+7CvxSJtZoSAzGw=",
|
||||
@@ -21,24 +17,14 @@ http_archive(
|
||||
|
||||
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",
|
||||
sha256 = "947df6f399593a54779b7706da8abaa43865769e02b15533519c800e23be419f",
|
||||
url = "https://github.com/wpilibsuite/bzlmodRio-opencv/releases/download/2027.4.13.0-3/bzlmodRio-opencv-2027.4.13.0-3.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()
|
||||
|
||||
# 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")
|
||||
|
||||
|
||||
@@ -140,6 +140,9 @@ wpilib_jni_java_library(
|
||||
maven_artifact_name = "apriltag-java",
|
||||
maven_group_id = "org.wpilib.apriltag",
|
||||
native_libs = [":apriltagjni"],
|
||||
plugins = [
|
||||
"//:avaje_jsonb_generator",
|
||||
],
|
||||
resource_strip_prefix = "apriltag/src/main/native/resources",
|
||||
resources = glob(["src/main/native/resources/**"]),
|
||||
visibility = ["//visibility:public"],
|
||||
@@ -147,9 +150,8 @@ wpilib_jni_java_library(
|
||||
"//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",
|
||||
"@maven//:io_avaje_avaje_json_core",
|
||||
"@maven//:io_avaje_avaje_jsonb",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -162,13 +164,13 @@ pkg_files(
|
||||
cc_test(
|
||||
name = "apriltag-cpp-test",
|
||||
size = "small",
|
||||
srcs = glob(["src/test/native/cpp/**"]),
|
||||
srcs = glob(["src/test/native/cpp/**/*.cpp"]),
|
||||
tags = [
|
||||
"no-asan",
|
||||
],
|
||||
deps = [
|
||||
":apriltag",
|
||||
"//thirdparty/googletest",
|
||||
"//thirdparty/catch2",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -182,7 +184,7 @@ wpilib_java_junit5_test(
|
||||
"//wpimath:wpimath-java",
|
||||
"//wpiutil:wpiutil-java",
|
||||
"@bzlmodrio-opencv//libraries/java/opencv",
|
||||
"@maven//:com_fasterxml_jackson_core_jackson_databind",
|
||||
"@maven//:io_avaje_avaje_jsonb",
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
@@ -31,81 +31,6 @@ else()
|
||||
)
|
||||
endif()
|
||||
|
||||
file(GLOB apriltag_jni_src src/main/native/cpp/jni/AprilTagJNI.cpp)
|
||||
|
||||
if(WITH_JAVA)
|
||||
include(UseJava)
|
||||
|
||||
set(CMAKE_JNI_TARGET true)
|
||||
|
||||
file(GLOB EJML_JARS "${WPILIB_BINARY_DIR}/wpimath/thirdparty/ejml/*.jar")
|
||||
file(GLOB JACKSON_JARS "${WPILIB_BINARY_DIR}/wpiutil/thirdparty/jackson/*.jar")
|
||||
find_file(
|
||||
OPENCV_JAR_FILE
|
||||
NAMES opencv-${OpenCV_VERSION_MAJOR}${OpenCV_VERSION_MINOR}${OpenCV_VERSION_PATCH}.jar
|
||||
PATHS
|
||||
${OPENCV_JAVA_INSTALL_DIR}
|
||||
${OpenCV_INSTALL_PATH}/bin
|
||||
${OpenCV_INSTALL_PATH}/share/java
|
||||
${OpenCV_INSTALL_PATH}/share/java/opencv4
|
||||
${OpenCV_INSTALL_PATH}/share/OpenCV/java
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
|
||||
file(GLOB_RECURSE JAVA_SOURCES src/main/java/*.java)
|
||||
file(
|
||||
GLOB_RECURSE JAVA_RESOURCES
|
||||
RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
src/main/native/resources/*.json
|
||||
)
|
||||
add_jar(
|
||||
apriltag_jar
|
||||
SOURCES ${JAVA_SOURCES}
|
||||
RESOURCES
|
||||
NAMESPACE "org/wpilib/vision/apriltag" ${JAVA_RESOURCES}
|
||||
INCLUDE_JARS
|
||||
wpimath_jar
|
||||
wpiunits_jar
|
||||
wpiutil_jar
|
||||
${EJML_JARS}
|
||||
${OPENCV_JAR_FILE}
|
||||
${JACKSON_JARS}
|
||||
OUTPUT_NAME apriltag
|
||||
OUTPUT_DIR ${WPILIB_BINARY_DIR}/${java_lib_dest}
|
||||
GENERATE_NATIVE_HEADERS apriltag_jni_headers
|
||||
)
|
||||
set_property(TARGET apriltag_jar PROPERTY FOLDER "java")
|
||||
|
||||
install_jar(apriltag_jar DESTINATION ${java_lib_dest})
|
||||
install_jar_exports(TARGETS apriltag_jar FILE apriltag_jar.cmake DESTINATION share/apriltag)
|
||||
|
||||
add_library(apriltagjni ${apriltag_jni_src} ${apriltaglib_src})
|
||||
wpilib_target_warnings(apriltagjni)
|
||||
target_link_libraries(apriltagjni PUBLIC apriltag)
|
||||
|
||||
set_property(TARGET apriltagjni PROPERTY FOLDER "libraries")
|
||||
|
||||
target_link_libraries(apriltagjni PRIVATE apriltag_jni_headers)
|
||||
add_dependencies(apriltagjni apriltag_jar)
|
||||
|
||||
install(TARGETS apriltagjni EXPORT apriltagjni)
|
||||
export(TARGETS apriltagjni FILE apriltagjni.cmake NAMESPACE apriltagjni::)
|
||||
endif()
|
||||
|
||||
if(WITH_JAVA_SOURCE)
|
||||
include(UseJava)
|
||||
include(CreateSourceJar)
|
||||
add_source_jar(
|
||||
apriltag_src_jar
|
||||
BASE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR}/src/main/java
|
||||
OUTPUT_NAME apriltag-sources
|
||||
OUTPUT_DIR ${WPILIB_BINARY_DIR}/${java_lib_dest}
|
||||
)
|
||||
set_property(TARGET apriltag_src_jar PROPERTY FOLDER "java")
|
||||
|
||||
install_jar(apriltag_src_jar DESTINATION ${java_lib_dest})
|
||||
endif()
|
||||
|
||||
generate_resources(
|
||||
src/main/native/resources/org/wpilib/vision/apriltag
|
||||
generated/main/cpp
|
||||
@@ -120,7 +45,7 @@ add_library(apriltag ${apriltag_native_src} ${apriltag_resources_src} ${apriltag
|
||||
set_target_properties(apriltag PROPERTIES DEBUG_POSTFIX "d")
|
||||
|
||||
set_property(TARGET apriltag PROPERTY FOLDER "libraries")
|
||||
target_compile_features(apriltag PUBLIC cxx_std_20)
|
||||
target_compile_features(apriltag PUBLIC cxx_std_23)
|
||||
wpilib_target_warnings(apriltag)
|
||||
|
||||
target_link_libraries(apriltag wpimath)
|
||||
@@ -152,7 +77,7 @@ install(FILES ${WPILIB_BINARY_DIR}/apriltag-config.cmake DESTINATION share/april
|
||||
install(EXPORT apriltag DESTINATION share/apriltag)
|
||||
|
||||
if(WITH_TESTS)
|
||||
wpilib_add_test(apriltag src/test/native/cpp)
|
||||
wpilib_add_test_catch2(apriltag src/test/native/cpp)
|
||||
target_include_directories(apriltag_test PRIVATE src/test/native/include)
|
||||
target_link_libraries(apriltag_test apriltag googletest)
|
||||
target_link_libraries(apriltag_test apriltag)
|
||||
endif()
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
# AprilTag
|
||||
|
||||
A C++ wrapper around the [University of Michigan's AprilTag detector](https://github.com/AprilRobotics/apriltag), alongside a vendored copy of their code with some patches (patches are located in [upstream_utils](../upstream_utils/apriltag_patches/)).
|
||||
|
||||
## Adding new field to AprilTagFields
|
||||
|
||||
### Adding field JSON
|
||||
|
||||
1. Add a field layout CSV file to `src/main/native/resources/edu/wpi/first/apriltag`
|
||||
1. Add a field layout CSV file to `src/main/native/resources/org/wpilib/vision/apriltag`
|
||||
1. See docstring in `convert_apriltag_layouts.py` for more
|
||||
2. Run `convert_apriltag_layouts.py` in the same directory as this readme to generate the JSON
|
||||
3. That script overwrites all generated JSONs, so undo undesired changes if necessary
|
||||
@@ -14,15 +16,15 @@
|
||||
|
||||
### Java updates
|
||||
|
||||
1. Update `src/main/java/edu/wpi/first/apriltag/AprilTagFields.java`
|
||||
1. Update `src/main/java/org/wpilib/vision/apriltag/AprilTagFields.java`
|
||||
1. Add enum value for new field to `AprilTagFields`
|
||||
2. Update `AprilTagFields.kDefaultField` if necessary
|
||||
|
||||
### C++ updates
|
||||
|
||||
1. Update `src/main/native/include/frc/apriltag/AprilTagFields.h`
|
||||
1. Update `src/main/native/include/wpi/apriltag/AprilTagFields.hpp`
|
||||
1. Add enum value for new field to `AprilTagFields`
|
||||
2. Update `AprilTagFields::kDefaultField` if necessary
|
||||
2. Update `src/main/native/cpp/AprilTagFields.cpp`
|
||||
2. Update `src/main/native/cpp/AprilTagFieldLayout.cpp`
|
||||
1. Add resource getter prototype like `std::string_view GetResource_2024_crescendo_json()`
|
||||
2. Add case for new field to switch in `LoadAprilTagLayoutField()`
|
||||
2. Add case for new field to switch in `LoadField(AprilTagField field)`
|
||||
|
||||
@@ -5,6 +5,3 @@ include(CMakeFindDependencyMacro)
|
||||
|
||||
@FILENAME_DEP_REPLACE@
|
||||
include(${SELF_DIR}/apriltag.cmake)
|
||||
if(@WITH_JAVA@)
|
||||
include(${SELF_DIR}/apriltag_jar.cmake)
|
||||
endif()
|
||||
|
||||
@@ -5,11 +5,12 @@ apply plugin: 'c'
|
||||
ext {
|
||||
nativeName = 'apriltag'
|
||||
devMain = 'org.wpilib.vision.apriltag.DevMain'
|
||||
nativeTestSuiteName = "${nativeName}Catch2Test"
|
||||
useJava = true
|
||||
useCpp = true
|
||||
sharedCvConfigs = [
|
||||
apriltagDev : [],
|
||||
apriltagTest: []]
|
||||
(nativeTestSuiteName): []]
|
||||
staticCvConfigs = []
|
||||
|
||||
def generateTask = createGenerateResourcesTask('main', 'APRILTAG', 'wpi::apriltag', project)
|
||||
@@ -46,6 +47,7 @@ apply from: "${rootDir}/shared/opencv.gradle"
|
||||
|
||||
dependencies {
|
||||
implementation project(':wpimath')
|
||||
annotationProcessor libs.avaje.jsonb.generator
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
|
||||
39
apriltag/robotpy_native_build_info.bzl
generated
39
apriltag/robotpy_native_build_info.bzl
generated
@@ -1,9 +1,11 @@
|
||||
# THIS FILE IS AUTO GENERATED
|
||||
|
||||
load("@aspect_bazel_lib//lib:copy_to_directory.bzl", "copy_to_directory")
|
||||
load("//shared/bazel/rules/robotpy:pybind_rules.bzl", "native_wrappery_library")
|
||||
load("//shared/bazel/rules/robotpy:robotpy_rules.bzl", "copy_native_file", "generate_native_files", "robotpy_library")
|
||||
|
||||
def define_native_wrapper(name, pyproject_toml = None):
|
||||
pyproject_toml = pyproject_toml or "src/main/python/native-pyproject.toml"
|
||||
|
||||
copy_to_directory(
|
||||
name = "{}.copy_headers".format(name),
|
||||
srcs = native.glob(["src/main/native/include/**"]) + native.glob(["src/generated/main/native/include/**"], allow_empty = True) + native.glob([
|
||||
@@ -20,25 +22,42 @@ def define_native_wrapper(name, pyproject_toml = None):
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
native_wrappery_library(
|
||||
libinit_files = ["native/apriltag/_init_robotpy_native_apriltag.py"]
|
||||
|
||||
generate_native_files(
|
||||
name = name,
|
||||
pyproject_toml = pyproject_toml or "src/main/python/native-pyproject.toml",
|
||||
libinit_file = "native/apriltag/_init_robotpy_native_apriltag.py",
|
||||
pc_file = "native/apriltag/robotpy-native-apriltag.pc",
|
||||
pyproject_toml = pyproject_toml,
|
||||
pc_deps = [
|
||||
"//wpimath:native/wpimath/robotpy-native-wpimath.pc",
|
||||
"//wpiutil:native/wpiutil/robotpy-native-wpiutil.pc",
|
||||
],
|
||||
libinit_files = libinit_files,
|
||||
pc_files = ["native/apriltag/robotpy-native-apriltag.pc"],
|
||||
)
|
||||
|
||||
copy_native_file(
|
||||
name = "apriltag",
|
||||
library = "shared/apriltag",
|
||||
base_path = "native/apriltag/",
|
||||
)
|
||||
|
||||
robotpy_library(
|
||||
name = name,
|
||||
distribution = "robotpy-native-apriltag",
|
||||
srcs = libinit_files,
|
||||
data = [
|
||||
name + ".pc_wrapper",
|
||||
":apriltag.copy_lib",
|
||||
"{}.copy_headers".format(name),
|
||||
],
|
||||
deps = [
|
||||
"//wpimath:robotpy-native-wpimath",
|
||||
"//wpiutil:robotpy-native-wpiutil",
|
||||
],
|
||||
headers = "{}.copy_headers".format(name),
|
||||
native_shared_library = "shared/apriltag",
|
||||
install_path = "native/apriltag/",
|
||||
strip_path_prefixes = ["apriltag"],
|
||||
requires = ["robotpy-native-wpiutil==0.0.0", "robotpy-native-wpimath==0.0.0"],
|
||||
summary = "WPILib AprilTag Library",
|
||||
requires = ["robotpy-native-wpiutil==0.0.0", "robotpy-native-wpimath==0.0.0"],
|
||||
python_requires = ">=3.11",
|
||||
strip_path_prefixes = ["apriltag"],
|
||||
entry_points = {
|
||||
"pkg_config": [
|
||||
"apriltag = native.apriltag",
|
||||
|
||||
4
apriltag/robotpy_pybind_build_info.bzl
generated
4
apriltag/robotpy_pybind_build_info.bzl
generated
@@ -1,7 +1,7 @@
|
||||
# THIS FILE IS AUTO GENERATED
|
||||
|
||||
load("//shared/bazel/rules/gen:gen-version-file.bzl", "generate_version_file")
|
||||
load("//shared/bazel/rules/robotpy:pybind_rules.bzl", "create_pybind_library", "robotpy_library")
|
||||
load("//shared/bazel/rules/robotpy:robotpy_rules.bzl", "create_pybind_library", "robotpy_library")
|
||||
load("//shared/bazel/rules/robotpy:semiwrap_helpers.bzl", "gen_libinit", "gen_modinit_hpp", "gen_pkgconf", "resolve_casters", "run_header_gen")
|
||||
load("//shared/bazel/rules/robotpy:semiwrap_tool_helpers.bzl", "scan_headers", "update_yaml_files")
|
||||
|
||||
@@ -198,6 +198,7 @@ def define_pybind_library(name, pkgcfgs = []):
|
||||
|
||||
robotpy_library(
|
||||
name = name,
|
||||
distribution = "robotpy-apriltag",
|
||||
srcs = native.glob(["src/main/python/robotpy_apriltag/**/*.py"]) + [
|
||||
"src/main/python/robotpy_apriltag/_init__apriltag.py",
|
||||
"{}.generate_version".format(name),
|
||||
@@ -219,6 +220,7 @@ def define_pybind_library(name, pkgcfgs = []):
|
||||
project_urls = {"Source code": "https://github.com/robotpy/mostrobotpy"},
|
||||
author_email = "RobotPy Development Team <robotpy@googlegroups.com>",
|
||||
requires = ["robotpy-native-apriltag==0.0.0", "robotpy-wpiutil==0.0.0", "robotpy-wpimath==0.0.0"],
|
||||
python_requires = ">=3.11",
|
||||
entry_points = {
|
||||
"pkg_config": ["apriltag = robotpy_apriltag"],
|
||||
},
|
||||
|
||||
@@ -4,22 +4,22 @@
|
||||
|
||||
package org.wpilib.vision.apriltag;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import io.avaje.jsonb.Json;
|
||||
import java.util.Objects;
|
||||
import org.wpilib.math.geometry.Pose3d;
|
||||
import org.wpilib.util.RawFrame;
|
||||
import org.wpilib.vision.apriltag.jni.AprilTagJNI;
|
||||
|
||||
/** Represents an AprilTag's metadata. */
|
||||
@SuppressWarnings("MemberName")
|
||||
@Json
|
||||
public class AprilTag {
|
||||
/** The tag's ID. */
|
||||
@JsonProperty(value = "ID")
|
||||
@Json.Property("ID")
|
||||
@SuppressWarnings("PMD.PublicFieldNamingConvention")
|
||||
public int ID;
|
||||
|
||||
/** The tag's pose. */
|
||||
@JsonProperty(value = "pose")
|
||||
@Json.Property("pose")
|
||||
public Pose3d pose;
|
||||
|
||||
/**
|
||||
@@ -29,10 +29,8 @@ public class AprilTag {
|
||||
* @param pose The tag's pose.
|
||||
*/
|
||||
@SuppressWarnings("ParameterName")
|
||||
@JsonCreator
|
||||
public AprilTag(
|
||||
@JsonProperty(required = true, value = "ID") int ID,
|
||||
@JsonProperty(required = true, value = "pose") Pose3d pose) {
|
||||
@Json.Creator
|
||||
public AprilTag(int ID, Pose3d pose) {
|
||||
this.ID = ID;
|
||||
this.pose = pose;
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@ import org.wpilib.vision.apriltag.jni.AprilTagJNI;
|
||||
*/
|
||||
public class AprilTagDetector implements AutoCloseable {
|
||||
/** Detector configuration. */
|
||||
@SuppressWarnings("MemberName")
|
||||
public static class Config {
|
||||
/**
|
||||
* How many threads should be used for computation. Default is single-threaded operation (1
|
||||
@@ -110,7 +109,6 @@ public class AprilTagDetector implements AutoCloseable {
|
||||
}
|
||||
|
||||
/** Quad threshold parameters. */
|
||||
@SuppressWarnings("MemberName")
|
||||
public static class QuadThresholdParameters {
|
||||
/** Threshold used to reject quads containing too few pixels. Default is 300 pixels. */
|
||||
public int minClusterPixels = 300;
|
||||
|
||||
@@ -4,17 +4,12 @@
|
||||
|
||||
package org.wpilib.vision.apriltag;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import io.avaje.jsonb.Json;
|
||||
import io.avaje.jsonb.Jsonb;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
@@ -43,8 +38,7 @@ import org.wpilib.math.geometry.Translation3d;
|
||||
* <p>Tag poses represent the center of the tag, with a zero rotation representing a tag that is
|
||||
* upright and facing away from the (blue) alliance wall (that is, towards the opposing alliance).
|
||||
*/
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
@JsonAutoDetect(getterVisibility = JsonAutoDetect.Visibility.NONE)
|
||||
@Json
|
||||
public class AprilTagFieldLayout {
|
||||
/** Common origin positions for the AprilTag coordinate system. */
|
||||
public enum OriginPosition {
|
||||
@@ -54,12 +48,12 @@ public class AprilTagFieldLayout {
|
||||
kRedAllianceWallRightSide,
|
||||
}
|
||||
|
||||
private final Map<Integer, AprilTag> m_apriltags = new HashMap<>();
|
||||
@Json.Ignore private final Map<Integer, AprilTag> m_apriltags = new HashMap<>();
|
||||
|
||||
@JsonProperty(value = "field")
|
||||
private FieldDimensions m_fieldDimensions;
|
||||
@Json.Property("field")
|
||||
FieldDimensions m_fieldDimensions;
|
||||
|
||||
private Pose3d m_origin;
|
||||
@Json.Ignore private Pose3d m_origin;
|
||||
|
||||
/**
|
||||
* Construct a new AprilTagFieldLayout with values imported from a JSON file.
|
||||
@@ -79,7 +73,7 @@ public class AprilTagFieldLayout {
|
||||
*/
|
||||
public AprilTagFieldLayout(Path path) throws IOException {
|
||||
AprilTagFieldLayout layout =
|
||||
new ObjectMapper().readValue(path.toFile(), AprilTagFieldLayout.class);
|
||||
Jsonb.instance().type(AprilTagFieldLayout.class).fromJson(Files.newBufferedReader(path));
|
||||
m_apriltags.putAll(layout.m_apriltags);
|
||||
m_fieldDimensions = layout.m_fieldDimensions;
|
||||
setOrigin(OriginPosition.kBlueAllianceWallRightSide);
|
||||
@@ -96,10 +90,10 @@ public class AprilTagFieldLayout {
|
||||
this(apriltags, new FieldDimensions(fieldLength, fieldWidth));
|
||||
}
|
||||
|
||||
@JsonCreator
|
||||
private AprilTagFieldLayout(
|
||||
@JsonProperty(required = true, value = "tags") List<AprilTag> apriltags,
|
||||
@JsonProperty(required = true, value = "field") FieldDimensions fieldDimensions) {
|
||||
@Json.Creator
|
||||
AprilTagFieldLayout(
|
||||
@Json.Alias("tags") List<AprilTag> apriltags,
|
||||
@Json.Alias("field") FieldDimensions fieldDimensions) {
|
||||
// To ensure the underlying semantics don't change with what kind of list is passed in
|
||||
for (AprilTag tag : apriltags) {
|
||||
m_apriltags.put(tag.ID, tag);
|
||||
@@ -113,7 +107,7 @@ public class AprilTagFieldLayout {
|
||||
*
|
||||
* @return The {@link AprilTag AprilTags} used in this layout.
|
||||
*/
|
||||
@JsonProperty("tags")
|
||||
@Json.Property("tags")
|
||||
public List<AprilTag> getTags() {
|
||||
return new ArrayList<>(m_apriltags.values());
|
||||
}
|
||||
@@ -123,7 +117,6 @@ public class AprilTagFieldLayout {
|
||||
*
|
||||
* @return length, in meters
|
||||
*/
|
||||
@JsonIgnore
|
||||
public double getFieldLength() {
|
||||
return m_fieldDimensions.fieldLength;
|
||||
}
|
||||
@@ -133,7 +126,6 @@ public class AprilTagFieldLayout {
|
||||
*
|
||||
* @return width, in meters
|
||||
*/
|
||||
@JsonIgnore
|
||||
public double getFieldWidth() {
|
||||
return m_fieldDimensions.fieldWidth;
|
||||
}
|
||||
@@ -147,7 +139,6 @@ public class AprilTagFieldLayout {
|
||||
*
|
||||
* @param origin The predefined origin
|
||||
*/
|
||||
@JsonIgnore
|
||||
public final void setOrigin(OriginPosition origin) {
|
||||
var pose =
|
||||
switch (origin) {
|
||||
@@ -168,7 +159,6 @@ public class AprilTagFieldLayout {
|
||||
*
|
||||
* @param origin The new origin for tag transformations
|
||||
*/
|
||||
@JsonIgnore
|
||||
public final void setOrigin(Pose3d origin) {
|
||||
m_origin = origin;
|
||||
}
|
||||
@@ -178,7 +168,6 @@ public class AprilTagFieldLayout {
|
||||
*
|
||||
* @return the origin
|
||||
*/
|
||||
@JsonIgnore
|
||||
public Pose3d getOrigin() {
|
||||
return m_origin;
|
||||
}
|
||||
@@ -216,7 +205,7 @@ public class AprilTagFieldLayout {
|
||||
* @throws IOException If writing to the file fails.
|
||||
*/
|
||||
public void serialize(Path path) throws IOException {
|
||||
new ObjectMapper().writeValue(path.toFile(), this);
|
||||
Jsonb.instance().type(AprilTagFieldLayout.class).toJson(this, Files.newBufferedWriter(path));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -227,42 +216,38 @@ public class AprilTagFieldLayout {
|
||||
* @throws UncheckedIOException If the layout does not exist.
|
||||
*/
|
||||
public static AprilTagFieldLayout loadField(AprilTagFields field) {
|
||||
if (field.m_fieldLayout == null) {
|
||||
if (field.fieldLayout == null) {
|
||||
try {
|
||||
field.m_fieldLayout = loadFromResource(field.m_resourceFile);
|
||||
field.fieldLayout = loadFromResource(field.resourceFile);
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(
|
||||
"Could not load AprilTagFieldLayout from " + field.m_resourceFile, e);
|
||||
"Could not load AprilTagFieldLayout from " + field.resourceFile, e);
|
||||
}
|
||||
}
|
||||
// Copy layout because the layout's origin is mutable
|
||||
return new AprilTagFieldLayout(
|
||||
field.m_fieldLayout.getTags(),
|
||||
field.m_fieldLayout.getFieldLength(),
|
||||
field.m_fieldLayout.getFieldWidth());
|
||||
field.fieldLayout.getTags(),
|
||||
field.fieldLayout.getFieldLength(),
|
||||
field.fieldLayout.getFieldWidth());
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserializes a field layout from a resource within a internal jar file.
|
||||
*
|
||||
* <p>Users should use {@link AprilTagFields#loadAprilTagLayoutField()} to load official layouts
|
||||
* and {@link #AprilTagFieldLayout(String)} for custom layouts.
|
||||
* <p>Users should use {@link #loadField(AprilTagFields)} to load official layouts and {@link
|
||||
* #AprilTagFieldLayout(String)} for custom layouts.
|
||||
*
|
||||
* @param resourcePath The absolute path of the resource
|
||||
* @return The deserialized layout
|
||||
* @throws IOException If the resource could not be loaded
|
||||
*/
|
||||
public static AprilTagFieldLayout loadFromResource(String resourcePath) throws IOException {
|
||||
InputStream stream = AprilTagFieldLayout.class.getResourceAsStream(resourcePath);
|
||||
if (stream == null) {
|
||||
// Class.getResourceAsStream() returns null if the resource does not exist.
|
||||
throw new IOException("Could not locate resource: " + resourcePath);
|
||||
}
|
||||
InputStreamReader reader = new InputStreamReader(stream, StandardCharsets.UTF_8);
|
||||
try {
|
||||
return new ObjectMapper().readerFor(AprilTagFieldLayout.class).readValue(reader);
|
||||
} catch (IOException e) {
|
||||
throw new IOException("Failed to load AprilTagFieldLayout: " + resourcePath);
|
||||
try (InputStream stream = AprilTagFieldLayout.class.getResourceAsStream(resourcePath)) {
|
||||
if (stream == null) {
|
||||
// Class.getResourceAsStream() returns null if the resource does not exist.
|
||||
throw new IOException("Could not locate resource: " + resourcePath);
|
||||
}
|
||||
return Jsonb.instance().type(AprilTagFieldLayout.class).fromJson(stream);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -278,21 +263,17 @@ public class AprilTagFieldLayout {
|
||||
return Objects.hash(m_apriltags, m_origin);
|
||||
}
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
@JsonAutoDetect(getterVisibility = JsonAutoDetect.Visibility.NONE)
|
||||
private static class FieldDimensions {
|
||||
@SuppressWarnings("MemberName")
|
||||
@JsonProperty(value = "length")
|
||||
static class FieldDimensions {
|
||||
@Json.Property(value = "length")
|
||||
public final double fieldLength;
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
@JsonProperty(value = "width")
|
||||
@Json.Property(value = "width")
|
||||
public final double fieldWidth;
|
||||
|
||||
@JsonCreator()
|
||||
@Json.Creator()
|
||||
FieldDimensions(
|
||||
@JsonProperty(required = true, value = "length") double fieldLength,
|
||||
@JsonProperty(required = true, value = "width") double fieldWidth) {
|
||||
@Json.Alias(value = "length") double fieldLength,
|
||||
@Json.Alias(value = "width") double fieldWidth) {
|
||||
this.fieldLength = fieldLength;
|
||||
this.fieldWidth = fieldWidth;
|
||||
}
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
|
||||
package org.wpilib.vision.apriltag;
|
||||
|
||||
import java.io.UncheckedIOException;
|
||||
|
||||
/** Loadable AprilTag field layouts. */
|
||||
public enum AprilTagFields {
|
||||
/** 2022 Rapid React. */
|
||||
@@ -30,23 +28,11 @@ public enum AprilTagFields {
|
||||
public static final AprilTagFields kDefaultField = k2026RebuiltWelded;
|
||||
|
||||
/** Resource filename. */
|
||||
public final String m_resourceFile;
|
||||
public final String resourceFile;
|
||||
|
||||
AprilTagFieldLayout m_fieldLayout;
|
||||
AprilTagFieldLayout fieldLayout;
|
||||
|
||||
AprilTagFields(String resourceFile) {
|
||||
m_resourceFile = kBaseResourceDir + resourceFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a {@link AprilTagFieldLayout} from the resource JSON.
|
||||
*
|
||||
* @return AprilTagFieldLayout of the field
|
||||
* @throws UncheckedIOException If the layout does not exist
|
||||
* @deprecated Use {@link AprilTagFieldLayout#loadField(AprilTagFields)} instead.
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "2025")
|
||||
public AprilTagFieldLayout loadAprilTagLayoutField() {
|
||||
return AprilTagFieldLayout.loadField(this);
|
||||
this.resourceFile = kBaseResourceDir + resourceFile;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ package org.wpilib.vision.apriltag;
|
||||
import org.wpilib.math.geometry.Transform3d;
|
||||
|
||||
/** A pair of AprilTag pose estimates. */
|
||||
@SuppressWarnings("MemberName")
|
||||
public class AprilTagPoseEstimate {
|
||||
/**
|
||||
* Constructs a pose estimate.
|
||||
|
||||
@@ -10,7 +10,6 @@ import org.wpilib.vision.apriltag.jni.AprilTagJNI;
|
||||
/** Pose estimators for AprilTag tags. */
|
||||
public class AprilTagPoseEstimator {
|
||||
/** Configuration for the pose estimator. */
|
||||
@SuppressWarnings("MemberName")
|
||||
public static class Config {
|
||||
/**
|
||||
* Creates a pose estimator configuration.
|
||||
|
||||
@@ -52,10 +52,10 @@ bool AprilTag::Generate16h5AprilTagImage(wpi::util::RawFrame* frame, int id) {
|
||||
}
|
||||
|
||||
void wpi::apriltag::to_json(wpi::util::json& json, const AprilTag& apriltag) {
|
||||
json = wpi::util::json{{"ID", apriltag.ID}, {"pose", apriltag.pose}};
|
||||
json = wpi::util::json::object("ID", apriltag.ID, "pose", apriltag.pose);
|
||||
}
|
||||
|
||||
void wpi::apriltag::from_json(const wpi::util::json& json, AprilTag& apriltag) {
|
||||
apriltag.ID = json.at("ID").get<int>();
|
||||
apriltag.ID = json.at("ID").get_int();
|
||||
apriltag.pose = json.at("pose").get<wpi::math::Pose3d>();
|
||||
}
|
||||
|
||||
@@ -22,16 +22,16 @@ AprilTagFieldLayout::AprilTagFieldLayout(std::string_view path) {
|
||||
throw std::runtime_error(fmt::format("Cannot open file: {}", path));
|
||||
}
|
||||
|
||||
wpi::util::json json =
|
||||
wpi::util::json::parse(fileBuffer.value()->GetCharBuffer());
|
||||
auto buf = fileBuffer.value()->GetCharBuffer();
|
||||
auto json = wpi::util::json::parse_or_throw({buf.data(), buf.size()});
|
||||
|
||||
for (const auto& tag : json.at("tags").get<std::vector<AprilTag>>()) {
|
||||
for (auto&& jtag : json.at("tags").get_array()) {
|
||||
auto tag = jtag.get<AprilTag>();
|
||||
m_apriltags[tag.ID] = tag;
|
||||
}
|
||||
m_fieldWidth =
|
||||
wpi::units::meter_t{json.at("field").at("width").get<double>()};
|
||||
m_fieldWidth = wpi::units::meter_t{json.at("field").at("width").get_number()};
|
||||
m_fieldLength =
|
||||
wpi::units::meter_t{json.at("field").at("length").get<double>()};
|
||||
wpi::units::meter_t{json.at("field").at("length").get_number()};
|
||||
}
|
||||
|
||||
AprilTagFieldLayout::AprilTagFieldLayout(std::vector<AprilTag> apriltags,
|
||||
@@ -113,23 +113,24 @@ void wpi::apriltag::to_json(wpi::util::json& json,
|
||||
tagVector.push_back(pair.second);
|
||||
}
|
||||
|
||||
json = wpi::util::json{{"field",
|
||||
{{"length", layout.m_fieldLength.value()},
|
||||
{"width", layout.m_fieldWidth.value()}}},
|
||||
{"tags", tagVector}};
|
||||
auto field = wpi::util::json::object("length", layout.m_fieldLength.value(),
|
||||
"width", layout.m_fieldWidth.value());
|
||||
json = wpi::util::json::object("field", std::move(field), "tags",
|
||||
std::move(tagVector));
|
||||
}
|
||||
|
||||
void wpi::apriltag::from_json(const wpi::util::json& json,
|
||||
AprilTagFieldLayout& layout) {
|
||||
layout.m_apriltags.clear();
|
||||
for (const auto& tag : json.at("tags").get<std::vector<AprilTag>>()) {
|
||||
for (auto&& jtag : json.at("tags").get_array()) {
|
||||
auto tag = jtag.get<AprilTag>();
|
||||
layout.m_apriltags[tag.ID] = tag;
|
||||
}
|
||||
|
||||
layout.m_fieldLength =
|
||||
wpi::units::meter_t{json.at("field").at("length").get<double>()};
|
||||
wpi::units::meter_t{json.at("field").at("length").get_number()};
|
||||
layout.m_fieldWidth =
|
||||
wpi::units::meter_t{json.at("field").at("width").get<double>()};
|
||||
wpi::units::meter_t{json.at("field").at("width").get_number()};
|
||||
}
|
||||
|
||||
// Use namespace declaration for forward declaration
|
||||
@@ -174,11 +175,6 @@ AprilTagFieldLayout AprilTagFieldLayout::LoadField(AprilTagField field) {
|
||||
throw std::invalid_argument("Invalid Field");
|
||||
}
|
||||
|
||||
wpi::util::json json = wpi::util::json::parse(fieldString);
|
||||
wpi::util::json json = wpi::util::json::parse_or_throw(fieldString);
|
||||
return json.get<AprilTagFieldLayout>();
|
||||
}
|
||||
|
||||
AprilTagFieldLayout wpi::apriltag::LoadAprilTagLayoutField(
|
||||
AprilTagField field) {
|
||||
return AprilTagFieldLayout::LoadField(field);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,10 @@
|
||||
#include "wpi/math/geometry/Pose3d.hpp"
|
||||
#include "wpi/util/RawFrame.hpp"
|
||||
#include "wpi/util/SymbolExports.hpp"
|
||||
#include "wpi/util/json_fwd.hpp"
|
||||
|
||||
namespace wpi::util {
|
||||
class json;
|
||||
} // namespace wpi::util
|
||||
|
||||
namespace wpi::apriltag {
|
||||
|
||||
|
||||
@@ -14,7 +14,10 @@
|
||||
#include "wpi/math/geometry/Pose3d.hpp"
|
||||
#include "wpi/units/length.hpp"
|
||||
#include "wpi/util/SymbolExports.hpp"
|
||||
#include "wpi/util/json_fwd.hpp"
|
||||
|
||||
namespace wpi::util {
|
||||
class json;
|
||||
} // namespace wpi::util
|
||||
|
||||
namespace wpi::apriltag {
|
||||
/**
|
||||
@@ -161,15 +164,4 @@ void to_json(wpi::util::json& json, const AprilTagFieldLayout& layout);
|
||||
WPILIB_DLLEXPORT
|
||||
void from_json(const wpi::util::json& json, AprilTagFieldLayout& layout);
|
||||
|
||||
/**
|
||||
* Loads an AprilTagFieldLayout from a predefined field
|
||||
*
|
||||
* @param field The predefined field
|
||||
* @return AprilTagFieldLayout of the field
|
||||
* @deprecated Use AprilTagFieldLayout::LoadField() instead
|
||||
*/
|
||||
[[deprecated("Use AprilTagFieldLayout::LoadField() instead")]]
|
||||
WPILIB_DLLEXPORT AprilTagFieldLayout
|
||||
LoadAprilTagLayoutField(AprilTagField field);
|
||||
|
||||
} // namespace wpi::apriltag
|
||||
|
||||
@@ -4,10 +4,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string_view>
|
||||
|
||||
#include "wpi/util/SymbolExports.hpp"
|
||||
|
||||
namespace wpi::apriltag {
|
||||
|
||||
/**
|
||||
|
||||
@@ -12,6 +12,7 @@ requires = [
|
||||
name = "robotpy-native-apriltag"
|
||||
version = "0.0.0"
|
||||
description = "WPILib AprilTag Library"
|
||||
requires-python = ">=3.11"
|
||||
license = "BSD-3-Clause"
|
||||
|
||||
dependencies = [
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
build-backend = "hatchling.build"
|
||||
requires = [
|
||||
"semiwrap~=0.3.0",
|
||||
"hatch-meson~=0.1.0",
|
||||
"hatch-meson~=0.1.2",
|
||||
"hatch-robotpy~=0.2.1",
|
||||
"hatchling",
|
||||
"robotpy-native-apriltag==0.0.0",
|
||||
@@ -14,6 +14,7 @@ requires = [
|
||||
name = "robotpy-apriltag"
|
||||
version = "0.0.0"
|
||||
description = "RobotPy bindings for WPILib's AprilTag library"
|
||||
requires-python = ">=3.11"
|
||||
authors = [
|
||||
{name = "RobotPy Development Team", email = "robotpy@googlegroups.com"},
|
||||
]
|
||||
@@ -63,7 +64,7 @@ wraps = ["robotpy-native-apriltag"]
|
||||
depends = ["wpiutil", "wpimath"]
|
||||
|
||||
[tool.semiwrap.extension_modules."robotpy_apriltag._apriltag".headers]
|
||||
# frc/apriltag
|
||||
# wpi/apriltag
|
||||
AprilTag = "wpi/apriltag/AprilTag.hpp"
|
||||
AprilTagDetection = "wpi/apriltag/AprilTagDetection.hpp"
|
||||
AprilTagDetector = "wpi/apriltag/AprilTagDetector.hpp"
|
||||
|
||||
@@ -3,8 +3,6 @@ functions:
|
||||
ignore: true
|
||||
from_json:
|
||||
ignore: true
|
||||
LoadAprilTagLayoutField:
|
||||
ignore: true
|
||||
classes:
|
||||
wpi::apriltag::AprilTagFieldLayout:
|
||||
enums:
|
||||
|
||||
@@ -25,7 +25,6 @@ import org.wpilib.math.util.Units;
|
||||
import org.wpilib.util.runtime.RuntimeLoader;
|
||||
|
||||
class AprilTagDetectorTest {
|
||||
@SuppressWarnings("MemberName")
|
||||
AprilTagDetector detector;
|
||||
|
||||
@BeforeAll
|
||||
@@ -110,7 +109,6 @@ class AprilTagDetectorTest {
|
||||
detector.removeFamily("tag16h5");
|
||||
}
|
||||
|
||||
@SuppressWarnings("PMD.AssignmentInOperand")
|
||||
public Mat loadImage(String resource) throws IOException {
|
||||
Mat encoded;
|
||||
try (InputStream is = getClass().getResource(resource).openStream()) {
|
||||
|
||||
@@ -13,7 +13,7 @@ class AprilTagGenerationTest {
|
||||
@Test
|
||||
void test36h11() {
|
||||
var frame = AprilTag.generate36h11AprilTagImage(1);
|
||||
assertEquals(PixelFormat.kGray, frame.getPixelFormat());
|
||||
assertEquals(PixelFormat.GRAY, frame.getPixelFormat());
|
||||
assertEquals(10, frame.getWidth());
|
||||
assertEquals(10, frame.getHeight());
|
||||
int stride = frame.getStride();
|
||||
|
||||
@@ -7,7 +7,7 @@ package org.wpilib.vision.apriltag;
|
||||
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import io.avaje.jsonb.Jsonb;
|
||||
import java.util.List;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.wpilib.math.geometry.Pose3d;
|
||||
@@ -25,13 +25,9 @@ class AprilTagSerializationTest {
|
||||
Units.feetToMeters(54.0),
|
||||
Units.feetToMeters(27.0));
|
||||
|
||||
var objectMapper = new ObjectMapper();
|
||||
var layoutType = Jsonb.instance().type(AprilTagFieldLayout.class);
|
||||
|
||||
var deserialized =
|
||||
assertDoesNotThrow(
|
||||
() ->
|
||||
objectMapper.readValue(
|
||||
objectMapper.writeValueAsString(layout), AprilTagFieldLayout.class));
|
||||
var deserialized = assertDoesNotThrow(() -> layoutType.fromJson(layoutType.toJson(layout)));
|
||||
|
||||
assertEquals(layout, deserialized);
|
||||
}
|
||||
|
||||
@@ -4,55 +4,55 @@
|
||||
|
||||
#include "wpi/apriltag/AprilTagDetector.hpp"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
using namespace wpi::apriltag;
|
||||
|
||||
TEST(AprilTagDetectorTest, ConfigDefaults) {
|
||||
TEST_CASE("AprilTagDetectorTest ConfigDefaults", "[apriltag][detector]") {
|
||||
AprilTagDetector detector;
|
||||
auto config = detector.GetConfig();
|
||||
ASSERT_EQ(config, AprilTagDetector::Config{});
|
||||
REQUIRE(config == AprilTagDetector::Config{});
|
||||
}
|
||||
|
||||
TEST(AprilTagDetectorTest, QtpDefaults) {
|
||||
TEST_CASE("AprilTagDetectorTest QtpDefaults", "[apriltag][detector]") {
|
||||
AprilTagDetector detector;
|
||||
auto params = detector.GetQuadThresholdParameters();
|
||||
ASSERT_EQ(params, AprilTagDetector::QuadThresholdParameters{});
|
||||
REQUIRE(params == AprilTagDetector::QuadThresholdParameters{});
|
||||
}
|
||||
|
||||
TEST(AprilTagDetectorTest, SetConfigNumThreads) {
|
||||
TEST_CASE("AprilTagDetectorTest SetConfigNumThreads", "[apriltag][detector]") {
|
||||
AprilTagDetector detector;
|
||||
detector.SetConfig({.numThreads = 2});
|
||||
auto config = detector.GetConfig();
|
||||
ASSERT_EQ(config.numThreads, 2);
|
||||
REQUIRE(config.numThreads == 2);
|
||||
}
|
||||
|
||||
TEST(AprilTagDetectorTest, QtpMinClusterPixels) {
|
||||
TEST_CASE("AprilTagDetectorTest QtpMinClusterPixels", "[apriltag][detector]") {
|
||||
AprilTagDetector detector;
|
||||
detector.SetQuadThresholdParameters({.minClusterPixels = 8});
|
||||
auto params = detector.GetQuadThresholdParameters();
|
||||
ASSERT_EQ(params.minClusterPixels, 8);
|
||||
REQUIRE(params.minClusterPixels == 8);
|
||||
}
|
||||
|
||||
TEST(AprilTagDetectorTest, Add16h5) {
|
||||
TEST_CASE("AprilTagDetectorTest Add16h5", "[apriltag][detector]") {
|
||||
AprilTagDetector detector;
|
||||
ASSERT_TRUE(detector.AddFamily("tag16h5"));
|
||||
REQUIRE(detector.AddFamily("tag16h5"));
|
||||
// duplicate addition is also okay
|
||||
ASSERT_TRUE(detector.AddFamily("tag16h5"));
|
||||
REQUIRE(detector.AddFamily("tag16h5"));
|
||||
}
|
||||
|
||||
TEST(AprilTagDetectorTest, Add36h11) {
|
||||
TEST_CASE("AprilTagDetectorTest Add36h11", "[apriltag][detector]") {
|
||||
AprilTagDetector detector;
|
||||
ASSERT_TRUE(detector.AddFamily("tag36h11"));
|
||||
REQUIRE(detector.AddFamily("tag36h11"));
|
||||
}
|
||||
|
||||
TEST(AprilTagDetectorTest, AddMultiple) {
|
||||
TEST_CASE("AprilTagDetectorTest AddMultiple", "[apriltag][detector]") {
|
||||
AprilTagDetector detector;
|
||||
ASSERT_TRUE(detector.AddFamily("tag16h5"));
|
||||
ASSERT_TRUE(detector.AddFamily("tag36h11"));
|
||||
REQUIRE(detector.AddFamily("tag16h5"));
|
||||
REQUIRE(detector.AddFamily("tag36h11"));
|
||||
}
|
||||
|
||||
TEST(AprilTagDetectorTest, RemoveFamily) {
|
||||
TEST_CASE("AprilTagDetectorTest RemoveFamily", "[apriltag][detector]") {
|
||||
AprilTagDetector detector;
|
||||
// okay to remove non-existent family
|
||||
detector.RemoveFamily("tag16h5");
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#include "wpi/apriltag/AprilTag.hpp"
|
||||
#include "wpi/apriltag/AprilTagFieldLayout.hpp"
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
using namespace wpi::apriltag;
|
||||
|
||||
TEST(AprilTagJsonTest, DeserializeMatches) {
|
||||
TEST_CASE("AprilTagJsonTest DeserializeMatches", "[apriltag][json]") {
|
||||
auto layout = AprilTagFieldLayout{
|
||||
std::vector{AprilTag{1, wpi::math::Pose3d{}},
|
||||
AprilTag{3, wpi::math::Pose3d{0_m, 1_m, 0_m,
|
||||
@@ -23,6 +23,6 @@ TEST(AprilTagJsonTest, DeserializeMatches) {
|
||||
|
||||
AprilTagFieldLayout deserialized;
|
||||
wpi::util::json json = layout;
|
||||
EXPECT_NO_THROW(deserialized = json.get<AprilTagFieldLayout>());
|
||||
EXPECT_EQ(layout, deserialized);
|
||||
CHECK_NOTHROW(deserialized = json.get<AprilTagFieldLayout>());
|
||||
CHECK(layout == deserialized);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#include "wpi/apriltag/AprilTag.hpp"
|
||||
#include "wpi/apriltag/AprilTagFieldLayout.hpp"
|
||||
@@ -13,7 +13,8 @@
|
||||
|
||||
using namespace wpi::apriltag;
|
||||
|
||||
TEST(AprilTagPoseSetOriginTest, TransformationMatches) {
|
||||
TEST_CASE("AprilTagPoseSetOriginTest TransformationMatches",
|
||||
"[apriltag][field-layout][pose]") {
|
||||
auto layout = AprilTagFieldLayout{
|
||||
std::vector<AprilTag>{
|
||||
AprilTag{
|
||||
@@ -29,8 +30,8 @@ TEST(AprilTagPoseSetOriginTest, TransformationMatches) {
|
||||
|
||||
auto mirrorPose = wpi::math::Pose3d{
|
||||
54_ft, 27_ft, 0_ft, wpi::math::Rotation3d{0_deg, 0_deg, 180_deg}};
|
||||
EXPECT_EQ(mirrorPose, *layout.GetTagPose(1));
|
||||
CHECK(mirrorPose == *layout.GetTagPose(1));
|
||||
mirrorPose = wpi::math::Pose3d{50_ft, 23_ft, 4_ft,
|
||||
wpi::math::Rotation3d{0_deg, 0_deg, 0_deg}};
|
||||
EXPECT_EQ(mirrorPose, *layout.GetTagPose(2));
|
||||
CHECK(mirrorPose == *layout.GetTagPose(2));
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#include "wpi/apriltag/AprilTagFieldLayout.hpp"
|
||||
#include "wpi/apriltag/AprilTagFields.hpp"
|
||||
@@ -21,7 +21,8 @@ std::vector<AprilTagField> GetAllFields() {
|
||||
return output;
|
||||
}
|
||||
|
||||
TEST(AprilTagFieldsTest, TestLoad2022RapidReact) {
|
||||
TEST_CASE("AprilTagFieldsTest TestLoad2022RapidReact",
|
||||
"[apriltag][field-layout]") {
|
||||
AprilTagFieldLayout layout =
|
||||
AprilTagFieldLayout::LoadField(AprilTagField::k2022RapidReact);
|
||||
|
||||
@@ -30,39 +31,36 @@ TEST(AprilTagFieldsTest, TestLoad2022RapidReact) {
|
||||
wpi::math::Pose3d{127.272_in, 216.01_in, 67.932_in,
|
||||
wpi::math::Rotation3d{0_deg, 0_deg, 0_deg}};
|
||||
auto maybePose = layout.GetTagPose(1);
|
||||
EXPECT_TRUE(maybePose);
|
||||
EXPECT_EQ(expectedPose, *maybePose);
|
||||
REQUIRE(maybePose);
|
||||
CHECK(expectedPose == *maybePose);
|
||||
|
||||
// Blue Terminal Near Station
|
||||
expectedPose =
|
||||
wpi::math::Pose3d{4.768_in, 67.631_in, 35.063_in,
|
||||
wpi::math::Rotation3d{0_deg, 0_deg, 46.25_deg}};
|
||||
maybePose = layout.GetTagPose(5);
|
||||
EXPECT_TRUE(maybePose);
|
||||
EXPECT_EQ(expectedPose, *maybePose);
|
||||
REQUIRE(maybePose);
|
||||
CHECK(expectedPose == *maybePose);
|
||||
|
||||
// Upper Hub Blue-Near
|
||||
expectedPose =
|
||||
wpi::math::Pose3d{332.321_in, 183.676_in, 95.186_in,
|
||||
wpi::math::Rotation3d{0_deg, 26.75_deg, 69_deg}};
|
||||
maybePose = layout.GetTagPose(53);
|
||||
EXPECT_TRUE(maybePose);
|
||||
EXPECT_EQ(expectedPose, *maybePose);
|
||||
REQUIRE(maybePose);
|
||||
CHECK(expectedPose == *maybePose);
|
||||
|
||||
// Doesn't exist
|
||||
maybePose = layout.GetTagPose(54);
|
||||
EXPECT_FALSE(maybePose);
|
||||
CHECK_FALSE(maybePose);
|
||||
}
|
||||
|
||||
// Test all of the fields in the enum
|
||||
class AllFieldsFixtureTest : public ::testing::TestWithParam<AprilTagField> {};
|
||||
|
||||
TEST_P(AllFieldsFixtureTest, CheckEntireEnum) {
|
||||
AprilTagField field = GetParam();
|
||||
EXPECT_NO_THROW(AprilTagFieldLayout::LoadField(field));
|
||||
TEST_CASE("AprilTagFieldsTest CheckEntireEnum", "[apriltag][field-layout]") {
|
||||
for (auto field : GetAllFields()) {
|
||||
CAPTURE(field);
|
||||
CHECK_NOTHROW(AprilTagFieldLayout::LoadField(field));
|
||||
}
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(ValuesEnumTestInstTests, AllFieldsFixtureTest,
|
||||
::testing::ValuesIn(GetAllFields()));
|
||||
|
||||
} // namespace wpi::apriltag
|
||||
|
||||
@@ -2,10 +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 <gtest/gtest.h>
|
||||
#include <catch2/catch_session.hpp>
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
int ret = RUN_ALL_TESTS();
|
||||
return ret;
|
||||
return Catch::Session().run(argc, argv);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ file(GLOB benchmarkCpp_src src/main/native/cpp/*.cpp src/main/native/thirdparty/
|
||||
|
||||
add_executable(benchmarkCpp ${benchmarkCpp_src})
|
||||
|
||||
target_compile_features(benchmarkCpp PUBLIC cxx_std_20)
|
||||
target_compile_features(benchmarkCpp PUBLIC cxx_std_23)
|
||||
|
||||
wpilib_target_warnings(benchmarkCpp)
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ This command runs the C++ benchmarks on desktop.
|
||||
./gradlew benchmark:runCpp
|
||||
```
|
||||
|
||||
## Deploy to a roboRIO
|
||||
## Deploy to a Systemcore
|
||||
|
||||
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.
|
||||
|
||||
@@ -30,19 +30,20 @@ This command deploys the C++ project with all dependencies statically linked.
|
||||
./gradlew benchmark:deployStatic
|
||||
```
|
||||
|
||||
This command deploys the Java project and all required dependencies. It also installs the JRE if it's not currently installed.
|
||||
This command deploys the Java project and all required dependencies.
|
||||
```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
|
||||
ssh systemcore@robot.local sudo systemctl stop robot
|
||||
ssh systemcore@robot.local sudo ~/robotCommand
|
||||
```
|
||||
|
||||
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.
|
||||
Deploying any of these to a Systemcore will disable the current startup project until it is redeployed.
|
||||
|
||||
## Faster builds
|
||||
|
||||
|
||||
@@ -37,6 +37,11 @@ application {
|
||||
|
||||
apply plugin: 'com.gradleup.shadow'
|
||||
|
||||
shadowJar {
|
||||
mergeServiceFiles()
|
||||
duplicatesStrategy = DuplicatesStrategy.INCLUDE
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
url = 'https://frcmaven.wpi.edu/artifactory/ex-mvn'
|
||||
@@ -93,35 +98,35 @@ deploy {
|
||||
all {
|
||||
postdeploy << { ctx ->
|
||||
ctx.execute("sync")
|
||||
ctx.execute("sudo ldconfig /home/systemcore/frc/third-party/lib")
|
||||
ctx.execute("sudo ldconfig /home/systemcore/wpilib/third-party/lib")
|
||||
}
|
||||
}
|
||||
|
||||
benchmarkCpp(NativeExecutableArtifact) {
|
||||
libraryDirectory = '/usr/local/frc/third-party/lib'
|
||||
libraryDirectory = '/home/systemcore/wpilib/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("echo '/home/systemcore/benchmarkCpp' > /home/systemcore/robotCommand")
|
||||
ctx.execute("chmod +x /home/systemcore/robotCommand; chown systemcore /home/systemcore/robotCommand")
|
||||
ctx.execute("setcap cap_sys_nice+eip \"/home/systemcore/benchmarkCpp\"")
|
||||
ctx.execute('chmod +x benchmarkCpp')
|
||||
}
|
||||
}
|
||||
|
||||
benchmarkCppStatic(NativeExecutableArtifact) {
|
||||
libraryDirectory = '/usr/local/frc/third-party/lib'
|
||||
libraryDirectory = '/home/systemcore/wpilib/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("echo '/home/systemcore/benchmarkCppStatic' > /home/systemcore/robotCommand")
|
||||
ctx.execute("chmod +x /home/systemcore/robotCommand; chown systemcore /home/systemcore/robotCommand")
|
||||
ctx.execute("setcap cap_sys_nice+eip \"/home/systemcore/benchmarkCppStatic\"")
|
||||
ctx.execute('chmod +x benchmarkCppStatic')
|
||||
}
|
||||
}
|
||||
|
||||
benchmarkCppJava(NativeExecutableArtifact) {
|
||||
libraryDirectory = '/usr/local/frc/third-party/lib'
|
||||
libraryDirectory = '/home/systemcore/wpilib/third-party/lib'
|
||||
def excludes = getLibraryFilter().getExcludes()
|
||||
excludes.add('**/*.so.debug')
|
||||
excludes.add('**/*.so.*.debug')
|
||||
@@ -130,8 +135,8 @@ deploy {
|
||||
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")
|
||||
ctx.execute("echo 'java -XX:+UseSerialGC -Djava.library.path=/home/systemcore/wpilib/third-party/lib -Djava.lang.invoke.stringConcat=BC_SB -jar /home/systemcore/benchmark-all.jar' > /home/systemcore/robotCommand")
|
||||
ctx.execute("chmod +x /home/systemcore/robotCommand; chown systemcore /home/systemcore/robotCommand")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
128
benchmark/src/main/java/wpilib/robot/CartPoleBenchmark.java
Normal file
128
benchmark/src/main/java/wpilib/robot/CartPoleBenchmark.java
Normal file
@@ -0,0 +1,128 @@
|
||||
// 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 wpilib.robot;
|
||||
|
||||
import static org.wpilib.math.autodiff.NumericalIntegration.rk4;
|
||||
import static org.wpilib.math.autodiff.Variable.cos;
|
||||
import static org.wpilib.math.autodiff.Variable.sin;
|
||||
import static org.wpilib.math.autodiff.VariableMatrix.solve;
|
||||
import static org.wpilib.math.optimization.Constraints.eq;
|
||||
import static org.wpilib.math.optimization.Constraints.ge;
|
||||
import static org.wpilib.math.optimization.Constraints.le;
|
||||
|
||||
import org.ejml.simple.SimpleMatrix;
|
||||
import org.wpilib.math.autodiff.Variable;
|
||||
import org.wpilib.math.autodiff.VariableMatrix;
|
||||
import org.wpilib.math.optimization.Problem;
|
||||
import org.wpilib.math.optimization.solver.Options;
|
||||
import org.wpilib.math.util.MathUtil;
|
||||
|
||||
public final class CartPoleBenchmark {
|
||||
private CartPoleBenchmark() {
|
||||
// Utility class.
|
||||
}
|
||||
|
||||
@SuppressWarnings("LocalVariableName")
|
||||
private static VariableMatrix cartPoleDynamics(VariableMatrix x, VariableMatrix u) {
|
||||
final double m_c = 5.0; // Cart mass (kg)
|
||||
final double m_p = 0.5; // Pole mass (kg)
|
||||
final double l = 0.5; // Pole length (m)
|
||||
final double g = 9.806; // Acceleration due to gravity (m/s²)
|
||||
|
||||
var q = x.segment(0, 2);
|
||||
var qdot = x.segment(2, 2);
|
||||
var theta = q.get(1);
|
||||
var thetadot = qdot.get(1);
|
||||
|
||||
// [ m_c + m_p m_p l cosθ]
|
||||
// M(q) = [m_p l cosθ m_p l² ]
|
||||
var M =
|
||||
new VariableMatrix(
|
||||
new Variable[][] {
|
||||
{new Variable(m_c + m_p), cos(theta).times(m_p * l)},
|
||||
{cos(theta).times(m_p * l), new Variable(m_p * Math.pow(l, 2))}
|
||||
});
|
||||
|
||||
// [0 −m_p lθ̇ sinθ]
|
||||
// C(q, q̇) = [0 0 ]
|
||||
var C =
|
||||
new VariableMatrix(
|
||||
new Variable[][] {
|
||||
{new Variable(0), thetadot.times(-m_p * l).times(sin(theta))},
|
||||
{new Variable(0), new Variable(0)}
|
||||
});
|
||||
|
||||
// [ 0 ]
|
||||
// τ_g(q) = [-m_p gl sinθ]
|
||||
var tau_g =
|
||||
new VariableMatrix(new Variable[][] {{new Variable(0)}, {sin(theta).times(-m_p * g * l)}});
|
||||
|
||||
// [1]
|
||||
// B = [0]
|
||||
var B = new VariableMatrix(new double[][] {{1}, {0}});
|
||||
|
||||
// q̈ = M⁻¹(q)(τ_g(q) − C(q, q̇)q̇ + Bu)
|
||||
var qddot = new VariableMatrix(4);
|
||||
qddot.segment(0, 2).set(qdot);
|
||||
qddot.segment(2, 2).set(solve(M, tau_g.minus(C.times(qdot)).plus(B.times(u))));
|
||||
return qddot;
|
||||
}
|
||||
|
||||
/** Cart-pole benchmark. */
|
||||
public static void cartPole() {
|
||||
final double T = 5.0; // s
|
||||
final double dt = 0.05; // s
|
||||
final int N = (int) (T / dt);
|
||||
|
||||
final double u_max = 20.0; // N
|
||||
final double d_max = 2.0; // m
|
||||
|
||||
final var x_initial = new SimpleMatrix(new double[][] {{0.0}, {0.0}, {0.0}, {0.0}});
|
||||
final var x_final = new SimpleMatrix(new double[][] {{1.0}, {Math.PI}, {0.0}, {0.0}});
|
||||
|
||||
var problem = new Problem();
|
||||
|
||||
// x = [q, q̇]ᵀ = [x, θ, ẋ, θ̇]ᵀ
|
||||
var X = problem.decisionVariable(4, N + 1);
|
||||
|
||||
// Initial guess
|
||||
for (int k = 0; k < N + 1; ++k) {
|
||||
X.get(0, k).setValue(MathUtil.lerp(x_initial.get(0), x_final.get(0), (double) k / N));
|
||||
X.get(1, k).setValue(MathUtil.lerp(x_initial.get(1), x_final.get(1), (double) k / N));
|
||||
}
|
||||
|
||||
// u = f_x
|
||||
var U = problem.decisionVariable(1, N);
|
||||
|
||||
// Initial conditions
|
||||
problem.subjectTo(eq(X.col(0), x_initial));
|
||||
|
||||
// Final conditions
|
||||
problem.subjectTo(eq(X.col(N), x_final));
|
||||
|
||||
// Cart position constraints
|
||||
problem.subjectTo(ge(X.row(0), 0.0));
|
||||
problem.subjectTo(le(X.row(0), d_max));
|
||||
|
||||
// Input constraints
|
||||
problem.subjectTo(ge(U, -u_max));
|
||||
problem.subjectTo(le(U, u_max));
|
||||
|
||||
// Dynamics constraints - RK4 integration
|
||||
for (int k = 0; k < N; ++k) {
|
||||
problem.subjectTo(
|
||||
eq(X.col(k + 1), rk4(CartPoleBenchmark::cartPoleDynamics, X.col(k), U.col(k), dt)));
|
||||
}
|
||||
|
||||
// Minimize sum squared inputs
|
||||
var J = new Variable(0.0);
|
||||
for (int k = 0; k < N; ++k) {
|
||||
J = J.plus(U.col(k).T().times(U.col(k)).get(0));
|
||||
}
|
||||
problem.minimize(J);
|
||||
|
||||
problem.solve(new Options().withDiagnostics(true));
|
||||
}
|
||||
}
|
||||
@@ -37,6 +37,13 @@ public class Main {
|
||||
new Runner(opt).run();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
@BenchmarkMode(Mode.AverageTime)
|
||||
@OutputTimeUnit(TimeUnit.MICROSECONDS)
|
||||
public void cartPole() {
|
||||
CartPoleBenchmark.cartPole();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
@BenchmarkMode(Mode.AverageTime)
|
||||
@OutputTimeUnit(TimeUnit.MICROSECONDS)
|
||||
|
||||
@@ -103,7 +103,7 @@ BENCHMARK(BM_SetInsert)->Ranges({{1<<10, 8<<10}, {128, 512}});
|
||||
// arbitrary set of arguments to run the microbenchmark on.
|
||||
// The following example enumerates a dense range on
|
||||
// one parameter, and a sparse range on the second.
|
||||
static void CustomArguments(benchmark::internal::Benchmark* b) {
|
||||
static void CustomArguments(benchmark::Benchmark* b) {
|
||||
for (int i = 0; i <= 10; ++i)
|
||||
for (int j = 32; j <= 1024*1024; j *= 8)
|
||||
b->Args({i, j});
|
||||
@@ -171,7 +171,6 @@ BENCHMARK(BM_test)->Unit(benchmark::kMillisecond);
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
#include <initializer_list>
|
||||
#include <iosfwd>
|
||||
#include <limits>
|
||||
#include <map>
|
||||
@@ -239,6 +238,16 @@ BENCHMARK(BM_test)->Unit(benchmark::kMillisecond);
|
||||
_Pragma("diagnostic push") \
|
||||
_Pragma("diag_suppress deprecated_entity_with_custom_message")
|
||||
#define BENCHMARK_RESTORE_DEPRECATED_WARNING _Pragma("diagnostic pop")
|
||||
#elif defined(_MSC_VER)
|
||||
#define BENCHMARK_BUILTIN_EXPECT(x, y) x
|
||||
#define BENCHMARK_DEPRECATED_MSG(msg) __declspec(deprecated(msg))
|
||||
#define BENCHMARK_WARNING_MSG(msg) \
|
||||
__pragma(message(__FILE__ "(" BENCHMARK_INTERNAL_TOSTRING( \
|
||||
__LINE__) ") : warning note: " msg))
|
||||
#define BENCHMARK_DISABLE_DEPRECATED_WARNING \
|
||||
__pragma(warning(push)) \
|
||||
__pragma(warning(disable : 4996))
|
||||
#define BENCHMARK_RESTORE_DEPRECATED_WARNING __pragma(warning(pop))
|
||||
#else
|
||||
#define BENCHMARK_BUILTIN_EXPECT(x, y) x
|
||||
#define BENCHMARK_DEPRECATED_MSG(msg)
|
||||
@@ -476,10 +485,11 @@ void RegisterProfilerManager(ProfilerManager* profiler_manager);
|
||||
|
||||
// Add a key-value pair to output as part of the context stanza in the report.
|
||||
BENCHMARK_EXPORT
|
||||
void AddCustomContext(const std::string& key, const std::string& value);
|
||||
void AddCustomContext(std::string key, std::string value);
|
||||
|
||||
class Benchmark;
|
||||
|
||||
namespace internal {
|
||||
class Benchmark;
|
||||
class BenchmarkImp;
|
||||
class BenchmarkFamilies;
|
||||
|
||||
@@ -611,6 +621,17 @@ inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp const& value) {
|
||||
_ReadWriteBarrier();
|
||||
}
|
||||
|
||||
template <class Tp>
|
||||
inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp& value) {
|
||||
internal::UseCharPointer(&reinterpret_cast<char const volatile&>(value));
|
||||
_ReadWriteBarrier();
|
||||
}
|
||||
|
||||
template <class Tp>
|
||||
inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp&& value) {
|
||||
internal::UseCharPointer(&reinterpret_cast<char const volatile&>(value));
|
||||
_ReadWriteBarrier();
|
||||
}
|
||||
#else
|
||||
template <class Tp>
|
||||
inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp&& value) {
|
||||
@@ -956,6 +977,8 @@ class BENCHMARK_EXPORT BENCHMARK_INTERNAL_CACHELINE_ALIGNED State {
|
||||
BENCHMARK_ALWAYS_INLINE
|
||||
std::string name() const { return name_; }
|
||||
|
||||
size_t range_size() const { return range_.size(); }
|
||||
|
||||
private:
|
||||
// items we expect on the first cache line (ie 64 bytes of the struct)
|
||||
// When total_iterations_ is 0, KeepRunning() and friends will return false.
|
||||
@@ -1102,20 +1125,15 @@ struct ThreadRunnerBase {
|
||||
virtual void RunThreads(const std::function<void(int)>& fn) = 0;
|
||||
};
|
||||
|
||||
namespace internal {
|
||||
|
||||
// Define alias of ThreadRunner factory function type
|
||||
using threadrunner_factory =
|
||||
std::function<std::unique_ptr<ThreadRunnerBase>(int)>;
|
||||
|
||||
typedef void(Function)(State&);
|
||||
|
||||
// ------------------------------------------------------
|
||||
// Benchmark registration object. The BENCHMARK() macro expands
|
||||
// into an internal::Benchmark* object. Various methods can
|
||||
// be called on this object to change the properties of the benchmark.
|
||||
// Each method returns "this" so that multiple method calls can
|
||||
// chained into one expression.
|
||||
// Benchmark registration object. The BENCHMARK() macro expands into a
|
||||
// Benchmark* object. Various methods can be called on this object to
|
||||
// change the properties of the benchmark. Each method returns "this" so
|
||||
// that multiple method calls can chained into one expression.
|
||||
class BENCHMARK_EXPORT Benchmark {
|
||||
public:
|
||||
virtual ~Benchmark();
|
||||
@@ -1206,7 +1224,7 @@ class BENCHMARK_EXPORT Benchmark {
|
||||
// Pass this benchmark object to *func, which can customize
|
||||
// the benchmark by calling various methods like Arg, Args,
|
||||
// Threads, etc.
|
||||
Benchmark* Apply(void (*custom_arguments)(Benchmark* benchmark));
|
||||
Benchmark* Apply(const std::function<void(Benchmark* benchmark)>&);
|
||||
|
||||
// Set the range multiplier for non-dense range. If not called, the range
|
||||
// multiplier kRangeMultiplier will be used.
|
||||
@@ -1329,11 +1347,11 @@ class BENCHMARK_EXPORT Benchmark {
|
||||
const char* GetArgName(int arg) const;
|
||||
|
||||
private:
|
||||
friend class BenchmarkFamilies;
|
||||
friend class BenchmarkInstance;
|
||||
friend class internal::BenchmarkFamilies;
|
||||
friend class internal::BenchmarkInstance;
|
||||
|
||||
std::string name_;
|
||||
AggregationReportMode aggregation_report_mode_;
|
||||
internal::AggregationReportMode aggregation_report_mode_;
|
||||
std::vector<std::string> arg_names_; // Args for all benchmark runs
|
||||
std::vector<std::vector<int64_t>> args_; // Args for all benchmark runs
|
||||
|
||||
@@ -1350,7 +1368,7 @@ class BENCHMARK_EXPORT Benchmark {
|
||||
bool use_manual_time_;
|
||||
BigO complexity_;
|
||||
BigOFunc* complexity_lambda_;
|
||||
std::vector<Statistics> statistics_;
|
||||
std::vector<internal::Statistics> statistics_;
|
||||
std::vector<int> thread_counts_;
|
||||
|
||||
callback_function setup_;
|
||||
@@ -1361,17 +1379,28 @@ class BENCHMARK_EXPORT Benchmark {
|
||||
BENCHMARK_DISALLOW_COPY_AND_ASSIGN(Benchmark);
|
||||
};
|
||||
|
||||
namespace internal {
|
||||
|
||||
// clang-format off
|
||||
typedef BENCHMARK_DEPRECATED_MSG("Use ::benchmark::Benchmark instead")
|
||||
::benchmark::Benchmark Benchmark;
|
||||
typedef BENCHMARK_DEPRECATED_MSG(
|
||||
"Use ::benchmark::threadrunner_factory instead")
|
||||
::benchmark::threadrunner_factory threadrunner_factory;
|
||||
// clang-format on
|
||||
|
||||
typedef void(Function)(State&);
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// Create and register a benchmark with the specified 'name' that invokes
|
||||
// the specified functor 'fn'.
|
||||
//
|
||||
// RETURNS: A pointer to the registered benchmark.
|
||||
internal::Benchmark* RegisterBenchmark(const std::string& name,
|
||||
internal::Function* fn);
|
||||
Benchmark* RegisterBenchmark(const std::string& name, internal::Function* fn);
|
||||
|
||||
template <class Lambda>
|
||||
internal::Benchmark* RegisterBenchmark(const std::string& name, Lambda&& fn);
|
||||
Benchmark* RegisterBenchmark(const std::string& name, Lambda&& fn);
|
||||
|
||||
// Remove all registered benchmarks. All pointers to previously registered
|
||||
// benchmarks are invalidated.
|
||||
@@ -1380,7 +1409,7 @@ BENCHMARK_EXPORT void ClearRegisteredBenchmarks();
|
||||
namespace internal {
|
||||
// The class used to hold all Benchmarks created from static function.
|
||||
// (ie those created using the BENCHMARK(...) macros.
|
||||
class BENCHMARK_EXPORT FunctionBenchmark : public Benchmark {
|
||||
class BENCHMARK_EXPORT FunctionBenchmark : public benchmark::Benchmark {
|
||||
public:
|
||||
FunctionBenchmark(const std::string& name, Function* func)
|
||||
: Benchmark(name), func_(func) {}
|
||||
@@ -1392,7 +1421,7 @@ class BENCHMARK_EXPORT FunctionBenchmark : public Benchmark {
|
||||
};
|
||||
|
||||
template <class Lambda>
|
||||
class LambdaBenchmark : public Benchmark {
|
||||
class LambdaBenchmark : public benchmark::Benchmark {
|
||||
public:
|
||||
void Run(State& st) override { lambda_(st); }
|
||||
|
||||
@@ -1406,15 +1435,15 @@ class LambdaBenchmark : public Benchmark {
|
||||
};
|
||||
} // namespace internal
|
||||
|
||||
inline internal::Benchmark* RegisterBenchmark(const std::string& name,
|
||||
internal::Function* fn) {
|
||||
inline Benchmark* RegisterBenchmark(const std::string& name,
|
||||
internal::Function* fn) {
|
||||
return internal::RegisterBenchmarkInternal(
|
||||
::benchmark::internal::make_unique<internal::FunctionBenchmark>(name,
|
||||
fn));
|
||||
}
|
||||
|
||||
template <class Lambda>
|
||||
internal::Benchmark* RegisterBenchmark(const std::string& name, Lambda&& fn) {
|
||||
Benchmark* RegisterBenchmark(const std::string& name, Lambda&& fn) {
|
||||
using BenchType =
|
||||
internal::LambdaBenchmark<typename std::decay<Lambda>::type>;
|
||||
return internal::RegisterBenchmarkInternal(
|
||||
@@ -1423,16 +1452,16 @@ internal::Benchmark* RegisterBenchmark(const std::string& name, Lambda&& fn) {
|
||||
}
|
||||
|
||||
template <class Lambda, class... Args>
|
||||
internal::Benchmark* RegisterBenchmark(const std::string& name, Lambda&& fn,
|
||||
Args&&... args) {
|
||||
Benchmark* RegisterBenchmark(const std::string& name, Lambda&& fn,
|
||||
Args&&... args) {
|
||||
return benchmark::RegisterBenchmark(
|
||||
name, [=](benchmark::State& st) { fn(st, args...); });
|
||||
}
|
||||
|
||||
// The base class for all fixture tests.
|
||||
class Fixture : public internal::Benchmark {
|
||||
class Fixture : public Benchmark {
|
||||
public:
|
||||
Fixture() : internal::Benchmark("") {}
|
||||
Fixture() : Benchmark("") {}
|
||||
|
||||
void Run(State& st) override {
|
||||
this->SetUp(st);
|
||||
@@ -1455,14 +1484,29 @@ class Fixture : public internal::Benchmark {
|
||||
// ------------------------------------------------------
|
||||
// Macro to register benchmarks
|
||||
|
||||
// clang-format off
|
||||
#if defined(__clang__)
|
||||
#define BENCHMARK_DISABLE_COUNTER_WARNING \
|
||||
_Pragma("GCC diagnostic push") \
|
||||
_Pragma("GCC diagnostic ignored \"-Wunknown-warning-option\"") \
|
||||
_Pragma("GCC diagnostic ignored \"-Wc2y-extensions\"")
|
||||
#define BENCHMARK_RESTORE_COUNTER_WARNING _Pragma("GCC diagnostic pop")
|
||||
#else
|
||||
#define BENCHMARK_DISABLE_COUNTER_WARNING
|
||||
#define BENCHMARK_RESTORE_COUNTER_WARNING
|
||||
#endif
|
||||
// clang-format on
|
||||
|
||||
// Check that __COUNTER__ is defined and that __COUNTER__ increases by 1
|
||||
// every time it is expanded. X + 1 == X + 0 is used in case X is defined to be
|
||||
// empty. If X is empty the expression becomes (+1 == +0).
|
||||
BENCHMARK_DISABLE_COUNTER_WARNING
|
||||
#if defined(__COUNTER__) && (__COUNTER__ + 1 == __COUNTER__ + 0)
|
||||
#define BENCHMARK_PRIVATE_UNIQUE_ID __COUNTER__
|
||||
#else
|
||||
#define BENCHMARK_PRIVATE_UNIQUE_ID __LINE__
|
||||
#endif
|
||||
BENCHMARK_RESTORE_COUNTER_WARNING
|
||||
|
||||
// Helpers for generating unique variable names
|
||||
#define BENCHMARK_PRIVATE_NAME(...) \
|
||||
@@ -1475,17 +1519,19 @@ class Fixture : public internal::Benchmark {
|
||||
#define BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method) \
|
||||
BaseClass##_##Method##_Benchmark
|
||||
|
||||
#define BENCHMARK_PRIVATE_DECLARE(n) \
|
||||
/* NOLINTNEXTLINE(misc-use-anonymous-namespace) */ \
|
||||
static ::benchmark::internal::Benchmark const* const BENCHMARK_PRIVATE_NAME( \
|
||||
n) BENCHMARK_UNUSED
|
||||
#define BENCHMARK_PRIVATE_DECLARE(n) \
|
||||
BENCHMARK_DISABLE_COUNTER_WARNING \
|
||||
/* NOLINTNEXTLINE(misc-use-anonymous-namespace) */ \
|
||||
static ::benchmark::Benchmark const* const BENCHMARK_PRIVATE_NAME(n) \
|
||||
BENCHMARK_RESTORE_COUNTER_WARNING BENCHMARK_UNUSED
|
||||
|
||||
#define BENCHMARK(...) \
|
||||
BENCHMARK_PRIVATE_DECLARE(_benchmark_) = \
|
||||
(::benchmark::internal::RegisterBenchmarkInternal( \
|
||||
::benchmark::internal::make_unique< \
|
||||
::benchmark::internal::FunctionBenchmark>(#__VA_ARGS__, \
|
||||
__VA_ARGS__)))
|
||||
#define BENCHMARK(...) \
|
||||
BENCHMARK_PRIVATE_DECLARE(_benchmark_) = \
|
||||
(::benchmark::internal::RegisterBenchmarkInternal( \
|
||||
::benchmark::internal::make_unique< \
|
||||
::benchmark::internal::FunctionBenchmark>( \
|
||||
#__VA_ARGS__, \
|
||||
static_cast<::benchmark::internal::Function*>(__VA_ARGS__))))
|
||||
|
||||
// Old-style macros
|
||||
#define BENCHMARK_WITH_ARG(n, a) BENCHMARK(n)->Arg((a))
|
||||
@@ -1526,21 +1572,25 @@ class Fixture : public internal::Benchmark {
|
||||
BENCHMARK_PRIVATE_DECLARE(n) = \
|
||||
(::benchmark::internal::RegisterBenchmarkInternal( \
|
||||
::benchmark::internal::make_unique< \
|
||||
::benchmark::internal::FunctionBenchmark>(#n "<" #a ">", n<a>)))
|
||||
::benchmark::internal::FunctionBenchmark>( \
|
||||
#n "<" #a ">", \
|
||||
static_cast<::benchmark::internal::Function*>(n<a>))))
|
||||
|
||||
#define BENCHMARK_TEMPLATE2(n, a, b) \
|
||||
BENCHMARK_PRIVATE_DECLARE(n) = \
|
||||
(::benchmark::internal::RegisterBenchmarkInternal( \
|
||||
::benchmark::internal::make_unique< \
|
||||
::benchmark::internal::FunctionBenchmark>(#n "<" #a "," #b ">", \
|
||||
n<a, b>)))
|
||||
#define BENCHMARK_TEMPLATE2(n, a, b) \
|
||||
BENCHMARK_PRIVATE_DECLARE(n) = \
|
||||
(::benchmark::internal::RegisterBenchmarkInternal( \
|
||||
::benchmark::internal::make_unique< \
|
||||
::benchmark::internal::FunctionBenchmark>( \
|
||||
#n "<" #a "," #b ">", \
|
||||
static_cast<::benchmark::internal::Function*>(n<a, b>))))
|
||||
|
||||
#define BENCHMARK_TEMPLATE(n, ...) \
|
||||
BENCHMARK_PRIVATE_DECLARE(n) = \
|
||||
(::benchmark::internal::RegisterBenchmarkInternal( \
|
||||
::benchmark::internal::make_unique< \
|
||||
::benchmark::internal::FunctionBenchmark>( \
|
||||
#n "<" #__VA_ARGS__ ">", n<__VA_ARGS__>)))
|
||||
#n "<" #__VA_ARGS__ ">", \
|
||||
static_cast<::benchmark::internal::Function*>(n<__VA_ARGS__>))))
|
||||
|
||||
// This will register a benchmark for a templatized function,
|
||||
// with the additional arguments specified by `...`.
|
||||
@@ -1661,9 +1711,11 @@ class Fixture : public internal::Benchmark {
|
||||
::benchmark::internal::make_unique<UniqueName>()))
|
||||
|
||||
#define BENCHMARK_TEMPLATE_INSTANTIATE_F(BaseClass, Method, ...) \
|
||||
BENCHMARK_DISABLE_COUNTER_WARNING \
|
||||
BENCHMARK_TEMPLATE_PRIVATE_INSTANTIATE_F( \
|
||||
BaseClass, Method, BENCHMARK_PRIVATE_NAME(BaseClass##Method), \
|
||||
__VA_ARGS__)
|
||||
__VA_ARGS__) \
|
||||
BENCHMARK_RESTORE_COUNTER_WARNING
|
||||
|
||||
// This macro will define and register a benchmark within a fixture class.
|
||||
#define BENCHMARK_F(BaseClass, Method) \
|
||||
@@ -1798,6 +1850,7 @@ class BENCHMARK_EXPORT BenchmarkReporter {
|
||||
complexity(oNone),
|
||||
complexity_lambda(),
|
||||
complexity_n(0),
|
||||
statistics(),
|
||||
report_big_o(false),
|
||||
report_rms(false),
|
||||
allocs_per_iter(0.0) {}
|
||||
|
||||
@@ -708,11 +708,12 @@ void RegisterProfilerManager(ProfilerManager* manager) {
|
||||
internal::profiler_manager = manager;
|
||||
}
|
||||
|
||||
void AddCustomContext(const std::string& key, const std::string& value) {
|
||||
void AddCustomContext(std::string key, 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) {
|
||||
if (!internal::global_context->emplace(std::move(key), std::move(value))
|
||||
.second) {
|
||||
std::cerr << "Failed to add custom context \"" << key << "\" as it already "
|
||||
<< "exists with value \"" << value << "\"\n";
|
||||
}
|
||||
@@ -722,6 +723,7 @@ namespace internal {
|
||||
|
||||
void (*HelperPrintf)();
|
||||
|
||||
namespace {
|
||||
void PrintUsageAndExit() {
|
||||
HelperPrintf();
|
||||
std::flush(std::cout);
|
||||
@@ -810,6 +812,8 @@ void ParseCommandLineFlags(int* argc, char** argv) {
|
||||
}
|
||||
}
|
||||
|
||||
} // end namespace
|
||||
|
||||
int InitializeStreams() {
|
||||
static std::ios_base::Init init;
|
||||
return 0;
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
namespace benchmark {
|
||||
namespace internal {
|
||||
|
||||
BenchmarkInstance::BenchmarkInstance(Benchmark* benchmark, int family_idx,
|
||||
BenchmarkInstance::BenchmarkInstance(benchmark::Benchmark* benchmark,
|
||||
int family_idx,
|
||||
int per_family_instance_idx,
|
||||
const std::vector<int64_t>& args,
|
||||
int thread_count)
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace internal {
|
||||
// Information kept per benchmark we may want to run
|
||||
class BenchmarkInstance {
|
||||
public:
|
||||
BenchmarkInstance(Benchmark* benchmark, int family_idx,
|
||||
BenchmarkInstance(benchmark::Benchmark* benchmark, int family_idx,
|
||||
int per_family_instance_idx,
|
||||
const std::vector<int64_t>& args, int thread_count);
|
||||
|
||||
@@ -52,7 +52,7 @@ class BenchmarkInstance {
|
||||
|
||||
private:
|
||||
BenchmarkName name_;
|
||||
Benchmark& benchmark_;
|
||||
benchmark::Benchmark& benchmark_;
|
||||
const int family_index_;
|
||||
const int per_family_instance_index_;
|
||||
AggregationReportMode aggregation_report_mode_;
|
||||
|
||||
@@ -75,7 +75,7 @@ class BenchmarkFamilies {
|
||||
static BenchmarkFamilies* GetInstance();
|
||||
|
||||
// Registers a benchmark family and returns the index assigned to it.
|
||||
size_t AddBenchmark(std::unique_ptr<Benchmark> family);
|
||||
size_t AddBenchmark(std::unique_ptr<benchmark::Benchmark> family);
|
||||
|
||||
// Clear all registered benchmark families.
|
||||
void ClearBenchmarks();
|
||||
@@ -89,7 +89,7 @@ class BenchmarkFamilies {
|
||||
private:
|
||||
BenchmarkFamilies() {}
|
||||
|
||||
std::vector<std::unique_ptr<Benchmark>> families_;
|
||||
std::vector<std::unique_ptr<benchmark::Benchmark>> families_;
|
||||
Mutex mutex_;
|
||||
};
|
||||
|
||||
@@ -98,7 +98,8 @@ BenchmarkFamilies* BenchmarkFamilies::GetInstance() {
|
||||
return &instance;
|
||||
}
|
||||
|
||||
size_t BenchmarkFamilies::AddBenchmark(std::unique_ptr<Benchmark> family) {
|
||||
size_t BenchmarkFamilies::AddBenchmark(
|
||||
std::unique_ptr<benchmark::Benchmark> family) {
|
||||
MutexLock l(mutex_);
|
||||
size_t index = families_.size();
|
||||
families_.push_back(std::move(family));
|
||||
@@ -135,7 +136,7 @@ bool BenchmarkFamilies::FindBenchmarks(
|
||||
int next_family_index = 0;
|
||||
|
||||
MutexLock l(mutex_);
|
||||
for (std::unique_ptr<Benchmark>& family : families_) {
|
||||
for (std::unique_ptr<benchmark::Benchmark>& family : families_) {
|
||||
int family_index = next_family_index;
|
||||
int per_family_instance_index = 0;
|
||||
|
||||
@@ -179,7 +180,7 @@ bool BenchmarkFamilies::FindBenchmarks(
|
||||
|
||||
++per_family_instance_index;
|
||||
|
||||
// Only bump the next family index once we've estabilished that
|
||||
// Only bump the next family index once we've established that
|
||||
// at least one instance of this family will be run.
|
||||
if (next_family_index == family_index) {
|
||||
++next_family_index;
|
||||
@@ -191,8 +192,9 @@ bool BenchmarkFamilies::FindBenchmarks(
|
||||
return true;
|
||||
}
|
||||
|
||||
Benchmark* RegisterBenchmarkInternal(std::unique_ptr<Benchmark> bench) {
|
||||
Benchmark* bench_ptr = bench.get();
|
||||
benchmark::Benchmark* RegisterBenchmarkInternal(
|
||||
std::unique_ptr<benchmark::Benchmark> bench) {
|
||||
benchmark::Benchmark* bench_ptr = bench.get();
|
||||
BenchmarkFamilies* families = BenchmarkFamilies::GetInstance();
|
||||
families->AddBenchmark(std::move(bench));
|
||||
return bench_ptr;
|
||||
@@ -206,13 +208,15 @@ bool FindBenchmarksInternal(const std::string& re,
|
||||
return BenchmarkFamilies::GetInstance()->FindBenchmarks(re, benchmarks, Err);
|
||||
}
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
//=============================================================================//
|
||||
// Benchmark
|
||||
//=============================================================================//
|
||||
|
||||
Benchmark::Benchmark(const std::string& name)
|
||||
: name_(name),
|
||||
aggregation_report_mode_(ARM_Unspecified),
|
||||
aggregation_report_mode_(internal::ARM_Unspecified),
|
||||
time_unit_(GetDefaultTimeUnit()),
|
||||
use_default_time_unit_(true),
|
||||
range_multiplier_(kRangeMultiplier),
|
||||
@@ -253,7 +257,7 @@ Benchmark* Benchmark::Unit(TimeUnit unit) {
|
||||
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_);
|
||||
internal::AddRange(&arglist, start, limit, range_multiplier_);
|
||||
|
||||
for (int64_t i : arglist) {
|
||||
args_.push_back({i});
|
||||
@@ -266,8 +270,8 @@ Benchmark* Benchmark::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_);
|
||||
internal::AddRange(&arglists[i], ranges[i].first, ranges[i].second,
|
||||
range_multiplier_);
|
||||
}
|
||||
|
||||
ArgsProduct(arglists);
|
||||
@@ -330,7 +334,8 @@ Benchmark* Benchmark::Args(const std::vector<int64_t>& args) {
|
||||
return this;
|
||||
}
|
||||
|
||||
Benchmark* Benchmark::Apply(void (*custom_arguments)(Benchmark* benchmark)) {
|
||||
Benchmark* Benchmark::Apply(
|
||||
const std::function<void(Benchmark* benchmark)>& custom_arguments) {
|
||||
custom_arguments(this);
|
||||
return this;
|
||||
}
|
||||
@@ -381,8 +386,8 @@ Benchmark* Benchmark::MinWarmUpTime(double t) {
|
||||
|
||||
Benchmark* Benchmark::Iterations(IterationCount n) {
|
||||
BM_CHECK(n > 0);
|
||||
BM_CHECK(IsZero(min_time_));
|
||||
BM_CHECK(IsZero(min_warmup_time_));
|
||||
BM_CHECK(internal::IsZero(min_time_));
|
||||
BM_CHECK(internal::IsZero(min_warmup_time_));
|
||||
iterations_ = n;
|
||||
return this;
|
||||
}
|
||||
@@ -394,21 +399,23 @@ Benchmark* Benchmark::Repetitions(int n) {
|
||||
}
|
||||
|
||||
Benchmark* Benchmark::ReportAggregatesOnly(bool value) {
|
||||
aggregation_report_mode_ = value ? ARM_ReportAggregatesOnly : ARM_Default;
|
||||
aggregation_report_mode_ =
|
||||
value ? internal::ARM_ReportAggregatesOnly : internal::ARM_Default;
|
||||
return this;
|
||||
}
|
||||
|
||||
Benchmark* Benchmark::DisplayAggregatesOnly(bool value) {
|
||||
// If we were called, the report mode is no longer 'unspecified', in any case.
|
||||
using internal::AggregationReportMode;
|
||||
aggregation_report_mode_ = static_cast<AggregationReportMode>(
|
||||
aggregation_report_mode_ | ARM_Default);
|
||||
aggregation_report_mode_ | internal::ARM_Default);
|
||||
|
||||
if (value) {
|
||||
aggregation_report_mode_ = static_cast<AggregationReportMode>(
|
||||
aggregation_report_mode_ | ARM_DisplayReportAggregatesOnly);
|
||||
aggregation_report_mode_ | internal::ARM_DisplayReportAggregatesOnly);
|
||||
} else {
|
||||
aggregation_report_mode_ = static_cast<AggregationReportMode>(
|
||||
aggregation_report_mode_ & ~ARM_DisplayReportAggregatesOnly);
|
||||
aggregation_report_mode_ & ~internal::ARM_DisplayReportAggregatesOnly);
|
||||
}
|
||||
|
||||
return this;
|
||||
@@ -462,7 +469,7 @@ 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);
|
||||
internal::AddRange(&thread_counts_, min_threads, max_threads, 2);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -514,6 +521,8 @@ TimeUnit Benchmark::GetTimeUnit() const {
|
||||
return use_default_time_unit_ ? GetDefaultTimeUnit() : time_unit_;
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
|
||||
//=============================================================================//
|
||||
// FunctionBenchmark
|
||||
//=============================================================================//
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include "check.h"
|
||||
|
||||
@@ -123,7 +123,12 @@ BenchmarkReporter::Run CreateRunReport(
|
||||
: 0;
|
||||
}
|
||||
|
||||
internal::Finish(&report.counters, results.iterations, seconds,
|
||||
// The CPU time is the total time taken by all thread. If we used that as
|
||||
// the denominator, we'd be calculating the rate per thread here. This is
|
||||
// why we have to divide the total cpu_time by the number of threads for
|
||||
// global counters to get a global rate.
|
||||
const double thread_seconds = seconds / b.threads();
|
||||
internal::Finish(&report.counters, results.iterations, thread_seconds,
|
||||
b.threads());
|
||||
}
|
||||
return report;
|
||||
@@ -191,7 +196,7 @@ class ThreadRunnerDefault : public ThreadRunnerBase {
|
||||
explicit ThreadRunnerDefault(int num_threads)
|
||||
: pool(static_cast<size_t>(num_threads - 1)) {}
|
||||
|
||||
void RunThreads(const std::function<void(int)>& fn) final {
|
||||
void RunThreads(const std::function<void(int)>& fn) override 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));
|
||||
@@ -212,7 +217,8 @@ class ThreadRunnerDefault : public ThreadRunnerBase {
|
||||
};
|
||||
|
||||
std::unique_ptr<ThreadRunnerBase> GetThreadRunner(
|
||||
const threadrunner_factory& userThreadRunnerFactory, int num_threads) {
|
||||
const benchmark::threadrunner_factory& userThreadRunnerFactory,
|
||||
int num_threads) {
|
||||
return userThreadRunnerFactory
|
||||
? userThreadRunnerFactory(num_threads)
|
||||
: std::make_unique<ThreadRunnerDefault>(num_threads);
|
||||
@@ -400,7 +406,7 @@ bool BenchmarkRunner::ShouldReportIterationResults(
|
||||
}
|
||||
|
||||
double BenchmarkRunner::GetMinTimeToApply() const {
|
||||
// In order to re-use functionality to run and measure benchmarks for running
|
||||
// In order to reuse 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
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#include "internal_macros.h"
|
||||
|
||||
namespace benchmark {
|
||||
enum LogColor {
|
||||
COLOR_DEFAULT,
|
||||
@@ -17,11 +19,14 @@ enum LogColor {
|
||||
COLOR_WHITE
|
||||
};
|
||||
|
||||
PRINTF_FORMAT_STRING_FUNC(1, 0)
|
||||
std::string FormatString(const char* msg, va_list args);
|
||||
std::string FormatString(const char* msg, ...);
|
||||
PRINTF_FORMAT_STRING_FUNC(1, 2) std::string FormatString(const char* msg, ...);
|
||||
|
||||
PRINTF_FORMAT_STRING_FUNC(3, 0)
|
||||
void ColorPrintf(std::ostream& out, LogColor color, const char* fmt,
|
||||
va_list args);
|
||||
PRINTF_FORMAT_STRING_FUNC(3, 4)
|
||||
void ColorPrintf(std::ostream& out, LogColor color, const char* fmt, ...);
|
||||
|
||||
// Returns true if stdout appears to be a terminal that supports colored
|
||||
|
||||
@@ -179,6 +179,8 @@ std::map<std::string, std::string> KvPairsFromEnv(
|
||||
return value;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
// Parses a string as a command line flag. The string should have
|
||||
// the format "--flag=value". When def_optional is true, the "=value"
|
||||
// part can be omitted.
|
||||
@@ -217,6 +219,8 @@ const char* ParseFlagValue(const char* str, const char* flag,
|
||||
return flag_end + 1;
|
||||
}
|
||||
|
||||
} // end namespace
|
||||
|
||||
BENCHMARK_EXPORT
|
||||
bool ParseBoolFlag(const char* str, const char* flag, bool* value) {
|
||||
// Gets the value of the flag as a string.
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
|
||||
#include "complexity.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
|
||||
#include "benchmark/benchmark.h"
|
||||
@@ -25,6 +24,8 @@
|
||||
|
||||
namespace benchmark {
|
||||
|
||||
namespace {
|
||||
|
||||
// Internal function to calculate the different scalability forms
|
||||
BigOFunc* FittingCurve(BigO complexity) {
|
||||
switch (complexity) {
|
||||
@@ -48,6 +49,8 @@ BigOFunc* FittingCurve(BigO complexity) {
|
||||
}
|
||||
}
|
||||
|
||||
} // end namespace
|
||||
|
||||
// Function to return an string for the calculated complexity
|
||||
std::string GetBigOString(BigO complexity) {
|
||||
switch (complexity) {
|
||||
@@ -68,6 +71,8 @@ std::string GetBigOString(BigO complexity) {
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
// Find the coefficient for the high-order term in the running time, by
|
||||
// minimizing the sum of squares of relative error, for the fitting curve
|
||||
// given by the lambda expression.
|
||||
@@ -152,6 +157,8 @@ LeastSq MinimalLeastSq(const std::vector<ComplexityN>& n,
|
||||
return best_fit;
|
||||
}
|
||||
|
||||
} // end namespace
|
||||
|
||||
std::vector<BenchmarkReporter::Run> ComputeBigO(
|
||||
const std::vector<BenchmarkReporter::Run>& reports) {
|
||||
typedef BenchmarkReporter::Run Run;
|
||||
|
||||
@@ -97,6 +97,7 @@ void ConsoleReporter::ReportRuns(const std::vector<Run>& reports) {
|
||||
}
|
||||
}
|
||||
|
||||
PRINTF_FORMAT_STRING_FUNC(3, 4)
|
||||
static void IgnoreColorPrint(std::ostream& out, LogColor /*unused*/,
|
||||
const char* fmt, ...) {
|
||||
va_list args;
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
namespace benchmark {
|
||||
namespace internal {
|
||||
|
||||
namespace {
|
||||
|
||||
double Finish(Counter const& c, IterationCount iterations, double cpu_time,
|
||||
double num_threads) {
|
||||
double v = c.value;
|
||||
@@ -39,6 +41,8 @@ double Finish(Counter const& c, IterationCount iterations, double cpu_time,
|
||||
return v;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void Finish(UserCounters* l, IterationCount iterations, double cpu_time,
|
||||
double num_threads) {
|
||||
for (auto& c : *l) {
|
||||
|
||||
@@ -12,29 +12,23 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
#include "benchmark/benchmark.h"
|
||||
#include "check.h"
|
||||
#include "complexity.h"
|
||||
#include "string_util.h"
|
||||
#include "timers.h"
|
||||
|
||||
// File format reference: http://edoceo.com/utilitas/csv-file-format.
|
||||
|
||||
namespace benchmark {
|
||||
|
||||
namespace {
|
||||
std::vector<std::string> elements = {
|
||||
const std::vector<const char*> elements = {
|
||||
"name", "iterations", "real_time", "cpu_time",
|
||||
"time_unit", "bytes_per_second", "items_per_second", "label",
|
||||
"error_occurred", "error_message"};
|
||||
} // namespace
|
||||
|
||||
std::string CsvEscape(const std::string& s) {
|
||||
std::string tmp;
|
||||
@@ -51,6 +45,7 @@ std::string CsvEscape(const std::string& s) {
|
||||
}
|
||||
return '"' + tmp + '"';
|
||||
}
|
||||
} // namespace
|
||||
|
||||
BENCHMARK_EXPORT
|
||||
bool CSVReporter::ReportContext(const Context& context) {
|
||||
|
||||
@@ -36,6 +36,9 @@
|
||||
// declarations of some other intrinsics, breaking compilation.
|
||||
// Therefore, we simply declare __rdtsc ourselves. See also
|
||||
// http://connect.microsoft.com/VisualStudio/feedback/details/262047
|
||||
//
|
||||
// Note that MSVC defines the x64 preprocessor macros when building
|
||||
// for Arm64EC, despite it using Arm64 assembly instructions.
|
||||
#if defined(COMPILER_MSVC) && !defined(_M_IX86) && !defined(_M_ARM64) && \
|
||||
!defined(_M_ARM64EC)
|
||||
extern "C" uint64_t __rdtsc();
|
||||
@@ -79,7 +82,10 @@ inline BENCHMARK_ALWAYS_INLINE int64_t Now() {
|
||||
int64_t ret;
|
||||
__asm__ volatile("rdtsc" : "=A"(ret));
|
||||
return ret;
|
||||
#elif defined(__x86_64__) || defined(__amd64__)
|
||||
|
||||
// Note that Clang, like MSVC, defines the x64 preprocessor macros when building
|
||||
// for Arm64EC, despite it using Arm64 assembly instructions.
|
||||
#elif (defined(__x86_64__) || defined(__amd64__)) && !defined(__arm64ec__)
|
||||
uint64_t low, high;
|
||||
__asm__ volatile("rdtsc" : "=a"(low), "=d"(high));
|
||||
return static_cast<int64_t>((high << 32) | low);
|
||||
@@ -139,7 +145,7 @@ inline BENCHMARK_ALWAYS_INLINE int64_t Now() {
|
||||
struct timespec ts = {0, 0};
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
return static_cast<int64_t>(ts.tv_sec) * 1000000000 + ts.tv_nsec;
|
||||
#elif defined(__aarch64__)
|
||||
#elif defined(__aarch64__) || defined(__arm64ec__)
|
||||
// System timer of ARMv8 runs at a different frequency than the CPU's.
|
||||
// The frequency is fixed, typically in the range 1-50MHz. It can be
|
||||
// read at CNTFRQ special register. We assume the OS has set up
|
||||
|
||||
@@ -106,6 +106,16 @@
|
||||
#define BENCHMARK_MAYBE_UNUSED
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
#define PRINTF_FORMAT_STRING_FUNC(format_arg, first_idx) \
|
||||
__attribute__((format(printf, format_arg, first_idx)))
|
||||
#elif defined(__MINGW32__)
|
||||
#define PRINTF_FORMAT_STRING_FUNC(format_arg, first_idx) \
|
||||
__attribute__((format(__MINGW_PRINTF_FORMAT, format_arg, first_idx)))
|
||||
#else
|
||||
#define PRINTF_FORMAT_STRING_FUNC(format_arg, first_idx)
|
||||
#endif
|
||||
|
||||
// clang-format on
|
||||
|
||||
#endif // BENCHMARK_INTERNAL_MACROS_H_
|
||||
|
||||
@@ -81,7 +81,9 @@ std::string FormatKV(std::string const& key, bool value) {
|
||||
|
||||
std::string FormatKV(std::string const& key, int64_t value) {
|
||||
std::stringstream ss;
|
||||
ss << '"' << StrEscape(key) << "\": " << value;
|
||||
// We really want to just dump the integer as-is,
|
||||
// without the system locale interfering.
|
||||
ss << '"' << StrEscape(key) << "\": " << std::to_string(value);
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
|
||||
@@ -214,7 +214,7 @@ PerfCounters PerfCounters::Create(
|
||||
// This should never happen but if it does, we give up on the
|
||||
// entire batch as recovery would be a mess.
|
||||
GetErrorLogInstance() << "***WARNING*** Failed to start counters. "
|
||||
"Claring out all counters.\n";
|
||||
"Clearing out all counters.\n";
|
||||
|
||||
// Close all performance counters
|
||||
for (int id : counter_ids) {
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
#ifndef BENCHMARK_RE_H_
|
||||
#define BENCHMARK_RE_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "internal_macros.h"
|
||||
|
||||
// clang-format off
|
||||
|
||||
@@ -112,13 +112,14 @@ std::string ToBinaryStringFullySpecified(double value, int precision,
|
||||
return mantissa + ExponentToPrefix(exponent, one_k == Counter::kIs1024);
|
||||
}
|
||||
|
||||
PRINTF_FORMAT_STRING_FUNC(1, 0)
|
||||
std::string StrFormatImp(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);
|
||||
|
||||
// TODO(ericwf): use std::array for first attempt to avoid one memory
|
||||
// allocation guess what the size might be
|
||||
// Use std::array for first attempt to avoid one memory allocation guess what
|
||||
// the size might be
|
||||
std::array<char, 256> local_buff = {};
|
||||
|
||||
// 2015-10-08: vsnprintf is used instead of snd::vsnprintf due to a limitation
|
||||
|
||||
@@ -463,7 +463,7 @@ std::string GetSystemName() {
|
||||
DWCOUNT, NULL, 0, NULL, NULL);
|
||||
str.resize(len);
|
||||
WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, hostname, DWCOUNT, &str[0],
|
||||
str.size(), NULL, NULL);
|
||||
static_cast<int>(str.size()), NULL, NULL);
|
||||
#endif
|
||||
return str;
|
||||
#elif defined(BENCHMARK_OS_QURT)
|
||||
|
||||
14
build.gradle
14
build.gradle
@@ -108,6 +108,10 @@ ext.addTaskToCopyAllOutputs = { task ->
|
||||
copyAllOutputs.from task.archiveFile
|
||||
}
|
||||
|
||||
ext.makeZipBaseName = { group, artifactId ->
|
||||
return "_GROUP_${group.replace(".", "_")}_ID_${artifactId}_CLS"
|
||||
}
|
||||
|
||||
subprojects {
|
||||
apply plugin: 'eclipse'
|
||||
apply plugin: 'idea'
|
||||
@@ -120,8 +124,8 @@ subprojects {
|
||||
|
||||
plugins.withType(JavaPlugin) {
|
||||
java {
|
||||
sourceCompatibility = 21
|
||||
targetCompatibility = 21
|
||||
sourceCompatibility = 25
|
||||
targetCompatibility = 25
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,11 +145,13 @@ subprojects {
|
||||
options.encoding = 'UTF-8'
|
||||
}
|
||||
|
||||
// Enables UTF-8 support in Javadoc
|
||||
// Enables UTF-8 support in Javadoc, disables 4 MB of fonts being added to every Javadoc JAR, add our styles
|
||||
tasks.withType(Javadoc) {
|
||||
options.addStringOption("charset", "utf-8")
|
||||
options.addStringOption("docencoding", "utf-8")
|
||||
options.addStringOption("encoding", "utf-8")
|
||||
options.addBooleanOption("-no-fonts", true)
|
||||
options.addStringOption("-add-stylesheet", "${rootDir}/docs/javadoc.css")
|
||||
}
|
||||
|
||||
// Sign outputs with Developer ID
|
||||
@@ -187,5 +193,5 @@ ext.getCurrentArch = {
|
||||
}
|
||||
|
||||
wrapper {
|
||||
gradleVersion = '9.2.0'
|
||||
gradleVersion = '9.4.1'
|
||||
}
|
||||
|
||||
@@ -3,57 +3,6 @@ project(cameraserver)
|
||||
include(CompileWarnings)
|
||||
include(AddTest)
|
||||
|
||||
# Java bindings
|
||||
if(WITH_JAVA)
|
||||
include(UseJava)
|
||||
|
||||
#find JAR file, copy it locally
|
||||
set(OPENCV_JAVA_INSTALL_DIR ${OpenCV_INSTALL_PATH}/share/java/opencv4)
|
||||
|
||||
find_file(
|
||||
OPENCV_JAR_FILE
|
||||
NAMES opencv-${OpenCV_VERSION_MAJOR}${OpenCV_VERSION_MINOR}${OpenCV_VERSION_PATCH}.jar
|
||||
PATHS
|
||||
${OPENCV_JAVA_INSTALL_DIR}
|
||||
${OpenCV_INSTALL_PATH}/bin
|
||||
${OpenCV_INSTALL_PATH}/share/java
|
||||
${OpenCV_INSTALL_PATH}/share/OpenCV/java
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
|
||||
file(GLOB_RECURSE JAVA_SOURCES src/main/java/*.java)
|
||||
|
||||
add_jar(
|
||||
cameraserver_jar
|
||||
${JAVA_SOURCES}
|
||||
INCLUDE_JARS wpiutil_jar cscore_jar ntcore_jar ${OPENCV_JAR_FILE}
|
||||
OUTPUT_NAME cameraserver
|
||||
OUTPUT_DIR ${WPILIB_BINARY_DIR}/${java_lib_dest}
|
||||
)
|
||||
set_property(TARGET cameraserver_jar PROPERTY FOLDER "java")
|
||||
|
||||
install_jar(cameraserver_jar DESTINATION ${java_lib_dest})
|
||||
install_jar_exports(
|
||||
TARGETS cameraserver_jar
|
||||
FILE cameraserver_jar.cmake
|
||||
DESTINATION share/cameraserver
|
||||
)
|
||||
endif()
|
||||
|
||||
if(WITH_JAVA_SOURCE)
|
||||
include(UseJava)
|
||||
include(CreateSourceJar)
|
||||
add_source_jar(
|
||||
cameraserver_src_jar
|
||||
BASE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR}/src/main/java
|
||||
OUTPUT_NAME cameraserver-sources
|
||||
OUTPUT_DIR ${WPILIB_BINARY_DIR}/${java_lib_dest}
|
||||
)
|
||||
set_property(TARGET cameraserver_src_jar PROPERTY FOLDER "java")
|
||||
|
||||
install_jar(cameraserver_src_jar DESTINATION ${java_lib_dest})
|
||||
endif()
|
||||
|
||||
file(GLOB_RECURSE cameraserver_native_src src/main/native/cpp/*.cpp)
|
||||
add_library(cameraserver ${cameraserver_native_src})
|
||||
set_target_properties(cameraserver PROPERTIES DEBUG_POSTFIX "d")
|
||||
|
||||
@@ -8,6 +8,3 @@ find_dependency(OpenCV)
|
||||
|
||||
@FILENAME_DEP_REPLACE@
|
||||
include(${SELF_DIR}/cameraserver.cmake)
|
||||
if(@WITH_JAVA@)
|
||||
include(${SELF_DIR}/cameraserver_jar.cmake)
|
||||
endif()
|
||||
|
||||
@@ -47,9 +47,8 @@ import org.wpilib.vision.stream.CameraServer;
|
||||
*/
|
||||
|
||||
public final class Main {
|
||||
private static String configFile = "/boot/frc.json";
|
||||
private static String configFile = "/boot/CameraServerConfig.json";
|
||||
|
||||
@SuppressWarnings("MemberName")
|
||||
public static class CameraConfig {
|
||||
public String name;
|
||||
public String path;
|
||||
|
||||
@@ -46,9 +46,9 @@
|
||||
*/
|
||||
|
||||
#ifdef __RASPBIAN__
|
||||
static const char* configFile = "/boot/frc.json";
|
||||
static const char* configFile = "/boot/CameraServerConfig.json";
|
||||
#else
|
||||
static const char* configFile = "frc.json";
|
||||
static const char* configFile = "CameraServerConfig.json";
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
@@ -69,8 +69,8 @@ bool ReadCameraConfig(const wpi::util::json& config) {
|
||||
|
||||
// name
|
||||
try {
|
||||
c.name = config.at("name").get<std::string>();
|
||||
} catch (const wpi::util::json::exception& e) {
|
||||
c.name = config.at("name").get_string();
|
||||
} catch (const std::logic_error& e) {
|
||||
wpi::util::print(stderr,
|
||||
"config error in '{}': could not read camera name: {}\n",
|
||||
configFile, e.what());
|
||||
@@ -79,8 +79,8 @@ bool ReadCameraConfig(const wpi::util::json& config) {
|
||||
|
||||
// path
|
||||
try {
|
||||
c.path = config.at("path").get<std::string>();
|
||||
} catch (const wpi::util::json::exception& e) {
|
||||
c.path = config.at("path").get_string();
|
||||
} catch (const std::logic_error& e) {
|
||||
wpi::util::print(
|
||||
stderr, "config error in '{}': camera '{}': could not read path: {}\n",
|
||||
configFile, c.name, e.what());
|
||||
@@ -103,17 +103,16 @@ bool ReadConfig() {
|
||||
}
|
||||
|
||||
// parse file
|
||||
wpi::util::json j;
|
||||
try {
|
||||
j = wpi::util::json::parse(fileBuffer.value()->GetCharBuffer());
|
||||
} catch (const wpi::util::json::parse_error& e) {
|
||||
wpi::util::print(stderr, "config error in '{}': byte {}: {}\n", configFile,
|
||||
e.byte, e.what());
|
||||
auto buf = fileBuffer.value()->GetCharBuffer();
|
||||
auto j = wpi::util::json::parse({buf.data(), buf.size()});
|
||||
if (!j) {
|
||||
wpi::util::print(stderr, "config error in '{}': {}\n", configFile,
|
||||
j.error());
|
||||
return false;
|
||||
}
|
||||
|
||||
// top level must be an object
|
||||
if (!j.is_object()) {
|
||||
if (!j->is_object()) {
|
||||
wpi::util::print(stderr, "config error in '{}': must be JSON object\n",
|
||||
configFile);
|
||||
return false;
|
||||
@@ -121,8 +120,8 @@ bool ReadConfig() {
|
||||
|
||||
// team number
|
||||
try {
|
||||
team = j.at("team").get<unsigned int>();
|
||||
} catch (const wpi::util::json::exception& e) {
|
||||
team = j->at("team").get_int();
|
||||
} catch (const std::logic_error& e) {
|
||||
wpi::util::print(stderr,
|
||||
"config error in '{}': could not read team number: {}\n",
|
||||
configFile, e.what());
|
||||
@@ -130,9 +129,9 @@ bool ReadConfig() {
|
||||
}
|
||||
|
||||
// ntmode (optional)
|
||||
if (j.count("ntmode") != 0) {
|
||||
if (auto ntmode = j->lookup("ntmode")) {
|
||||
try {
|
||||
auto str = j.at("ntmode").get<std::string>();
|
||||
auto str = ntmode->get_string();
|
||||
if (wpi::util::equals_lower(str, "client")) {
|
||||
server = false;
|
||||
} else if (wpi::util::equals_lower(str, "server")) {
|
||||
@@ -143,7 +142,7 @@ bool ReadConfig() {
|
||||
"config error in '{}': could not understand ntmode value '{}'\n",
|
||||
configFile, str);
|
||||
}
|
||||
} catch (const wpi::util::json::exception& e) {
|
||||
} catch (const std::logic_error& e) {
|
||||
wpi::util::print(stderr,
|
||||
"config error in '{}': could not read ntmode: {}\n",
|
||||
configFile, e.what());
|
||||
@@ -152,12 +151,12 @@ bool ReadConfig() {
|
||||
|
||||
// cameras
|
||||
try {
|
||||
for (auto&& camera : j.at("cameras")) {
|
||||
for (auto&& camera : j->at("cameras").get_array()) {
|
||||
if (!ReadCameraConfig(camera)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} catch (const wpi::util::json::exception& e) {
|
||||
} catch (const std::logic_error& e) {
|
||||
wpi::util::print(stderr,
|
||||
"config error in '{}': could not read cameras: {}\n",
|
||||
configFile, e.what());
|
||||
|
||||
@@ -483,15 +483,15 @@ public final class CameraServer {
|
||||
/** Provide string description of pixel format. */
|
||||
private static String pixelFormatToString(PixelFormat pixelFormat) {
|
||||
return switch (pixelFormat) {
|
||||
case kMJPEG -> "MJPEG";
|
||||
case kYUYV -> "YUYV";
|
||||
case kRGB565 -> "RGB565";
|
||||
case kBGR -> "BGR";
|
||||
case kBGRA -> "BGRA";
|
||||
case kGray -> "Gray";
|
||||
case kY16 -> "Y16";
|
||||
case kUYVY -> "UYVY";
|
||||
case kUnknown -> "Unknown";
|
||||
case MJPEG -> "MJPEG";
|
||||
case YUYV -> "YUYV";
|
||||
case RGB565 -> "RGB565";
|
||||
case BGR -> "BGR";
|
||||
case BGRA -> "BGRA";
|
||||
case GRAY -> "Gray";
|
||||
case Y16 -> "Y16";
|
||||
case UYVY -> "UYVY";
|
||||
case UNKNOWN -> "Unknown";
|
||||
};
|
||||
}
|
||||
|
||||
@@ -610,7 +610,7 @@ public final class CameraServer {
|
||||
*/
|
||||
public static MjpegServer addSwitchedCamera(String name) {
|
||||
// create a dummy CvSource
|
||||
CvSource source = new CvSource(name, PixelFormat.kMJPEG, 160, 120, 30);
|
||||
CvSource source = new CvSource(name, PixelFormat.MJPEG, 160, 120, 30);
|
||||
MjpegServer server = startAutomaticCapture(source);
|
||||
synchronized (CameraServer.class) {
|
||||
m_fixedSources.put(server.getHandle(), source.getHandle());
|
||||
@@ -725,7 +725,7 @@ public final class CameraServer {
|
||||
* @return OpenCV source for the MJPEG stream
|
||||
*/
|
||||
public static CvSource putVideo(String name, int width, int height) {
|
||||
CvSource source = new CvSource(name, PixelFormat.kMJPEG, width, height, 30);
|
||||
CvSource source = new CvSource(name, PixelFormat.MJPEG, width, height, 30);
|
||||
startAutomaticCapture(source);
|
||||
return source;
|
||||
}
|
||||
|
||||
@@ -186,7 +186,7 @@ std::vector<std::string> Instance::GetSourceStreamValues(CS_Source source) {
|
||||
value = "mjpg:" + value;
|
||||
}
|
||||
|
||||
#ifdef __FRC_SYSTEMCORE__
|
||||
#ifdef __FIRST_SYSTEMCORE__
|
||||
// Look to see if we have a passthrough server for this source
|
||||
// Only do this on the systemcore
|
||||
for (const auto& i : m_sinks) {
|
||||
@@ -251,15 +251,15 @@ void Instance::UpdateStreamValues() {
|
||||
|
||||
static std::string PixelFormatToString(wpi::util::PixelFormat pixelFormat) {
|
||||
switch (pixelFormat) {
|
||||
case wpi::util::PixelFormat::kMJPEG:
|
||||
case wpi::util::PixelFormat::MJPEG:
|
||||
return "MJPEG";
|
||||
case wpi::util::PixelFormat::kYUYV:
|
||||
case wpi::util::PixelFormat::YUYV:
|
||||
return "YUYV";
|
||||
case wpi::util::PixelFormat::kRGB565:
|
||||
case wpi::util::PixelFormat::RGB565:
|
||||
return "RGB565";
|
||||
case wpi::util::PixelFormat::kBGR:
|
||||
case wpi::util::PixelFormat::BGR:
|
||||
return "BGR";
|
||||
case wpi::util::PixelFormat::kGray:
|
||||
case wpi::util::PixelFormat::GRAY:
|
||||
return "Gray";
|
||||
default:
|
||||
return "Unknown";
|
||||
@@ -508,7 +508,7 @@ cs::UsbCamera CameraServer::StartAutomaticCapture(std::string_view name,
|
||||
cs::MjpegServer CameraServer::AddSwitchedCamera(std::string_view name) {
|
||||
auto& inst = ::GetInstance();
|
||||
// create a dummy CvSource
|
||||
cs::CvSource source{name, wpi::util::PixelFormat::kMJPEG, 160, 120, 30};
|
||||
cs::CvSource source{name, wpi::util::PixelFormat::MJPEG, 160, 120, 30};
|
||||
cs::MjpegServer server = StartAutomaticCapture(source);
|
||||
inst.m_fixedSources[server.GetHandle()] = source.GetHandle();
|
||||
|
||||
@@ -632,7 +632,7 @@ cs::CvSink CameraServer::GetVideo(std::string_view name,
|
||||
cs::CvSource CameraServer::PutVideo(std::string_view name, int width,
|
||||
int height) {
|
||||
::GetInstance();
|
||||
cs::CvSource source{name, wpi::util::PixelFormat::kMJPEG, width, height, 30};
|
||||
cs::CvSource source{name, wpi::util::PixelFormat::MJPEG, width, height, 30};
|
||||
StartAutomaticCapture(source);
|
||||
return source;
|
||||
}
|
||||
|
||||
@@ -24,8 +24,7 @@ macro(add_doxygen_docs)
|
||||
set(DOXYGEN_WARN_AS_ERROR "FAIL_ON_WARNINGS_PRINT")
|
||||
list(FILTER dirs EXCLUDE REGEX fmt|memory|units)
|
||||
list(
|
||||
APPEND
|
||||
DOXYGEN_EXCLUDE_PATTERNS
|
||||
APPEND DOXYGEN_EXCLUDE_PATTERNS
|
||||
# apriltag
|
||||
"apriltag_pose.h"
|
||||
# llvm
|
||||
|
||||
@@ -13,3 +13,23 @@ macro(wpilib_add_test name srcdir)
|
||||
endif()
|
||||
add_test(NAME ${name} COMMAND ${name}_test)
|
||||
endmacro()
|
||||
|
||||
macro(wpilib_add_test_catch2 name)
|
||||
set(wpilib_catch2_test_src)
|
||||
foreach(src ${ARGN})
|
||||
if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${src}")
|
||||
file(GLOB_RECURSE wpilib_catch2_dir_src ${src}/*.cpp)
|
||||
list(APPEND wpilib_catch2_test_src ${wpilib_catch2_dir_src})
|
||||
else()
|
||||
list(APPEND wpilib_catch2_test_src ${src})
|
||||
endif()
|
||||
endforeach()
|
||||
add_executable(${name}_test ${wpilib_catch2_test_src})
|
||||
set_property(TARGET ${name}_test PROPERTY FOLDER "tests")
|
||||
wpilib_target_warnings(${name}_test)
|
||||
target_link_libraries(${name}_test catch2)
|
||||
catch_discover_tests(${name}_test)
|
||||
if(MSVC)
|
||||
target_compile_options(${name}_test PRIVATE /wd4101 /wd4251 /utf-8)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
@@ -63,5 +63,6 @@ macro(wpilib_target_warnings target)
|
||||
AND ${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU"
|
||||
)
|
||||
target_compile_options(${target} PRIVATE -gz=zlib)
|
||||
target_link_options(${target} PRIVATE -gz=zlib)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
macro(add_source_jar target)
|
||||
set(oneValueArgs OUTPUT_NAME OUTPUT_DIR)
|
||||
cmake_parse_arguments(SOURCE_JAR "" "${oneValueArgs}" "BASE_DIRECTORIES" ${ARGN})
|
||||
foreach(base_package_dir ${SOURCE_JAR_BASE_DIRECTORIES})
|
||||
file(GLOB_RECURSE directories LIST_DIRECTORIES true ${base_package_dir}/*.directoriesonly)
|
||||
# Find all packages
|
||||
foreach(directory ${directories})
|
||||
cmake_path(
|
||||
RELATIVE_PATH
|
||||
directory
|
||||
BASE_DIRECTORY ${base_package_dir}
|
||||
OUTPUT_VARIABLE package_name
|
||||
)
|
||||
file(GLOB package_sources ${directory}/*.java)
|
||||
if(package_sources STREQUAL "")
|
||||
continue()
|
||||
endif()
|
||||
# If package sources are scattered across different places, consolidate them under one package
|
||||
list(FIND packages ${package_name} index)
|
||||
if(index EQUAL -1)
|
||||
list(APPEND packages ${package_name})
|
||||
endif()
|
||||
list(APPEND ${package_name} ${package_sources})
|
||||
endforeach()
|
||||
endforeach()
|
||||
set(resources "")
|
||||
foreach(package ${packages})
|
||||
string(APPEND resources "NAMESPACE \"${package}\" ${${package}} ")
|
||||
endforeach()
|
||||
cmake_language(
|
||||
EVAL CODE
|
||||
"add_jar(${target} RESOURCES ${resources} OUTPUT_NAME ${SOURCE_JAR_OUTPUT_NAME} OUTPUT_DIR ${SOURCE_JAR_OUTPUT_DIR})"
|
||||
)
|
||||
endmacro()
|
||||
@@ -8,8 +8,7 @@ string(REGEX REPLACE "[^a-zA-Z0-9]" "_" funcName "${inputBase}")
|
||||
set(funcName "GetResource_${funcName}")
|
||||
|
||||
file(
|
||||
WRITE
|
||||
"${output}"
|
||||
WRITE "${output}"
|
||||
"#include <stddef.h>\n#include <string_view>\nextern \"C\" {\nstatic const unsigned char contents[] = {"
|
||||
)
|
||||
|
||||
@@ -17,8 +16,7 @@ string(REGEX MATCHALL ".." outputData "${fileHex}")
|
||||
string(REGEX REPLACE ";" ", 0x" outputData "${outputData}")
|
||||
file(APPEND "${output}" " 0x${outputData} };\n")
|
||||
file(
|
||||
APPEND
|
||||
"${output}"
|
||||
APPEND "${output}"
|
||||
"const unsigned char* ${prefix}${funcName}(size_t* len) {\n *len = ${fileSize};\n return contents;\n}\n}\n"
|
||||
)
|
||||
|
||||
@@ -26,8 +24,7 @@ if(NOT namespace STREQUAL "")
|
||||
file(APPEND "${output}" "namespace ${namespace} {\n")
|
||||
endif()
|
||||
file(
|
||||
APPEND
|
||||
"${output}"
|
||||
APPEND "${output}"
|
||||
"std::string_view ${funcName}() {\n return std::string_view(reinterpret_cast<const char*>(contents), ${fileSize});\n}\n"
|
||||
)
|
||||
if(NOT namespace STREQUAL "")
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user