Index a GCC 13 Static Library with x86_64-linux-gnu-gcc-ranlib
You will build a small object file, put it in a static archive, create the archive's symbol index with x86_64-linux-gnu-gcc-ranlib-13, and verify that a linker can use the result. The command is a GCC 13 wrapper around ranlib: its useful distinction is that it supplies the GCC 13 plugin option for you.
The route
Jump straight to the step you need, or tick off Done means at the end.
This guide applies to the installed Ubuntu toolchain checked here: gcc-13 and gcc-13-x86-64-linux-gnu are version 13.3.0-6ubuntu2~24.04.1. The wrapper invokes the ranlib found through PATH, so the exact version printed by the delegated program can differ from the Debian package version. Allow about five minutes if GCC and binutils are already installed.
Checkpoint: know what the wrapper changes
The four installed manpage names in this toolchain describe the same program. The wrapper accepts ranlib options and archive arguments, then adds an appropriate --plugin option for GCC 13. It does not compile source, create an archive, or install a library. Creating an archive is the job of ar; indexing it is the job of ranlib or the equivalent ar -s.
Check the executable and its delegated version first:
$ command -v x86_64-linux-gnu-gcc-ranlib-13
/usr/bin/x86_64-linux-gnu-gcc-ranlib-13
$ x86_64-linux-gnu-gcc-ranlib-13 --version
GNU ranlib (GNU Binutils) 2.47.20260726
...
Your version text may differ. What matters here is that the command exists and exits successfully. If it is missing, check the installed GCC and cross-toolchain packages before changing PATH.
Step 1: create a test object
Use a temporary directory so the exercise does not alter a project. This command needs no elevated privileges.
$ workdir=$(mktemp -d)
$ cd "$workdir"
$ cat > answer.c <<'EOF'
int answer(void) { return 42; }
EOF
$ x86_64-linux-gnu-gcc-13 -c answer.c -o answer.o
At this checkpoint, answer.o should exist. A compiler error concerns the source or compiler, not ranlib. Confirm the target file before continuing:
$ test -f answer.o && echo "object ready"
object ready
Step 2: make the archive
Create a conventional static library with ar. The r operation replaces or adds members, and c creates the archive without a warning if it is new.
$ x86_64-linux-gnu-ar rcs libanswer.a answer.o
$ x86_64-linux-gnu-ar t libanswer.a
answer.o
If your installation uses a different ar name, inspect the available names with command -v. Do not guess a path in a build script: tool names vary between distributions.
Step 3: write the symbol index
Now run the GCC 13 wrapper against the archive. This changes libanswer.a in place by writing or refreshing its archive index. It does not change answer.o.
$ x86_64-linux-gnu-gcc-ranlib-13 libanswer.a
$ echo $?
0
There is normally no output on success. A non-zero status means the archive could not be read or updated, or that an option was invalid. Keep the original archive or rebuild it if a failed operation matters to your workflow; there is no separate undo command for an in-place index update.
Step 4: verify the index and link
Use nm to print the archive map. The symbol from answer.o should appear, which proves the index names the function that a linker can find.
$ x86_64-linux-gnu-nm -s libanswer.a
Archive index:
answer
answer.o:
0000000000000000 T answer
Output formatting can vary with binutils, but look for an Archive index: section and the answer symbol. If it is absent, rerun the wrapper against the exact archive you are inspecting. A frequent trap is updating one copy and linking another.
Finish with a link test. This creates a second temporary executable and makes the result observable:
$ cat > main.c <<'EOF'
int answer(void);
int main(void) { return answer() == 42 ? 0 : 1; }
EOF
$ x86_64-linux-gnu-gcc-13 main.c -L. -lanswer -o check-answer
$ ./check-answer
$ echo $?
0
The -L. option makes the current temporary directory eligible for library lookup, while -lanswer selects libanswer.a. If the link reports an undefined reference, check the archive name, the library search path and the symbol spelling before blaming the index.
Useful options and boundaries
The wrapper passes ranlib options through. Use --help for the installed usage, --version for the delegated binutils version, and -D for deterministic archive metadata. Deterministic mode makes UID, GID and timestamp fields in the symbol-map member zero, which helps reproducible builds. The local ranlib documentation says it is enabled by default when binutils was configured for deterministic archives; -U requests the opposite.
$ x86_64-linux-gnu-gcc-ranlib-13 --help
$ x86_64-linux-gnu-gcc-ranlib-13 -D libanswer.a
Do not pass a source file and expect compilation, and do not use this command to add or remove archive members. For those operations use the appropriate compiler or ar command. Ordinary archive work does not require sudo; using elevated privileges can leave root-owned build artefacts that your normal account cannot replace.
Common failure checks
- Command not found: confirm the cross compiler tools are installed and inspect
PATH. The aliasesgcc-ranlib,gcc-ranlib-13andx86_64-linux-gnu-gcc-ranlibmay resolve to the same wrapper, but use the versioned triplet name when a build must select GCC 13 explicitly. - No archive index: make sure
arcreated a real archive and that ranlib received the archive path, not the object path. Runx86_64-linux-gnu-ar t libanswer.aand thenx86_64-linux-gnu-nm -s libanswer.a. - Plugin error: inspect
PATHand the GCC installation rather than adding a random--pluginpath. The wrapper exists to supply the appropriate plugin argument for its GCC 13 installation. - Link still fails: confirm that the library is named
libanswer.a, that-Lpoints at its directory, and that the object exports the expected symbol. Runnm answer.oto compare the symbol name.
Done means
x86_64-linux-gnu-gcc-ranlib-13 --versionexits successfully.- The archive contains the intended object member.
nm -sshows the archive index and expected symbol.- A test link and execution return status zero.
When the test is complete, remove the temporary directory with rm -rf -- "$workdir". That deletion is irreversible, so check that workdir still names the temporary directory before running it. In a real project, keep the archive and let the build system regenerate its index when the member set changes.