Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save razielanarki/8a407e4f0c66f7d906ab8107ad854453 to your computer and use it in GitHub Desktop.
Save razielanarki/8a407e4f0c66f7d906ab8107ad854453 to your computer and use it in GitHub Desktop.
build .deb of facebook/watchman on ubuntu 24.10 (amd64)

notes:

  • tested on ubuntu 24.10-dev (oricular), probably works on 24.04-LTS (noble) too
  • autogen.sh is modified to include the build steps from:
    • install-system-packages.sh (now requires user confirmation before installing anything)
    • watchman/build/pacakage/make-deb.sh
  • fixes and uses --no-facebook-internal (thus disables eden fs support)
    (the binary size is reduced from ~11 MB to ~3 MB)
  • uses --scratch-path=built/scratch as the build folder
    (so the build doesn't fail half-way if/when it runs out of free space under /run/user/$UID/tmp)
  • the output folder is moved to built/built
  • changes the version number format from YYYYmmdd.HHmmss.0 to YYYY.mm.dd.00 (like the upstream releases)

usage:

  • clone facebook/watchman
  • apply diff below
  • run autogen.sh
  • the resulting .deb will be in the built/deb folder
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c44906df1..bfd00e799 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -46,7 +46,7 @@ include_directories("${CMAKE_CURRENT_SOURCE_DIR}/external/install/include")
option(ENABLE_EDEN_SUPPORT "If enabled, add support for the Eden \
virtual filesystem. That requires fbthrift."
- ON)
+ OFF)
# Determine whether we are the git repo produced by shipit, a staging
# area produced by shipit in the FB internal CI, or whether
@@ -109,7 +109,7 @@ else()
find_program(GIT git)
if(GIT)
execute_process(
- COMMAND "${GIT}" "show" "-s" "--format=%H;%cd" "--date=format:%Y%m%d.%H%M%S.0"
+ COMMAND "${GIT}" "show" "-s" "--format=%H;%cd" "--date=format:%Y.%m.%d.00"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
RESULT_VARIABLE git_result
OUTPUT_VARIABLE git_data
@@ -155,7 +155,7 @@ file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/watchman/config.h.new" "#pragma once\n")
if(NOT WIN32)
set(WATCHMAN_STATE_DIR "${CMAKE_INSTALL_PREFIX}/var/run/watchman" CACHE STRING
"Run-time path of the persistent state directory")
- set(INSTALL_WATCHMAN_STATE_DIR OFF CACHE BOOL
+ set(INSTALL_WATCHMAN_STATE_DIR ON CACHE BOOL
"Whether WATCHMAN_STATE_DIR should be created by the cmake install
target. Disabling this is useful in the case where the CMAKE_INSTALL_PREFIX
is owned by a non-privileged user but where the WATCHMAN_STATE_DIR requires
@@ -349,12 +349,12 @@ link_directories(${LIBEVENT_LIBDIR})
find_package(edencommon CONFIG REQUIRED)
find_package(fmt CONFIG REQUIRED)
find_package(folly CONFIG REQUIRED)
+find_package(wangle CONFIG REQUIRED)
+find_package(FBThrift CONFIG REQUIRED)
+find_package(fb303 CONFIG REQUIRED)
if (ENABLE_EDEN_SUPPORT)
find_package(fizz CONFIG REQUIRED)
- find_package(wangle CONFIG REQUIRED)
- find_package(FBThrift CONFIG REQUIRED)
- find_package(fb303 CONFIG REQUIRED)
find_package(cpptoml CONFIG REQUIRED)
include_directories(${FB303_INCLUDE_DIR})
endif()
diff --git a/autogen.sh b/autogen.sh
index df6c85d35..57b70f697 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -7,18 +7,99 @@
cd "$(dirname "$0")"
+TOPLEVEL="$(git rev-parse --show-toplevel)"
+OUTDIR="$TOPLEVEL/built"
+SCRATCH="$OUTDIR/scratch"
+
+NPROCESSORS_ONLN="$(which getconf &> /dev/null && getconf _NPROCESSORS_ONLN || echo 4)"
+
+COMMON_ARGS=(
+ --scratch-path="$SCRATCH"
+ --num-jobs="$(( ${NPROCESSORS_ONLN%.*} / 3 + 1 ))"
+ --no-facebook-internal
+ --allow-system-packages
+ --skip-upload
+)
+
+PROJECT="$(basename "$TOPLEVEL")"
+PREFIX="/usr/local"
+
+BUILD_ARGS=(
+ --no-tests
+ --src-dir="$TOPLEVEL"
+ --project-install-prefix="$PROJECT:$PREFIX"
+ "$PROJECT"
+)
+
set -x
-PREFIX=${PREFIX:-/usr/local}
-python3 build/fbcode_builder/getdeps.py build \
- --allow-system-packages \
- --src-dir=. \
- "--project-install-prefix=watchman:$PREFIX" \
- watchman
-python3 build/fbcode_builder/getdeps.py fixup-dyn-deps \
- --allow-system-packages \
- --src-dir=. \
- "--project-install-prefix=watchman:$PREFIX" \
- --final-install-prefix "$PREFIX" \
- watchman built
-
-find built -ls
+
+GETDEPS="$TOPLEVEL/build/fbcode_builder/getdeps.py"
+
+[ "$1" = "list" ] && {
+ $GETDEPS \
+ list-deps \
+ "${COMMON_ARGS[@]}" \
+ "${BUILD_ARGS[@]}"
+ exit
+}
+
+[ "$1" = "clean" ] && {
+ $GETDEPS \
+ clean \
+ "${COMMON_ARGS[@]}"
+ shift
+ (( $# == 0 )) && exit
+}
+
+$GETDEPS \
+ install-system-deps \
+ --recursive \
+ --os-type linux \
+ --distro ubuntu \
+ --distro-version oracular \
+ --interactive \
+ "${COMMON_ARGS[@]}" \
+ "${BUILD_ARGS[@]}"
+
+[ "$1" = "deps" ] && exit
+
+$GETDEPS \
+ build \
+ --build-type MinSizeRel \
+ "${COMMON_ARGS[@]}" \
+ "${BUILD_ARGS[@]}"
+
+[ "$1" = "build" ] && exit
+
+BUILT="$OUTDIR/built"
+
+$GETDEPS \
+ fixup-dyn-deps \
+ --final-install-prefix "$PREFIX" \
+ --strip \
+ "${COMMON_ARGS[@]}" \
+ "${BUILD_ARGS[@]}" \
+ "$BUILT"
+
+[ "$1" = "fixup" ] && exit
+
+# strip "$BUILT/bin/watchman"
+# strip "$BUILT/bin/watchmanctl"
+
+PACKAGE_VERSION=$("$BUILT/bin/watchman" --version)
+UBUNTU_VERSION="${UBUNTU_VERSION:-"$(lsb_release -rs 2>/dev/null)"}"
+
+FAKEROOT="$SCRATCH/deb"
+WORKDIR="$FAKEROOT/.$PREFIX"
+
+mkdir -p "$WORKDIR"
+cp -ar "$BUILT/bin" "$WORKDIR"
+cp -ar "$TOPLEVEL/watchman/build/package/watchman-deb/DEBIAN" "$FAKEROOT"
+
+"$TOPLEVEL/watchman/build/package/substcontrol.py" \
+ "$FAKEROOT/DEBIAN/control" \
+ "$PACKAGE_VERSION" \
+ "$UBUNTU_VERSION"
+
+mkdir -p "$OUTDIR/deb"
+dpkg-deb -b "$FAKEROOT" "$OUTDIR/deb/watchman"_"ubuntu$UBUNTU_VERSION"_"v$PACKAGE_VERSION.deb"
diff --git a/build/fbcode_builder/getdeps.py b/build/fbcode_builder/getdeps.py
index 890d0e74d..f34ac8562 100755
--- a/build/fbcode_builder/getdeps.py
+++ b/build/fbcode_builder/getdeps.py
@@ -345,6 +345,19 @@ class InstallSysDepsCmd(ProjectCmdBase):
default=False,
help="Don't install, just print the commands specs we would run",
)
+ parser.add_argument(
+ "--non-interactive",
+ action="store_true",
+ dest="noninteractive",
+ default=True,
+ help="Do not ask for confirmation before automatically installing packages",
+ )
+ parser.add_argument(
+ "--interactive",
+ action="store_false",
+ dest="noninteractive",
+ help="Ask for confirmation before installing packages",
+ )
parser.add_argument(
"--os-type",
help="Filter to just this OS type to run",
@@ -409,11 +422,13 @@ class InstallSysDepsCmd(ProjectCmdBase):
if manager == "rpm":
packages = sorted(set(all_packages["rpm"]))
if packages:
- cmd_args = ["sudo", "dnf", "install", "-y"] + packages
+ noninteractive = ["-y"] if args.noninteractive else []
+ cmd_args = ["sudo", "dnf", "install"] + noninteractive + packages
elif manager == "deb":
packages = sorted(set(all_packages["deb"]))
if packages:
- cmd_args = ["sudo", "apt", "install", "-y"] + packages
+ noninteractive = ["-y"] if args.noninteractive else []
+ cmd_args = ["sudo", "apt", "install"] + noninteractive + packages
elif manager == "homebrew":
packages = sorted(set(all_packages["homebrew"]))
if packages:
@@ -1318,7 +1333,7 @@ def parse_args():
"--facebook-internal",
help="Setup the build context as an FB internal build",
action="store_true",
- default=None,
+ default=False,
)
add_common_arg(
"--no-facebook-internal",
diff --git a/build/fbcode_builder/manifests/double-conversion b/build/fbcode_builder/manifests/double-conversion
index 2d7265e8d..6359714be 100644
--- a/build/fbcode_builder/manifests/double-conversion
+++ b/build/fbcode_builder/manifests/double-conversion
@@ -9,6 +9,7 @@ sha256 = 95004b65e43fefc6100f337a25da27bb99b9ef8d4071a36a33b5e83eb1f82021
double-conversion
[debs]
+libdouble-conversion3
libdouble-conversion-dev
[rpms]
diff --git a/build/fbcode_builder/manifests/fbthrift b/build/fbcode_builder/manifests/fbthrift
index 3d852d8d1..00b013365 100644
--- a/build/fbcode_builder/manifests/fbthrift
+++ b/build/fbcode_builder/manifests/fbthrift
@@ -16,6 +16,7 @@ fbthrift = thrift/lib/rust
[build]
builder = cmake
job_weight_mib = 2048
+patchfile = fbthrift.patch
[dependencies]
fizz
diff --git a/build/fbcode_builder/manifests/fmt b/build/fbcode_builder/manifests/fmt
index eb79496e3..96963d54d 100644
--- a/build/fbcode_builder/manifests/fmt
+++ b/build/fbcode_builder/manifests/fmt
@@ -5,6 +5,10 @@ name = fmt
url = https://github.com/fmtlib/fmt/archive/refs/tags/9.1.0.tar.gz
sha256 = 5dea48d1fcddc3ec571ce2058e13910a0d4a6bab4cc09a809d8b1dd1c88ae6f2
+[debs]
+libfmt9
+libfmt-dev
+
[build]
builder = cmake
subdir = fmt-9.1.0
diff --git a/build/fbcode_builder/manifests/python-setuptools b/build/fbcode_builder/manifests/python-setuptools
index 7ca2e1e49..5662ed7f6 100644
--- a/build/fbcode_builder/manifests/python-setuptools
+++ b/build/fbcode_builder/manifests/python-setuptools
@@ -5,5 +5,8 @@ name = python-setuptools
url = https://files.pythonhosted.org/packages/c0/7a/3da654f49c95d0cc6e9549a855b5818e66a917e852ec608e77550c8dc08b/setuptools-69.1.1-py3-none-any.whl
sha256 = 02fa291a0471b3a18b2b2481ed902af520c69e8ae0919c13da936542754b4c56
+[debs]
+python3-setuptools
+
[build]
builder = python-wheel
diff --git a/build/fbcode_builder/manifests/python-six b/build/fbcode_builder/manifests/python-six
index a712188dc..ccb32580f 100644
--- a/build/fbcode_builder/manifests/python-six
+++ b/build/fbcode_builder/manifests/python-six
@@ -5,5 +5,8 @@ name = python-six
url = https://files.pythonhosted.org/packages/73/fb/00a976f728d0d1fecfe898238ce23f502a721c0ac0ecfedb80e0d88c64e9/six-1.12.0-py2.py3-none-any.whl
sha256 = 3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c
+[debs]
+python3-six
+
[build]
builder = python-wheel
diff --git a/build/fbcode_builder/patches/fbthrift.patch b/build/fbcode_builder/patches/fbthrift.patch
new file mode 100644
index 000000000..83cfdf8e1
--- /dev/null
+++ b/build/fbcode_builder/patches/fbthrift.patch
@@ -0,0 +1,31 @@
+diff --git a/thrift/compiler/CMakeLists.txt b/thrift/compiler/CMakeLists.txt
+diff --git a/thrift/cmake/FBThriftConfig.cmake.in b/thrift/cmake/FBThriftConfig.cmake.in
+index d3d53d7c14..5969bf1fcc 100644
+--- a/thrift/cmake/FBThriftConfig.cmake.in
++++ b/thrift/cmake/FBThriftConfig.cmake.in
+@@ -55,7 +55,6 @@ if(FBThrift_py_FOUND)
+ endif()
+
+ set(FBThrift_FOUND True)
+-check_required_components(FBThrift)
+
+ if (FBThrift_FOUND AND NOT FBThrift_FIND_QUIETLY)
+ message(STATUS "Found FBThrift: ${FBTHRIFT_PREFIX_DIR}")
+--- a/thrift/compiler/CMakeLists.txt
++++ b/thrift/compiler/CMakeLists.txt
+@@ -73,7 +73,6 @@ add_library(
+ ast/t_structured.cc
+ ast/t_type.cc
+ ast/t_typedef.cc
+- ast/visitor.cc
+ )
+ target_link_libraries(
+ compiler_ast
+@@ -130,6 +129,7 @@ add_library(
+ lib/cpp2/util.cc
+ lib/go/util.cc
+ lib/java/util.cc
++ lib/python/util.cc
+ lib/rust/util.cc
+ )
+ target_link_libraries(
diff --git a/watchman/build/package/watchman-deb/DEBIAN/control b/watchman/build/package/watchman-deb/DEBIAN/control
index eec02613b..3a4364ec6 100644
--- a/watchman/build/package/watchman-deb/DEBIAN/control
+++ b/watchman/build/package/watchman-deb/DEBIAN/control
@@ -1,7 +1,17 @@
Package: watchman
Version: %VERSION%
Architecture: amd64
-Maintainer: Meta Platforms, Inc.
-Standards-Version: 4.6.1.1
-Description: A file watching service
+Maintainer: Raziel Anarki <[email protected]>
Depends: %DEPENDS%
+Suggests: python3-pywatchman
+Section: utils
+Priority: optional
+Homepage: https://facebook.github.io/watchman
+Description: File watching service
+ Watchman can be used to watch files and record when they actually change.
+ It can be used to trigger actions (such as rebuilding assets) when
+ matching files change. If you require to perform an action based on
+ whether a file changes or not, watchman may be the tool you need. By
+ giving watchman a pattern and an action to take when the files change,
+ you can trigger an activity to be taken.
+Original-Maintainer: Meta Platforms, Inc.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment