Skip to content

Instantly share code, notes, and snippets.

@Un1Gfn
Last active March 2, 2019 13:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Un1Gfn/66c0f31abbd0a5790246839ff8c0871e to your computer and use it in GitHub Desktop.
Save Un1Gfn/66c0f31abbd0a5790246839ff8c0871e to your computer and use it in GitHub Desktop.
GCC: Are directories specified with -I and -L searched before the default or after header/linker search path?

GCC: Are directories specified with -I and -L searched before the default or after header/linker search path?

Create files

zlib.h

int z_foo();

zlib.c

int z_foo(){
  return 16;
}

main.c

#include <zlib.h>
int main(){
  return z_foo();
}

Dynamic(Shared)

Cleanup

rm -fv *.o *.a *.so* *.out

Create shared library in conflict with zlib /usr/lib/libz.so.1.2.11

$ file /usr/lib/*libz.* /usr/include/zlib*
/usr/lib/libz.a:         current ar archive
/usr/lib/libz.so:        symbolic link to libz.so.1.2.11
/usr/lib/libz.so.1:      symbolic link to libz.so.1.2.11
/usr/lib/libz.so.1.2.11: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=5bbdb8b0958891549bb245beab9a1b248d97199a, stripped
/usr/include/zlib.h:     C source, ASCII text
$ gcc -c -fPIC -o zlib.o zlib.c
$ gcc -shared -fPIC -Wl,-soname,libz.so.1 -o libz.so.1.2.11 zlib.o -lc
$ ln -s libz.so.1.2.11 libz.so.1
$ ln -s libz.so.1 libz.so

Reckless attempt

$ gcc main.c -lz
main.c: In function ‘main’:
main.c:3:10: warning: implicit declaration of function ‘z_foo’ [-Wimplicit-function-declaration]
   return z_foo();
          ^~~~~
/usr/bin/ld: /tmp/ccuh5KJN.o: in function `main':
main.c:(.text+0xa): undefined reference to `z_foo'
collect2: error: ld returned 1 exit status

Add current directory to the list of directories to be searched for header files during preprocessing

$ gcc -I. main.c -lz
/usr/bin/ld: /tmp/ccpe6MS5.o: in function `main':
main.c:(.text+0xa): undefined reference to `z_foo'
collect2: error: ld returned 1 exit status

"implicit declaration" warning disappears. This proves that directories specified with -I are searched before the default header search path. ./zlib.h takes precedence over /usr/include/zlib.h.

Add current directory to the list of directories to be searched for -l.

$ gcc -I. -L. main.c -lz
# empty
$ ldd a.out
  linux-vdso.so.1 (0x00007ffdd9b05000)
  libz.so.1 => /usr/lib/libz.so.1 (0x00007f91e95f8000)
  libc.so.6 => /usr/lib/libc.so.6 (0x00007f91e9434000)
  # The following is incorrect
  /lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007f91e9840000)
$ file a.out
a.out: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=ed58aed7bd61329f8dd8347318171c5ae22abf77, not stripped

No errors. This proves that directories specified with -L are searched before the default linker search path. ./libz.so.1.2.11 takes precedence over /usr/lib/libz.so.1.2.11.

Run

$ LD_LIBRARY_PATH="$LD_LIBRARY_PATH":"$(pwd)" ./a.out
$ echo $?
16

Reference:

Static

Cleanup

rm -vf *.o *.a *.so* *.out

Create static library in conflict with zlib /usr/lib/libz.a

$ gcc -c -o zlib.o zlib.c
$ ar rcs libz.a zlib.o # https://en.wikipedia.org/wiki/Static_library#Creating_static_libraries_in_C/C++
$ ar tv libz.a
rw-r--r-- 0/0   1208 Jan  1 08:00 1970 zlib.o

Reckless attempt

$ gcc -static main.c -lz
main.c: In function ‘main’:
main.c:4:10: warning: implicit declaration of function ‘z_foo’ [-Wimplicit-function-declaration]
   return z_foo();
          ^~~~~
/usr/bin/ld: /tmp/ccJqJeHK.o: in function `main':
main.c:(.text+0xa): undefined reference to `z_foo'
collect2: error: ld returned 1 exit status

Add current directory to the list of directories to be searched for header files during preprocessing

$ gcc -static -I. main.c -lz
/usr/bin/ld: /tmp/ccgwDmJ2.o: in function `main':
main.c:(.text+0xa): undefined reference to `z_foo'
collect2: error: ld returned 1 exit status

"implicit declaration" warning disappears. This proves that directories specified with -I are searched before the default header search path. ./zlib.h takes precedence over /usr/include/zlib.h.

Add current directory to the list of directories to be searched for -l.

$ gcc -static -I. -L. main.c -lz
# empty
$ ldd a.out
  not a dynamic executable
$ file a.out
a.out: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 3.2.0, BuildID[sha1]=bd3a624bdfbdbd6d9f6616ee1c5f178d470f1e78, not stripped

No errors. This proves that directories specified with -L are searched before the default linker search path. ./libz.a takes precedence over /usr/lib/libz.a.

Run

$ ./a.out
$ echo $?
16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment