Specify target glibc at command line

tl;dr.

“how do I target a glibc version via cmdline.”

Preamble

Hello I’m working towards being able to target an older version of glibc as my company has upgraded from centos7 to rocky9.

Background

So,

I am close to building from source via a build.zig fully for rocky9. (Close enough that I can hand it a couple things I’ve done manually and successfully compile and run.)

So I’d like to try to target the older glibc now. (Specifically 2.17.0 I think).

Unfortunately, one of the manual steps I’m doing is compiling spdlog with zig cc via cmake.

CC="zig cc" CXX="zig c++" cmake -B build_zig

Which will then emit a static lib I can use later. Writing the build.zig for spdlog looked to be a headache so if possible I’d like to avoid fully fleshing that out at present even if I’m going to do it eventually in the long term.

So all that to say how do I target a glibc version via cmdline. It’s likely something to do with -target.

Then I can see if my backwards compilation proof of concept would work.

Thanks in advance,

P.S. Do I need to be recompiling the libraries. It seems like an obvious yes givin my builds won’t run if I don’t recompile spdlog. The usual method would be to compile spdlog with g++ and then link. But if I try to do that with zig (Clang) it gets mad at me. Recompiling with the aforementioned CC=... cmd seems to fix that though.

I think my company is using one of the package installs of spdlog so recompiling spdlog from source may be unnecessary if it’s not required. (It seems like it is.)

The gnu libc version follows the gnu abi:
zig cc -target x86_64-linux-gnu.2.17

To list all the available versions: zig targets | jq -r .glibc[] (2.0-2.38)

3 Likes

Hey dimdin,

I always appreciate the help.

I’ve another question for you.

So I’m playing with zig at work, and my code works and all, but if I want to get people to actually use my thing it needs to be as frictionless as possible.

So here is the new problem. I’m getting the following error.

undefined reference to `thingy::Subscribe(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >,
 std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&, bool)

I assume this is because I’m building a shared library with zig and therefore clang while the rest of my company will be building with g++.

I’ve done a bit of research and a bit of asking chatgpt about the problem.

It sounds like I may need to pass -stdlib=libstdc++ to clang to make sure I’m creating the .so with the same backend std libs. I tried to just toss that into my cpp flags in build.zig but I got the following.

masking service names with -----

install
└─ install -----
   └─ zig build-exe ------- Debug native
      └─ zig build-lib ------ Debug native 4 errors
:1:1: error: argument unused during compilation: '-stdlib=libstdc++'
:1:1: error: argument unused during compilation: '-stdlib=libstdc++'
:1:1: error: argument unused during compilation: '-stdlib=libstdc++'
:1:1: error: argument unused during compilation: '-stdlib=libstdc++'
error: the following command failed with 4 compilation errors:

So I clearly can’t just do that.

Do you know how to pass this argument successfully to clang. I perused the functions attached to my lib in neovim and didn’t see anything obvious.

Oh and to be clear I know for a fact that function is defined.

I don’t know and I cannot find a way to prevent linking to libstdc++
I noticed that -nostdinc++ is accepted as an argument.
An idea is to compile with:

zig c++ -nostdinc++ -I/path/to/libc++/include -o file.o file.cpp

and then link using:

zig ld.lld --nostdlib file.o -L/path/to/libc++/lib -lc++