Используйте тот же make файл для make (Linux) и nmake (Windows)
У меня есть простой C-Programm (1 исходный файл), который я хочу скомпилировать в Linux и Windows через make resp. NMAKE. Есть ли возможность выполнить это с помощью одного файла makefile?
Я подумал о чем-то вроде
ifeq($(MAKE), nmake)
// nmake code here
else
// make code here
endif
К сожалению, nmake, похоже, не понимает ifeq
, поэтому я не могу это использовать. У меня есть рабочий файл makefile, но это дает очень уродливые результаты:
hello: hello.c
$(CC) hello.c
Это работает в обеих системах. Проблема в том, что результат зависит от поведения по умолчанию соответствующих компиляторов. В Linux я получаю исполняемый файл с именем "a.out", а не "привет". В Windows я получаю "hello.exe", но есть также "hello.obj", который я не хочу иметь.
Кто-нибудь знает об альтернативном пути? Или это то, что я пытаюсь сделать абсолютно невозможным?
Ответы
Ответ 1
Это, вероятно, не невозможно, но, скорее всего, так сложно, что было бы проще писать два make файла в любом случае.
Оба GNU make (используемые в Linux) и nmake содержат директивы, поэтому некоторые распространенные вещи могут быть помещены в общий make файл, который включен в основной файл makefile.
Ответ 2
Для этого вам следует использовать CMake. С одним исходным файлом это должно быть довольно просто!
EDIT:
Вот как вы могли бы создать простой проект:
cmake_minimum_required(VERSION 2.8)
project(Simple)
include_directories("${PROJECT_BINARY_DIR}")
add_executable(Simple simple.cpp)
Чтобы создать простой проект, вы должны сделать следующее (это предполагает, что файлы вашего источника и CMakeLists.txt находятся в ~/src/simple
:
[email protected]~/src/simple$ mkdir build
[email protected]~/src/simple$ cd build
[email protected]~/src/simple$ cmake ..
[email protected]~/src/simple$ make
Ответ 3
Я хотел использовать тот же make файл, который будет использоваться make и nmake. Поскольку make распознает продолжение строки в строках комментариев, но nmake не делает этого, это означает, что мы можем иметь отдельные инструкции для make и nmake. например:
# \
!ifndef 0 # \
# nmake code here \
MV=move # \
RM=del # \
CP=copy # \
!else
# make code here
MV=mv -f
RM=rm -f
CP=cp -f
# \
!endif
Просто убедитесь, что определенный код nmake завершен с помощью #\
Ответ 4
Я просто подумал о чем-то совершенно другом.
Если вы придерживаетесь своего чрезвычайно простого Makefile, который, как вы говорите, работает, и просто ставьте "стандартные" переменные CC и CFLAGS в ваших соответствующих средах, скажем
export CC=gcc
соответственно
set CC=CL.EXE
и
export CFLAGS=-o myexecutable
соответственно
set CFLAGS=/out:myexecutable.exe
он может работать.
Имейте в виду, я не уверен в том, какие именно варианты использовать, вам придется самим понять их. Но AFAIK оба делают варианты распознающими один и тот же набор флагов. Вы даже можете установить их в соответствующих командных строках (но не в make файле, так как NMAKE использует другой синтаксис ifeq...)
Ответ 5
Да, вы можете сделать это с помощью одного Makefile. Лучшим источником для этого материала является книга О'Рейли:
Управление проектами с помощью GNU Make, третье издание Robert Mecklenburg
См. главу 7: Переносимые файлы Makefile.
В сводке, метод должен протестировать переменную среды ComSpec, которая говорит, что присутствует интерпретатор команд Windows:
ifdef COMSPEC
MV ?= move
RM ?= del
else
MV ?= mv -f
RM ?= rm -f
endif
Я переношу это с помощью переносимой оболочки script, которая использует sed для редактирования make файла для Nmake или Gnu-make.
Ответ 6
Я не могу найти способ использовать общий make файл для работы как GNU make, так и MS nmake, главным образом потому, что у них есть несовместимый синтаксис для директив "include" и/или "if". MS nmake требует использования! префикс для директив. например,! if,! include и т.д.
Если разрешено иметь отдельные макросы, его можно обмануть. Здесь я представляю лучший способ, который я нашел до сих пор, чтобы сделать makefile совместимым как с GNU make, так и с MS nmake, соблюдая следующие правила:
- MS nmake считывает файл TOOLS.ini для макросов по умолчанию.
- MS suite использует .obj как расширение объектного файла.
- GNU make считывает файлы, определенные в переменной среды MAKEFILES.
- GNU suite использует .o как расширение объектного файла.
- GNU не нужно давать исполняемый файл расширения .exe для цели.
Примечание. Следующие испытания были протестированы с использованием MS Visual Studio 2015 и MINGW32.
Шаг 1: создайте следующий пакетный файл DOS и пусть он запускается всякий раз, когда вызывается приглашение CMD.
set MAKEFILES=TOOLS.gcc
call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"
Шаг 2. Создайте файл TOOLS.ini в рабочем каталоге, как показано ниже: (этот файл не зависит от зависимостей вашего проекта, за исключением библиотек)
[NMAKE]
LDLIBS =
CDEBUG = /Zi
LDEBUG = /debug:full
WDFLAGS = /wd4996 /wd4774 /wd4018 /wd4710 /wd4820
CFLAGS = /nologo $(CDEBUG) /EHsc /Wall $(WDFLAGS)
LDFLAGS = /nologo $(LDEBUG)
RM = del /F /Q
LINK = "$(VCINSTALLDIR)bin\link" $(LDFLAGS)
CP = copy
CC = cl
CPP = $(CC) /P
X = .exe
O = .obj
.obj.exe:
$(LINK) $** $(LOADLIBES) $(LDLIBS) /Out:[email protected]
Шаг 3. Создайте TOOLS.gcc в рабочем каталоге, как показано ниже: (этот файл не зависит от зависимостей вашего проекта, за исключением библиотек)
LD_LIBS =
LDLIBS =
CDEBUG = -g
LDEBUG = -g
CFLAGS = $(CDEBUG)
LDFLAGS = $(LDEBUG)
RM = rm -f
LINK = gcc $(LDFLAGS)
CP = cp
CC = gcc
CPP = $(CC) -E
X =
O = .o
%: %.o
$(LINK) $^ $(LOADLIBES) $(LDLIBS) -o [email protected]
Шаг 4: отредактируйте свой make файл, как показано ниже (обратите внимание на $(X) и $(O)), где указаны только зависимости.
SHELL = /usr/bin/sh
app: app1$(X) app2$(X)
app1$(X): app1$(O)
app2$(X): app2$(O)
clean:
$(RM) *.exe *.o *.obj *.ilk *.pdb *.tmp *.i *~
Шаг 5: Наслаждайтесь GNU make и MS nmake с тем же make файлом
$ nmake
$ make clean
$ nmake clean
$ make