When tools/top.mk finds it is running on Windows, it expects SHELL set to cmd.exe.

Some Windows development environments invoke a mingw version of gnu make
with SHELL set to /bin/sh or /bin/bash (either explicitly or by default),
in which case tinyUSB make fails when a $(shell...) command feeds DOS syntax to sh.
We can't just use sh, as many Windows environments won't have unix utilities
like realpath (used by this makefile for sh shell commands).

This fix forces SHELL=cmd.exe on Windows and documents the issue.
Also adds additional documentation to help the next person...

With this fix, tinyUSB can be easily built and debugged in environments like
NXP's MCUxpresso (import as a makefile project).
This commit is contained in:
Dave Nadler 2023-01-22 12:11:50 -05:00
parent ea098aeda1
commit 9b6ef4fcbc

View File

@ -1,30 +1,41 @@
ifneq ($(lastword a b),b)
$(error This Makefile require make 3.81 or newer)
$(error This Makefile requires make 3.81 or newer)
endif
# Detect whether shell style is windows or not
# https://stackoverflow.com/questions/714100/os-detecting-makefile/52062069#52062069
ifeq '$(findstring ;,$(PATH))' ';'
CMDEXE := 1
# PATH contains semicolon - so we're definitely on Windows.
CMDEXE := 1# makefile shell commands should use syntax for DOS CMD, not unix sh
# Unfortunately, SHELL may point to sh or bash, which can't accept DOS syntax.
# $(info top.mk: SHELL=$(SHELL))
# We can't just use sh, because while sh and/or bash shell may be available,
# many Windows environments won't have utilities like realpath used below, so...
SHELL := cmd.exe# Force DOS command shell on Windows.
endif
#$(info top.mk: SHELL=$(SHELL))
#$(info top.mk: CMDEXE=$(CMDEXE)...)
# Set TOP to be the path to get from the current directory (where make was
# invoked) to the top of the tree. $(lastword $(MAKEFILE_LIST)) returns
# the name of this makefile relative to where make was invoked.
THIS_MAKEFILE := $(lastword $(MAKEFILE_LIST))# this makefile is the one most recently appended to the list of makefiles
TOP := $(patsubst %/tools/top.mk,%,$(THIS_MAKEFILE))# strip off /tools/top.mk to get for example ../../..
#$(info top.mk: Initial TOP=$(TOP))
THIS_MAKEFILE := $(lastword $(MAKEFILE_LIST))
TOP := $(patsubst %/tools/top.mk,%,$(THIS_MAKEFILE))
# Set TOP to an absolute path, for example /tinyUSB (from ../../..)
ifeq ($(CMDEXE),1)
TOP := $(subst \,/,$(shell for %%i in ( $(TOP) ) do echo %%~fi))
else
TOP := $(shell realpath $(TOP))
endif
#$(info Top directory is $(TOP))
#$(info top.mk: Top directory is $(TOP))
# Set CURRENT_PATH to the relative path from TOP to the current directory, ie examples/device/cdc_msc_freertos
ifeq ($(CMDEXE),1)
CURRENT_PATH := $(subst $(TOP)/,,$(subst \,/,$(shell echo %CD%)))
else
CURRENT_PATH := $(shell realpath --relative-to=$(TOP) `pwd`)
endif
#$(info Path from top is $(CURRENT_PATH))
#$(info top.mk: Path from top is $(CURRENT_PATH))