четверг, 4 августа 2016 г.

[prog] Демонстрация поведения разных ObjPlacement в MxxRu

В предыдущем посте написал много слов о том, что такое ObjPlacement и какие ObjPlacement как себя ведут. Похоже, проще один раз показать :)

Итак, пусть у нас есть вот такая файловая структура:

.
├── build.rb
└── demo
    ├── prj.rb
    └── src
        └── some_rather_long_path
            └── to_source
                └── file
                    └── main.cpp

Где main.cpp -- это классический hello_world:

#include <iostream>

int main() {
   std::cout << "Hello, world" << std::endl;
}

Проектный файл для этого hello_world имеет простейший вид (файл demo/prj.rb):

gem 'Mxx_ru'
require 'mxx_ru/cpp'

MxxRu::Cpp::exe_target {
  target 'demo.app'
  cpp_source 'src/some_rather_long_path/to_source/file/main.cpp'
}

Ну и в build.rb пока ничего интересного нет вообще:

#!/usr/bin/ruby
gem 'Mxx_ru''>= 1.6.12'
require 'mxx_ru/cpp'

MxxRu::Cpp::composite_target( MxxRu::BUILD_ROOT ) {
  required_prj 'demo/prj.rb'
}

Запускаем сборку ./build.rb --mxx-cpp-release и получаем следующее содержимое:

.
├── build.rb
├── demo
│   ├── prj.rb
│   └── src
│       └── some_rather_long_path
│           └── to_source
│               └── file
│                   ├── main.cpp
│                   └── o
│                       └── main.o
└── demo.app

Включаем в build.rb использование RuntimeSubdirObjPlacement:

MxxRu::Cpp::composite_target( MxxRu::BUILD_ROOT ) {
  global_obj_placement MxxRu::Cpp::RuntimeSubdirObjPlacement.new( 'target' )
  required_prj 'demo/prj.rb'
}

И в результате сборки проекта получаем:

.
├── build.rb
├── demo
│   ├── prj.rb
│   └── src
│       └── some_rather_long_path
│           └── to_source
│               └── file
│                   └── main.cpp
└── target
    └── release
        ├── demo
        │   └── src
        │       └── some_rather_long_path
        │           └── to_source
        │               └── file
        │                   └── main.o
        └── demo.app

Заменяем RuntimeSubdirObjPlacement на ToolsetRuntimeSubdirObjPlacement:

MxxRu::Cpp::composite_target( MxxRu::BUILD_ROOT ) {
  global_obj_placement MxxRu::Cpp::ToolsetRuntimeSubdirObjPlacement.new( 'target' )
  required_prj 'demo/prj.rb'
}

После чего собираем этот же проект и GCC, и clang-ом. Получаем на выходе:

.
├── build.rb
├── demo
│   ├── prj.rb
│   └── src
│       └── some_rather_long_path
│           └── to_source
│               └── file
│                   └── main.cpp
└── target
    ├── clang_3_8_0_2ubuntu3__x86_64_pc_linux_gnu
    │   └── release
    │       ├── demo
    │       │   └── src
    │       │       └── some_rather_long_path
    │       │           └── to_source
    │       │               └── file
    │       │                   └── main.o
    │       └── demo.app
    └── gcc_5_4_0__x86_64_linux_gnu
        └── release
            ├── demo
            │   └── src
            │       └── some_rather_long_path
            │           └── to_source
            │               └── file
            │                   └── main.o
            └── demo.app

Теперь меняем ObjPlacement на PrjAwareRuntimeSubdirObjPlacement, но без флага USE_COMPILER_ID:

MxxRu::Cpp::composite_target( MxxRu::BUILD_ROOT ) {
  global_obj_placement MxxRu::Cpp::PrjAwareRuntimeSubdirObjPlacement.new( 'target' )
  required_prj 'demo/prj.rb'
}

Получаем:

.
├── build.rb
├── demo
│   ├── prj.rb
│   └── src
│       └── some_rather_long_path
│           └── to_source
│               └── file
│                   └── main.cpp
└── target
    ├── _objs
    │   └── release
    │       └── demo_prj_rb
    │           └── demo___file-7d6a0a4f61b4
    │               └── main.o
    └── release
        └── demo.app

Можно увидеть, что для размещения объектника main.o был сдалан подкаталог со странным именем. Это сделано специально для того, чтобы не получалось слишком уж развестистых и глубоких деревьев. Путь к исходному файлу сперва модифицируется путем замены разделителей на подчеркивания. А затем, если результат оказывается слишком длинным, из него формируется новое имя, содержащее кусочки исходного имени и несколько первых символов sha1-хэша.

Ну и осталось показать результат действия PrjAwareRuntimeSubdirObjPlacement с ключиком USE_COMPILER_ID:

MxxRu::Cpp::composite_target( MxxRu::BUILD_ROOT ) {
  global_obj_placement MxxRu::Cpp::PrjAwareRuntimeSubdirObjPlacement.new(
    'target',
    MxxRu::Cpp::PrjAwareRuntimeSubdirObjPlacement::USE_COMPILER_ID )

  required_prj 'demo/prj.rb'
}

Компилируем проект и GCC, и clang, и получаем:

.
├── build.rb
├── demo
│   ├── prj.rb
│   └── src
│       └── some_rather_long_path
│           └── to_source
│               └── file
│                   └── main.cpp
└── target
    ├── clang_3_8_0_2ubuntu3__x86_64_pc_linux_gnu
    │   └── release
    │       └── demo.app
    ├── gcc_5_4_0__x86_64_linux_gnu
    │   └── release
    │       └── demo.app
    └── _objs
        ├── clang_3_8_0_2ubuntu3__x86_64_pc_linux_gnu
        │   └── release
        │       └── demo_prj_rb
        │           └── demo___file-7d6a0a4f61b4
        │               └── main.o
        └── gcc_5_4_0__x86_64_linux_gnu
            └── release
                └── demo_prj_rb
                    └── demo___file-7d6a0a4f61b4
                        └── main.o

В общем, вот как MxxRu позволяет разбираться с промежуточными и финальными результатами компиляции. Штатными, как говорится, средствами. Плюс всегда есть возможность запрограммировать что-нибудь свое :)

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