Mocking: Link-time wrap
Example: share/doc/aceunit/examples/hello_world_mocked_link
How it works
Section titled “How it works”Instead of rewriting the object file with objcopy, this approach uses the GNU/LLVM linker’s --wrap feature:
cc hello_test.o hello.o mock_puts.o testcases.o libaceunit-fork.a \ -Wl,--wrap=puts -Wl,--wrap=main-Wl,--wrap=puts makes every call to puts in the linked objects resolve to __wrap_puts instead, while the real puts remains reachable as __real_puts. mock_puts.c defines __wrap_puts() to record calls into a buffer.
-Wl,--wrap=main is used differently: nothing needs to intercept calls to main() here, since nothing calls it as an ordinary function. The wrap simply frees up the main symbol so hello.c’s original main() becomes reachable as __real_main(argc, argv), which the test calls directly:
void test_hello(void) { __real_main(0, NULL); assert_puts("Hello, world!\n");}When to use this
Section titled “When to use this”- You’re on a GNU ld or LLVM lld toolchain (not available on the Darwin/macOS linker — see Darwin interposer instead).
- You’d rather keep object files untouched and push the redirection entirely into link flags.
See also: objcopy override for the object-file-rewriting alternative, or Compile-time macro if you want zero dependency on linker features at all.