Компиляция условной библиотеки Boost.Build для каждого проекта - PullRequest
3 голосов
/ 07 августа 2009

У меня есть проект C ++, созданный с использованием Boost.Build. Проект состоит из 3 подпроектов.

    . [root]
    \-- source
        \-- common
            \-- config
                \-- config.cpp
        \-- project_1
            \-- Jamfile.jam
        \-- project_2
            \-- Jamfile.jam
        \-- project_3
            \-- Jamfile.jam
    \-- Jamroot.jam

Jamroot.jam:

    project my_project 
        : requirements 
          multi 
          debug:DEBUG
        : default-build
          static
        : build-dir bin
        ;

    alias project_1 : source/project_1 ;
    alias project_2 : source/project_2 ;
    alias project_3 : source/project_3 ;

    install dist : project_1 project_2 project_3
        : on EXE
        ;

Каждый проект имеет Jamfile.jam в соответствии с этим шаблоном:

    project project_N
      : requirements 
          CONFIG_DEFINE_1=
          CONFIG_DEFINE_2=
      ; 

    lib config : [ glob ../common/config/*.cpp ] ;

    exe project_N 
        : [ glob *.cpp ]  config
        :  
        ;

config.cpp использует определения CONFIG_DEFINE_1 и CONFIG_DEFINE_2 для условной компиляции (на самом деле это просто константы), поэтому для каждого проекта существует отдельная версия библиотеки config.

Проблема заключается в том, что такой подход заставляет библиотеку config перестраиваться при каждом построении всего проекта, независимо от того, были ли файлы изменены или нет. То есть сборка в первый раз, когда все компилируется и связывается, сборка во второй раз без каких-либо изменений - для каждого project_N создается только библиотека config. Как правильно настроить здание, чтобы не происходило компиляции с избыточностью?

1 Ответ

1 голос
/ 09 сентября 2009

Насколько я понимаю, ваша конфигурируемая библиотека является общей для разных проектов и использует разные определения для каждого проекта.

Невозможно преодолеть перекомпиляцию в этом случае, независимо от ускоренной сборки или любой другой системы сборки. Между компиляциями файлов cpp предварительно обработанные файлы имеют изменения.

Если вы хотите избежать перекомпиляции, один из вариантов - разделить библиотеку конфигурации на разные библиотеки для каждого проекта, но в зависимости от того, как выглядит config, наличие большого количества дублирующегося кода редко желательно ...

Единственный другой вариант, о котором я могу подумать, - это сокращение объема кода, который необходимо каждый раз перекомпилировать.

например. у вас есть исходный файл LargeFunction.cpp с

 #if CONFIG_DEFINE_1
     void VeryLargeFunction() {
        ...
     }
 #elif CONFIG_DEFINE_2
     void VeryLargeFunction() {
        ...
     }
 #endif

Разделите его на три файла, один из которых содержит функцию VeryLargeFunction, как определено для DEFINE_1, один - как определено для DEFINE_2, а другой - просто включает эти два на основе значений определений.

 #if CONFIG_DEFINE_1
    #include "definitionFileFor1"
 #elif CONFIG_DEFINE_2
    #include "definitionFileFor2"
 #endif

Этот файл по-прежнему нужно перекомпилировать каждый раз, но объектные файлы, содержащие «настоящий» код, не будут.

Вы будете эффективно связывать существующие объектные файлы только при каждой компиляции, т.е. перекомпилировать все

Недостаток заключается в дополнительном обслуживании, и различные определения функций находятся в разных файлах, поэтому код становится немного сложнее для чтения.

...