From 6ca05a6fa3b2069a579abd3bc3898515acb00a8c Mon Sep 17 00:00:00 2001 From: Mara Broda Date: Sun, 3 May 2026 16:30:39 +0200 Subject: [PATCH 1/3] add homebrew formula --- Formula/libdave.rb | 75 ++++++++++++++++++++++++++++++++ README.md | 5 ++- cpp/CMakeLists.txt | 54 +++++++++++++++++++---- cpp/README.md | 24 +++++++++- cpp/cmake/libdaveConfig.cmake.in | 10 +++++ 5 files changed, 157 insertions(+), 11 deletions(-) create mode 100644 Formula/libdave.rb create mode 100644 cpp/cmake/libdaveConfig.cmake.in diff --git a/Formula/libdave.rb b/Formula/libdave.rb new file mode 100644 index 0000000..d0b9e3e --- /dev/null +++ b/Formula/libdave.rb @@ -0,0 +1,75 @@ +class Libdave < Formula + desc "Discord's DAVE library for end-to-end encryption" + homepage "https://github.com/discord/libdave" + url "https://github.com/discord/libdave/archive/refs/tags/v1.1.1/cpp.tar.gz" + sha256 "23827d585a2020e1bfc01f0b999d6db63de6033be38ff43b6e4e3b4067139325" + license "MIT" + version "1.1.1" + head "https://github.com/discord/libdave.git", branch: "main" + + depends_on "cmake" => :build + depends_on "nlohmann-json" + depends_on "openssl@3" + + resource "mlspp" do + url "https://github.com/cisco/mlspp/archive/1cc50a124a3bc4e143a787ec934280dc70c1034d.tar.gz" + sha256 "7a9d6318627e548903bc65c3dc5a4de4a90290983efea9a49af8561ed3f999f5" + end + + def install + prefix_path = [ + Formula["nlohmann-json"].opt_prefix, + Formula["openssl@3"].opt_prefix, + prefix, + ].join(";") + + resource("mlspp").stage do + system "cmake", "-S", ".", "-B", "build", + *std_cmake_args, + "-DBUILD_SHARED_LIBS=ON", + "-DTESTING=OFF", + "-DDISABLE_GREASE=ON", + "-DMLS_CXX_NAMESPACE=mlspp", + "-DCMAKE_PREFIX_PATH=#{prefix_path}", + "-DOPENSSL_ROOT_DIR=#{Formula["openssl@3"].opt_prefix}" + system "cmake", "--build", "build" + system "cmake", "--install", "build" + end + + system "cmake", "-S", "cpp", "-B", "build", + *std_cmake_args, + "-DBUILD_SHARED_LIBS=ON", + "-DTESTING=OFF", + "-DPERSISTENT_KEYS=OFF", + "-DCMAKE_PREFIX_PATH=#{prefix_path}", + "-DOPENSSL_ROOT_DIR=#{Formula["openssl@3"].opt_prefix}" + system "cmake", "--build", "build" + system "cmake", "--install", "build" + end + + test do + (testpath/"CMakeLists.txt").write <<~CMAKE + cmake_minimum_required(VERSION 3.20) + project(libdave_smoke LANGUAGES CXX) + + find_package(libdave CONFIG REQUIRED) + + add_executable(libdave_smoke main.cpp) + target_link_libraries(libdave_smoke PRIVATE libdave::libdave) + CMAKE + + (testpath/"main.cpp").write <<~CPP + #include + + int main() { + return discord::dave::MaxSupportedProtocolVersion() > 0 ? 0 : 1; + } + CPP + + system "cmake", "-S", ".", "-B", "build", + "-DCMAKE_BUILD_TYPE=Release", + "-DCMAKE_PREFIX_PATH=#{opt_prefix};#{Formula["openssl@3"].opt_prefix}" + system "cmake", "--build", "build" + system "./build/libdave_smoke" + end +end diff --git a/README.md b/README.md index ead1a20..7af8b31 100644 --- a/README.md +++ b/README.md @@ -4,4 +4,7 @@ This repository contains the JS and C++ libraries which together implement Disco The DAVE protocol is described in detail in the [protocol whitepaper](https://github.com/discord/dave-protocol). -See the [cpp README](/cpp/README.md) or the [js README](/js/README.md) for information specific to each library. \ No newline at end of file +The C++ library can be installed on macOS with Homebrew via this repository's +tap; see the [cpp README](/cpp/README.md) for the tap and install commands. + +See the [cpp README](/cpp/README.md) or the [js README](/js/README.md) for information specific to each library. diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 52058b1..d068f6e 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.20) project( libdave - VERSION 1.0 + VERSION 1.1.1 LANGUAGES CXX C ) @@ -14,7 +14,8 @@ option(ENABLE_SANITIZERS "Enable address and undefined behavior sanitizers" OFF) option(INSTALL_VCPKG_LICENSES "Installs license files from vcpkg deps which require it" OFF) include(CheckCXXCompilerFlag) -include(CMakeFindDependencyMacro) +include(CMakePackageConfigHelpers) +include(GNUInstallDirs) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) @@ -102,9 +103,10 @@ else() endif() find_package(nlohmann_json REQUIRED) -find_dependency(MLSPP REQUIRED) +find_package(MLSPP REQUIRED) set(CMAKE_STATIC_LIBRARY_PREFIX "") +set(LIBDAVE_INSTALL_CMAKEDIR "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}") SET(LIB_NAME ${PROJECT_NAME}) file(GLOB_RECURSE LIB_HEADERS CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/*.h" "${CMAKE_CURRENT_SOURCE_DIR}/includes/*.h") @@ -187,13 +189,13 @@ target_include_directories( ${LIB_NAME} PUBLIC $ - $ + $ PRIVATE $ ) -target_link_libraries(${LIB_NAME} PRIVATE OpenSSL::Crypto) -target_link_libraries(${LIB_NAME} PRIVATE MLSPP::mlspp) +target_link_libraries(${LIB_NAME} PUBLIC OpenSSL::Crypto) +target_link_libraries(${LIB_NAME} PUBLIC MLSPP::mlspp) if (APPLE AND PERSISTENT_KEYS) target_link_libraries(${LIB_NAME} PUBLIC "-framework CoreFoundation" "-framework Security") @@ -201,8 +203,42 @@ endif() set(CMAKE_SKIP_INSTALL_ALL_DEPENDENCY ON) -install(TARGETS ${LIB_NAME} INCLUDES DESTINATION "include") -install(DIRECTORY ${PROJECT_SOURCE_DIR}/includes/ DESTINATION "include") +configure_package_config_file( + ${CMAKE_CURRENT_SOURCE_DIR}/cmake/libdaveConfig.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/libdaveConfig.cmake + INSTALL_DESTINATION ${LIBDAVE_INSTALL_CMAKEDIR} +) + +write_basic_package_version_file( + ${CMAKE_CURRENT_BINARY_DIR}/libdaveConfigVersion.cmake + VERSION ${PROJECT_VERSION} + COMPATIBILITY SameMajorVersion +) + +install( + TARGETS ${LIB_NAME} + EXPORT libdave-targets + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} +) + +install( + EXPORT libdave-targets + NAMESPACE libdave:: + FILE libdaveTargets.cmake + DESTINATION ${LIBDAVE_INSTALL_CMAKEDIR} +) + +install( + FILES + ${CMAKE_CURRENT_BINARY_DIR}/libdaveConfig.cmake + ${CMAKE_CURRENT_BINARY_DIR}/libdaveConfigVersion.cmake + DESTINATION ${LIBDAVE_INSTALL_CMAKEDIR} +) + +install(DIRECTORY ${PROJECT_SOURCE_DIR}/includes/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) if (INSTALL_VCPKG_LICENSES) set(DEPS_NEEDING_LICENSE mlspp nlohmann-json) @@ -222,4 +258,4 @@ if (INSTALL_VCPKG_LICENSES) endforeach() endif() -install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/../LICENSE DESTINATION "licenses" RENAME ${LIB_NAME}) \ No newline at end of file +install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/../LICENSE DESTINATION "licenses" RENAME ${LIB_NAME}) diff --git a/cpp/README.md b/cpp/README.md index e38673b..75d9daf 100644 --- a/cpp/README.md +++ b/cpp/README.md @@ -40,6 +40,28 @@ make cclean make shared ``` +### Homebrew (macOS) + +Homebrew requires formulae to be installed from a tap. Because this repository +is named `discord/libdave` rather than `discord/homebrew-libdave`, tap it with +an explicit URL first: +``` +brew tap discord/libdave https://github.com/discord/libdave +brew install --build-from-source discord/libdave/libdave +``` + +To install the latest repository head instead of the latest tagged release referenced by the formula, run: +``` +brew tap discord/libdave https://github.com/discord/libdave +brew install --build-from-source --HEAD discord/libdave/libdave +``` + +The Homebrew install exports a CMake package, so downstream projects can consume libdave with: +``` +find_package(libdave CONFIG REQUIRED) +target_link_libraries(your_target PRIVATE libdave::libdave) +``` + ### SSL -By default the library builds with OpenSSL 3, however you can modify `VCPKG_MANIFEST_DIR` in the [Makefile](Makefile) to build with OpenSSL 1.1 or BoringSSL instead. \ No newline at end of file +By default the library builds with OpenSSL 3, however you can modify `VCPKG_MANIFEST_DIR` in the [Makefile](Makefile) to build with OpenSSL 1.1 or BoringSSL instead. diff --git a/cpp/cmake/libdaveConfig.cmake.in b/cpp/cmake/libdaveConfig.cmake.in new file mode 100644 index 0000000..1ecb9c0 --- /dev/null +++ b/cpp/cmake/libdaveConfig.cmake.in @@ -0,0 +1,10 @@ +@PACKAGE_INIT@ + +include(CMakeFindDependencyMacro) + +find_dependency(OpenSSL REQUIRED) +find_dependency(MLSPP REQUIRED) + +include("${CMAKE_CURRENT_LIST_DIR}/libdaveTargets.cmake") + +check_required_components(libdave) From 7e7f44e149d33f4eedc325a3c8197fca2618ce1f Mon Sep 17 00:00:00 2001 From: Mara Broda Date: Sun, 3 May 2026 16:43:09 +0200 Subject: [PATCH 2/3] rewrite rpath --- Formula/libdave.rb | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/Formula/libdave.rb b/Formula/libdave.rb index d0b9e3e..d799778 100644 --- a/Formula/libdave.rb +++ b/Formula/libdave.rb @@ -16,6 +16,27 @@ class Libdave < Formula sha256 "7a9d6318627e548903bc65c3dc5a4de4a90290983efea9a49af8561ed3f999f5" end + def rewrite_local_dylib_linkage! + dylibs = Dir[lib/"*.dylib"].sort + dylib_names = dylibs.map { |path| File.basename(path) } + + dylibs.each do |dylib| + system "install_name_tool", "-id", (opt_lib/File.basename(dylib)).to_s, dylib + end + + dylibs.each do |dylib| + Utils.safe_popen_read("otool", "-L", dylib).lines.drop(1).each do |line| + dependency = line.strip.split.first + next unless dependency&.start_with?("@rpath/") + + dependency_name = dependency.delete_prefix("@rpath/") + next unless dylib_names.include?(dependency_name) + + system "install_name_tool", "-change", dependency, (opt_lib/dependency_name).to_s, dylib + end + end + end + def install prefix_path = [ Formula["nlohmann-json"].opt_prefix, @@ -45,9 +66,15 @@ def install "-DOPENSSL_ROOT_DIR=#{Formula["openssl@3"].opt_prefix}" system "cmake", "--build", "build" system "cmake", "--install", "build" + + rewrite_local_dylib_linkage! end test do + if OS.mac? + system "/usr/bin/ruby", "-e", "require 'fiddle'; Fiddle.dlopen(ARGV.fetch(0))", lib/"libdave.dylib" + end + (testpath/"CMakeLists.txt").write <<~CMAKE cmake_minimum_required(VERSION 3.20) project(libdave_smoke LANGUAGES CXX) From 3078e95b18e18d4a0acd1d88fbdfd9b808ea72ff Mon Sep 17 00:00:00 2001 From: Mara Broda Date: Sun, 3 May 2026 16:48:24 +0200 Subject: [PATCH 3/3] revision 1 --- Formula/libdave.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Formula/libdave.rb b/Formula/libdave.rb index d799778..cc97d1a 100644 --- a/Formula/libdave.rb +++ b/Formula/libdave.rb @@ -5,6 +5,7 @@ class Libdave < Formula sha256 "23827d585a2020e1bfc01f0b999d6db63de6033be38ff43b6e4e3b4067139325" license "MIT" version "1.1.1" + revision 1 head "https://github.com/discord/libdave.git", branch: "main" depends_on "cmake" => :build @@ -37,6 +38,10 @@ def rewrite_local_dylib_linkage! end end + def post_install + rewrite_local_dylib_linkage! if OS.mac? + end + def install prefix_path = [ Formula["nlohmann-json"].opt_prefix, @@ -67,7 +72,7 @@ def install system "cmake", "--build", "build" system "cmake", "--install", "build" - rewrite_local_dylib_linkage! + rewrite_local_dylib_linkage! if OS.mac? end test do