Как написать программу на C++, которая будет легко компилироваться в Linux и Windows?

Я делаю программу на C++.

одним из моих самых больших неприятностей с C++ является его предполагаемая независимость от платформы.

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

конечно, вы всегда можете переключиться на какую-то эмуляцию, такую как Cygwin и wine, но я спрашиваю вас, действительно ли нет другого способа?

9 ответов


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

во-первых, вам нужно начать использовать какую-то кросс-платформенную систему сборки, например проектов SCons. Во-вторых, вы должны убедиться, что все библиотеки, которые вы используете, построены как кросс-платформенные. И незначительный третий момент, я бы рекомендовал использовать компилятор, который существует на всех целевых платформах, gcc приходит на ум здесь (C++ - довольно сложный зверь, и все компиляторы имеют свои собственные специфические причуды).

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

GTK+ и QT два API, которые приходят с их собственными наборами виджетов (кнопки, списки и т. д.), в то время как wxWidgets, в - это скорее API-интерфейс оболочки для текущего набора собственных виджетов платформ. Это означает, что два первых могут выглядеть немного по-разному по сравнению с остальной частью системы в то время как последний будет выглядеть как родная программа.

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

оба из которых содержит все, от графики до входа и аудио-программ, либо через плагины или встроенные.

кроме того, если вы чувствуете, что стандартная библиотека в C++ немного отсутствует, проверьте Boost для некоторой общецелевой кросс-платформенной сладости.

Удачи.


C++ - это кросс-платформа. Проблема заключается в том, что вы используете зависимые от платформы библиотеки.

Я предполагаю, что вы действительно говорите о UI componenets - в этом случае я предлагаю использовать что - то вроде GTK+, Qt или wxWindows-каждый из которых имеет компоненты UI, которые могут быть скомпилированы для разных систем.

единственное решение - найти и использовать независимые от платформы библиотеки.

и, на стороне записки, ни Cygwin или вина эмуляция-это 100% собственные реализации той же функциональности, что и их соответствующие системы.


Как только вы узнаете о gotchas, это на самом деле не так сложно. Весь код, над которым я сейчас работаю, компилируется на 32 и 64-битных Windows, все вкусы Linux, а также Unix (Sun, HP и IBM). Очевидно, что это не продукты GUI. Кроме того, мы не используем сторонние библиотеки, если мы не собираем их сами.

у меня один .H файл, содержащий весь код, специфичный для компилятора. Например, Microsoft и gcc не согласны с тем, как указать 8-разрядный целое число. Так что ... ч я

#if defined(_MSC_VER)
   typedef __int8 int8_t;
 #elif defined(__unix)
   typedef char int8_t;
 #endif

там же совсем немного кода, который uniformizes некоторых низкоуровневых вызовов функций, например:

#if defined(_MSC_VER)
  #define SplitPath(Path__,Drive__,Name__,Ext__) _splitpath(Path__,Drive__,Dir__,Name__,Ext__)
#elif defined(__unix)
  #define SplitPath(Path__,Drive__,Name__,Ext__) UnixSplitPath(Path__,Drive__,Name__,Ext__)
#endif

теперь в этом случае я считаю, что мне пришлось написать функцию UnixSplitPath () - будут времена, когда вам это нужно. Но большую часть времени вам просто нужно найти правильную функцию замены. В моем коде я вызову SplitPath (), даже если это не собственная функция на любой платформе; #defines будет сортировать ее для мне. Нужно время, чтобы тренироваться.

Веришь или нет, мой .H файл имеет длину всего 240 строк. В этом нет ничего особенного. И что включает в себя решения проблем такого рода.

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

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


придерживайтесь ANSI C++ и библиотек, которые являются кросс-платформенными, и вы должны быть в порядке.


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

этот слой может содержать общие классы для доступа к файлам, печати, GUI и т. д.

все (не платформы) код, который использует этот слой теперь может компилируется один раз в Windows и один раз в Linux.


скомпилируйте его в окне И снова в Linux. Если вы не использовали библиотеки платформы, он должен работать. Это не похоже на Java, где вы компилируете его один раз, и он работает везде. Никто не сделал виртуальную машину для C++, и, вероятно, никогда не будет. Код, который вы пишете на C++ будет работать на любой платформе. Вам просто нужно сначала скомпилировать его на каждой платформе.


предложения:

  • используйте typedef для ints. Или #include Некоторые машины думают, что int составляет 8 байт, некоторые 4. (Раньше было 2 и 4. Как изменились времена.)

  • используйте инкапсуляцию везде, где это возможно. Компилятор моего последнего окна думал, что %lld был %I64d", дал screwy возвращаемые значения для vsnprintf (), аналогичные проблемы с close () и сокетами и т. д.

  • следите за размером стека / ограничениями размера буфера. Я столкнулся с ограничением буфера 8K UDP под Windows, среди других проблем.

  • по какой-то причине компилятор C++ моего окна не будет принимать динамические распределения из стека. Например: void foo (int a) { int b[a]; } осознавайте такие вещи. Планируйте, как вы будете перекодировать.

  • #ifdef может быть вашим лучшим другом. И твой злейший враг! (В то же время!)

Это, безусловно, можно сделать. Но скомпилировать и тестируйте рано и часто!


также Linux и Windows имеют различную модель данных. См. статью: забытые проблемы разработки 64-битных программ


Стандарт C++ код компилируется без ошибок на любой платформе. Попробуйте использовать Кровопролитие Dev C++ в windows (вместо VC++ / Borland C++).

поскольку Bloodshed Dev c++ подтверждает стандарты C++, поэтому программы, скомпилированные с его помощью, будут скомпилированы на linux без ошибок в большинстве случаев.