2013-07-17 4 views
3

У меня следующие библиотеки lib_A, lib_B, lib_C, lib_D. Я делаю что-то подобное в моих Cmake файлах (порядок важен):cmake library linking order

  1. ADD_LIBRARY (lib_A)
  2. ADD_LIBRARY (lib_B)
  3. ADD_LIBRARY (lib_C)
  4. ADD_LIBRARY (lib_D)
  5. TARGET_LINK_LIBRARIES (lib_B lib_C)
  6. TARGET_LINK_LIBRARIES (lib_A lib_B)
  7. ADD_EXECUTABLE (EXEC)
  8. TARGET_LINK_LIBRARIES (EXEC lib_A)
  9. TARGET_LINK_LIBRARIES (EXEC lib_D)

Это приводит к следующей команды линкера.

линкер -llib_A -llib_D -llib_B -llib_C

Q1. Почему lib_B и lib_C после lib_D?

Q2. Когда я изменяю CMake немного и сделать что-то вроде этого:

8_ TARGET_LINK_LIBRARIES (lib_A lib_D) 9_ TARGET_LINK_LIBRARIES (EXEC lib_A)

затем связывая порядок, как это линкер -llib_A -llib_B -llib_C -llib_D Здесь lib_B и lib_C находятся перед lib_D. Это означает, что target_link_libraries работает по-разному для исполняемых целей и целей библиотеки. Я прав?

Проблема в том, что lib_B и lib_C также зависят от lib_D, но я не хочу делать target_link_libraries (lib_B lib_D) и target_link_libraries (lib_C lib_D), потому что у меня больше таких случаев, и мне нужно будет это сделать вручную для каждой библиотеки. Конечно, как в Q2 решает проблему, но Q3 - этот заказ гарантирован каким-то образом по cmake или это просто случайность?

Спасибо

+0

Не уверен, что о разница в порядке между exes и libs, но если B и C оба зависят от D, вы должны действительно указать это. – Fraser

+0

Проблема в том, что B и C логически являются частью платформы, независимой от A и A, зависит от платформы lib D. Я знаю, что я должен это делать, но у меня их много, и это делает вручную, приложит немало усилий для ее поддержания и обеспечения некоторое автоматическое решение увеличит сложность моей системы сборки на основе cmake. Другая проблема заключается в том, что, когда я буду явно устанавливать эту зависимость D для каждой независимой от платформы библиотеки, это приведет к тому, что D будет отображаться в списке компоновщиков много раз. – user2301299

+0

У меня такая же проблема с внешней библиотекой - например, boost. Я хотел бы избежать установки зависимости для повышения в каждой библиотеке. – user2301299

ответ

0

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

Кстати, вы можете сжать ваш target_link_libraries в одну строку на цели, как:

TARGET_LINK_LIBRARIES(exec lib_A lib_D) 

И, если Exec не зависит напрямую от lib_D, вы можете избежать ссылки, если вы правильно связаны lib_A в lib_D.

Во всяком случае, в отношении Q1: даже если заказ гарантируется CMake, не гарантируется путь ваш компоновщика будет рассматривать его, вы будете страдать от боли, если вы полагаетесь на эту

+0

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