summaryrefslogtreecommitdiff
path: root/GNUmakefile
blob: f6b2b10efa531ed55a27f0f5388bd180b2395035 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
# GNUmakefile - Main build script for sbc-harness project
#
# Copyright (C) 2024-2025  Luke T. Shumaker <lukeshu@lukeshu.com>
# SPDX-License-Identifier: AGPL-3.0-or-later

# Project configuration ########################################################

kicad/version = 9.0.4
kicad/symbols-dir = /usr/share/kicad/symbols
kicad/footprints-dir = /usr/share/kicad/footprints

sparkfun-eagle-libraries/version = 2354daeed58cd6bcfcb97f2669765dce8ef2aaf0

paripalpp/version = 785f33cc5c67a854384e9e055c7c98d31522b097

all: build
.PHONY: all

# Configure GNU Make itself ####################################################

ifeq ($(filter notintermediate,$(.FEATURES)),)
$(error This $(firstword $(MAKEFILE_LIST)) requies GNU Make 4.4 or later for .NOTINTERMEDIATE)
endif

.NOTINTERMEDIATE:
.DELETE_ON_ERROR:
SHELL = bash -e -o pipefail

.PHONY: FORCE

empty :=
space := $(empty) $(empty)

# `generate` ###################################################################

generate/files =

generate/files += COPYING.txt
COPYING.txt:
	wget --no-use-server-timestamps -O $@ https://gitlab.com/ohwr/project/cernohl/-/wikis/uploads/819d71bea3458f71fba6cf4fb0f2de6b/cern_ohl_s_v2.txt

# Symbols ############################################################

generate/files += symbols/COPYING.kicad.md
symbols/COPYING.kicad.md:
	wget --no-use-server-timestamps -O $@ https://gitlab.com/kicad/libraries/kicad-symbols/-/raw/$(kicad/version)/LICENSE.md
# Usage: $(eval $(call patched-kicad-sym,LIBNAME,SYMNAME[,SED_ARGS[,NEW_SYMNAME]]))
define patched-kicad-sym
generate/files += symbols/kicad-$(1)-$(or $(4),$(2)).orig.kicad_sym
symbols/kicad-$(1)-$(or $(4),$(2)).orig.kicad_sym: $$(kicad/symbols-dir)/$(1).kicad_sym build-aux/kicad-sym-extract build-aux/kicad_sexpr.py $$(MAKEFILE_LIST)
	./build-aux/kicad-sym-extract <$$< $(2) | sed -E -e 's/(\(property "Description" "[^"]*)"/\1 (LukeShu'\''s version)"/' $(3) >$$@
	kicad-cli sym upgrade --force $$@
endef
$(eval $(call patched-kicad-sym,74xx,74CBTLV3257))
$(eval $(call patched-kicad-sym,Connector,HDMI_A, -e 's/HDMI_A/HDMI_A_Sink/g',HDMI_A_Sink))
$(eval $(call patched-kicad-sym,Connector,Micro_SD_Card, -e 's/ Socket//'))
$(eval $(call patched-kicad-sym,Connector,Micro_SD_Card, -e 's/Card/Socket/g' -e 's/Socket Socket/Socket/g',Micro_SD_Socket))
$(eval $(call patched-kicad-sym,Connector,Micro_SD_Card_Det1, -e 's/Card/Socket/g' -e 's/Socket Socket/Socket/g',Micro_SD_Socket_Det1))
$(eval $(call patched-kicad-sym,Connector,RJ45_Amphenol_RJMG1BD3B8K1ANR, -e 's/Amphenol/Cetus/g' -e 's/RJMG1BD3B8K1ANR/J1B1211CCD/g',RJ45_Cetus_J1B1211CCD))
$(eval $(call patched-kicad-sym,Connector,RJ45_Amphenol_RJMG1BD3B8K1ANR, -e 's/Amphenol/HanRun/g' -e 's/RJMG1BD3B8K1ANR/HR913550A/g',RJ45_HanRun_HR913550A))
$(eval $(call patched-kicad-sym,Interface_Ethernet,W5500))
$(eval $(call patched-kicad-sym,MCU_RaspberryPi,RP2040))
$(eval $(call patched-kicad-sym,Relay_SolidState,CPC1017N, -e 's/CPC1017N/KAQY214S/g',KAQY214S))
$(eval $(call patched-kicad-sym,Transistor_FET,AO3401A, -e 's/AO3401A/AO3407A/g' -e 's/4\.0A/4.3A/g',AO3407A))

# Footprints #########################################################

# KiCad
generate/files += footprints.orig.pretty/COPYING.kicad.md
footprints.orig.pretty/COPYING.kicad.md:
	wget --no-use-server-timestamps -O $@ https://gitlab.com/kicad/libraries/kicad-footprints/-/raw/$(kicad/version)/LICENSE.md
