Build a GCC 13 Static Archive with gcc-ar
You will turn a GCC-compiled object file into a static library, list the archive member, and confirm that the archive has a symbol index. The command is x86_64-linux-gnu-gcc-ar-13, also available through the aliases gcc-ar-13 and gcc-ar.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about ten minutes. You need the GCC 13 compiler, the installed x86_64-linux-gnu-gcc-ar-13 wrapper, a writable working directory, and ordinary shell access. The examples do not need sudo. They create and replace files in the directory you choose, so do not run them in a directory containing an archive you care about.
This machine provides GCC package version 13.3.0-6ubuntu2~24.04.1 and the wrapper invokes GNU ar 2.47.20260726. Package and binutils versions differ across distributions; check yours before relying on diagnostic wording.
1. Check the wrapper before using it
The installed manpage defines gcc-ar as a wrapper around ar that adds the appropriate --plugin option for GCC 13. It accepts ar's options and arguments rather than defining a separate archive format.
$ command -v x86_64-linux-gnu-gcc-ar-13
/usr/bin/x86_64-linux-gnu-gcc-ar-13
$ x86_64-linux-gnu-gcc-ar-13 --version
GNU ar (GNU Binutils) 2.47.20260726
$ dpkg-query -W -f='${Package} ${Version}\n' gcc-13 gcc-13-x86-64-linux-gnu
gcc-13 13.3.0-6ubuntu2~24.04.1
gcc-13-x86-64-linux-gnu 13.3.0-6ubuntu2~24.04.1
Checkpoint: the first command must resolve to the wrapper you intend to use. If it prints a different path, use that path consistently in the remaining commands or fix the toolchain selection before building.
2. Compile a small object file
Make a source file in a clean temporary directory, then compile it without linking. The -c option produces an object file and does not create an executable.
$ workdir=$(mktemp -d)
$ printf '%s\n' 'int answer(void) { return 42; }' > "$workdir/answer.c"
$ x86_64-linux-gnu-gcc-13 -c "$workdir/answer.c" -o "$workdir/answer.o"
$ file "$workdir/answer.o"
/tmp/tmp.ABC123/answer.o: ELF 64-bit LSB relocatable, x86-64, ...
The temporary directory name and the full file description vary. The useful checks are a successful compiler exit status and an object file at the requested path. If x86_64-linux-gnu-gcc-13 is absent, install or select the matching compiler through your normal package process; changing the archive command will not fix a missing compiler.
3. Create the archive with the wrapper
Use ar's r operation to insert or replace a member, c to suppress the warning when creating the archive, and s to create or update the symbol index. The compact form is rcs.
$ x86_64-linux-gnu-gcc-ar-13 rcs "$workdir/libanswer.a" "$workdir/answer.o"
$ test -s "$workdir/libanswer.a" && echo "archive created"
archive created
That command changes the archive named by libanswer.a. The r operation replaces an existing member with the same name, so treat it as an overwrite. If you want to preserve an existing archive, choose a new output path first. Do not add sudo: elevated privileges do not improve the wrapper's plugin handling and can leave root-owned build files behind.
The wrapper supplies the plugin selection that GCC's link-time optimisation workflow may need. For an ordinary non-LTO object, the result is still a normal ar archive. The wrapper does not compile source code, link a program, or make the archive a shared library.
4. Inspect the member and its index
Use the same wrapper for read-only ar operations. The t operation lists archive members, while nm -s prints the archive's symbol table when one is present.
$ x86_64-linux-gnu-gcc-ar-13 t "$workdir/libanswer.a"
answer.o
$ nm -s "$workdir/libanswer.a"
Archive index:
answer
answer.o:
0000000000000000 T answer
Exact addresses and formatting can vary with the toolchain. The checkpoint is that answer.o appears in the table and the index names answer. If the member is present but no index is shown, run the wrapper with the standalone s operation, then inspect again:
$ x86_64-linux-gnu-gcc-ar-13 s "$workdir/libanswer.a"
$ nm -s "$workdir/libanswer.a" | sed -n '1,5p'
The installed ar documentation says that an index speeds linking against the library. It is metadata inside the archive, not a separate file you need to copy.
5. Use the archive in a link test
Compile a caller and link it against the archive with the GCC 13 driver. Put the object before the library on the command line, and use -L and -lanswer to select libanswer.a.
$ printf '%s\n' '#include <stdio.h>' 'int answer(void);' 'int main(void) { printf("%d\n", answer()); }' > "$workdir/main.c"
$ x86_64-linux-gnu-gcc-13 "$workdir/main.c" -L"$workdir" -lanswer -o "$workdir/app"
$ "$workdir/app"
42
If the linker reports an undefined reference, check the archive name, the library search path, and the symbol index. If it reports that the archive cannot be found, inspect the exact path with ls -l "$workdir/libanswer.a". These are ordinary commands and do not require elevated privileges.
6. Clean up without touching other files
Once you have checked the result, remove only the temporary directory created for this exercise:
$ rm -rf -- "$workdir"
$ test ! -e "$workdir" && echo "temporary files removed"
temporary files removed
This deletion is irreversible. If you need the archive or executable, copy them to a deliberate project path before running it. If you accidentally used an existing directory instead of the value from mktemp -d, stop and restore from your project's backup rather than deleting more files.
Common traps
- Using plain
arfor a GCC 13 LTO workflow: the wrapper exists to add the appropriate GCC plugin option. Use the matchinggcc-arwrapper when the build uses GCC's archive tooling. - Confusing an archive with a shared library:
.astores object members for static linking. It is not loaded at runtime like a.so. - Forgetting
s: the member can exist while the symbol index is missing or stale. Create or update it, then verify withnm -s. - Overwriting by accident:
rcsreplaces a same-named member. Use a new archive path when testing changes you may need to undo. - Trusting a successful archive command too much: inspect the member, inspect the index, and perform a small link test. Each checks a different part of the workflow.
Done means
- The GCC 13 wrapper and its package version were checked.
- A relocatable object was compiled without elevated privileges.
libanswer.acontainsanswer.oand has a visible symbol index.- A GCC 13 link test ran and printed
42. - You know that
rcscan replace an existing archive member. - Temporary files were removed only after the output was checked.