mirror of
https://github.com/UzixLS/kicad-libs-my.git
synced 2025-07-18 15:01:20 +03:00
add makefile-pcb-release
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@ -5,3 +5,4 @@
|
||||
!/mykicadws2.kicad_wks
|
||||
!/mypower.kicad_sym
|
||||
!/my.kicad_sym
|
||||
!/makefile-pcb-release
|
376
makefile-pcb-release
Normal file
376
makefile-pcb-release
Normal file
@ -0,0 +1,376 @@
|
||||
PRO="your_project.kicad_pro"
|
||||
PRO_DIR=$(dir ${PRO})
|
||||
NAME=$(basename $(notdir ${PRO}))
|
||||
SCHFILE=${PRO_DIR}/${NAME}.kicad_sch
|
||||
PCBFILE=${PRO_DIR}/${NAME}.kicad_pcb
|
||||
REV=$(shell sed -En 's/.*\(rev "(.*)"\).*/\1/p' "${SCHFILE}")
|
||||
|
||||
KICAD_VER=7.0
|
||||
PYTHON=python
|
||||
IBOM_SCRIPT_WIN=${USERPROFILE}/Documents/KiCad/${KICAD_VER}/3rdparty/plugins/org_openscopeproject_InteractiveHtmlBom/generate_interactive_bom.py
|
||||
IBOM_SCRIPT_NIX=${HOME}/.local/share/kicad/${KICAD_VER}/3rdparty/plugins/org_openscopeproject_InteractiveHtmlBom/generate_interactive_bom.py
|
||||
IBOM_SCRIPT=$(if $(wildcard ${IBOM_SCRIPT_NIX}),${IBOM_SCRIPT_NIX},${IBOM_SCRIPT_WIN})
|
||||
COLORS_DIR_WIN=${USERPROFILE}/AppData/Roaming/kicad/${KICAD_VER}/colors
|
||||
COLORS_DIR_NIX=${HOME}/.config/kicad/${KICAD_VER}/colors
|
||||
COLORS_DIR=$(if $(wildcard ${COLORS_DIR_NIX}),${COLORS_DIR_NIX},${COLORS_DIR_WIN})
|
||||
|
||||
.PHONY: all clean gerber pdf ibom
|
||||
.FORCE:
|
||||
all: gerber pdf ibom
|
||||
|
||||
clean:
|
||||
rm -rf "${PRO_DIR}/out/"
|
||||
|
||||
|
||||
%/gerber.zip: .FORCE
|
||||
rm -rf $@ "$(@D)/gerber/"
|
||||
mkdir -p "$(@D)/gerber/"
|
||||
kicad-cli pcb export drill --output "$(@D)/gerber/" \
|
||||
--format excellon \
|
||||
--drill-origin absolute \
|
||||
--excellon-units mm \
|
||||
--excellon-separate-th \
|
||||
--excellon-zeros-format decimal \
|
||||
--generate-map \
|
||||
--map-format gerberx2 \
|
||||
"${PCBFILE}"
|
||||
kicad-cli pcb export gerbers --output "$(@D)/gerber/" \
|
||||
--layers F.Cu,B.Cu,In1.Cu,In2.Cu,F.Silkscreen,B.Silkscreen,F.Mask,B.Mask,F.Paste,B.Paste,Edge.Cuts \
|
||||
--no-protel-ext \
|
||||
--no-x2 \
|
||||
--disable-aperture-macros \
|
||||
"${PCBFILE}"
|
||||
zip -rj $@ "$(@D)/gerber/"
|
||||
rm -rf "$(@D)/gerber/"
|
||||
|
||||
gerber: ${PRO_DIR}/out/gerber.zip
|
||||
|
||||
|
||||
%/bom_interactive.html: .FORCE
|
||||
mkdir -p "$(@D)"
|
||||
${PYTHON} "${IBOM_SCRIPT}" "${PCBFILE}" \
|
||||
--dnp-field DNP \
|
||||
--group-fields "Value,Footprint" \
|
||||
--include-nets \
|
||||
--normalize-field-case \
|
||||
--no-browser \
|
||||
--dest-dir "$(abspath $(@D))" \
|
||||
--name-format "$(@F)"
|
||||
|
||||
ibom: ${PRO_DIR}/out/bom_interactive.html
|
||||
|
||||
|
||||
%/schematic.pdf:
|
||||
mkdir -p $(@D)
|
||||
$(file >${COLORS_DIR}/pdf_export.json,${pdf_export_json})
|
||||
kicad-cli sch export pdf --theme pdf_export --output "$@" --no-background-color "${SCHFILE}"
|
||||
rm "${COLORS_DIR}/pdf_export.json"
|
||||
|
||||
|
||||
define LAYERS
|
||||
{'file': "F_Edge_Cuts", 'name': "Edge.Cuts", 'mirror': False, 'border': True},
|
||||
{'file': "F_Cu", 'name': "F.Cu", 'mirror': False, 'border': False},
|
||||
{'file': "F_Paste", 'name': "F.Paste", 'mirror': False, 'border': False},
|
||||
{'file': "F_Fab", 'name': "F.Fab", 'mirror': False, 'border': False},
|
||||
{'file': "User_Drawings", 'name': "User.Drawings", 'mirror': False, 'border': False},
|
||||
{'file': "User_Eco1", 'name': "User.Eco1", 'mirror': False, 'border': False},
|
||||
{'file': "B_Edge_Cuts", 'name': "Edge.Cuts", 'mirror': True, 'border': True},
|
||||
{'file': "B_Cu", 'name': "B.Cu", 'mirror': True, 'border': False},
|
||||
{'file': "B_Paste", 'name': "B.Paste", 'mirror': True, 'border': False},
|
||||
{'file': "B_Fab", 'name': "B.Fab", 'mirror': True, 'border': False},
|
||||
endef
|
||||
%/assembly_f.pdf %/assembly_b.pdf:
|
||||
mkdir -p $(@D)
|
||||
$(file >${COLORS_DIR}/pdf_export.json,${pdf_export_json})
|
||||
$(file >$(@D)/plot.py,${plot_py})
|
||||
${PYTHON} "$(@D)/plot.py" "${PCBFILE}"
|
||||
qpdf "$(@D)/${NAME}-F_Edge_Cuts.pdf" --overlay "$(@D)/${NAME}-F_Cu.pdf" -- "$(@D)/assembly_f.pdf"
|
||||
qpdf --replace-input "$(@D)/assembly_f.pdf" --overlay "$(@D)/${NAME}-F_Paste.pdf" --
|
||||
qpdf --replace-input "$(@D)/assembly_f.pdf" --overlay "$(@D)/${NAME}-F_Fab.pdf" --
|
||||
qpdf --replace-input "$(@D)/assembly_f.pdf" --overlay "$(@D)/${NAME}-User_Drawings.pdf" --
|
||||
qpdf --replace-input "$(@D)/assembly_f.pdf" --overlay "$(@D)/${NAME}-User_Eco1.pdf" --
|
||||
qpdf "$(@D)/${NAME}-B_Edge_Cuts.pdf" --overlay "$(@D)/${NAME}-B_Cu.pdf" -- "$(@D)/assembly_b.pdf"
|
||||
qpdf --replace-input "$(@D)/assembly_b.pdf" --overlay "$(@D)/${NAME}-B_Paste.pdf" --
|
||||
qpdf --replace-input "$(@D)/assembly_b.pdf" --overlay "$(@D)/${NAME}-B_Fab.pdf" --
|
||||
rm "${COLORS_DIR}/pdf_export.json" "$(@D)/plot.py" "$(@D)/${NAME}-F_Edge_Cuts.pdf" "$(@D)/${NAME}-F_Cu.pdf" "$(@D)/${NAME}-F_Paste.pdf" "$(@D)/${NAME}-F_Fab.pdf" "$(@D)/${NAME}-User_Drawings.pdf" "$(@D)/${NAME}-User_Eco1.pdf" "$(@D)/${NAME}-B_Edge_Cuts.pdf" "$(@D)/${NAME}-B_Cu.pdf" "$(@D)/${NAME}-B_Paste.pdf" "$(@D)/${NAME}-B_Fab.pdf"
|
||||
|
||||
|
||||
%/bom.pdf:
|
||||
mkdir -p "$(@D)"
|
||||
kicad-cli sch export python-bom --output "$(@D)/bom.xml" "${SCHFILE}"
|
||||
$(file >$(@D)/bom2csv.xsl,${bom2csv_xsl})
|
||||
xsltproc -o "$(@D)/bom.csv" "$(@D)/bom2csv.xsl" "$(@D)/bom.xml"
|
||||
$(file >$(@D)/bom.rst,${bom_rst})
|
||||
$(file >$(@D)/bom.rst.style,${bom_rst_style})
|
||||
rst2pdf -s "$(@D)/bom.rst.style" "$(@D)/bom.rst" "$@"
|
||||
rm "$(@D)/bom2csv.xsl" "$(@D)/bom.rst" "$(@D)/bom.rst.style" "$(@D)/bom.csv" "$(@D)/bom.xml"
|
||||
|
||||
|
||||
# Current KiCad version cannot automatically export 3D or VRML file, so you need to manually do it and save result to out/*_3d.png
|
||||
%_3d.jpg: %_3d.png
|
||||
convert "$<" -quality 90 "$@"
|
||||
%_3d.pdf: %_3d.jpg
|
||||
convert "$<" -density 250 "$@"
|
||||
|
||||
|
||||
PC := %
|
||||
.SECONDEXPANSION:
|
||||
%/pcb.pdf: $$(@D)/schematic.pdf $$(@D)/assembly_f.pdf $$(@D)/assembly_b.pdf $$(@D)/bom.pdf $$(patsubst $${PC}.png,$${PC}.pdf,$$(wildcard $$(@D)/*_3d.png))
|
||||
qpdf --empty --pages $+ -- "$@"
|
||||
rm $+
|
||||
|
||||
pdf: ${PRO_DIR}/out/pcb.pdf
|
||||
|
||||
|
||||
|
||||
define plot_py
|
||||
import os, pcbnew, sys
|
||||
layers = [ ${LAYERS} ]
|
||||
board = pcbnew.LoadBoard(sys.argv[1])
|
||||
settings_manager = pcbnew.GetSettingsManager()
|
||||
color_settings = settings_manager.GetColorSettings('pdf_export')
|
||||
plot_controller = pcbnew.PLOT_CONTROLLER(board)
|
||||
plot_controller.SetColorMode(True)
|
||||
plot_options = plot_controller.GetPlotOptions()
|
||||
plot_options.SetOutputDirectory(os.path.dirname(os.path.abspath(__file__)))
|
||||
plot_options.SetPlotInvisibleText(False)
|
||||
# plot_options.SetPlotPadsOnSilkLayer(False)
|
||||
plot_options.SetUseAuxOrigin(False)
|
||||
plot_options.SetScale(1.0)
|
||||
plot_options.SetAutoScale(False)
|
||||
# plot_options.SetPlotMode(PLOT_MODE)
|
||||
# plot_options.SetLineWidth(2000)
|
||||
plot_options.SetNegative(False)
|
||||
plot_options.SetPlotValue(True)
|
||||
plot_options.SetPlotReference(True)
|
||||
plot_options.SetPlotViaOnMaskLayer(True)
|
||||
plot_options.SetColorSettings(color_settings)
|
||||
plot_options.SetBlackAndWhite(False)
|
||||
for layer in layers:
|
||||
layer_id = board.GetLayerID(layer['name'])
|
||||
if pcbnew.IsCopperLayer(layer_id):
|
||||
plot_options.SetDrillMarksType(pcbnew.DRILL_MARKS_FULL_DRILL_SHAPE)
|
||||
else:
|
||||
plot_options.SetDrillMarksType(pcbnew.DRILL_MARKS_NO_DRILL_SHAPE)
|
||||
plot_options.SetPlotFrameRef(layer['border'])
|
||||
plot_options.SetMirror(layer['mirror'])
|
||||
plot_controller.SetLayer(layer_id)
|
||||
plot_controller.OpenPlotfile(layer['file'], pcbnew.PLOT_FORMAT_PDF, '')
|
||||
plot_controller.PlotLayer()
|
||||
endef
|
||||
|
||||
|
||||
define pdf_export_json
|
||||
{
|
||||
"3d_viewer": {
|
||||
"background_bottom": "rgb(102, 102, 128)",
|
||||
"background_top": "rgb(204, 204, 230)",
|
||||
"board": "rgba(51, 43, 23, 0.902)",
|
||||
"copper": "rgb(179, 156, 0)",
|
||||
"silkscreen_bottom": "rgb(230, 230, 230)",
|
||||
"silkscreen_top": "rgb(230, 230, 230)",
|
||||
"soldermask_bottom": "rgba(20, 51, 36, 0.831)",
|
||||
"soldermask_top": "rgba(20, 51, 36, 0.831)",
|
||||
"solderpaste": "rgb(128, 128, 128)",
|
||||
"use_board_stackup_colors": true
|
||||
},
|
||||
"board": {
|
||||
"anchor": "rgb(255, 38, 226)",
|
||||
"aux_items": "rgb(255, 255, 255)",
|
||||
"b_adhes": "rgb(0, 0, 132)",
|
||||
"b_crtyd": "rgb(38, 233, 255)",
|
||||
"b_fab": "rgb(0, 0, 0)",
|
||||
"b_mask": "rgba(0, 132, 0, 0.300)",
|
||||
"b_paste": "rgba(0, 132, 0, 0.300)",
|
||||
"b_silks": "rgb(255, 0, 0)",
|
||||
"background": "rgb(255, 255, 255)",
|
||||
"cmts_user": "rgb(89, 148, 220)",
|
||||
"conflicts_shadow": "rgba(255, 0, 5, 0.502)",
|
||||
"copper": {
|
||||
"b": "rgba(0, 132, 0, 0.100)",
|
||||
"f": "rgba(0, 132, 0, 0.100)",
|
||||
"in1": "rgb(127, 200, 127)",
|
||||
"in10": "rgb(237, 124, 51)",
|
||||
"in11": "rgb(91, 195, 235)",
|
||||
"in12": "rgb(247, 111, 142)",
|
||||
"in13": "rgb(167, 165, 198)",
|
||||
"in14": "rgb(40, 204, 217)",
|
||||
"in15": "rgb(232, 178, 167)",
|
||||
"in16": "rgb(242, 237, 161)",
|
||||
"in17": "rgb(237, 124, 51)",
|
||||
"in18": "rgb(91, 195, 235)",
|
||||
"in19": "rgb(247, 111, 142)",
|
||||
"in2": "rgb(206, 125, 44)",
|
||||
"in20": "rgb(167, 165, 198)",
|
||||
"in21": "rgb(40, 204, 217)",
|
||||
"in22": "rgb(232, 178, 167)",
|
||||
"in23": "rgb(242, 237, 161)",
|
||||
"in24": "rgb(237, 124, 51)",
|
||||
"in25": "rgb(91, 195, 235)",
|
||||
"in26": "rgb(247, 111, 142)",
|
||||
"in27": "rgb(167, 165, 198)",
|
||||
"in28": "rgb(40, 204, 217)",
|
||||
"in29": "rgb(232, 178, 167)",
|
||||
"in3": "rgb(79, 203, 203)",
|
||||
"in30": "rgb(242, 237, 161)",
|
||||
"in4": "rgb(219, 98, 139)",
|
||||
"in5": "rgb(167, 165, 198)",
|
||||
"in6": "rgb(40, 204, 217)",
|
||||
"in7": "rgb(232, 178, 167)",
|
||||
"in8": "rgb(242, 237, 161)",
|
||||
"in9": "rgb(141, 203, 129)"
|
||||
},
|
||||
"cursor": "rgb(255, 255, 255)",
|
||||
"dwgs_user": "rgb(0, 0, 0)",
|
||||
"eco1_user": "rgb(0, 0, 0)",
|
||||
"eco2_user": "rgb(0, 0, 72)",
|
||||
"edge_cuts": "rgb(72, 72, 0)",
|
||||
"f_adhes": "rgb(132, 0, 132)",
|
||||
"f_crtyd": "rgb(255, 38, 226)",
|
||||
"f_fab": "rgb(0, 0, 0)",
|
||||
"f_mask": "rgba(0, 132, 0, 0.300)",
|
||||
"f_paste": "rgba(0, 132, 0, 0.300)",
|
||||
"f_silks": "rgb(255, 0, 0)",
|
||||
"footprint_text_invisible": "rgb(132, 132, 132)",
|
||||
"grid": "rgb(194, 194, 194)",
|
||||
"grid_axes": "rgb(72, 72, 72)",
|
||||
"locked_shadow": "rgba(255, 38, 226, 0.502)",
|
||||
"margin": "rgb(255, 38, 226)",
|
||||
"pad_plated_hole": "rgb(194, 194, 0)",
|
||||
"pad_through_hole": "rgb(227, 183, 46)",
|
||||
"page_limits": "rgb(132, 132, 132)",
|
||||
"plated_hole": "rgb(26, 196, 210)",
|
||||
"ratsnest": "rgba(0, 248, 255, 0.349)",
|
||||
"user_1": "rgb(194, 194, 194)",
|
||||
"user_2": "rgb(89, 148, 220)",
|
||||
"user_3": "rgb(180, 219, 210)",
|
||||
"user_4": "rgb(216, 200, 82)",
|
||||
"user_5": "rgb(194, 194, 194)",
|
||||
"user_6": "rgb(89, 148, 220)",
|
||||
"user_7": "rgb(180, 219, 210)",
|
||||
"user_8": "rgb(216, 200, 82)",
|
||||
"user_9": "rgb(232, 178, 167)",
|
||||
"via_blind_buried": "rgb(187, 151, 38)",
|
||||
"via_hole": "rgb(227, 183, 46)",
|
||||
"via_micro": "rgb(0, 132, 132)",
|
||||
"via_through": "rgb(236, 236, 236)",
|
||||
"worksheet": "rgb(200, 114, 171)"
|
||||
},
|
||||
"meta": {
|
||||
"name": "pdf_export",
|
||||
"version": 5
|
||||
},
|
||||
"schematic": {
|
||||
"anchor": "rgb(0, 0, 255)",
|
||||
"aux_items": "rgb(0, 0, 0)",
|
||||
"background": "rgb(245, 244, 239)",
|
||||
"brightened": "rgb(255, 0, 255)",
|
||||
"bus": "rgb(0, 0, 132)",
|
||||
"bus_junction": "rgb(0, 0, 132)",
|
||||
"component_body": "rgb(255, 255, 194)",
|
||||
"component_outline": "rgb(132, 0, 0)",
|
||||
"cursor": "rgb(15, 15, 15)",
|
||||
"fields": "rgb(132, 0, 132)",
|
||||
"grid": "rgb(181, 181, 181)",
|
||||
"grid_axes": "rgb(0, 0, 132)",
|
||||
"hidden": "rgb(94, 194, 194)",
|
||||
"hovered": "rgb(0, 0, 255)",
|
||||
"junction": "rgb(0, 150, 0)",
|
||||
"label_global": "rgb(132, 0, 0)",
|
||||
"label_hier": "rgb(114, 86, 0)",
|
||||
"label_local": "rgb(15, 15, 15)",
|
||||
"netclass_flag": "rgb(72, 72, 72)",
|
||||
"no_connect": "rgb(0, 0, 132)",
|
||||
"note": "rgb(0, 0, 194)",
|
||||
"note_background": "rgba(0, 0, 0, 0.000)",
|
||||
"override_item_colors": false,
|
||||
"page_limits": "rgb(181, 181, 181)",
|
||||
"pin": "rgb(132, 0, 0)",
|
||||
"pin_name": "rgb(0, 100, 100)",
|
||||
"pin_number": "rgb(169, 0, 0)",
|
||||
"private_note": "rgb(72, 72, 255)",
|
||||
"reference": "rgb(0, 100, 100)",
|
||||
"shadow": "rgba(102, 179, 255, 0.800)",
|
||||
"sheet": "rgb(132, 0, 0)",
|
||||
"sheet_background": "rgba(255, 255, 255, 0.000)",
|
||||
"sheet_fields": "rgb(132, 0, 132)",
|
||||
"sheet_filename": "rgb(114, 86, 0)",
|
||||
"sheet_label": "rgb(0, 100, 100)",
|
||||
"sheet_name": "rgb(0, 100, 100)",
|
||||
"value": "rgb(0, 100, 100)",
|
||||
"wire": "rgb(0, 150, 0)",
|
||||
"worksheet": "rgb(132, 0, 0)"
|
||||
}
|
||||
}
|
||||
endef
|
||||
|
||||
|
||||
define bom2csv_xsl
|
||||
<!--XSL style sheet to convert EESCHEMA XML Partlist Format to grouped CSV BOM Format
|
||||
Copyright (C) 2014, Wolf Walter.
|
||||
Copyright (C) 2013, Stefan Helmert.
|
||||
GPL v2.
|
||||
-->
|
||||
|
||||
<!DOCTYPE xsl:stylesheet [
|
||||
<!ENTITY nl "
"> <!--new line CR, LF, or LF, your choice -->
|
||||
]>
|
||||
|
||||
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
|
||||
<xsl:output method="text"/>
|
||||
<xsl:key name="partTypeByValueAndFootprint" match="comp" use="concat(footprint, '-', value)" />
|
||||
<xsl:key name="headentr" match="field" use="@name"/>
|
||||
|
||||
<xsl:template match="/export">
|
||||
<xsl:text>References, Value, Footprint, Qty</xsl:text>
|
||||
<xsl:apply-templates select="components"/>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="components">
|
||||
<!-- for Muenchian grouping of footprint and value combination -->
|
||||
<xsl:for-each select="comp[count(. | key('partTypeByValueAndFootprint', concat(footprint, '-', value))[1]) = 1]">
|
||||
<xsl:sort select="@ref" />
|
||||
<xsl:text>&nl;</xsl:text>
|
||||
<!-- list of all references -->
|
||||
<xsl:for-each select="key('partTypeByValueAndFootprint', concat(footprint, '-', value))">
|
||||
<xsl:sort select="@ref" />
|
||||
<xsl:value-of select="@ref"/><xsl:text> </xsl:text>
|
||||
</xsl:for-each><xsl:text>,</xsl:text>
|
||||
<!-- quantity of parts with same footprint and value -->
|
||||
<xsl:value-of select="value"/><xsl:text>,</xsl:text>
|
||||
<xsl:value-of select="footprint"/><xsl:text>,</xsl:text>
|
||||
<xsl:value-of select="count(key('partTypeByValueAndFootprint', concat(footprint, '-', value)))"/>
|
||||
</xsl:for-each>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
||||
endef
|
||||
|
||||
|
||||
define bom_rst
|
||||
Bill Of Materials
|
||||
-----------------
|
||||
.. csv-table::
|
||||
:file: bom.csv
|
||||
:header-rows: 1
|
||||
:widths: 4,4,5,1
|
||||
.. footer:: ${NAME} rev.${REV} BOM page ###Page###/###Total###
|
||||
endef
|
||||
|
||||
define bom_rst_style
|
||||
pageSetup:
|
||||
spacing-footer: 0mm
|
||||
spacing-header: 0mm
|
||||
margin-bottom: 5mm
|
||||
margin-gutter: 0mm
|
||||
margin-left: 7mm
|
||||
margin-right: 7mm
|
||||
margin-top: 5mm
|
||||
styles:
|
||||
base
|
||||
fontSize: 9
|
||||
table-heading:
|
||||
fontName: stdBold
|
||||
endef
|
||||
|
||||
|
||||
export PATH:=/cygdrive/c/Program Files/KiCad/${KICAD_VER}/bin:/cygdrive/c/Program Files/qpdf/bin:${PATH}
|
Reference in New Issue
Block a user