Подтвердить что ты не робот

Обработка stdafx.h в кросс-платформенном коде

У меня есть программа на Visual С++, которая использует предварительно скомпилированные заголовки (stdafx.h). Теперь мы переносим приложение в Linux с помощью gcc 4.x.

Вопрос заключается в том, как обрабатывать предварительно скомпилированный заголовок в обеих средах. Я googled, но не могу прийти к выводу.

Очевидно, я хочу оставить stdafx.h в Visual Studio, так как база кода довольно большая, а предварительно скомпилированные заголовки увеличивают время компиляции.

Но вопрос в том, что делать в Linux. Вот что я нашел:

  • Оставьте stdafx.h как есть. gcc компилирует код значительно быстрее, чем VС++ (или это только моя машина Linux сильнее...:)), поэтому я, возможно, доволен этой опцией.
  • Используйте подход здесь - сделайте stdafx.h похожим (установите USE_PRECOMPILED_HEADER только для VS):

    #ifdef USE_PRECOMPILED_HEADER
    ... my stuff
    #endif 
    
  • Используйте подход здесь - скомпилируйте VС++ с /FI до неявно include stdafx.h в каждом файле cpp. Поэтому в VS ваш код можно легко переключать, чтобы компилироваться без предварительно скомпилированных заголовков, и код не должен изменяться.
    Мне лично не нравятся зависимости, а беспорядок stdafx.h подталкивает большую базу кода. Поэтому вариант привлекателен для меня - на Linux у вас нет stdafx.h, но при этом можно включить только предварительно скомпилированные заголовки на VS только /FI.

  • В компиляции Linux stdafx.h только как предварительно скомпилированный заголовок (mimic Visual Studio)

Ваше мнение? Существуют ли другие подходы к решению проблемы?

4b9b3361

Ответ 1

Лучше всего использовать предварительно скомпилированные заголовки для быстрой компиляции.

Вы также можете использовать предварительно скомпилированные заголовки в gcc. См. здесь.

Скомпилированный предварительно скомпилированный заголовок будет иметь расширение, добавленное как .gch вместо .pch.

Так, например, если вы предварительно компилируете stdafx.h, у вас будет предварительно скомпилированный заголовок, который будет автоматически искать вызванный stdafx.h.gch в любое время, когда вы включаете stdafx.h

Пример:

stdafx.h:

#include <string>
#include <stdio.h>

a.cpp:

#include "stdafx.h"
int main(int argc, char**argv)
{
  std::string s = "Hi";
  return 0;
}

Затем скомпилируйте как:

> g++ -c stdafx.h -o stdafx.h.gch
> g++ a.cpp
> ./a.out

Ваша компиляция будет работать, даже если вы удалите stdafx.h после шага 1.

Ответ 2

Я использовал вариант 3 в прошлый раз мне нужно было сделать то же самое. Мой проект был довольно маленьким, но это работало чудесно.

Ответ 3

Я либо поеду на вариант 4, либо на вариант 2. Я экспериментировал с прекомпилированными заголовками как на разных версиях VS, так и на GCC на Linux (сообщения в блогах об этом здесь и здесь). По моему опыту, VS намного более чувствителен к длине включенных путей, количеству каталогов в пути включения и количеству файлов include, чем g++. Когда я измерил время сборки правильно упорядоченных предварительно скомпилированных заголовков, это существенно изменило бы время компиляции под VS, тогда как g++ в значительной степени не впечатлило это.

Собственно, на основании вышеизложенного, что я делал в последний раз, когда я работал над проектом, когда это было необходимо, чтобы обуздать время компиляции, было прекомпилировать эквивалент stdafx.h под Windows, где это имело смысл и просто использовало его как обычный файл под Linux.

Ответ 4

Очень простое решение. Добавьте фиктивную запись файла для "stdafx.h" в среду Linux.

Ответ 5

Это просто, действительно:


Project- > Настройки проекта (Alt + F7)


Параметры проекта-Диалог:
С++ → Категория: Предварительно скомпилированные заголовки → Предварительно скомпилированные заголовки с переключателями → отключить

Ответ 6

Так как stdafx.h по умолчанию все компоненты, относящиеся к Windows, я поместил пустой stdafx.h на другую платформу. Таким образом, ваш исходный код остается идентичным при эффективном отключении stdafx от Linux без необходимости удаления всех строк #include "stdafx.h" из вашего кода.

Ответ 7

Я бы использовал только вариант 1 в большой команде разработчиков. Варианты 2, 3 и 4 часто останавливают производительность других членов вашей команды, поэтому вы можете сэкономить несколько минут в день во время компиляции.

Вот почему:

Предположим, что половина ваших разработчиков использует VS и половину использования gcc. Время от времени какой-то разработчик VS забудет включить заголовок в .cpp файл. Он не заметит, потому что stdafx.h неявно включает его. Таким образом, он подталкивает свои изменения в контроле версий, а затем несколько других членов команды gcc получат ошибки компилятора.  Таким образом, за каждые 5 минут в день вы получаете, используя предварительно скомпилированные заголовки, 5 других людей тратят время, исправляя недостающие заголовки.

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

Вариант 4 звучит привлекательно, но что, если вы хотите использовать другой компилятор в какой-то момент? Вариант 4 работает только в том случае, если вы используете только VS и gcc.

Обратите внимание, что опция 1 может сделать компиляцию gcc несколько секунд. Хотя это может быть и не заметно.

Ответ 8

Если вы используете CMake в своем проекте, то есть модули, которые автоматизируют его для вас, очень удобно, например, см. cmake-precompiled-header здесь. Чтобы использовать его, просто включите модуль и вызовите:

include( cmake-precompiled-header/PrecompiledHeader.cmake )
add_precompiled_header( ${target} ${header} FORCEINCLUDE SOURCE_CXX ${source} )

Другой модуль под названием Cotire создает предварительно скомпилированный файл заголовка (нет необходимости вручную писать StdAfx.h) и ускоряет сборку другими способами - см. здесь.

Ответ 9

Я сделал как вариант 2 (#ifdef), так и вариант 4 (PCH для gcc) для кросс-платформенного кода без проблем.

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