SCons для создания разделяемой библиотеки (.so) со статической библиотекой (.a)

Я пытаюсь заставить SCons сделать общую библиотеку. Одним из элементов, входящих в .so, является .a статическая библиотека.

У меня есть строка типа:

env_2.SharedLibrary('libstuff.so', \
  Split("""stuff.cxx mylib/libMine.a""")

И при запуске я получаю эту ошибку:

scons: *** Source file: mylib/libMine.a \
is static and is not compatible with shared target: libstuff.so

Однако я знаю, что общую библиотеку можно создать из .a с помощью такой команды:

g++ -m32 -shared -o libstuff.so stuff.o mylib/libMine.a

Будем очень признательны за любые идеи о том, как заставить это работать или какие-либо обходные пути.


Смежный вопрос: как заставить scons поместить дополнительную строку -shared в командную строку LINK для вызова Program()? Если бы я мог это сделать, я думаю, это удовлетворило бы мои потребности.


person xavjuan    schedule 11.02.2010    source источник


Ответы (6)


Попробуйте установить env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME']=1 в вашем SConstruct.

person Liang Wul    schedule 02.11.2010
comment
Это «волшебное вуду» сработало и на меня. Я удивлен, потому что не увидел никакой разницы в параметрах команды компиляции после добавления в SConstruct. Надеюсь, знахарь, придумавший эту магию, объяснит ее нам, смертным. - person Be Kind To New Users; 18.02.2013
comment
Построитель SharedLibrary проверяет, были ли все заданные объектные файлы созданы с помощью построителя SharedObject (и, следовательно, с помощью -fPIC). env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME']=1 отключает эту проверку. Вы должны сами решить, действительно ли это хорошая идея... - person ElektroKraut; 22.04.2014

Эта проблема не характерна для scons. Чтобы создать разделяемую библиотеку, вам потребуются объекты, скомпилированные с независимым от позиции кодом (-fPIC). Лучше всего сделать общую библиотеку из исходных файлов, скомпилированных с правильными параметрами.

В SCons вы можете определить список целей, которые используются для сборки как libMine.a, так и libShared.so.


Обновление: по вашему второму вопросу SharedLibrary может сделать то, что вам нужно:

SharedLibrary('foo', ['f1.c', 'f2.c', 'f3.c'])

Если нет, LINKFLAGS устанавливает флаги, переданные команде связи.

person Dave Bacher    schedule 11.02.2010
comment
Я думаю, вы правы, что в .a есть файлы .o, НЕ созданные с использованием -fPIC. Однако g++ -m32 -shared .... все еще как-то работает. - person xavjuan; 12.02.2010
comment
Я вернулся и скомпилировал файлы, идущие в .a, с параметром -fPIC, но это, похоже, не помогло. - person xavjuan; 12.02.2010

У меня такая же проблема под cygwin. Я передал параметры «-fPIC» в gcc при создании объектов и получил следующее предупреждение:

предупреждение: -fPIC игнорируется для цели (весь код не зависит от позиции)

Я также передал «-shared» в команду ссылки. И я наконец получил ошибку

«***.lib является статическим и несовместим с общей целью: myso.dll»

Кажется, scons не позволяет создавать так непосредственно из файлов obj или lib, и можно либо создать так из списка исходных файлов (используя SharedLibrary()), либо исходный файл + параметр «LIBS», как говорит dummytaurus. Мне любопытно об этом.

person NovelX    schedule 20.06.2010

env_2.SharedLibrary('libstuff.so', Split("""stuff.cxx"""), LIBS='libMine.a', LIBPATH='mylib')

Это должно работать.

person Community    schedule 24.02.2010
comment
@shoosh Да, это так. Построитель SharedLibrary использует ProgramScanner для поиска зависимостей, указанных через LIBS. - person Jonathon Reinhart; 20.06.2015

Проблема в функции SharedFlagChecker (Default.py), которая проверяет только внутренний «общий» флаг. Документация SCons наводит вас на мысль, что она сохраняет различие между общими объектами и статическими объектами через суффикс (SHOBJSUFFIX), но это не так. Исправить легко. В файле scons-local.../SCons/Default.py найдите SharedFlagChecker и отредактируйте:

def SharedFlagChecker(source, target, env):
    same = env.subst('$STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME')
    if same == '0' or same == '' or same == 'False':
        for src in source:
            try:
                shared = src.attributes.shared
            except AttributeError:
                # Replace this line: shared = None
                shared = env.Dictionary()['SHOBJSUFFIX'] == src.suffix
            if not shared:
                raise SCons.Errors.UserError("Source file: ...") 

Теперь объекты, созданные с помощью конструктора SharedObject, можно будет компоновать в общей библиотеке.

person M. A. Moshier    schedule 24.02.2013
comment
Вы должны использовать env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME']=True и не взламывать код, чтобы отключить это. Это на странице руководства. - person bdbaddog; 20.06.2015

Решение для решения этой проблемы использовало «SharedObject» следующим образом:

ASN1CObjectFile = envCProcesses.SharedObject(target = "OTCMsg.os",
                                             source = "OTCMsg.c",
                                             CFLAGS = envCProcesses["CFLAGS"] + ["-Wno-unused"])

а также:

OTCLibSharedLibrary = envCProcesses.SharedLibrary(env["OTC_LIBPATH"] + "/libOTCLib" + env["SHLIBSUFFIX"],
                                              ASN1CObjectFile +
                                              [ASN1AllocatorSource,
                                               "OTCLib.c"],
                                              LIBPREFIX = "")

С наилучшими пожеланиями,

person L-Sebastien    schedule 30.07.2018
comment
env[OTC_LIBPATH] + /libOTCLib + env[SHLIBSUFFIX] можно переписать как ${OTC_LIBPATH}/libOTCLib$SHLIBSUFFIX - person bdbaddog; 03.08.2018