How can I let GCC check if a shared object library provides definitions to all functions that have been declared in a header file? Given the example below, how can I verify during compilation steps that 'mylib.h' and 'mylib.c' are "compatible" without having an executable that (kind of) tests the library and header in the way that it then really links both?
mylib.h:
#ifndef MYLIB_H
#define MYLIB_H
int test(int);
#endif
mylib.c:
#include "mylib.h"
int test_(int arg) { // Note: The definition here, does not fit the declaration!
return arg * 2;
}
main.c:
#include <stdio.h>
#include "mylib.h"
int main(int argc, char* argv[]) {
printf("%d\n", test(42));
return 0;
}
I would like to have some warnings that the header file can result in undefined references with the shared object file if used by some application (edited wording for clarification), but it's as follows:
gcc -c -fPIC -o mylib.o mylib.c
gcc -shared -Wl,--no-undefined,--no-allow-shlib-undefined -o libmylib.so mylib.o
# no error/warning here!
gcc -L ./ -o main main.o -lmylib
main.o: In function `main':
main.c:(.text+0x15): undefined reference to `test'
collect2: error: ld returned 1 exit status
As shown, I tried to use the correct linker options '-Wl,--no-undefined,--no-allow-shlib-undefined' but it doesn't help, even if use the same options as shown here: Force GCC to notify about undefined references in shared libraries
gcc -fPIC -shared -Wl,-soname,libmylib.so -Wl,--no-undefined -o libmylib.so mylib.c
-This means, I cannot reproduce the answer to the linked question!-
EDIT:
From discussions, I understand that the options like --no-allow-shlib-undefined aim for a different case, i.e., give warnings if a shared object calls/references some other library and references are undefined. Anyways, the aforementioned work-around is to have a little test that warns about undefined references:
test-ref.c:
#include "mylib.h"
int main(int argc, char* argv[]) {
test(0);
}
which, if compiled and linked, gives the desired warning:
gcc -L . -o test-ref-noexec test-ref.c -lmylib
/tmp/ccF4ob56.o: In function `main':
test-ref.c:(.text+0x15): undefined reference to `test'
collect2: error: ld returned 1 exit status
Note: The point is that it's not necessary to execute the binary and, therefore, arguments provided to the function don't matter at all. In that sense, I assume(d) GCC/linker could do this kind of check for a some defined header file or warn about any undefined reference etc.
For the sake of completeness, I use the following setting:
uname -a
Linux ubuntu 4.4.0-96-generic #119-Ubuntu SMP Tue Sep 12 14:59:54 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/5/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 5.4.0-6ubuntu1~16.04.4' --with-bugurl=file:///usr/share/doc/gcc-5/README.Bugs --enable-languages=c,ada,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-5 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-5-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-5-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-5-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.4)