# Usage: $(eval $(call patched-kicad-fp,LIBNAME,FPNAME[,SED_ARGS[,NEW_FPNAME]]))
define patched-kicad-fp
generate/files += footprints.orig.pretty/$(or $(4),$(2)).kicad_mod
footprints.orig.pretty/$(or $(4),$(2)).kicad_mod: $$(kicad/footprints-dir)/$(1).pretty/$(2).kicad_mod $$(MAKEFILE_LIST)
	sed -E -e 's/(\(property "Description" "[^"]*)"/\1 (LukeShu'\''s version)"/' $(3) <$$< >$$@
endef
$(eval $(call patched-kicad-fp,Connector_RJ,RJ45_Hanrun_HR911105A_Horizontal, -e 's/Hanrun/HanRun/g' -e 's/HR911105A/HR913550A/g',RJ45_HanRun_HR913550A_Horizontal))
$(eval $(call patched-kicad-fp,Connector_USB,USB_C_Receptacle_Palconn_UTC16-G, -e 's/Palconn/ShouHan/g' -e 's/Palconn_UTC16/Type-C_16PIN_2MD_073/g','USB_C_Receptacle_ShouHan_Type-C_16PIN_2MD_073'))

# SparkFun
generate/files += footprints.orig.pretty/COPYING.sparkfun.md
3rd-party/SparkFun-readme.md:
	wget --no-use-server-timestamps -O $@ https://raw.githubusercontent.com/sparkfun/SparkFun-Eagle-Libraries/$(sparkfun-eagle-libraries/version)/readme.md
footprints.orig.pretty/COPYING.sparkfun.md: 3rd-party/SparkFun-readme.md $(MAKEFILE_LIST)
	sed -n '/License/,$$p' <$< >$@
generate/files += footprints.orig.pretty/SparkFun-Micro_SD_Card.kicad_mod
%.pretty: %.lbr
	rm -rf -- $@
	kicad-cli fp upgrade --output=$@ $<
3rd-party/SparkFun-Boards.lbr:
	wget --no-use-server-timestamps -O $@ https://raw.githubusercontent.com/sparkfun/SparkFun-Eagle-Libraries/$(sparkfun-eagle-libraries/version)/SparkFun-Boards.lbr
3rd-party/SparkFun-Boards.pretty/MICRO-SDCARD.kicad_mod: 3rd-party/SparkFun-Boards.pretty
footprints.orig.pretty/SparkFun-Micro_SD_Card.kicad_mod: 3rd-party/SparkFun-Boards.pretty/MICRO-SDCARD.kicad_mod $(MAKEFILE_LIST)
	sed 's/$(patsubst %.kicad_mod,%,$(<F))/$(patsubst %.kicad_mod,%,$(@F))/g' <$< >$@

# paripalpp
generate/files += footprints.orig.pretty/COPYING.paripalpp.txt
footprints.orig.pretty/COPYING.paripalpp.txt:
	wget --no-use-server-timestamps -O $@ https://raw.githubusercontent.com/paripalpp/KiCAD_libralies/$(paripalpp/version)/LICENCE
generate/files += footprints.pretty/TS-1088-AR02016.kicad_mod
footprints.orig.pretty/TS-1088-AR02016.kicad_mod:
	wget --no-use-server-timestamps -O $@ https://raw.githubusercontent.com/paripalpp/KiCAD_libralies/$(paripalpp/version)/footprints/Button_Switch_additional.pretty/TS-1088-AR02016.kicad_mod

# Other ##############################################################

generate/files += build-aux/sources.mk
ifeq ($(INNER),)
nonsource/files += COPYING.txt
nonsource/files += symbols/COPYING.kicad.md
nonsource/files += symbols/COPYING.rpi.md
nonsource/files += footprints.orig.pretty/COPYING.kicad.md
nonsource/files += footprints.orig.pretty/COPYING.sparkfun.md
nonsource/files += footprints.orig.pretty/COPYING.paripalpp.txt
# 100644 blob/regular file
# 100755 blob/executable file
# 120000 blob/symlink
# 160000 commit (submodule)
# 040000 tree (directory)
build-aux/sources.mk: $(if $(wildcard .git),FORCE)
	git ls-files --format='%(objectmode) %(path)'              \
	| sed -n 's/^100... //p'                                   \
	| grep -vFx $(foreach f,$(nonsource/files),-e $f)          \
	| sed 's,^,$(CURDIR)/,' | xargs editorconfig               \
	| sed -nE -e 's,\[$(CURDIR)/(.*)\],\1,p' -e 's/^_mode=//p' \
	| sed -E '{N;s/(.*)\n(.*)/sources_\2 += \1/;}'             \
	| sort                                                     \
	>$@.tmp
	if ! cmp -s $@.tmp $@; then mv $@.tmp $@; fi
	@echo '################################################################################'
