Friday, February 20, 2009

CMake + libperl

Начну с того, что встроенный модуль CMake никуда не годится:

SET(PERL_POSSIBLE_INCLUDE_PATHS
/usr/lib/perl/5.8.3/CORE
/usr/lib/perl/5.8.2/CORE
/usr/lib/perl/5.8.1/CORE
/usr/lib/perl/5.8.0/CORE
/usr/lib/perl/5.8/CORE
)

Естественно, пользоваться им нельзя. Кроме того, у перла до 5.8.9 есть очень гадкая особенность - DynaLoader.a, который есть в ldflags'ах. Если собирается приложение с -fPIC, то порядок линковки объектов важен, и DynaLoader имеет свойство ломать сборку. Я решил эту проблему копированием DynaLoader.a за угол с добавлением префикса lib. Выглядит это так:

# Find perl libraries and cflags
EXECUTE_PROCESS(COMMAND ${PERL_EXECUTABLE} -MExtUtils::Embed -e ccopts OUTPUT_VARIABLE PERL_CFLAGS)
EXECUTE_PROCESS(COMMAND ${PERL_EXECUTABLE} -MExtUtils::Embed -e ldopts OUTPUT_VARIABLE PERL_LDFLAGS)
STRING(REGEX REPLACE "[\r\n]" " " PERL_CFLAGS ${PERL_CFLAGS})
STRING(REGEX REPLACE " +$" "" PERL_CFLAGS ${PERL_CFLAGS})
STRING(REGEX REPLACE "[\r\n]" " " PERL_LDFLAGS ${PERL_LDFLAGS})
STRING(REGEX REPLACE " +$" "" PERL_LDFLAGS ${PERL_LDFLAGS})
# Handle DynaLoader
STRING(REGEX MATCH "/[^ ]*/DynaLoader.a" PERL_DYNALOADER ${PERL_LDFLAGS})
STRING(REGEX REPLACE "/[^ ]*/DynaLoader.a " "" PERL_LDFLAGS ${PERL_LDFLAGS})

IF(PERL_DYNALOADER)
EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E copy ${PERL_DYNALOADER} ${project_BINARY_DIR}/compat/libdynaloader.a)
LINK_DIRECTORIES(${rspamd_BINARY_DIR}/compat/)
ENDIF(PERL_DYNALOADER)

Этот метод работает как при наличии DynaLoader.a, так и при его отсутствии. Достаточно в настройках таргета добавить следующее:

IF(PERL_DYNALOADER)
TARGET_LINK_LIBRARIES(target dynaloader)
ENDIF(PERL_DYNALOADER)

No comments:

Post a Comment