Есть некий файлик mylib/ldap.c
, в котором есть функция int search(LDAP *ld, const char *id)
. Этот файлик входит в разделяемую библиоту libfoobar.
Задача — изолировать и оттестировать функцию foobar. Однако проблема в том, что эта функция использует как другие функции с библиотеки libfoobar
так и функции с libldap-2.4
.
Библиотека libfoobar
собирается отдельно от тестов (отдельным CMake проектом). Затем тест собирается приблизительно так:
add_executable(search_test search_test.c)
set_target_properties(search_test PROPERTIES
LINK_FLAGS "-Wl,--wrap=internalFunc -Wl,--wrap=ldap_search_s"
)
target_link_libraries(search_test ${FOOBAR_LIBRARIES})
add_test(NAME search_test COMMAND search_test)
search_test.c
:int __wrap_internalFunc(const char *str) {
fprintf(stderr, "## DEBUG: __wrap_internalFunc: %s\n", str);
return __real_internalFunc(str);
}
static void test_search(void **state) {
LDAP *ld = (*(TEST_DATA **) state)->ldap;
int err = search(ld, "something");
assert(err == LDAP_SUCCESS);
}
Проблема состоит в том, что --wrap не срабатывает для внутренних функций, т.е. search()
не дергает __wrap_internalFunc()
, а напрямую лезет к оригинальной internalFunc()
(internalFunc не является static и находится в одном исходном файле с search()). Пробовал собирать libfoobar статически — не помогает.
Помогите пожалуйста понять процесс линковки, и где моя ошибка.
P.S. Собственно, заюзана фича --wrap
из ld. man ld:
--wrap=symbol
Use a wrapper function for symbol. Any undefined reference to symbol will be resolved to «__wrap_ symbol ». Any undefined reference to «__real_ symbol » will be resolved to symbol.
This can be used to provide a wrapper for a system function. The wrapper function should be called «__wrap_ symbol ». If it wishes to call the system function, it should call «__real_ symbol ».Here is a trivial example:
void * __wrap_malloc (size_t c) { printf ("malloc called with %zu\n", c); return __real_malloc (c); }
If you link other code with this file using --wrap malloc, then all calls to «malloc» will call the function «__wrap_malloc» instead. The call to «__real_malloc» in «__wrap_malloc» will call the real «malloc» function.
You may wish to provide a «__real_malloc» function as well, so that links without the --wrap option will succeed. If you do this, you should not put the definition of «__real_malloc» in the same file as «__wrap_malloc»; if you do, the assembler may resolve the call before the linker has a chance to wrap it to «malloc».