servidores - unix vs linux
Makefile que distingue entre Windows y sistemas tipo Unix (5)
Me gustaría tener el mismo Makefile para construir en Linux y en Windows.
Tal vez le gustará CMake
Me gustaría tener el mismo Makefile para construir en Linux y en Windows. Utilizo la marca GNU predeterminada en Linux y la marca mingw32-make (también GNU make ) en Windows.
Quiero que el Makefile detecte si funciona en Windows o Linux.
Por ejemplo, make clean
command en Windows se ve así:
clean:
del $(DESTDIR_TARGET)
Pero en Linux:
clean:
rm $(DESTDIR_TARGET)
También me gustaría usar diferentes separadores de directorios en Windows ( /
) y Linux ( /
).
¿Es posible detectar el sistema operativo Windows en Makefile?
PD: no quiero emular Linux en Windows (cygwin, etc.)
Hay una pregunta similar: sistema operativo que detecta el archivo MAKE , pero no encontré la respuesta aquí.
El truco de SystemRoot no funcionó para mí en Windows XP pero esto hizo:
ifeq ($(OS),Windows_NT)
#Windows stuff
...
else
#Linux stuff
....
endif
La comprobación de WINDIR o COMSPEC distingue entre mayúsculas y minúsculas. En cambio, se me ocurrió la siguiente solución, espero que ayude a alguien algún día:
# detect if running under unix by finding ''rm'' in $PATH :
ifeq ($(wildcard $(addsuffix /rm,$(subst :, ,$(PATH)))),)
WINMODE=1
else
WINMODE=0
endif
ifeq ($(WINMODE),1)
# native windows setup :
UNLINK = del $(subst /,/,$(1))
CAT = type $(subst /,/,$(1))
else
# cross-compile setup :
UNLINK = $(RM) $(1)
CAT = cat $(1)
endif
Lo resolví buscando una variable env que solo se configurará en Windows.
ifdef SYSTEMROOT
RM = del /Q
FixPath = $(subst /,/,$1)
else
ifeq ($(shell uname), Linux)
RM = rm -f
FixPath = $1
endif
endif
clean:
$(RM) $(call FixPath,objs/*)
Debido a que% SystemRoot% es la ruta al directorio de Windows, debe establecerse en todas las computadoras con Windows pero no en Linux.
A continuación, los bloques configuran variables para los diferentes programas, así como una función para convertir las barras diagonales en barras diagonales inversas.
Debe tener que usar $ (llamar a FixPath, ruta) cuando llama a un comando externo (los comandos internos funcionan bien). También podría usar algo como:
/ := /
y entonces
objs$(/)*
si te gusta ese formato mejor.
Probablemente deberías usar la variable $ (RM) para eliminar algunos archivos.