I'm working on a Go project on a Windows machine and trying to use a Makefile
to build multiple Go Lambda functions for deployment to AWS. My project structure is set up with each Lambda function in a separate directory under src/functions
, and each has its own main.go
. I'm encountering an issue when running my Makefile's build command in PowerShell through VS Code terminal.
Foler structure
/project-root
/cdk.out
/src
/functions
/hello
main.go
/goodbye
main.go
Makefile
Here's the relevant part of my Makefile
:
GOOS=linux
GOARCH=amd64
FUNCTIONS_DIR := src/functions
FUNCTIONS := $(notdir $(wildcard $(FUNCTIONS_DIR)/*))
build:
@echo "Building functions..."
@$(foreach func, $(FUNCTIONS), \
GOOS=$(GOOS) GOARCH=$(GOARCH) go build -o $(FUNCTIONS_DIR)/$(func)/bootstrap $(FUNCTIONS_DIR)/$(func)/main.go; \
echo "Built $(func)/bootstrap"; \
)
When I run make build
, I receive the following error:
"Building functions..."
go: unsupported GOOS/GOARCH pair linux /amd64
make: *** [Makefile:25: build] Error 2
I am aware that environment variables in Windows should be set differently, and I've tried using both PowerShell and Command Prompt syntaxes with no success.
Here's what I have tried:
PowerShell Syntax:
build:
@echo "Building functions..."
@$(foreach func, $(FUNCTIONS), \
$Env:GOOS='linux'; $Env:GOARCH='amd64'; go build -o $(FUNCTIONS_DIR)/$(func)/bootstrap $(FUNCTIONS_DIR)/$(func)/main.go; \
echo "Built $(func)/bootstrap"; \
)
Command Prompt Syntax:
build:
@echo "Building functions..."
@$(foreach func, $(FUNCTIONS), \
set GOOS=linux && set GOARCH=amd64 && go build -o $(FUNCTIONS_DIR)/$(func)/bootstrap $(FUNCTIONS_DIR)/$(func)/main.go; \
echo "Built $(func)/bootstrap"; \
)
I've confirmed that Go is installed correctly, and the go build
command works fine when run directly in the terminal for a single function directory.
How can I adjust my Makefile
to correctly set environment variables and build my project on Windows?
The first thing you should do is remove the @
at the beginning of your makefile recipes, so you can see the actual commands that are being invoked, and check carefully that they contain what you expect. Using @
is like running your compiler with output redirected to /dev/null so you can't see the output then trying to figure out what's wrong.
In your case, the problem is that $
is a special character to make; it introduces a make variable. So in this line:
$Env:GOOS='linux'; $Env:GOARCH='amd64'
the $
is expanded by make and since $E
is an empty variable, make will invoke:
nv:GOOS='linux'; nv:GOARCH='amd64'
which is wrong. If you hadn't added the @
then make would show you this incorrect text.
You need to double the dollar sign to escape it:
$$Env:GOOS='linux'; $$Env:GOARCH='amd64'