Ещё раз линковка
От: remark Россия http://www.1024cores.net/
Дата: 21.09.06 13:44
Оценка:
Не знаю, как лучше назвать топик... Вобщем, проблема следующая.
Есть какой-то общий компонент, например, перевод строки в юникод и обратно. Компонент лежит в h и cpp файлах.
Этот компонент включается в какую-то lib'ку, например lib'ка для работы с БД.
Далее эта lib'ка включается в проект, который собирает exe-файл. И в этот же проект включается исходный компонент для перевода строк в юникод.

Соответственно при сборке exe линкер может ругаеться, что имеется несколько определений этого самого компонета для перевода строк в юникод.

Вопрос: как с этим бороться?

Вариант убрать этот компонет из lib'ки не катит, т.к. эта lib'ка может подключаться в проект, который сам его не включает.

Вариантов может быть много. Например, один компонент может включаться в 2 разные lib'ки. И потом эти 2 lib'ки в один проект. Или ещё как-то.

Ставить у всех общих компонетов __declspec(selectany) (да, среда msvc71) тоже не катит, т.к. их много.


1024cores — all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re: Ещё раз линковка
От: Aera Беларусь  
Дата: 21.09.06 13:56
Оценка:
Здравствуйте, remark, Вы писали:

R>И в этот же проект включается исходный компонент для перевода строк в юникод.


Зачем? Ты сам создаешь себе проблему.

R>Соответственно при сборке exe линкер может ругаеться, что имеется несколько определений этого самого компонета для перевода строк в юникод.


R>Вопрос: как с этим бороться?


Включать не более одного раза.
--
RedApe
Re: Re: Ещё раз линковка
От: Аноним  
Дата: 21.09.06 13:58
Оценка:
Вынести этот компонент в отдельную либу и линковать с ней.
Posted via RSS
Re[2]: Ещё раз линковка
От: remark Россия http://www.1024cores.net/
Дата: 21.09.06 14:08
Оценка:
Здравствуйте, Aera, Вы писали:

A>Здравствуйте, remark, Вы писали:


R>>И в этот же проект включается исходный компонент для перевода строк в юникод.


A>Зачем? Ты сам создаешь себе проблему.


R>>Соответственно при сборке exe линкер может ругаеться, что имеется несколько определений этого самого компонета для перевода строк в юникод.


R>>Вопрос: как с этим бороться?


A>Включать не более одного раза.



Проблема гораздо шире, чем пример. Есть _очень_ много различных вспомогательных компонетов, есть _много_ либок, есть _много_ проектов. За всем не уследишь. тем более, что одна и та же либка может включаться в несколько проектов.

Или вот процитирую себя из исходного поста:

Вариантов может быть много. Например, один компонент может включаться в 2 разные lib'ки. И потом эти 2 lib'ки в один проект. Или ещё как-то.


Вы не поняли проблемы.


1024cores — all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[2]: Ещё раз линковка
От: remark Россия http://www.1024cores.net/
Дата: 21.09.06 14:11
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Вынести этот компонент в отдельную либу и линковать с ней.


Смотри мой ответ здесь
Автор: remark
Дата: 21.09.06


Компонетов _очень_ много, и они маленькие.

Плодить несколько сот либок, каждая из которых состоит из одного исходного файла, тем более, что каждую либку надо собирать в 8 вариантах (что бы линковалась с разными проектами) не катит.



1024cores — all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re: Ещё раз линковка
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 21.09.06 14:16
Оценка:
Здравствуйте, remark, Вы писали:

R>Не знаю, как лучше назвать топик... Вобщем, проблема следующая.

R>Есть какой-то общий компонент, например, перевод строки в юникод и обратно. Компонент лежит в h и cpp файлах.
R>Этот компонент включается в какую-то lib'ку, например lib'ка для работы с БД.
R>Далее эта lib'ка включается в проект, который собирает exe-файл. И в этот же проект включается исходный компонент для перевода строк в юникод.

R>Соответственно при сборке exe линкер может ругаеться, что имеется несколько определений этого самого компонета для перевода строк в юникод.


R>Вопрос: как с этим бороться?


