LINUX.ORG.RU

Как прилинковать статические библиотеки к статической библиотеке в cmake?

 , ,


1

3

Здравствуйте.

Есть проект, в котором генерируется статическая либа, а потом к ней прилинковываются статически статические либы.

add_library(lib STATIC ${SOURCE_FILES})
target_link_libraries(lib
     some_prebuilt_lib1.a
     some_prebuilt_lib2.a
        )

Проблема в том, что эти some_prebuilt_lib.a заранее скомпилированы и положены в папку. Я cmake указываю просто полные пути к ним. И по логике, он их статически прилинковать и всё - на выходе я получу одну жирную lib с другими статическими либами внутри.

Но так не происходит и либы не прилинковываются. Вижу я это по тому, что когда я пытаюсь статически прилинковать мою либу к другому проекту, то вижу кучу отсутсвующих символов. Что я делаю не так? Пути указываю правильные.

★★

Последнее исправление: zamazan4ik (всего исправлений: 1)

Никак. Статические библиотеки можно прилинковывать только к бинарнику (или к shared library, если с pic собрано).

kawaii_neko ★★★★
()

Нельзя статически линковать библиотеки в библиотеки. Не все компиляторы так умеют и по этой причине и cmake не хочет уметь. Пруф.

peregrine ★★★★★
()
Ответ на: комментарий от zamazan4ik

add_custom_command

Но, как тебе сказали. Это очень плохо. А если кто-то попробует слинковать и твою объединённую и исходную библиотеки?

AlexVR ★★★★★
()
Ответ на: комментарий от AlexVR

Тут есть такой вариант - если я буду делать динамическую библиотеку, то насколько я знаю, iOS в пролёте, так как у них запрещены .so. Нужно билдить в статику, но тогда придётся все зависимости тянуть динамически.

zamazan4ik ★★
() автор топика
Ответ на: комментарий от zamazan4ik

Вижу я это по тому, что когда я пытаюсь статически прилинковать мою либу к другому проекту, то вижу кучу отсутсвующих символов. Что я делаю не так?

Возможно порядок линковки статических библиотек к итоговому проекту. Ниже работающий пример. Поменяй местами последние две строки в CMakeLists.txt, и всё перестанет линковаться.

hello.hpp:

#pragma once
#include <string>
std::string hello();

hello.cpp:

#include "hello.hpp"
std::string hello() { return "Hello"; }

hello_world.hpp:

#pragma once
#include "hello.hpp"
std::string hello_world();

hello_world.cpp:

#include "hello_world.hpp"
std::string hello_world() { return hello() + ", world!"; }

test.cpp:

#include <iostream>
#include "hello_world.hpp"
int main() {
  std::cout << hello_world() << std::endl;
  return 0;
}

CMakeLists.txt:

cmake_minimum_required(VERSION 2.8)
add_library(hello STATIC hello.cpp)
add_library(hello_world STATIC hello_world.cpp)
add_executable(test test.cpp)
target_link_libraries(test hello_world) # First
target_link_libraries(test hello)       # Second

AlexVR ★★★★★
()
Ответ на: комментарий от AlexVR

С проблемами порядка линковки я разобрался.

Теперь осталась вроде как последняя проблема: с помощью ar собрал все мои статические либы в одну, но архив таблицы символов никак не создаётся.

zamazan4ik ★★
() автор топика
Ответ на: комментарий от zamazan4ik

Может такое умеет делать libtool?

libtool дял статических библиотек дополнительно делает «la» файлы, в которых прописываются нужные для нее статические либы. Но я бы не рекомендовал связываться с этим говном.

Что мешает в cmake-config-е для своего пакета прописать findlibrary до нужных библиотек и добавить их в $PACKAGE_LIBRARIES?

kawaii_neko ★★★★
()
Ответ на: комментарий от vodz

конечно же я вызываю :) Только вот это не особо помогает (вполне возможно, что вызываю неправильно) :

ar crs lib.a otherliba.a otherlibb.a
ranlib lib.a

zamazan4ik ★★
() автор топика
Последнее исправление: zamazan4ik (всего исправлений: 1)
Ответ на: комментарий от zamazan4ik

неправильно

Ты упаковываешь архивы в архив. А нужно из архивов вытащить .o файлы, а потом все эти файлы запаковать в новый .a. Другими словами, никакой вложенности архивов быть не должно.

i-rinat ★★★★★
()
Ответ на: комментарий от zamazan4ik

А, так работать не будет. Ндо распаковать oth*.a и класть в lib.a *.o, ranlib работает с obj

vodz ★★★★★
()
Ответ на: комментарий от i-rinat

хм, а я думал, что ar здесь автоматом сможет распаковать *.a в *.o, а после уже соберёт как надо. Ладно, сейчас буду скриптами исправлять

zamazan4ik ★★
() автор топика
Ответ на: комментарий от zamazan4ik

ar здесь автоматом сможет распаковать *.a в *.o, а после уже соберёт как надо

echo -e "create lib.a\naddlib otherliba.a\naddlib otherlibb.a\nsave\nend" | ar -M
i-rinat ★★★★★
()
15 декабря 2017 г.

add_library(<name> OBJECT <src>...)

Creates a special “object library” target. An object library compiles source files but does not archive or link their object files into a library. Instead other targets created by add_library() or add_executable() may reference the objects using an expression of the form $<TARGET_OBJECTS:objlib> as a source, where objlib is the object library name. For example:

add_library(... $<TARGET_OBJECTS:objlib> ...)

add_executable(... $<TARGET_OBJECTS:objlib> ...)

will include objlib’s object files in a library and an executable along with those compiled from their own sources. Object libraries may contain only sources (and headers) that compile to object files. They may contain custom commands generating such sources, but not PRE_BUILD, PRE_LINK, or POST_BUILD commands. Object libraries cannot be imported, exported, installed, or linked. Some native build systems may not like targets that have only object files, so consider adding at least one real source file to any target that references $<TARGET_OBJECTS:objlib>.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.