endif

generate:
ifeq ($(INNER),)
generate: $(generate/files)
endif
.PHONY: generate

generate-clean:
	rm -f -- $(generate/files)
.PHONY: generate-clean

# `build` and `check` ##########################################################

build: output/jlcpcb
#build: output/pcbway
build: generate
.PHONY: build

_STD_PATH := $(subst $(space),:,$(filter-out $(VIRTUAL_ENV)/bin,$(subst :,$(space),$(PATH))))
_STD_PYTHONPATH := $(shell unset PYTHONPATH VIRTUAL_ENV; PATH=$(_STD_PATH); type python3 >&2; python3 -c 'import sys; print(":".join(sys.path))')

export MYPYPATH = $(CURDIR)/build-aux/mypy-stubs
export VIRTUAL_ENV = $(CURDIR)/build-aux/venv
export PATH = $(VIRTUAL_ENV)/bin:$(_STD_PATH)
# We need to include the standard non-venv path, so that kikit can find kicad.
export PYTHONPATH = $(CURDIR)/3rd-party/kicad-library-utils/common:$(_STD_PYTHONPATH)

build-aux/venv: build-aux/requirements.txt
	unset PYTHONPATH VIRTUAL_ENV; python3 -m venv $@
	unset PYTHONPATH VIRTUAL_ENV; $@/bin/pip install -r $<
	touch --no-create $@

output/jlcpcb: sbc-harness.kicad_sch sbc-harness.kicad_pcb build-aux/venv
	rm -rf $@
	kikit fab jlcpcb \
	  --no-drc --nametemplate='sbc-harness-{}' \
	  --assembly --schematic=sbc-harness.kicad_sch --field='LCSC Part #' \
	  sbc-harness.kicad_pcb $@
# When uploaded as a CSV, JLCPCB detects our UTF-8 as GB-18030 (or one
# of the many other Chinese codepages that agree with GB-18030 for the
# UTF-8 bytes of "Ωµ±").  So put it in an XLS so JLC gets the encoding
# right.
	build-aux/csv2xls JLCPCB_BOM <$@/sbc-harness-bom.csv >$@/sbc-harness-bom.xls
	rm $@/sbc-harness-bom.csv
	rm -r $@/gerber
output/pcbway: sbc-harness.kicad_sch sbc-harness.kicad_pcb build-aux/venv
	rm -rf $@
	kikit fab pcbway \
	  --no-drc --nametemplate='sbc-harness-{}' \
	  --assembly --schematic=sbc-harness.kicad_sch --partNumber='LCSC Part #' \
	  sbc-harness.kicad_pcb $@

check: generate
.PHONY: check

# `lint` and `format` ##########################################################

-include build-aux/sources.mk
sources_all := $(foreach v,$(filter sources_%,$(.VARIABLES)),$($v))

# `lint` ###############################
lint: lint/src
lint/src:
	$(MAKE) -k INNER=t $(patsubst sources_%,lint/%,$(filter-out sources_all,$(filter sources_%,$(.VARIABLES))))
$(patsubst sources_%,lint/%,$(filter-out sources_all,$(filter sources_%,$(.VARIABLES)))): build-aux/lint-src
	./build-aux/lint-src $(@F) $(sources_$(@F))
lint/python3 lint/python3-type-stubs: build-aux/venv
.PHONY: lint lint/%

# `format` #############################
# generic ##########
format: $(patsubst sources_%,format/%,$(filter-out sources_all sources_unknown,$(filter sources_%,$(.VARIABLES))))
.PHONY: format format/%
# specific #########
format/sh format/bash: format/%:
	shfmt --write --case-indent --simplify $(sources_$(@F))
format/python3 format/python3-type-stubs: ./build-aux/venv
	black $(sources_$(@F))
	isort $(sources_$(@F))
format/kicad-symbol-lib:
	for file in $(sources_$(@F)); do kicad-cli sym upgrade --force "$$file"; done
format/kicad-footprint:
	for dir in $(sort $(dir $(sources_$(@F)))); do kicad-cli fp upgrade --force "$$dir"; done
# --fix[more] is broken ATM
#       ./3rd-party/kicad-library-utils/klc-check/check_footprint.py --fixmore -- $(sources_$(@F))
format/kicad-project format/kicad-schematic format/kicad-symbol-lib-table format/kicad-pcb format/kicad-footprint-lib-table:
	@: TODO: Write/adopt formatters for these file types
format/make format/cmake format/gitignore format/ini format/9p-idl format/9p-log format/markdown format/pip format/man-cat:
	@: TODO: Write/adopt formatters for these file types