У меня есть программа foo
Я пытаюсь скомпилировать и связать, и я сталкиваюсь с курицей и яйцом dillemma.G ++/LD не удается: не удается найти библиотеку, когда библиотека на самом деле не нужна
По причинам, которые я объясню ниже, внутри данной директории я вынужден добавить ссылку на несколько библиотек, которые мы построим (назовем их libA
и libB
) независимо от моей цели. Я знаю, что мне действительно нужно libA
для моей программы; поэтому после того, как все библиотеки построены и этот двоичный файл построен, я проверил с ldd -u -r foo
, чтобы показать, что libB
является неиспользованной прямой зависимостью.
Будучи неиспользованным, я изменил make-файлы и флаги таким образом, чтобы libB
был окутан -Wl --as-needed
и -Wl --no-as-needed
. Я делаю rebuild, снова использую ldd
, и на этот раз он не показывает неиспользуемые депо. Все идет нормально.
Теперь самое интересное: С его неиспользованной я бы ожидать, что если libB
не найден/в наличии/построен, что я все еще должен быть в состоянии собрать и связать foo
, как долго libA
доступна. (пример: если я сделал новую проверку и только построил libA
, прежде чем пытаться скомпилировать этот конкретный тест). Но ld
ошибки вне с /usr/bin/ld: cannot find -lB
Это говорит о том, что ld
нужно найти libB
, даже если он не будет нуждаться в какой-либо из символов, которые она предоставляет? Это не имеет смысла. Если все символические зависимости уже выполнены, зачем вообще нужно смотреть на эту другую библиотеку? (Это объясняло бы проблему ld и почему это невозможно)
Есть ли способ, который я могу сказать «Эй, не жалуйтесь, если вы не можете найти эту библиотеку, и нам не нужно будет связываться с ней ?»
Обещанные причины ниже
По различным причинам, независящим от меня, я должен поделиться MAKEFLAGS со многими другими тестами в этом каталоге из-за проектов Makefile иерархии. Существует два уровня makefile для всех этих тестов, в которых foo
является фальшивой целью, его рецепт make -f generictest.mk target=foo
, а generictest.mk
просто говорит, что исходный файл $(target).C
, что этот двоичный файл должен использовать каждую созданную библиотеку, указывает относительный путь к наш корневой каталог, а затем включает общий make-файл root. Основной make-файл корневого каталога расширяет все остальные компоненты (флаги, параметры, компилятор, авто-ген зависимостей через g ++ и т. Д.), А главное для каждого оператора, который сказал «использовать libX» в generictest.mk
, добавляет -lX
к флагам (или в моем случае окутаны по мере необходимости)
Хотя я хорошо знаю, что есть много вещей, которые являются очень неидеальными и/или ужасно неправильными с точки зрения лучших правил makefile с этим, у меня нет полномочий/физическая способность изменять его. И по сравнению с альтернативой, используемой в других папках, где другие делают отдельные конкретные копии этого файла makefile для каждой цели, я очень предпочитаю это; потому что это заставляет меня редактировать все из них всякий раз, когда нужно пересмотреть весь наш шаблон, и дает много других опечаток и проблем.
Я мог бы создать еще один файл generictest.mk
, который можно использовать для некоторых тестов, и объединить их, используя каждый из них на основе фактических потребностей библиотеки, но это было бы довольно аккуратно, если бы мне не приходилось до тех пор, пока я сказал «вы не все из них, вам нужен каждый из них, но только если вы на самом деле его используете ».
Файл makefile неверен - или разработан теперь устаревшие предположения. Перепроектируйте его так, чтобы вы не пытались связываться с библиотеками, которые не существуют и не являются необходимыми для рассматриваемой тестовой программы. Другой вариант - убедиться, что 'libB' построен - он становится явной зависимостью целей в' makefile' ('generictest.mk'). Во всяком случае, должно быть, конечно; если программы связаны с ним, программы (или линии командной строки) зависят от существующих библиотек. –
@JonathanLeffler Я знаю, что он сильно искажен. У меня просто нет возможности изменить его. Опять я согласен со всем, что вы сказали; но это мне не помогает. Я могу заставить его зависеть от libB, но я не хочу тратить время на создание libB, когда мне это не нужно. Их не существует, потому что я их не построил; в «реальной» сборке они, как правило, все будут существовать. – UpAndAdam
OK; если вы не будете слушать слова мудрости, вам придется продолжать гноиться в болоте разбитых сборок. Или подождите, пока какой-нибудь гений придумает решение. Но лучше всего не бороться с системой, навязанной компилятором и компоновщиком; лучше всего исправить нарушение в инструментах, которые злоупотребляют компилятором и компоновщиком (что означает файл 'generictest.mk'). Ваш звонок ... получайте удовольствие! («Я не могу исправить» не сокращает его в программном обеспечении, программное обеспечение податливо - вот почему оно называется _soft_. Если это сила, которая навязывает правила, спросите их, как обойти свою дилемму .) –