static library linking issue using SUSE Linux and C

948 Views Asked by At

I have some very simple C code I was trying to compile to try to understand how static libraries work and also BFDs.

I built the code using this gcc command and it could not find libbfd, and libbfd.a static library is located in both /usr/lib64 and I also copied it locally, and given I specified -L to both those directories to find the static library, it still could not find it:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "bfd.h"

unsigned int number_of_sections(bfd *abfd)
{
  return bfd_count_sections(abfd);
}

int main (int argc, char *argv[])
{
  bfd *ibfd = NULL;
  unsigned int numSections = 0;

  if (argc < 2)
    {
      printf("Argc < 2\n");
      exit(EXIT_FAILURE);
    }
  else
    {
      bfd_init();
      printf("filename = %s\n", argv[1]);
      ibfd = bfd_openr(argv[1], NULL);
      numSections = number_of_sections(ibfd);
      printf("num sections = %d\n", numSections);
    }
  return 1;
}

gcc -g -Wall -llibbfd -I. -I/usr/include -L. -L/usr/lib64 -o getsections ./getsections.c
/usr/lib64/gcc/x86_64-suse-linux/4.7/../../../../x86_64-suse-linux/bin/ld: cannot find -llibbfd
collect2: error: ld returned 1 exit status
make: *** [build] Error 1

I also made sure the path was on the LD_LIBRARY_PATH Linux environment variable:
printenv LD_LIBRARY_PATH
/usr/lib64:/usr/lib64/mpi/gcc/openmpi/lib64

I changed the gcc command slightly (-lbfd instead of -llibbfd) and here was the error:

gcc -g -Wall -lbfd -I. -I/usr/include -L. -L/usr/lib64 -o getsections ./getsections.c
/tmp/ccM9GYqT.o: 
In function `main':
/home/karen/dev/cs410_spring2014/./getsections.c:253: undefined reference to `bfd_init'
/home/karen/dev/cs410_spring2014/./getsections.c:255: undefined reference to `bfd_openr'
collect2: error: ld returned 1 exit status
make: *** [build] Error 1

I searched and searched and could not find the answer to what is most likely a very simple question, and I apologize in advance for my ignorance!

2

There are 2 best solutions below

0
On

This command line is incorrect:

gcc -g -Wall -lbfd -I. ...

You need to move -lbfd to the end of the link line. To understand why, read this.

2
On

Ah, right. Your problem is that you specified libraries before getsections.c which uses them.

The way linker works it pulls in from libraries only those object files that resolve some of the symbols linker is looking for and linker processes libraries and object files in order you specified them on command line. In this case when linker got to look at libbfd.a, there were no unresolved symbols linker needed to resolved, so it skipped all objects. Then linker got to process getsections.c which used bfd_init and bfd_openr. Alas that was the last item on the command line and linker still had those symbols unresolved.

Put -lbfd after your source file and linking should work.