LINUX.ORG.RU

CMakeLists.txt

 , ,


0

1

Есть проект, результатом которого должны быть две статические библиотеки. Дерево проекта выглядит так:

.
├── CMakeLists.txt
├── base
│   ├── CMakeLists.txt
│   ├──── base.h
│   └──── base.cpp
├── Test1
│   ├── CMakeLists.txt
│   │       └────  set(PROJ1 test1)
│   │              project(${PROJ1})
│   │              set(HDRSRT ../base/base.h test1.h)
│   │              set(SRCSRT ../base/base.cpp test1.cpp)
│   │              find_package(Qt5Core)
│   │              set(CMAKE_AUTOMOC ON)
│   │              add_library(${PROJ1} STATIC ${HDSRT} ${SRCSRT})
│   │              target_link_libraries(${PROJ1} Qt5::Core)
│   ├──── test1.h
│   └──── test1.cpp
└── Test2
    ├── CMakeLists.txt
    ├──── test2.h
    └──── test2.cpp

Тесты имеют общий базовый класс, base. Проект успешно собирается, и, даже работает. Но, если я пробую использовать две библиотеки олдновременно, получаю ошибку multiple definition методов базового класса. Подскажите, пожалуйста, как исправить ситуацию.

★★

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

Часто приходится переименовывать проект?

Ну какая разница? Бывает. Это также относится к переименовыванию целей.

Нет никакого «короче», речь шла про дублирование. Касательно «короче» мое мнение такое: CMake предлагает неймспейсы, так что нужно использовать их, и в рамках неймспейсов использовать короткие имена изначально.

Ты проигнорировал вот это:

Так дублирование всегда есть. Ты либо обращение к переменной дублируешь, либо ее значение. Или касательно скажем функций: либо ты один и тот же код дублируешь несколько раз, либо выносишь его в функцию и дублируешь уже ее вызов. Смысл в не том, чтобы дублирование было редко. А чтобы вызов/обращение к дублирующей сущности было кратким.

Потому что один раз переправить скрипт сборки проще, чем разбираться, что во что резолвится и как раскрывается, учитывая при этом кривые и косые правила CMake.

См. выше. Дублирование длинных имен хуже чем через короткое имя переменной.

CMake предлагает неймспейсы, так что нужно использовать их, и в рамках неймспейсов использовать короткие имена изначально.

Это которые в install и в export? А как они относятся к сокращению имени проекта или цели при том, что я просто создаю личный проект без задачи его реиспользования в других проектах через cmake?

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

Ну какая разница? Бывает.

sed в помощь.

Ты проигнорировал вот это:

Я еще раз говорю, что речь идет про дублирование. Ты почему-то сводишь дублирование исключительно к краткости. Речь же идет о

add_executable(a)

do_stuff(a)
do_stuff(a)
do_stuff(a)

// vs

do_stuff(${a})
do_stuff(${a})
do_stuff(${a})

где краткость не так важна.

См. выше. Дублирование длинных имен хуже чем через короткое имя переменной.

Хуже по какому критерию?

Это которые в install и в export?

Да.

А как они относятся к сокращению имени проекта

В рамках проекта вы используете короткое имя. При install/export собираете длинное.

или цели при том, что я просто создаю личный проект без задачи его реиспользования в других проектах через cmake?

В личном проекте вы можете писать скрипты сборки так, как вам угодно. Речь идет про best practices, рекомендуемые самими разработчиками CMake.

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

sed в помощь

Да конечно. Это гораздо удобнее того, чтобы поменять имя сразу в IDE/редакторе.

Я еще раз говорю, что речь идет про дублирование. Ты почему-то сводишь дублирование исключительно к краткости. Речь же идет о

Да елки зеленые. Я говорю про краткость в рамках дублирования. Я не писал, что нужно бороться с дублированием, как токовым. Я утверждал, что дублировать длинные имена более трудоемко чем короткие.

В рамках проекта вы используете короткое имя. При install/export собираете длинное.

Ха. Так вот если я создаю некую скажем библиотеку и настраиваю ее реиспользование через cmake ну и пусть еще имя пространства имен добавляю при экспорте. Все равно при подключении этой библиотеки в другой проект это ее имя с префиксом в виде пространства имен нужно будет один раз указать в target_link_libraries и все.

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

Это гораздо удобнее того, чтобы поменять имя сразу в IDE/редакторе.

Тем более.

Я утверждал, что дублировать длинные имена более трудоемко чем короткие.

А я с этим спорил?

Ха. Так вот если я создаю некую скажем библиотеку и настраиваю ее реиспользование через cmake ну и пусть еще имя пространства имен добавляю при экспорте. Все равно при подключении этой библиотеки в другой проект это ее имя с префиксом в виде пространства имен нужно будет один раз указать в target_link_libraries и все.

Не распарсил.

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

Тем более.

Это блин сарказм.

А я с этим спорил?

Косвенно. Утверждая, что не нужно прятать имена проекта/целей в переменные.

Не распарсил.

Ну вот я создал библиотеку. Затем настроил ее установку и создал соответствующие *.cmake файлы для того, что мою библиотеку можно было бы подключать в другие проекты через find_package / target_link_libraries. Ну добавил имя пространства имен, чтобы мою библиотеку нужно было искать и подключать например так:

find_package(MyLibrary REQUIRED)
# ...
target_link_libraries(some_target_name MLNS::Mylibrary)

Т.е. тут длинное имя используется только один раз.

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

Это блин сарказм.

Это очевидно.

Косвенно. Утверждая, что не нужно прятать имена проекта/целей в переменные.

Я продолжаю это утверждать. Исходный тезис был таков: прятать нужно на случай «вдруг переименовать придется» и чтобы не опечататься.

Я с этим тезисом не согласен, потому что случай переименования случается в обычной жизни крайне редко и не стоит возни, а опечататься можно с тем же успехом и в имени переменной – и CMake молча проигнорирует ошибку в обоих случаях. Итого, преимуществ никаких, а движений нужно больше.

Т.е. тут длинное имя используется только один раз.

Отлично, и? Я об этом и твержу.

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

Я с этим тезисом не согласен, потому что случай переименования случается в обычной жизни крайне редко и не стоит возни, а опечататься можно с тем же успехом и в имени переменной – и CMake молча проигнорирует ошибку в обоих случаях.

Да. Но опечатку проще сделать когда имя длиннее.

Отлично, и? Я об этом и твержу.

А фиг его знает что и. Видимо эта ветвь спора была обоюдно-непонята.

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

Спасибо!

Но это немного не по теме, по вашей ссылке есть более подходящий материал: «Борьба с ошибкой линковки «In function … undefined reference to» при сборке с заранее скомпиленными библиотеками» («Также в этом разделе»).

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

Исправить это можно, например, выделив базу в отдельную разделяемую библиотеку и линкуя тесты с ней

А можно тупо захачить, объявив все методы класса Base как inline. Нынче это означает не inline, а если на клетке с тигром написано «кошка», не верь глазам своим указание линкеру, что задвоения таких методов можно удалять.

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

А зачем? имя проекта, заданное в project(), можно использовать через ${PROJECT_NAME}

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