Мое мнение такое:
* компонент, какого бы размера он не был, составляет отдельную библиотеку;
* используется такой build-tool, который может отслеживать повторные подключения библиотек и игнорировать их. Т.е. если компоненту A нужны компоненты B и C, каждый из которых тянет компонент D, то build-tool должен подключить к A библиотеки компонентов B, C и D по одному разу.


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[3]: Ещё раз линковка
От: Aera Беларусь  
Дата: 21.09.06 14:23
Оценка:
Здравствуйте, remark, Вы писали:

R>

R>Вариантов может быть много. Например, один компонент может включаться в 2 разные lib'ки. И потом эти 2 lib'ки в один проект. Или ещё как-то.


R>Вы не поняли проблемы.


Действительно, я не понимаю проблемы.

Допустим есть у меня работа со строками — делаю string.lib. Затем создаю компоненты, которые, скажем, релизуют Regexp с использованием библиотек string.lib — regexp.lib

Что бы не было проблем нужно не включать в regexp.lib компоненты, которые уже входят в string.lib
Затем, для создания приложения, нужно перечислять все библиотеки:

main.exe = string.lib regexp.lib
--
RedApe
Re[2]: Ещё раз линковка
От: remark Россия http://www.1024cores.net/
Дата: 21.09.06 14:24
Оценка:
Здравствуйте, eao197, Вы писали:

E>Здравствуйте, remark, Вы писали:


R>>Не знаю, как лучше назвать топик... Вобщем, проблема следующая.

R>>Есть какой-то общий компонент, например, перевод строки в юникод и обратно. Компонент лежит в h и cpp файлах.
R>>Этот компонент включается в какую-то lib'ку, например lib'ка для работы с БД.
R>>Далее эта lib'ка включается в проект, который собирает exe-файл. И в этот же проект включается исходный компонент для перевода строк в юникод.

R>>Соответственно при сборке exe линкер может ругаеться, что имеется несколько определений этого самого компонета для перевода строк в юникод.


R>>Вопрос: как с этим бороться?


E>Мое мнение такое:

E>* компонент, какого бы размера он не был, составляет отдельную библиотеку;
E>* используется такой build-tool, который может отслеживать повторные подключения библиотек и игнорировать их. Т.е. если компоненту A нужны компоненты B и C, каждый из которых тянет компонент D, то build-tool должен подключить к A библиотеки компонентов B, C и D по одному разу.


Видимо, зря я его компонентом назвал
Ответ здесь
Автор: remark
Дата: 21.09.06
— класть каждый компонет в либку не катит. Они могут быть совсем смешными — типа получить путь, откуда запущен исполняемый файл, или сконвертить число в строку и т.д.

build-tool, тоже, к сожалению менять нельзя — это жёстко msvc2003


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[4]: Ещё раз линковка
От: remark Россия http://www.1024cores.net/
Дата: 21.09.06 14:32
Оценка:
Здравствуйте, Aera, Вы писали:

A>Здравствуйте, remark, Вы писали:


R>>

R>>Вариантов может быть много. Например, один компонент может включаться в 2 разные lib'ки. И потом эти 2 lib'ки в один проект. Или ещё как-то.


R>>Вы не поняли проблемы.


A>Действительно, я не понимаю проблемы.


A>Допустим есть у меня работа со строками — делаю string.lib. Затем создаю компоненты, которые, скажем, релизуют Regexp с использованием библиотек string.lib — regexp.lib


A>Что бы не было проблем нужно не включать в regexp.lib компоненты, которые уже входят в string.lib

A>Затем, для создания приложения, нужно перечислять все библиотеки:

A>
A>main.exe = string.lib regexp.lib
A>


Всё не так просто.
Помимо того, что _очень_ запарно создавать сотни маленьких либок и потом следить что куда включать.
Получается, что либка раскрывает детали своей реализации, она перекладывает обязанность по включению необходимых _ей_ либок на основной проект.
Допустим, я доработал regexp.lib, т.ч. теперь для её успешной линковки к основному проекту надо прилинковать помимо string.lib ещё и utils.lib.
В своих проектах я это поправил — т.е. добавил в них utils.lib. Но что произойдёт на следёющий день? Правильно, ко мне придут коллеги с ведром вазелина, и скажут, что нехорошо получилось, что у них перестали собираться их проекты.


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re: Дополнение
От: remark Россия http://www.1024cores.net/
Дата: 21.09.06 14:36
Оценка:
Здравствуйте, remark, Вы писали:

