In Suse I have got 2 libs which I have to use to link with my source files but they are interdependent on each other.
Means if the 2 libs are A and B than

A is dependent on B and B is dependent on A

In that case what should be the order in which we link the lib so that we dont get linking error
Or can there be any other solution

Recommended Answers

All 8 Replies

What have you tried?
AKAIK, the GNU linker re-scans libraries, so the order it less important.

What have you tried?
AKAIK, the GNU linker re-scans libraries, so the order it less important.

When I am trying to link,the linker is giving unsatisfied symbol.
because the symbol mentioned in one is dependent on the other

List one of them twice?

tried not working
I tried 1 2 1
2 1 2
1 2 1 2
2 1 2 1
no one is working

Works for me

$ cat a.c
#include <stdio.h>
extern void b();
void a ( ) {
  static int x = 1;
  printf("a called\n");
  if ( x-- > 0 ) {
    b();
  }
}

$ cat b.c
#include <stdio.h>
extern void a();
void b ( ) {
  printf("B called\n");
  a();
}

# Create two mutually dependent libraries
$ gcc -c a.c
$ ar cr libmya.a a.o
$ gcc -c b.c
$ ar cr libmyb.a b.o

# Symbols in each lib, which are mutually dependent.
$ nm libmya.a 

a.o:
00000000 T a
         U b
         U puts
00000000 d x.1585
$ nm libmyb.a 

b.o:
         U a
00000000 T b
         U puts

# Compile and run
$ gcc m.c -L. -lmya -lmyb
$ ./a.out 
a called
B called
a called

Works for me

Well, this is, how shall I put it, cheating. Watch my fingers:

nezachem@home ~/tmp/dani/salem $ cat main.c
int main() { a1(); return 0; }

nezachem@home ~/tmp/dani/salem $ cat a1.c
extern void b2(void);
void a1(void) { b2(); }

nezachem@home ~/tmp/dani/salem $ cat a2.c
extern void b1(void);
void a2(void) { b1(); }

nezachem@home ~/tmp/dani/salem $ cat b1.c
extern void a2(void);
void b1(void) { a2(); }

nezachem@home ~/tmp/dani/salem $ cat b2.c
extern void a2(void);
void b2(void) { a2(); }

nezachem@home ~/tmp/dani/salem $ gcc -c *.c
nezachem@home ~/tmp/dani/salem $ ar cr liba.a a*.o
nezachem@home ~/tmp/dani/salem $ ar cr libb.a b*.o
nezachem@home ~/tmp/dani/salem $ gcc -g main.o -L. -la -lb
./libb.a(b2.o): In function `b2':
b2.c:(.text+0x7): undefined reference to `a2'
collect2: ld returned 1 exit status
nezachem@home ~/tmp/dani/salem $ gcc -g main.o -L. -la -lb -la
./liba.a(a2.o): In function `a2':
a2.c:(.text+0x7): undefined reference to `b1'  
collect2: ld returned 1 exit status  
nezachem@home ~/tmp/dani/salem $ gcc -g main.o -L. -la -lb -la -lb
nezachem@home ~/tmp/dani/salem $

What is the difference? The linker pulls a complete object file from the library, and does it on demand. In your example each library has just one file; that's why your command line worked for you - your libraries has just one object apiece. In a more typical case, the libraries have much more:

nezachem@home ~/tmp/dani/salem $ nm liba.a

a1.o:
00000000 T a1
         U b2

a2.o:
00000000 T a2
         U b1
nezachem@home ~/tmp/dani/salem $ nm libb.a

b1.o:
         U a2
00000000 T b1

b2.o:
         U a2
00000000 T b2
nezachem@home ~/tmp/dani/salem $

and shall be mentioned in a proper order as many times as how badly they are entangled.
Which brings up a question to a TS: why your libraries are separate?

Which brings up a question to a TS: why your libraries are separate?

Actually we have a project in which we are using js open source files making it a lib and we have a seperate component lib.
Now they are certain files which are dependent on each other.
We cannot combine it either.
so we have seperate libs

Anyway, more RTM

-( archives -)
--start-group archives --end-group
The archives should be a list of archive files. They may be either
explicit file names, or -l options.

The specified archives are searched repeatedly until no new unde-
fined references are created. Normally, an archive is searched
only once in the order that it is specified on the command line.
If a symbol in that archive is needed to resolve an undefined sym-
bol referred to by an object in an archive that appears later on
the command line, the linker would not be able to resolve that ref-
erence. By grouping the archives, they all be searched repeatedly
until all possible references are resolved.

Using this option has a significant performance cost. It is best
to use it only when there are unavoidable circular references
between two or more archives.

And this command lines (note the extras in the last command to force gcc to pass options to ld)

$ gcc -c *.c
$ ar cr liba.a a*.o
$ ar cr libb.a b*.o
$ gcc -g main.o -L. -Wl,--start-group -la -lb -Wl,--end-group
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.