[sisyphus] связывание в ar

Alexey Morozov =?iso-8859-1?q?morozov_=CE=C1_novosoft=2Eru?=
Чт Окт 31 21:34:58 MSK 2002


Что-то я туплю не по-детски... То ли я дурак, то ли лыжи не едут...
Итак, в задаче дано:

-------- test29a.h -------
#ifndef __test29a_h
#define __test29a_h

#include <iostream>
using namespace std;

class singleton {
        static singleton s;
        singleton() { cout << __PRETTY_FUNCTION__ << endl; }
public:
        static singleton& get()
        {
                cout << __PRETTY_FUNCTION__ << endl;
                return s;
        }
        void run()
        {
                cout << __PRETTY_FUNCTION__ << endl;
        }
};

#endif /* __test29a_h */
--------- test29a.h -----------

--------- test29a.cc -----------
#include "test29a.h"

singleton singleton::s;
--------- test29a.cc -----------

--------- test29b.h -----------
#ifndef __test29b_h
#define __test29b_h

#include <iostream>
using namespace std;

class A {
public:
        A() {cout << __PRETTY_FUNCTION__ << endl;};
        void run();
};

#endif
-------- test29b.h ------------

-------- test29b.cc -----------
#include "test29b.h"
#include "test29a.h"

void A::run(void)
{
        cout << __PRETTY_FUNCTION__ << endl;
        singleton& s = singleton::get();
        s.run();
-------- test29b.cc -----------

-------- test29.cc ------------
include "test29b.h"

int main(void)
{
        A a;
        a.run();
}
------- test29.cc ------------

Как видите, все довольно просто. Имеется класс singleton и пользующийся
им класс A. Экземпляр класса A, в свою очередь инстанциируется в main.
Все, вроде бы, законно. Более того, после

for i in test29.cc test29a.cc test29b.cc; do c++ -c $i; done
c++ -o test29 test29.o test29a.o test29b.o

мы получаем вполне работоспособный бинарник. Однако, если мы после компиляции
сделаем

ar cru libtest29a.a test29a.o
ar cru libtest29b.a test29b.o

а затем

c++ -o test29 test29.o libtest29a.a libtest29b.a

то нас ждет... э-э-э, разочарование:
alex на pyro alex/tmp/c++ $ c++ -o test29 test29.o libtest29a.a libtest29b.a
libtest29b.a(test29b.o): In function `singleton::get()':
test29b.o(.gnu.linkonce.t._ZN9singleton3getEv+0x2d): undefined reference to `singleton::s'
collect2: ld returned 1 exit status
alex на pyro alex/tmp/c++ $ _

Небольшое расследование показало, что причиной неверной сборки является
/неправильный/ порядок указания библиотек. То есть, если libtest29b.a
поставить перед libtest29a.a, то все слинкуется нормально.

По-моему, это бага (хотя бы из соображений использования cross-linked
библиотек внутри некоторого проекта).

и ar, и ld из комплекта binutils-2.13.90.0.4-alt1

Что скажут ведущие си- и плюсоводы?




Подробная информация о списке рассылки Sisyphus