Я обычно работаю на нескольких разных компьютерах и нескольких разных операционных системах, таких как Mac OS X, Linux или Solaris. Для проекта, над которым я работаю, я извлекаю свой код из удаленного репозитория git.
Мне нравится работать над своими проектами независимо от того, в каком терминале я нахожусь. До сих пор я нашел способы обойти изменения ОС, меняя make-файл каждый раз, когда я переключаю компьютеры. Тем не менее, это утомительно и вызывает кучу головных болей.
Как я могу изменить мой make-файл, чтобы он определял, какую ОС я использую, и соответственно изменял синтаксис?
Вот make-файл:
cc = gcc -g
CC = g++ -g
yacc=$(YACC)
lex=$(FLEX)
all: assembler
assembler: y.tab.o lex.yy.o
$(CC) -o assembler y.tab.o lex.yy.o -ll -l y
assembler.o: assembler.c
$(cc) -o assembler.o assembler.c
y.tab.o: assem.y
$(yacc) -d assem.y
$(CC) -c y.tab.c
lex.yy.o: assem.l
$(lex) assem.l
$(cc) -c lex.yy.c
clean:
rm -f lex.yy.c y.tab.c y.tab.h assembler *.o *.tmp *.debug *.acts
PROCESSOR_ARCHITECTURE
envvar кажется виртуализированным в зависимости от того, является ли процесс 32-битным или 64-битным. Так что, если у васmake
32-разрядная версия, и вы пытаетесь создать 64-разрядное приложение, это не удастся. Использование его в сочетании сPROCESSOR_ARCHITEW6432
работал для меня (см. Это и то )make
команда добавила пару магических переменных с os и arch, вероятно, слишком много проблем.OS
установлен ли он в системах, отличных от Windows. Make обрабатывает unset так же, как empty, что вызывает переход кuname
блоку на основе. Вам просто нужно добавить проверку FreeBSD там./bin/sh: -c: line 0: syntax error near unexpected token
, Windows_NT '/ bin / sh: -c: строка 0:ifeq (,Windows_NT)' make: *** [os] Error 2
Команда uname ( http://developer.apple.com/documentation/Darwin/Reference/ManPages/man1/uname.1.html ) без параметров должна указывать имя операционной системы. Я бы использовал это, затем сделал бы условия на основе возвращаемого значения.
пример
источник
Определите операционную систему с помощью двух простых приемов:
OS
uname
командаИли более безопасный способ, если не в Windows и
uname
недоступен:Кен Джексон предлагает интересную альтернативу, если вы хотите отличить Cygwin / MinGW / MSYS / Windows. Посмотрите его ответ, который выглядит так:
Затем вы можете выбрать соответствующий материал в зависимости от
detected_OS
:Ноты:
Команда
uname
такая же, какuname -s
опция-s
(--kernel-name
) по умолчанию. Посмотрите, почемуuname -s
это лучше, чемuname -o
.Использование
OS
(вместоuname
) упрощает алгоритм идентификации. Вы по-прежнему можете использовать исключительноuname
, но вы должны иметь дело сif/else
блоками, чтобы проверить все варианты MinGW, Cygwin и т. Д.Переменная окружения
OS
всегда установлена"Windows_NT"
на разные версии Windows (см.%OS%
Переменную окружения в Википедии ).Альтернативой
OS
является переменная окруженияMSVC
(она проверяет наличие MS Visual Studio , см. Пример использования Visual C ++ ).Ниже я приведу полный пример использования
make
иgcc
для создания общей библиотеки:*.so
или в*.dll
зависимости от платформы. Пример настолько прост, насколько это возможно, чтобы быть более понятным.Для установки
make
иgcc
на Windows см. Cygwin или MinGW .Мой пример основан на пяти файлах
Напоминание:
Makefile
отступ с помощью табуляции . Осторожно при копировании-вставке ниже примеров файлов.Два
Makefile
файла1.
lib/Makefile
2.
app/Makefile
Чтобы узнать больше, прочитайте документацию по автоматическим переменным , указанную cfi .
Исходный код
-
lib/hello.h
-
lib/hello.c
-
app/main.c
Сборка
Исправьте копирование-вставку
Makefile
(замените начальные пробелы одной таблицей).make
Команда одинакова на обеих платформах. Данный вывод находится на Unix-подобных ОС:Бег
Приложение должно знать, где находится общая библиотека.
В Windows простое решение - скопировать библиотеку, в которой находится приложение:
В Unix-подобных ОС вы можете использовать
LD_LIBRARY_PATH
переменную окружения:Запустите команду в Windows:
Запустите команду в Unix-подобных ОС:
источник
uname
не Linux. Я привожу лишь один пример, который вам может не понадобиться, но это может помочь кому-то, кто ищет (в Интернете) способ реализацииMakefile
для обеих платформ ;-) Что я должен изменить в своем ответе? Приветствияlib/Makefile
примереtarget
используется.so
против.dll
. Параллельный пример дляapp/makefile
будет полезен для сравненияempty string
vs.exe
для имени файла приложения. Например, я обычно не вижуapp.exe
в Unix-подобных ОС. ;-)Я недавно экспериментировал, чтобы ответить на этот вопрос, который я задавал себе. Вот мои выводы:
Поскольку в Windows вы не можете быть уверены, что
uname
команда доступна, вы можете использоватьgcc -dumpmachine
. Это покажет цель компилятора.Также может возникнуть проблема при использовании,
uname
если вы хотите сделать кросс-компиляцию.Вот пример списка возможных выводов
gcc -dumpmachine
:Вы можете проверить результат в make-файле следующим образом:
Это хорошо сработало для меня, но я не уверен, что это надежный способ получить тип системы. По крайней мере, это надежно в отношении MinGW, и это все, что мне нужно, поскольку для него не требуется наличие
uname
команды или пакета MSYS в Windows.Подводя итог,
uname
дает вам систему, на которой вы компилируете, иgcc -dumpmachine
дает систему, для которой вы компилируете.источник
uname
идет с вMinGW
любом случае? Тем не менее, дополнительная заметка о кросс-компиляции - это здорово.$(shell $(CC) -dumpmachine)
. Начиная с OS X Sierra, команда -dumpmachine работает на Clang.x86_64-apple-darwin16.6.0
и работает Wether вас называют егоgcc
,cc
илиclang
, но неcl
Мерзавец Makefile содержит многочисленные примеры того , как обойтись без AUTOCONF / Automake, но по- прежнему работать на множестве платформ unixy.
источник
if (!usesAutotools(git)) aversionTo(autotools) = justified;
Я также поясню, что это только инструменты, к которым я не склонен. Я уверен, что люди из Autotools - хорошие люди.Обновление: теперь я считаю этот ответ устаревшим. Я разместил новое идеальное решение ниже.
Если ваш make-файл может работать не на Cygwin Windows, он
uname
может быть недоступен. Это неудобно, но это потенциальное решение. Вы должны сначала проверить Cygwin, чтобы исключить его, потому что вPATH
переменной окружения тоже есть WINDOWS .источник
uname
выдаю из обычного терминала CMD, это дает мне MINGW. Я имею в виду, я до сих порuname
без использования Cygwin. У меня также есть git bash, но я не пробовал uname на нем (сейчас я в Linux). Можете ли вы сказать мне, как эти два могут быть включены в ваш код?uname
не удалось запустить, мы бы поняли, что мы находимся в Windows?Это работа, которую GNU automake / autoconf предназначена для решения. Вы можете исследовать их.
В качестве альтернативы вы можете установить переменные окружения на ваших разных платформах и сделать ваш Makefile условным по отношению к ним.
источник
make
делать то, что я хочу. Теперь я тоже хочу попасть в automake / autoconf? - нет То, что можно сделать в make-файле, безусловно, должно быть сделано в make-файле, хотя бы для того, чтобы у меня не было нескольких точек остановки каждый раз, когда я хочу изменить compile & link.Я наконец нашел идеальное решение, которое решает эту проблему для меня.
Переменная UNAME имеет значение Linux, Cygwin, MSYS, Windows, FreeBSD, NetBSD (или предположительно Solaris, Darwin, OpenBSD, AIX, HP-UX) или Unknown. Затем его можно сравнить в оставшейся части файла Makefile, чтобы отделить любые чувствительные к ОС переменные и команды.
Ключ заключается в том, что Windows использует точки с запятой для разделения путей в переменной PATH, тогда как все остальные используют двоеточия. (Можно сделать каталог Linux с символом ';' в имени и добавить его в PATH, что может привести к поломке, но кто будет делать такие вещи?) Это, по-видимому, наименее рискованный способ обнаружения родной Windows, потому что он не нужен вызов оболочки Cygwin и MSYS PATH используют двоеточия, поэтому для них требуется uname .
Обратите внимание, что переменная среды ОС может использоваться для обнаружения Windows, но не для различия между Cygwin и собственной Windows. Тестирование на эхо кавычек работает, но требует вызова оболочки.
К сожалению, Cygwin добавляет некоторую информацию о версии к выводу uname , поэтому я добавил вызовы 'patsubst', чтобы изменить его на 'Cygwin'. Кроме того, uname для MSYS на самом деле имеет три возможных выхода, начиная с MSYS или MINGW, но я использую также patsubst, чтобы преобразовать все в просто «MSYS».
Если важно различать нативные системы Windows с и без некоторого uname.exe в пути, эту строку можно использовать вместо простого назначения:
Конечно, во всех случаях требуется GNU make или другая make, которая поддерживает используемые функции.
источник
Я столкнулся с этой проблемой сегодня, и мне она понадобилась в Solaris, поэтому здесь есть стандартный способ POSIX (что-то очень похожее).
источник
Вот простое решение, которое проверяет, находитесь ли вы в среде Windows или в стиле posix (Linux / Unix / Cygwin / Mac):
Он использует тот факт, что эхо существует как в posix-подобных средах, так и в средах Windows, и что в Windows оболочка не фильтрует кавычки.
источник
$PATH
может относиться к другомуecho
(Мой делает ...)-mwindows
флаг или выбрать между.dll
или.so
, это не получится.Обратите внимание, что Makefiles чрезвычайно чувствительны к пробелам. Вот пример Makefile, который запускает дополнительную команду в OS X и работает в OS X и Linux. В целом, однако, autoconf / automake - это путь к чему-то нетривиальному.
источник
Другой способ сделать это - использовать скрипт «configure». Если вы уже используете его в своем make-файле, вы можете использовать комбинацию uname и sed, чтобы все получилось. Сначала в вашем скрипте выполните:
Затем, чтобы поместить это в ваш Makefile, начните с Makefile.in, который должен иметь что-то вроде
в этом.
Используйте следующую команду sed в вашем скрипте configure после
UNAME=uname
бита.Теперь ваш make-файл должен быть
UNAME
определен как требуется. Если / elif / else заявления все, что осталось!источник
У меня был случай, когда мне пришлось обнаружить разницу между двумя версиями Fedora, чтобы настроить параметры командной строки для inkscape:
- в Fedora 31 по умолчанию используется inkscape 1.0beta, который используется
--export-file
- в Fedora <31 по умолчанию используется inkscape 0,92, который использует
--export-pdf
Мой Makefile содержит следующее
Это работает, потому что
/etc/os-release
содержит строкупоэтому команда оболочки в Makefile возвращает строку
VERSION_ID=<value>
, а затем действует команда eval для установки переменной MakefileVERSION_ID
. Очевидно, это можно настроить для других ОС в зависимости от того, как хранятся метаданные. Обратите внимание, что в Fedora нет переменной среды по умолчанию, которая дает версию ОС, в противном случае я бы использовал это!источник