From e91224bfaa043bb85cdfa6394f417e400522ff53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20D=C3=ADaz?= <4808907+akdev1l@users.noreply.github.com> Date: Wed, 2 Jul 2025 08:54:17 -0600 Subject: [PATCH] build: support static build #34728 --- BUILD.md | 23 +++++++++++++++++++++++ src/nvim/CMakeLists.txt | 4 ++++ 2 files changed, 27 insertions(+) diff --git a/BUILD.md b/BUILD.md index 6f808214e1..76ace5315c 100644 --- a/BUILD.md +++ b/BUILD.md @@ -259,6 +259,29 @@ cmake --build build - Using `ninja` is strongly recommended. 4. If treesitter parsers are not bundled, they need to be available in a `parser/` runtime directory (e.g. `/usr/share/nvim/runtime/parser/`). +### How to build static binary (on Linux) + +1. Use a linux distribution which uses musl C. We will use Alpine Linux but any distro with musl should work. (glibc does not support static linking) +2. Run make passing the `STATIC_BUILD` variable: `make CMAKE_EXTRA_FLAGS="-DSTATIC_BUILD=1"` + +In case you are not using Alpine Linux you can use a container to do the build the binary: + +```bash +podman run \ + --rm \ + -it \ + -v "$PWD:/workdir" \ + -w /workdir \ + alpine:latest \ + bash -c 'apk add build-base cmake coreutils curl gettext-tiny-dev && make CMAKE_EXTRA_FLAGS="-DSTATIC_BUILD=1"' +``` + +The resulting binary in `build/bin/nvim` will have all the dependencies statically linked: + +``` +build/bin/nvim: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), statically linked, BuildID[sha1]=b93fa8e678d508ac0a76a2e3da20b119105f1b2d, with debug_info, not stripped +``` + #### Debian 10 (Buster) example: ```sh diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index 11f1cab364..f881679f8d 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -748,7 +748,11 @@ endif() target_sources(nlua0 PUBLIC ${NLUA0_SOURCES}) +if(STATIC_BUILD) + target_link_options(nvim_bin PRIVATE -static-libgcc -static-libstdc++ -static) +endif() target_link_libraries(nvim_bin PRIVATE main_lib PUBLIC libuv) + install_helper(TARGETS nvim_bin) if(MSVC) install(FILES $ DESTINATION ${CMAKE_INSTALL_BINDIR} OPTIONAL)