Пытаюсь собрать приложение app
, прилинковав его к динамической библиотеке library
так, чтобы больше никаких dll для запуска app.exe
не требовалось (кроме системных и MSVCRT.dll). Использую MinGW
.
Для этого C++ runtime линкую с опцией -static
, что на выходе даёт "чистую" library.dll
(зависящую только от kernel32.dll и MSVCRT.dll судя по dependency walker-у):
set(LIB_NAME library)
set(LIB_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/include)
add_library(${LIB_NAME} SHARED)
target_sources(${LIB_NAME} PRIVATE ${LIB_INCLUDE_DIR}/${LIB_NAME}/Some.hpp src/Some.cpp) # Some.hpp и Some.cpp -- сорсы библиотеки
target_include_directories(${LIB_NAME} PUBLIC ${LIB_INCLUDE_DIR})
if (WIN32 AND MINGW)
target_link_options(${LIB_NAME} PUBLIC -static)
endif (WIN32 AND MINGW)
Проблемы начинаются при линковке приложения:
set(APP_NAME app)
add_executable(${APP_NAME})
target_sources(${APP_NAME} PRIVATE src/main.cpp) # main.cpp - сорс приложения
target_link_libraries(${APP_NAME} PRIVATE ${LIB_NAME})
На этапе линковки библиотеки к приложению ld
выдаёт
multiple definition of `_Unwind_SjLj_Resume'
Судя по всему, это происходит от того, что опция -static
передается приложению из-за PUBLIC
спецификатора, и мы получаем 2 одинаковые версии libstd++ и libgcc, встроенные как в библиотеку, так и в приложение (1 функция импортируется из main.cpp, другая из some.cpp).
Если поставить
target_link_options(${LIB_NAME} PRIVATE -static)
, то ошибок линковки не возникает, но приложение (в отличие от библиотеки) требует динамический рантайм для запуска, что не соответствует цели.
Единственный "рабочий" вариант, который я пока нашёл, линковать библиотеку к приложению следующим образом:
target_link_libraries(${APP_NAME} PRIVATE -Wl,--whole-archive ${LIB_NAME} -Wl,--no-whole-archive)
Однако не до конца понимаю смысл этого флага и правильность решения. Также почему-то dependency walker продолжает показывать зависимоть от .dll, хотя сейчас запуск возможен без неё.
Какое решение правильное?
UPD: после удаления и восстановления папки с CMake-кешем и перезапуска dependency walker-а предложение "почему-то dependency walker продолжает показывать зависимоть от .dll" стало неактуально.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Нужно ли вызвать ReleaseSemaphore в следующей ситуации?
Решалась задача: Шахматный король ходит по горизонтали, вертикали и диагонали, но только на 1 клеткуДаны две различные клетки шахматной доски,...
Чтобы не заморачиваться с написанием класса-обертки, думаю использовать лямбда + unique_ptr, иначе говоря, пишу