Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 2 additions & 6 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -151,18 +151,14 @@ use_repo(
#
"pybind11",
#
# TODO(jwnimmer-tri) Move this to be internal (+ deprecation). However, it
# has bzlmod support so the rework will be a bit nuanced and attacked as a
# dedicated commit.
# Deprecated 2026-02-01.
#
"lcm",
)

# Load Java dependencies.

# TODO(jwnimmer-tri) This is no longer used by Drake, but is kept around for
# backwards compatibility for the to-be-deprecated `@lcm` external. It will be
# deprecated for removal along with the entire @lcm repository soon enough.
# TODO(jwnimmer-tri) Remove this during @lcm deprecation removal on 2026-02-01.
maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven")
maven.install(
name = "lcm_maven",
Expand Down
8 changes: 3 additions & 5 deletions tools/workspace/lcm/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,17 @@ load(
"drake_py_unittest",
)

# TODO(jwnimmer-tri) These tests are no longer relevant for Drake, but are kept
# around as regression coverage of our `package.BUILD.bazel` file. This file
# (and its tests) will be removed when the `@lcm` deprecation is removed.
# Remove everything here on 2026-02-01 along with LCM deprecation.

drake_py_test(
name = "import_lcm_test",
allow_import_unittest = True,
deps = ["@lcm//:lcm-python"],
deps = ["@lcm//:lcm-python_non_deprecated"],
)

drake_py_unittest(
name = "no_lcm_warnings_test",
deps = ["@lcm//:lcm-python"],
deps = ["@lcm//:lcm-python_non_deprecated"],
)

add_lint_tests()
6 changes: 6 additions & 0 deletions tools/workspace/lcm/example/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ load(
"lcm_py_library",
)

# Remove everything here on 2026-02-01 along with LCM deprecation.
# This directory is a regression test for that deprecated external.

package(default_visibility = ["//visibility:private"])

_LCM_PACKAGE = "package1.package2"
Expand All @@ -23,6 +26,7 @@ lcm_cc_library(
aggregate_hdr = "package1/package2/package2.hpp",
lcm_package = _LCM_PACKAGE,
lcm_srcs = _LCM_SRCS,
macro_deprecation = None,
# Disable Drake's add_lint_tests() for this library.
# This line would not typically be required for non-Drake projects.
tags = ["nolint"],
Expand All @@ -32,6 +36,7 @@ lcm_java_library(
name = "java_lib",
lcm_package = _LCM_PACKAGE,
lcm_srcs = _LCM_SRCS,
macro_deprecation = None,
# Disable Drake's add_lint_tests() for this library.
# This line would not typically be required for non-Drake projects.
tags = ["nolint"],
Expand All @@ -41,6 +46,7 @@ lcm_py_library(
name = "py_lib",
lcm_package = _LCM_PACKAGE,
lcm_srcs = _LCM_SRCS,
macro_deprecation = None,
# Disable Drake's add_lint_tests() for this library.
# This line would not typically be required for non-Drake projects.
tags = ["nolint"],
Expand Down
33 changes: 31 additions & 2 deletions tools/workspace/lcm/lcm.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,8 @@ _lcm_library_gen = rule(
implementation = _lcmgen_impl,
)

MACRO_DEPRECATION = "DRAKE DEPRECATED: The starlark macros at `@drake//tools/workspace/lcm:lcm.bzl` are deprecated for removal. Instead, you should add LCM to your project's MODULE.bazel file as a bazel module and then use LCM's upstream Bazel support at `@lcm//lcm-bazel:*.bzl`. The deprecated code will be removed from Drake on or after 2026-01-01." # noqa

def lcm_cc_library(
name,
lcm_srcs = [],
Expand All @@ -147,6 +149,7 @@ def lcm_cc_library(
deprecation = None,
aggregate_hdr = None,
aggregate_hdr_strip_prefix = ["**/include/"],
macro_deprecation = MACRO_DEPRECATION,
_use_new_lcm_gen = False,
**kwargs):
"""Declares a cc_library on message classes generated from `*.lcm` files.
Expand Down Expand Up @@ -176,6 +179,8 @@ def lcm_cc_library(
fail("lcm_srcs is required")
if not lcm_package:
fail("lcm_package is required")
if macro_deprecation != None:
print(macro_deprecation)

helper_tags = []
for sticky_tag in ["manual", "nolint"]:
Expand All @@ -201,11 +206,15 @@ def lcm_cc_library(
tags = helper_tags,
)
else:
lcmgen = None
if macro_deprecation == None:
lcmgen = "@lcm//:lcm-gen_non_deprecated"
_lcm_library_gen(
name = name + "_lcm_library_gen",
language = "cc",
lcm_srcs = lcm_srcs,
lcm_package = lcm_package,
lcmgen = lcmgen,
outs = outs,
deprecation = deprecation,
tags = helper_tags,
Expand All @@ -226,7 +235,10 @@ def lcm_cc_library(
deps = kwargs.pop("deps", [])
if not _use_new_lcm_gen:
if "@lcm//:lcm_coretypes" not in deps:
deps = deps + ["@lcm//:lcm_coretypes"]
if macro_deprecation == None:
deps = deps + ["@lcm//:lcm_coretypes_non_deprecated"]
else:
deps = deps + ["@lcm//:lcm_coretypes"]

includes = kwargs.pop("includes", [])
if "." not in includes:
Expand All @@ -252,6 +264,7 @@ def lcm_py_library(
lcm_structs = [],
add_current_package_to_imports = True,
extra_srcs = [],
macro_deprecation = MACRO_DEPRECATION,
**kwargs):
"""Declares a py_library on message classes generated from `*.lcm` files.

Expand All @@ -275,13 +288,19 @@ def lcm_py_library(
fail("lcm_srcs is required")
if not lcm_package:
fail("lcm_package is required")
if macro_deprecation != None:
print(macro_deprecation)

outs = _lcm_outs(lcm_srcs, lcm_package, lcm_structs, ".py")
lcmgen = None
if macro_deprecation == None:
lcmgen = "@lcm//:lcm-gen_non_deprecated"
_lcm_library_gen(
name = name + "_lcm_library_gen",
language = "py",
lcm_srcs = lcm_srcs,
lcm_package = lcm_package,
lcmgen = lcmgen,
outs = outs,
)

Expand All @@ -300,6 +319,7 @@ def lcm_java_library(
lcm_srcs = [],
lcm_package = None,
lcm_structs = [],
macro_deprecation = MACRO_DEPRECATION,
**kwargs):
"""Declares a java_library on message classes generated from `*.lcm` files.

Expand All @@ -311,19 +331,28 @@ def lcm_java_library(
fail("lcm_srcs is required")
if not lcm_package:
fail("lcm_package is required")
if macro_deprecation != None:
print(macro_deprecation)

outs = _lcm_outs(lcm_srcs, lcm_package, lcm_structs, ".java")
lcmgen = None
if macro_deprecation == None:
lcmgen = "@lcm//:lcm-gen_non_deprecated"
_lcm_library_gen(
name = name + "_lcm_library_gen",
language = "java",
lcm_srcs = lcm_srcs,
lcm_package = lcm_package,
lcmgen = lcmgen,
outs = outs,
)

deps = kwargs.pop("deps", [])
if "@lcm//:lcm-java" not in deps:
deps = deps + ["@lcm//:lcm-java"]
if macro_deprecation == None:
deps = deps + ["@lcm//:lcm-java_non_deprecated"]
else:
deps = deps + ["@lcm//:lcm-java"]

java_library(
name = name,
Expand Down
41 changes: 38 additions & 3 deletions tools/workspace/lcm/package.BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,14 @@
load("@drake//tools/skylark:cc.bzl", "cc_binary", "cc_library")
load("@drake//tools/skylark:java.bzl", "java_binary", "java_library")
load("@drake//tools/skylark:py.bzl", "py_library")
load("@drake//tools/skylark:sh.bzl", "sh_binary")
load(
"@drake//tools/workspace:generate_export_header.bzl",
"generate_export_header",
)
load("@drake//tools/workspace:generate_file.bzl", "generate_file")

# TODO(jwnimmer-tri) Nothing in this file is used by Drake anymore, but is kept
# around for backwards compatibility. The @lcm repository will be deprecated for
# removal soon.
# Everything here is deprecated for removal on 2026-02-01.

licenses([
"notice", # BSD-3-Clause
Expand Down Expand Up @@ -62,6 +61,8 @@ LCM_PUBLIC_HEADER_INCLUDES = [
"lcm",
]

DEPRECATION = "DRAKE DEPRECATED: The @lcm module extension from drake_dep_repositories() is deprecated for removal. Upstream LCM now has native bazel support; use the upstream BUILD rules, instead. The deprecated code will be removed from Drake on or after 2026-02-01." # noqa

# We only build a shared-library flavor of liblcm.so, because its LGPL-licensed
# and thus should never be linked statically. Building C++ shared libraries
# in Bazel is not well-supported, but for C code is relatively trivial. This
Expand Down Expand Up @@ -112,6 +113,7 @@ cc_library(
srcs = ["libdrake_lcm.so"],
hdrs = LCM_PUBLIC_HEADERS,
includes = LCM_PUBLIC_HEADER_INCLUDES,
deprecation = DEPRECATION,
)

# This is the header-only library used by generated messages.
Expand All @@ -120,6 +122,7 @@ cc_library(
hdrs = ["lcm/lcm_coretypes.h"],
includes = ["."],
linkstatic = True,
deprecation = DEPRECATION,
)

cc_binary(
Expand All @@ -134,6 +137,7 @@ cc_binary(
":lcm",
"@glib",
],
deprecation = DEPRECATION,
)

cc_binary(
Expand All @@ -143,6 +147,7 @@ cc_binary(
],
copts = LCM_COPTS,
deps = [":lcm"],
deprecation = DEPRECATION,
)

cc_binary(
Expand All @@ -169,6 +174,7 @@ cc_binary(
deps = [
"@glib",
],
deprecation = DEPRECATION,
)

cc_binary(
Expand Down Expand Up @@ -241,6 +247,7 @@ py_library(
srcs = ["gen/lcm/__init__.py"], # Shim, from the genrule above.
imports = ["gen"],
deps = [":lcm-python-upstream"],
deprecation = DEPRECATION,
)

java_library(
Expand All @@ -253,12 +260,14 @@ java_library(
deps = [
"@lcm_maven//:net_sf_jchart2d_jchart2d",
],
deprecation = DEPRECATION,
)

java_binary(
name = "lcm-logplayer-gui",
main_class = "lcm.logging.LogPlayer",
runtime_deps = [":lcm-java"],
deprecation = DEPRECATION,
)

java_binary(
Expand All @@ -272,4 +281,30 @@ java_binary(
runtime_deps = [
":lcm-java",
],
deprecation = DEPRECATION,
)

cc_library(
name = "lcm_coretypes_non_deprecated",
deps = [":lcm_coretypes"],
visibility = ["@drake//tools/workspace/lcm:__subpackages__"],
)

py_library(
name = "lcm-python_non_deprecated",
deps = [":lcm-python"],
visibility = ["@drake//tools/workspace/lcm:__subpackages__"],
)

java_library(
name = "lcm-java_non_deprecated",
srcs = glob(["lcm-java/lcm/**/*.java"]),
javacopts = ["-XepDisableAllChecks"],
deps = ["@lcm_maven//:net_sf_jchart2d_jchart2d"],
visibility = ["@drake//tools/workspace/lcm:__subpackages__"],
)

sh_binary(
name = "lcm-gen_non_deprecated",
srcs = [":lcm-gen"],
)
10 changes: 4 additions & 6 deletions tools/workspace/lcm/repository.bzl
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
load("//tools/workspace:github.bzl", "github_archive")

# Everything here is deprecated for removal on 2026-02-01.

def lcm_repository(
name,
mirrors = None):
github_archive(
name = name,
repository = "lcm-proj/lcm",
upgrade_advice = """
When updating, lcm needs its own pull request separate from the rest of
the monthly upgrades.
""",
# TODO(jwnimmer-tri) At the moment we have both @lcm and @lcm_internal
# repositories. We are working to deprecate @lcm. In the meantime, be
# aware that we have a different pins for each repository.
# repositories, with @lcm being deprecated. Be aware that we have
# different pins for each repository.
commit = "v1.5.1",
sha256 = "40ba0b7fb7c9ad06d05e06b4787d743cf11be30eb4f1a03abf4a92641c5b1203", # noqa
build_file = ":package.BUILD.bazel",
Expand Down
4 changes: 2 additions & 2 deletions tools/workspace/lcm_internal/repository.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ def lcm_internal_repository(
the monthly upgrades.
""",
# TODO(jwnimmer-tri) At the moment we have both @lcm and @lcm_internal
# repositories. We are working to deprecate @lcm. In the meantime, be
# aware that we have a different pins for each repository.
# repositories, with @lcm being deprecated. Be aware that we have
# different pins for each repository.
# TODO(jwnimmer-tri) Once LCM has its next tagged release >v1.5.1, we
# should switch this back to a release tag instead of this hash.
commit = "e4bed2c86fbd6dd2280326801acf71cbd05074be",
Expand Down