Согласен, что это всё может не очень хорошо было изначально задумано. Но теперь как факт получилась описанная выше ситуация.
Менять очень много чего сейчас уже не получится, типа всё класть в либы.
Хотется просто как-то с минимальными усилями устранить множество варнингов при линковке.

Т.е. вопрос не "как надо было изначально сделать всё по-грамотному?", а вопрос "что делать теперь?"


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[5]: Ещё раз линковка
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 21.09.06 14:57
Оценка:
Здравствуйте, remark, Вы писали:

R>Помимо того, что _очень_ запарно создавать сотни маленьких либок и потом следить что куда включать.

R>Получается, что либка раскрывает детали своей реализации, она перекладывает обязанность по включению необходимых _ей_ либок на основной проект.
R>Допустим, я доработал regexp.lib, т.ч. теперь для её успешной линковки к основному проекту надо прилинковать помимо string.lib ещё и utils.lib.
R>В своих проектах я это поправил — т.е. добавил в них utils.lib. Но что произойдёт на следёющий день? Правильно, ко мне придут коллеги с ведром вазелина, и скажут, что нехорошо получилось, что у них перестали собираться их проекты.

Тогда либо ты перестраиваешь работу с либами, либо заставляешь подключать одни и те же исходники (функции вроде перевода чисел или работы с именами каталогов) в разные пространства имен. Например, так:
// string_util.h.inl
...bla-bla-bla...

// string_util.cpp.inl
...bla-bla-bla..

// string_lib/string_util.h
...
namespace string_lib {

#include "string_util.h.inl"

}

// string_lib/string_util.cpp
...
namespace string_lib {

#include "string_util.cpp.inl"

}

// regex/string_util.h
...
namespace regex {

#include "string_util.h.inl"

}

// regex/string_util.cpp
...
namespace regex {

#include "string_util.cpp.inl"

}


Но вообще все это всего лишь откладывание неприятного решения в долгий ящик. Уж если зуб прогнил до необходимости удаления, лучше сделать это пораньше. Может, пока проблемы не стали обрастать как снежный ком, применить таки кардинальное решение?

И разве к MSVS2003 нельзя внешний build-tool прикрутить?


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[2]: Дополнение
От: Константин Л. Франция  
Дата: 21.09.06 15:13
Оценка: 1 (1)
Здравствуйте, remark, Вы писали:

R>Здравствуйте, remark, Вы писали:


R>Согласен, что это всё может не очень хорошо было изначально задумано. Но теперь как факт получилась описанная выше ситуация.

R>Менять очень много чего сейчас уже не получится, типа всё класть в либы.
R>Хотется просто как-то с минимальными усилями устранить множество варнингов при линковке.

R>Т.е. вопрос не "как надо было изначально сделать всё по-грамотному?", а вопрос "что делать теперь?"


собрать весь этот хлам в common.lib

R>
Re: Ещё раз линковка
От: gear nuke  
Дата: 21.09.06 16:41
Оценка:
Здравствуйте, remark, Вы писали:

R>Есть какой-то общий компонент, например, перевод строки в юникод и обратно. Компонент лежит в h и cpp файлах.

R>Этот компонент включается в какую-то lib'ку, например lib'ка для работы с БД.
R>Далее эта lib'ка включается в проект, который собирает exe-файл. И в этот же проект включается исходный компонент для перевода строк в юникод.

R>Соответственно при сборке exe линкер может ругаеться, что имеется несколько определений этого самого компонета для перевода строк в юникод.


Можно не включать lib файлы в проект. Совсем.

Каждый cpp компилируется в отдельный lib.
В каждом h файле написать:
#pragma comment(lib, "foo") // имя либы

Теперь, когда включаем хидер, либа будет добавлена к проекту один раз (во-первых — #ifndef в h, во-вторых — дублирующиеся прагмы не конфликтуют).

Посколку хидер включает другие нужные хидеры, автоматом подключатся и нужные для линковки либы.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[2]: Ещё раз линковка
От: remark Россия http://www.1024cores.net/
Дата: 25.09.06 08:59
Оценка:
Здравствуйте, gear nuke, Вы писали:

GN>
GN>#pragma comment(lib, "foo") // имя либы
GN>



Проблема с pragma в том, что ей надо указывать путь относительно _проекта_, а не относительно текущего файла.
Утилита не может знать где лежит проект, тем более проектов много.
Поломается сборка.



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.