Сначала немного предыстории:
Я использую Visual Studio 2017 - Профессиональное дополнение
Разработка собственного приложения для Android на C++
Я использовал стандартный шаблон. Итак, у меня есть чистая библиотека C++ (11), в которой находится весь мой код. И предварительно скомпилированный заголовок, определенный в основном проекте, который ссылается на мою библиотеку.
Что я делаю
Я работаю над кодом, который требует большого количества встроенных данных.
Я искал в Google хорошие способы сделать это, но большинство из них кажутся очень хлопотными, и почти всегда были комментарии, в которых говорилось, что нужно просто помещать данные непосредственно в файлы заголовков, поскольку это наиболее переносимый способ.
Итак, теперь у меня есть несколько файлов заголовков, которые в основном содержат статические массивы данных. ПРИМЕЧАНИЕ они не являются «константными», как если бы вы это сделали, тогда Visual Studio 2017 попытается отобразить данные, если вы переместите определение переменной. Так что просто статично.
Затем все файлы заголовков объединяются в один файл заголовка, и на него, наконец, ссылаются в стандартном файле cpp. эффективно делая данные приватными для этого класса.
Все работает нормально. НО время компиляции становится очень медленным. И если я смотрю окно вывода, я вижу, что он тратит 80% своего времени на файл cpp (даже если не было изменений в данных или коде)
Теперь это не лучшее, что может сделать компилятор. Я ожидал, что компилятор пропустит это, поскольку не было изменений, которые напрямую влияют на файл cpp.
Я также попытался переместить вещи в предварительно скомпилированный заголовок. Но из-за этого для создания файла pch.h каждый раз требуется много времени.
Так что я делаю не так?
Обновлять
Я дважды проверил, что файлы не были изменены. Если я нажму F6 (сборка), а затем снова нажму, он все равно восстановит большие файлы.
Я также попытался переработать статические данные, чтобы они были определены в файле cpp. И это все равно без разницы.
Для наглядности это пример:
.cpp файл:
#include "Some.h"
unsigned char _someData[] =
{
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
};
unsigned char* Some::GetSomeData(void)
{
return _someData;
}
.h файл:
#pragma once
class Some
{
public:
static unsigned char* GetSomeData(void);
};
Через некоторое время я дважды проверю метки времени. Данные находятся в файле .h, поскольку данные генерируются другим автономным процессом. Этот процесс может воссоздать файл .h, не уничтожая ничего другого. Если я хочу, чтобы данные находились непосредственно в моем файле cpp, тогда мой набор инструментов должен быть более сложным и «знать» больше о системе. Это не было бы хорошим дизайном.
Забыл сказать, что я бы предпочел решение, отличное от Android. То есть кое-что, что я могу сделать только в родном C++, чтобы его можно было портировать для работы на Apple.
Определите данные в файле cpp и функции получения и объявите этот метод получения в файле .h. Кстати, какой фреймворк вы используете, чтобы приложение работало на Android и IOS?
Я могу подтвердить, что ни один из файлов не меняется между сборками. Простое нажатие F6 (сборка) дважды подряд будет иметь один и тот же эффект каждый раз (долгая компиляция в файле cpp)
@jaudo Мне потребуется время, чтобы переработать мой инструмент, чтобы он создавал файлы cpp. но я попробую. Что касается фреймворка. Это стандартный нативный кроссплатформенный шаблон C++ в Visual Studio. это называется (Приложение OpenGLES (Android, iOS)). На данный момент 99,9% всего моего кода находится в общей части C++, и именно так я хотел бы сохранить его.
@jaudo, поэтому я переделал свой инструмент. теперь он создает файл .h, содержащий GetData (); и теперь у меня также есть cpp, который определяет данные получения. И я могу сказать, что это не имело никакого значения. Единственное изменение состоит в том, что теперь он показывает мне много файлов, создание которых в сумме занимает столько же времени. Я понятия не имею, почему файлы cpp собираются каждый раз.
Вы сказали, что ваш файл cpp был создан с помощью инструмента. Вы запускаете свой инструмент перед каждой сборкой C++? Вы уверены, что выполните команду «Построить», а не «Перестроить»?
> Теперь это не лучшее, что может сделать компилятор. Я ожидал, что компилятор пропустит это, поскольку не было изменений, которые напрямую влияют на файл cpp. Что ж, MSVC не лучший компилятор, когда дело касается этих вещей. Но это действительно лучшее, что он может. Вы не можете ожидать, что компилятор «пропускает» части заголовков, потому что они не влияют на реальный код. Это просто принятие желаемого за действительное, и это очень неправильно.
@LightnessRacesinOrbit Вы можете удивляться, как хотите, пока это правда.
@jaudo Мой инструмент - это совершенно отдельный проект на C#, я запускаю его вручную как отдельный процесс. Нет никакого способа, чтобы это могло помешать перекомпиляции C++.
@PaulSpain: Кажется, вы меня неправильно поняли. Я пытаюсь сказать, что вы почти наверняка что-то упустили, учитывая представленные доказательства. Конечно, вы можете проигнорировать мой совет; Вы же не пришли сюда в поисках второго мнения, верно? :)
@LightnessRacesinOrbit вы совершенно правы .. Однако я уже знаю, что так быть не должно. отсюда и мой вопрос. Так получилось, что теперь я знаю, в чем была проблема. См. Комментарии к ответу SHR





