Mxx_ru обновился до версии 1.6.11
Установить Mxx_ru можно командой gem install Mxx_ru
Обновить Mxx_ru можно командой gem update Mxx_ru
Так же Mxx_ru можно загрузить с SourceForge (gem-файл).
Из мелочей: в данной версии появились новые шаблоны externals и ext-cmake-prj для mxxrugen. А так же новый тип obj_placement-а под именем ToolsetRuntimeSubdirObjPlacement, который создает имена подкаталогов с результатами компиляции вида vc14_0_19_00_23918_x64 и gccmingw_5_3_0__x86_64_w64_mingw32.
А из главного в этой версии реализована возможность использования проектов с CMake-вскими проектными файлами в рамках контролируемой Mxx_ru сборки. Как это может выглядеть покажу на примере подключения исходников библиотеки soci в Mxx_ru-шный проект.
Сперва добавляем загрузку нужной версии soci через MxxRu::externals:
MxxRu::arch_externals :soci do |e| e.url 'http://downloads.sourceforge.net/project/soci/soci/soci-3.2.3/soci-3.2.3.tar.gz' e.map_dir 'backends' => 'dev/soci' e.map_dir 'cmake' => 'dev/soci' e.map_dir 'core' => 'dev/soci' e.map_file 'CMakeLists.txt' => 'dev/soci/*' end |
Далее создаем Mxx_ru-ную обертку вокруг подпроекта soci и кладем ее в каталог dev/soci_mxxru. Получается что-то вроде:
my_prj/
`- externals.rb
`- dev/ # Рабочий корень проекта.
`- soci/ # Исходники soci, полученные с помощью MxxRu::externals.
`- backends/
`- cmake/
`- core/
`- CMakeLists.txt
`- soci_mxxru/ # Обертка для soci.
`- prj.rb
...
Внутри файла soci_mxxru/prj.rb имеем следующее:
require 'mxx_ru/cpp' MxxRu::Cpp::ext_cmake_project { where 'soci' with WITH_BOOST: :ON, WITH_ORACLE: :OFF, SOCI_EMPTY: :OFF, SOCI_SHARED: :ON, SOCI_STATIC: :OFF, SOCI_TESTS: :OFF includedir_subfolder "soci" includedir_subfolder "soci/postgresql" include_path "/usr/include/postgresql", MxxRu::Cpp::Target::OPT_UPSPREAD lib 'soci_core' lib 'soci_postgresql' } |
Сейчас пойдем по частям, дабы разобраться, что там происходит. Только сперва поясню, что my_prj -- это Unix-only проект, для которого нужен soci только с поддержкой PostgresSQL. Необходимые для этого хозяйства зависимости (как то библиотека libpg и Boost) ставятся через штатный менеджер зависимостей конкретного Unix-а (в моем случае это Ubuntu с apt-get).
Итак, сперва мы указываем, где брать главный CMakeLists.txt для сборки soci: where 'soci'. Эта запись означает, что CMakeLists.txt лежит в подкаталоге soci рабочего корневого каталога проекта.
Далее в конструкции 'with' перечисляются все опции, которые нам бы пришлось указывать для cmake, если бы soci мы собирали вручную. Т.е. весь этот набор из 'WITH_BOOST', 'WITH_ORACLE', 'SOCI_EMPTY' и т.д., трансформируется в последовательность аргументов -D для cmake.
Благодаря синтаксису Ruby, перечень опций для with можно записать разными способами. Можно так, как показано выше. Можно вот так:
with WITH_BOOST: 'ON', WITH_ORACLE: 'OFF', SOCI_EMPTY: 'OFF', SOCI_SHARED: 'ON', SOCI_STATIC: 'OFF', SOCI_TESTS: 'OFF' |
Можно вот так:
with :WITH_BOOST => 'ON', :WITH_ORACLE => 'OFF', :SOCI_EMPTY => 'OFF', :SOCI_SHARED => 'ON', :SOCI_STATIC => 'OFF', :SOCI_TESTS => 'OFF' |
Ну или еще несколькими комбинациями. Тут уж как кому нравится.
Гораздо интереснее вот эти две строки:
includedir_subfolder "soci" includedir_subfolder "soci/postgresql" |
Они нужны вот для чего. Когда сборка посредством cmake завершается, выполняется make install. В результате чего заголовочные файлы копируются в некоторый подкаталог с именем include. При этом Mxx_ru автоматически добавляет каталог include в include_path. Но в случае с soci в include выстраивается своя собственная структура подкаталогов:
include/
`- soci/
`- postgresql/
Для нормального использования soci нужно, чтобы include/soci, а так же include/soci/postgresql, попали в include_path. Для этого и нужны команды includedir_subfolder. Они указывают Mxx_ru что внутри includedir будут еще два подкаталога soci и soci/postgresql, которые так же должны попасть в include_path.
Инструкция include_path "/usr/include/postgresql", MxxRu::Cpp::Target::OPT_UPSPREAD предписывает явно добавить в include_path путь к заголовочным файлам libpg. Причем тут важно использование опции OPT_UPSPREAD. Это фишка Mxx_ru. Данная опция говорит о том, что данный путь к заголовкам libpg будет задан не для всех подпроектов моего проекта my_prj. А только для тех, кто прямо или косвенно зависит от soci_mxxru/prj.rb. Т.е. если я в неком проектном файле my_db_pool/prj.rb добавляю required_prj 'soci_mxxru/prj.rb', то при компиляции my_db_pool в опциях -I для компилятора будет фигурировать путь к libpg. А если в другом подпроекте my_logger/prj.rb я soci не использую, то при компиляции my_logger этот путь в опции -I добавляться не будет.
Кстати говоря, когда ext_cmake_project выполняет make install после сборки CMake-проекта, он добавляет результирующий include к include_path именно с опцией OPT_UPSPREAD. Аналогично работают и команды includedir_subfolders. Т.е. глобальный include_path всего моего проекта my_prj не будет захламлен путями к заголовочным файлам soci или libpg. Эти пути будут появляться только в тех подпроектах, которые от soci и libpg зависят.
Ну и финальные команды:
lib 'soci_core' lib 'soci_postgresql' |
Просто указывают, что все подпроекты, которые будут делать required_prj 'soci_mxxru/prj.rb' должны быть слинкованы с библиотеками soci_core и soci_postgresql.
Допустим, при сборке my_prj я сбрасываю результаты компиляции в подкаталог target/<build-mode> (где build-mode -- это либо release, либо debug). После компиляции в рабочем корне проекта у меня получится что-то вроде:
target/
└── release
├── include
│ └── soci
│ └── postgresql
├── ...
├── soci
│ └── cmake_build_gcc_5_2_1__x86_64_linux_gnu_release
│ ├── backends
│ │ ├── CMakeFiles
│ │ └── postgresql
│ │ ├── CMakeFiles
│ │ │ └── soci_postgresql.dir
│ │ └── test
│ │ └── CMakeFiles
│ ├── CMakeFiles
│ │ ├── 3.2.2
│ │ │ ├── CompilerIdC
│ │ │ └── CompilerIdCXX
│ │ ├── check.dir
│ │ └── CMakeTmp
│ ├── core
│ │ └── CMakeFiles
│ │ └── soci_core.dir
│ └── lib
...
По этой картинке станет более понятно, как же происходит работа с CMake-проектами.
Mxx_ru определяет, где именно будут оказываться результаты компиляции. За это в Mxx_ru отвечает такая штука, как obj_placement. В данном случае выбран такой obj_placement, который создает поддерево target/release.
В этом поддереве создаетя подкаталог для сборки soci. А в нем -- подкаталог, в котором будет работать cmake. В данном случае именя этого cmake_build-каталога выбрал сам Mxx_ru. Получилось, с учетом режима сборки и версии gcc, имя cmake_build_gcc_5_2_1__x86_64_linux_gnu_release.
Далее Mxx_ru переходит в этом cmake_build-каталог и запускает две команды:
cmake -DCMAKE_BUILD_TYPE=Release -DWITH_BOOST=ON ... -G "Unix Makefiles" path-to-my_prj-dev/soci
cmake --build . --target install
Т.е. cmake-сборка сначала конфигурируется с учетом режима сборки, типа компилятора, дополнительных опций и т.д. После чего выполняется сама сборка и последующий make install. При этом все .a/.so-файлы располагаются в target/release, а заголовочные файлы -- в target/release/include. При этом пути к библиотекам автоматически добавляются в lib_path, а пути к заголовочным файлам -- в include_path (ну об этом речь шла выше).
Если бы компиляция велась clang-ом в режиме debug, то в target была бы приблизительно такая же картинка, но с несколько другими именами:
target/
├── debug
│ ├── include
│ │ └── soci
│ │ └── postgresql
│ ├── ...
│ ├── soci
│ │ └── cmake_build_clang_3_6_2_1__x86_64_pc_linux_gnu_debug
│ │ ├── backends
│ │ │ ├── CMakeFiles
│ │ │ └── postgresql
│ │ │ ├── CMakeFiles
│ │ │ │ └── soci_postgresql.dir
│ │ │ └── test
│ │ │ └── CMakeFiles
│ │ ├── CMakeFiles
│ │ │ ├── 3.2.2
│ │ │ │ ├── CompilerIdC
│ │ │ │ └── CompilerIdCXX
│ │ │ ├── check.dir
│ │ │ └── CMakeTmp
│ │ ├── core
│ │ │ └── CMakeFiles
│ │ │ └── soci_core.dir
│ │ └── lib
│ ...
Если имена, которые Mxx_ru генерирует для cmake_build-каталога не нравятся (например, в результате пути к файлам оказываются слишком длинными, чего CMake категорически не любит), то можно задать собственное имя: build_dir_name 'cmakebld', например.
Так же, может потребоваться, чтобы заголовочные файлы после make install оказывались не в include, а в каком-то другом подкаталоге. Изменить это имя можно так: install_includedir 'my_headers'. Однако, сам my_headers всегда будет оказываться там, где на это укажет используемый в проекте obj_placement.
Вот в кратце, что сейчас позволяет делать ext_cmake_project. Это пока самая первая версия. Наверняка что-то еще будет меняться и добавляться по мере накопления опыта. Так что следите за анонсами ;)
Комментариев нет:
Отправить комментарий