[Bug 53895] New: Linker doesn't handle the references in .a libraries located in different directories properly

Claudiu ANGHEL claudiu.anghel at skynet.be
Sun Feb 2 13:14:02 UTC 2003


------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.
     
http://bugs.kde.org/show_bug.cgi?id=53895     
           Summary: Linker doesn't handle the references in .a libraries
                    located in different directories properly
           Product: kdevelop
           Version: 2.1.3
          Platform: SuSE RPMs
        OS/Version: Linux
            Status: UNCONFIRMED
          Severity: normal
          Priority: NOR
         Component: general
        AssignedTo: kdevelop-devel at barney.cs.uni-potsdam.de
        ReportedBy: claudiu.anghel at skynet.be


Version:           2.1.3 (using KDE KDE 3.0.5)
Installed from:    SuSE RPMs
Compiler:          gcc (GCC) 3.2 GNU ld version 2.12.90.0.15 20020717 (SuSE)
OS:          Linux

If you create a class A in a directory dira and another class B in a directory dirb (class B will use the class A) the linker will give unsolved references  when will create the executable (see the output bellow). When I create the directories I choose static linked libraries.

Here is an example for reproducing the problem and also 2 workaround that I found.

Example: (only the relevant part is shown, the #if,#endif ... are skipped

Create a class with "New class ...". In the dialog box choose the name A1, change the files to be generated from a1.h to dira/a1.h and from a1.cpp to dira/a1.cpp.OK
Create a class with "New class ...". In the dialog box choose the name B1, change the files to be generated from b1.h to dirb/b1.h and from b1.cpp to dirb/b1.cpp.OK

Bellow is the generated code with the extra function added manually:

In directory dira:

File a1.h

class A1 {
public: 
	A1();
	~A1();
        void doA1(void);
};

File a1.cpp

A1::A1(){}
A1::~A1(){}
void A1::doA1(void) { printf("doA1\n");}

In directory dirb:

File b1.h

#include "../dira/a1.h"
class B1 {
public: 
	B1();
        void doB1(void);
	~B1();
};

File b1.cpp

B1::B1(){}
B1::~B1(){}
void B1::doB1(void) {
    A1 a;
    a.doA1();
}

In the root directory:

File main.cpp

#include "dirb/b1.h"

int main(int argc, char *argv[]) {
    B1 b;
    b.doB1();

  return EXIT_SUCCESS;
}

The genrated Makefile.am will look like this:

####### kdevelop will overwrite this part!!! (begin)##########
bin_PROGRAMS = bugtest

## INCLUDES were found outside kdevelop specific part

bugtest_SOURCES = main.cpp 
bugtest_LDADD   = ./dira/libdira.a ./dirb/libdirb.a 

SUBDIRS = docs dira dirb 

EXTRA_DIST = main.cpp 

####### kdevelop will overwrite this part!!! (end)############
# set the include path found by configure
INCLUDES= $(all_includes)
 
# the library search path.
bugtest_LDFLAGS = $(all_libraries) 

-- End of Makefile.am


At the linking time you'll receive:
gmake[3]: Entering directory `/home/claudiu/bugtest/bugtest' 
/bin/sh ../libtool --silent --mode=link --tag=CXX g++ -Wnon-virtual-dtor -Wno-long-long -Wbad-function-cast -Wundef -Wall -pedantic -W -Wpointer-arith -Wmissing-prototypes -Wwrite-strings -ansi -D_XOPEN_SOURCE=500 -D_BSD_SOURCE -Wcast-align -Wconversion -O2 -O0 -g3 -Wall -fno-exceptions -fno-check-new -o bugtest main.o ./dira/libdira.a ./dirb/libdirb.a 
./dirb/libdirb.a(b1.o): In function `B1::doB1()': 
/home/claudiu/bugtest/bugtest/dirb/b1.cpp:25: undefined reference to `A1::A1[in-charge]()' 
/home/claudiu/bugtest/bugtest/dirb/b1.cpp:26: undefined reference to `A1::doA1()' 
/home/claudiu/bugtest/bugtest/dirb/b1.cpp:26: undefined reference to `A1::~A1 [in-charge]()' 
collect2: ld returned 1 exit status

Workarounds:
Workaround 1:

Add in your main function a reference to A1 class (eg. create an object of type A1)

int main(int argc, char *argv[]) {
    A1 a;
    B1 b;

    b.doB1();
    return EXIT_SUCCESS;
}
This one will work without running the automake or autoconf again.

Workaround 2:
Edit your Makefile.am in the root directory and change the line
bugtest_LDADD   = ./dira/libdira.a ./dirb/libdirb.a 
with
bugtest_LDADD   = ./dira/*.o ./dirb/libdirb.a 
This latest solution is not so good because the KDE will rewrite sometimes the Makefile.am

I don't know if this a ld bug or an automake, kde bug (is not setting the proper flags for linking).




More information about the KDevelop-devel mailing list