Вы можете рассмотреть возможность использования файлов данных (вне вашего кода), которые вы читаете при запуске программы. Это создаст некоторые накладные расходы (время чтения файла), но вы решите проблемы времени компиляции.
Я не верю, что это практично / возможно при разработке приложений для Android. Все данные должны находиться в файле APK. Я не смогу загрузить то, что было отправлено. Разве вы не знаете иначе?
Что насчет: 1) Файлы данных не отправляются 2) При первом запуске приложения загрузите файлы данных и сохраните их в хранилище.
В интересной возможности. Но это похоже на решение плана Б. Должно быть что-то не так, как я ожидаю, что компилятор будет работать. Но спасибо за хорошую идею! +1
Вы можете использовать ресурсы: developer.android.com/guide/topics/resources/…
Джаудо, мне придется внимательно изучить это, но похоже, что это не сработает в моем случае для нативной платформы C++ / кросс-платформы. (Забыл сказать, что это кроссплатформенный, но это то, что я имел в виду, когда сказал портативный)
Чтобы сэкономить время компиляции, попробуйте следующее:
extern переменных данных в заголовках.#include <file> и #include "file". если вы выберете неправильный метод включения (например, используйте <> для включения вашего файла или "" для включения системы), вы потратите больше времени на поиск файла.Если вы не хотите знать, почему проект или файл перекомпилировали или перекомпилировали, даже если изменений не было, вы можете сделать это следующим образом:
Удачи
Ваш первый номер 3 - самый важный. Конечно, причина повторяющейся перекомпиляции - это следующее, но исправление этого не решит проблему длительного времени компиляции.
Хорошо, спасибо за подсказку! Наконец-то я понял. С помощью настройки диагностики все становится ясно. Код перестраивался из-за отсутствия файла. Таким образом, даже если нет никаких изменений, он все равно все перестроит. Как только я получил эту деталь, было легко найти и исправить проблему. выглядело так, будто у меня был какой-то странный файл заголовка, который не был правильно удален, но на самом деле не нужен и поэтому не тормозил сборку. Большое спасибо за ваше время и помощь.
Очевидно, компилятор не должен перекомпилировать, если в коде не было изменений. Вот где вам следует искать. Сравните, например, временные метки исходного и объектного файлов. Во-вторых, зачем помещать данные в файл заголовка, который включен в один файл cpp. Почему бы просто не поместить данные в файл cpp? Это лучшая практика.