четверг, 26 июня 2008 г.

CMake 2.6 // ошибка в FindBoost?

В процессе работы над проектом решил попробовать новый FindBoost поставляемый с версией 2.6.

Немного технических подробностей.

Проект представляет из себя множество под-проектов представленных в виде дерева фолдеров:

project_root/
----> modules/
---------> module1/[hdr,src]
---------> module2/[hdr,src]
...
---------> moduleN/[hdr,src]

CMakeLists.txt в фолдере modules не сложен и выглядит примерно так

-- начало ----
# говорим, что проект у нас С++!!!
project(project_name_of_the_whole_system CXX)

add_directory(module1)
...
add_directory(moduleN)
-- конец ----

Не каждый модуль использует Boost, и старается быть, по возможности, независим, но каждый является C++ кодом.

Соответственно, для каждого нового модуля, появляющегося в проекте, берем шаблон вида:

-- начало ----
# меняем конфигурационные параметры - изменяемая часть шаблона
# говорим, что проект у нас С++!!!
project(project_name_of_the_specific_module CXX)

# означает что будет собираться библиотека
set(is_module_exec false)

# означает что мы зависим от специфичной библиотеки
set(is_module_use_lib1 true)

# используем Boost C++ lib
set(is_module_use_boost true)

# не изменяемая часть
# здесь конфигурируем, в зависимости от установленных параметров выше
include(ModuleConfig)

# далее строим модуль
...
-- конец ----

С Cmake 2.6, в начальную конфигурацию добавляю

set(is_module_required_boost_libs
thread
system
program_options
)

правлю внутренний ModuleConfig.cmake примерно так

if(is_module_required_boost_libs)
find_package(Boost COMPONENTS ${is_module_required_boost_libs})
else(is_module_required_boost_libs)
find_package(Boost)
endif(is_module_required_boost_libs)

На Windows все прошло замечательно, поскольку библиотеки там прилинковываются автоматически (autolink feature от Visual C++). Для GNU C++ такой возможности нет (или по крайней мере я о ней не знаю - если кто подскажет, буду очень признателен). Посему, для g++ приходиться хитрить.

FindBoost должен все найти для меня. А я, по идее, пробегаясь foreach(my_requested_name ${is_module_required_boost_libs}) по всем компонентам получаю набор библиотек Boost-а, необходимых для передачи линкеру.

Вроде бы все логично, однако при добавлении system компоненты FindBoost выставляет Boost_FOUND в false.
Что за дела? Начинаю ковыряться...

BOOST_ROOT указывает в /usr/local - там версия 1.34.1. libboost-system-gcc41-... там присуствует.
Выкидываю system из требуемых компонент буста для модуля. Вывожу отладочную информацию по фолдеру с библиотеками - получаю /usr/lib. Обнаруживаю там библиотеки версии 1.33.1, поставляемые с RH5, но с названием вида libboost-thread-mt... Где gcc[ver] в имени либы? libboost-system там дейсвительно нет. Но почему же он ищет там, не учитывая BOOST_ROOT переменную? Долго осознаю, что происходит... :-) Не понимаю. Ругаюсь. Пытаюсь обмануть систему генерации, установив помимо BOOST_ROOT еще и BOOST_LIBRARYDIR - результат тот же.
Начитаю курочить FindBoost.cmake отладочной информацией. Понимая, что проблема с именованиями - проверяю определение компилятора и его версии в скрипте FindBoost. Скрипт дает мне информацию, что это Intel-овский компилятор C++, поскольку это UNIX и компилятор NOT GNUCC. Чертовски логично, учитывая что, скорее всего, он GNUCXX для C++ проекта.

---- кусок FindBoost --------
IF (UNIX)
IF (APPLE)
SET (_boost_COMPILER "")
ELSE (APPLE)
IF (NOT CMAKE_COMPILER_IS_GNUCC)
# This is for the intel compiler
SET (_boost_COMPILER "-il")
ELSE (NOT CMAKE_COMPILER_IS_GNUCC)
#find out the version of gcc being used.
EXEC_PROGRAM(${CMAKE_CXX_COMPILER}
ARGS --version
OUTPUT_VARIABLE _boost_COMPILER_VERSION
)
---- кусок FindBoost --------

Вот так...
Проект у меня C++, Boost вроде тоже библиотека С++, а проверяем CMAKE_COMPILER_IS_GNUCC, вместо CMAKE_COMPILER_IS_GNUCXX.

Для проверки своего предположения, добавил в проектный скрипт информацию по компилятору. Действительно, если проект объявлен CXX, CMAKE_COMPILER_IS_GNUCC не определен.

Как обходной маневр (workaround) объявил проект, как

# говорим, что проект у нас не только С++, но и C!!!
project(project_name_of_the_whole_system CXX С)

Думаю, что необходимо спросить мнения CMake-ров на эту тему в список рассылки и завести проблему в cmake багтрэкер, по соображениям изложенным выше.

Такой вот длинный рассказ на ночь :-).

Благодарю за внимание всех, кто дочитал до конца.

Комментариев нет: