Skip to content

std.Build: add support for adding specific global search paths #22552

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

BratishkaErik
Copy link
Contributor

@BratishkaErik BratishkaErik commented Jan 20, 2025

This allows more granularity when adding search paths, complementing
--search-prefix for more specific use-cases.

Multi-arch library layout

On systems with multilib support (e.g. Gentoo with 32-bit and 64-bit
libraries in /usr/lib and /usr/lib64 respectively), using
--search-prefix option can cause incorrect library selected.

For example, if I want to link system libcurl library when building
Zig program for non-native or explicit native-compatible target,
I can try using --search-prefix /usr, which will automatically add:

  • /usr/bin as search path for binaries (fine),
  • /usr/lib as search path for libraries (incorrect),
  • /usr/include as search path for includes (fine),

In my case it will find 32-bit libraries for 64-bit target, causing
linker errors:

$ zig build -Dtarget=x86_64-linux-gnu.2.35 --search-prefix /usr

error: ld.lld: /usr/lib/libcurl.so is incompatible with elf_x86_64

New --search-paths option allows to add search paths explicitly,
using passed ZON file as a specification. You can repeat multiple
times to add many different search paths if needed.

.{
    .binaries = "/usr/bin"
    .libraries = "/usr/lib64",
    .includes = "/usr/include",
}

Other layouts (GCC or Android NDK etc.)

Another use-case is when binaries, libraries and includes are
distributed across different hierarchies. Suppose I want to correctly
find gcc binary and link gccjit library for my project:

.{
    .binaries = "/usr/x86_64-pc-linux-gnu/gcc-bin/14/",
    .libraries = "/usr/lib/gcc/x86_64-pc-linux-gnu/14",
    .includes = "/usr/lib/gcc/x86_64-pc-linux-gnu/14/include/",
}

Or use Android NDK:

.{
    // you can omit fields or set `null` if you don't want to search them.
    // .binaries = null,

    .libraries = "/path_to_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/aarch64-linux-android/35",
    .includes = "/path_to_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include",
}
.{
    .libraries = "/path_to_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/aarch64-linux-android",
}

@BratishkaErik
Copy link
Contributor Author

aarch64-linux-debug failure seems to be a regular error.BrokenPipe, not sure what causes x86_64-windows-release failure, it might be related but then why only 1 test and why debug worked fine

@alexrp
Copy link
Member

alexrp commented Mar 26, 2025

I like where this is going overall; seems obviously useful to distro maintainers. @andrewrk should probably have a look too though.

This allows more granularity when adding search paths, complementing
`--search-prefix` for more specific use-cases.

## Multi-arch library layout

On systems with multilib support (e.g. Gentoo with 32-bit and 64-bit
libraries in `/usr/lib` and `/usr/lib64` respectively), using
`--search-prefix` option can cause incorrect library selected.

For example, if I want to link system `libcurl` library when building
Zig program for non-native or explicit native-compatible target,
I can try using `--search-prefix /usr`, which will automatically add:
 * `/usr/bin` as search path for binaries (fine),
 * `/usr/lib` as search path for libraries (incorrect),
 * `/usr/include` as search path for includes (fine),

In my case it will find 32-bit libraries for 64-bit target, causing
linker errors:

```console
$ zig build -Dtarget=x86_64-linux-gnu.2.35 --search-prefix /usr

error: ld.lld: /usr/lib/libcurl.so is incompatible with elf_x86_64
```

New `--search-paths` option allows to add search paths explicitly,
using passed ZON file as a specification. You can repeat multiple
times to add many different search paths if needed.

```zig
.{
    .binaries = "/usr/bin"
    .libraries = "/usr/lib64",
    .includes = "/usr/include",
}
```

## Other layouts (GCC or Android NDK etc.)

Another use-case is when binaries, libraries and includes are
distributed across different hierarchies. Suppose I want to correctly
find `gcc` binary and link `gccjit` library for my project:

```zig
.{
    .binaries = "/usr/x86_64-pc-linux-gnu/gcc-bin/14/",
    .libraries = "/usr/lib/gcc/x86_64-pc-linux-gnu/14",
    .includes = "/usr/lib/gcc/x86_64-pc-linux-gnu/14/include/",
}
```

Or use Android NDK:

```zig
.{
    // you can omit fields or set `null` if you don't want to search them.
    // .binaries = null,

    .libraries = "/path_to_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/aarch64-linux-android/35",
    .includes = "/path_to_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include",
}
```

```zig
.{
    .libraries = "/path_to_ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/aarch64-linux-android",
}
```

Signed-off-by: Eric Joldasov <[email protected]>
@BratishkaErik BratishkaErik changed the title std.Build: add search prefix "exact" variant std.Build: add support for adding specific global search paths Mar 26, 2025
Copy link
Member

@alexrp alexrp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, but will let Andrew have a look also.

@alexrp alexrp requested a review from andrewrk March 26, 2025 13:52
includes: ?LazyPath = null,
};

pub fn binaries(self: SearchMethod, b: *std.Build) ?LazyPath {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe LazyPath is not the most suitable choice here? They are used by findProgram in configure phase, and so can't have generated LazyPath.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants