Command line to plot pdf

Hi all,

I search a way to plot PDF schematics and pcb within a command line. But i find anythings that work’s simply.
I found this post. It’s exactly that i want but it’s very old 2011 and it’s need to rebuild Kicad.

Do you have an equivalent or an other solution ?

May I ask what you application is? :slight_smile:

when i type in my terminal :
eeshema --plot pdf projectOne.sch
i hope to have a pdf document that contain my schematics.
And futher :
pcbnew --plot pdf projectOne.kicad_pcb ... (A trick that looks like this)
i hope to have a pdf document that contain my pcb botom and top face or more i don’t know…

But actually when you type :
kicad --help or eeschema --help ect… all is empty and kicad just want to open a project named “–help”.

Sorry if my response is not what you expect. I don’t know if you want to know what i try to do or an other things ?

I assume he wants to now your expected final application.
Why do you want to print via the command line and not from within the application window.
(Maybe what you want can be achieved via another route. But to give advice in that direction we need to know your use case.)

In other words we don’t know how to use the command line to print a project.

Ok i understand,

I have a project who contain many board (actually three but i have to do more…). So i have three projects that I modify regularly and i generate a pdf after each modification. The three boards are considering like one project.
With a script it’s fast to plot all pdf and to make one pdf off all on one clic.

1 Like

Well you could use git to achieve something similar. (Or even better)
see this forum post: (especially the link in the first post)

With that you have the added benefit that you have the old project files in the version control.
And with the graphical diff tool you can even see what changed between commits.

I’m not sure if the diff tool in the linked post is finished.
Here is an alternative if you are interested.

It could even be used to do what you want to achieve without git.

Thank “Rene_Poschl” with “eeplot” i can do what i want.
I had not seen it the last time because it’s all at th end off page.

The diff tool plotgitkicad is already usable. Agreed that it isn’t easy to compile. I plan to provide binaries.

I’m also looking for command line options for common output actions. I think my use case is very similar to OP, except I’m focused on the pcb, not the schematic.

I have a collection of projects that I want to panelize. I iterate over them quite frequently and have scripted panelization to a generate a new kicad_pcb file. I would then want to script also outputting fab files without having to go inte pcbnew and clicketiclick a lot before generating my plots. Next step is plotting gerbers/drill files to gcode with https://github.com/pcb2gcode/pcb2gcode.

Basically, that I have to click in ui to generate the fab outputs in pcbnew is what’s disrupting my workflow. Is there a way to do this command line? Would it be hard to implement? Basically I would like a cli tool with all the options in the plot menu:

Something like

pcbnew --plot myproject.kicad_pcb --layer=B.Cu --output myproject.gbl --Xx=Yy

or even better if I could actually pipe to the next command like a good unix tool :slight_smile:

This I mean:

https://lists.launchpad.net/kicad-developers/msg06055.html

Was this merged but later removed or am I not understanding how to call pcbnew from cli? Maybe it’s just me that doesn’t understand how to call pcbnew from cli. I get obvious “i’m trying to open this ui app wrongly” kindof error:

Just trying stuff like > /Applications/Kicad/pcbnew.app/Contents/MacOS/pcbnew --help

Found these python script examples, but not entirely sure how to actually use it? https://raw.githubusercontent.com/KiCad/kicad-source-mirror/698197ec8d147782efb7f4deefaf2a47bab95a67/demos/python_scripts_examples/gen_gerber_and_drill_files_board.py

So now I’m down the hole of trying to script kicad from outside on OSX: Make python lib pcbnew global on mac

The simplest way I have found of getting python scripts to play nicely on macOS is to put the Kicad python executable path in the shebang line ;

#!/Applications/Kicad/kicad.app/Contents/Applications/pcbnew.app/Contents/MacOS/Python

and then do a sys.import.

import sys
sys.path.insert(0, "/Applications/Kicad/kicad.app/Contents/Frameworks/python/site-packages/")
import pcbnew
from pcbnew import *

Make the script executable (chmod a+x scriptname.py) and then it can be run in place (./scriptname.py).

Here is a script that will plot Gerbers - save it somewhere and call it whatever you want, make it executable (chmod a+x), pass it the *.kicad_pcb name and the desired output directory. e.g.

./plotgerber.py ~/path/to/board.kicad_pcb ~/Desktop/MYGERBERS

Here is the script - I can’t take any credit for writing it - it was cribbed and adapted from elsewhere.

#!/Applications/Kicad/kicad.app/Contents/Applications/pcbnew.app/Contents/MacOS/Python

"""
Kicad plot pcb file.
Plot Gerber files in plot directory
"""

import sys
sys.path.insert(0, "/Applications/Kicad/kicad.app/Contents/Frameworks/python/site-packages/")
import pcbnew
from pcbnew import *

# Load board and initialize plot controller
boardName = sys.argv[1]
filePath = sys.argv[2]
board = LoadBoard(boardName)
pctl = pcbnew.PLOT_CONTROLLER(board)
popt = pctl.GetPlotOptions()
plotDir = filePath

popt.SetOutputDirectory(plotDir)
popt.SetPlotFrameRef(False)
popt.SetLineWidth(pcbnew.FromMM(0.15))
popt.SetAutoScale(False)
popt.SetScale(1)
popt.SetMirror(False)
popt.SetUseGerberAttributes(True)
popt.SetExcludeEdgeLayer(False)
popt.SetUseAuxOrigin(False)
pctl.SetColorMode(True)


layers = [
    ("F_Cu", pcbnew.F_Cu, "Top layer"),
    ("B_Cu", pcbnew.B_Cu, "Bottom layer"),
    ("B_Paste", pcbnew.B_Paste, "Paste bottom"),
    ("F_Paste", pcbnew.F_Paste, "Paste top"),
    ("F_SilkS", pcbnew.F_SilkS, "Silk top"),
    ("B_SilkS", pcbnew.B_SilkS, "Silk top"),
    ("B_Mask", pcbnew.B_Mask, "Mask bottom"),
    ("F_Mask", pcbnew.F_Mask, "Mask top"),
    ("Edge_Cuts", pcbnew.Edge_Cuts, "Edges"),
    ("Margin", pcbnew.Margin, "Margin"),
    ("In1_Cu", pcbnew.In1_Cu, "Inner1"),
    ("In2_Cu", pcbnew.In2_Cu, "Inner2"),
    ("Dwgs_User", pcbnew.Dwgs_User, "Dwgs_User"),
    ("Cmts_User", pcbnew.Cmts_User, "Comments_User"),
    ("Eco1_User", pcbnew.Eco1_User, "ECO1"),
    ("Eco2_User", pcbnew.Eco2_User, "ECO2"),
    ("B_Fab", pcbnew.B_Fab, "Fab bottom"),
    ("F_Fab", pcbnew.F_Fab, "Fab top"),
    ("B_Adhes", pcbnew.B_Adhes, "Adhesive bottom"),
    ("F_Adhes", pcbnew.F_Adhes, "Adhesive top"),
    ("B_CrtYd", pcbnew.B_CrtYd, "Courtyard bottom"),
    ("F_CrtYd", pcbnew.F_CrtYd, "Courtyard top"),
]

for layer_info in layers:
    pctl.SetLayer(layer_info[1])
    pctl.OpenPlotfile(layer_info[0], pcbnew.PLOT_FORMAT_GERBER, layer_info[2])
    pctl.PlotLayer()

pctl.ClosePlot()
1 Like

Thanks! I actually tried you approach but didn’t get it working.

First off, there is no python executable placed there so I need that - last night I tried by softlinking which didn’t work:

lrwxr-xr-x  1 viktor  staff     7B Jan 29 22:41 /Applications/Kicad/kicad.app/Contents/Applications/pcbnew.app/Contents/MacOS/python@ -> python3
~/D/e/p/kicad-python-scripts ❯❯❯ ./generate-gerbers.py
zsh: ./generate-gerbers.py: bad interpreter: /Applications/Kicad/pcbnew.app/Contents/MacOS/python: no such file or directory

So now I tried actually copying like you suggested in another post:

~/D/e/p/kicad-python-scripts ❯❯❯ cp /usr/bin/python /Applications/Kicad/kicad.app/Contents/Applications/pcbnew.app/Contents/MacOS/python
~/D/e/p/kicad-python-scripts ❯❯❯ ./generate-gerbers.py
Traceback (most recent call last):
  File "./generate-gerbers.py", line 34, in <module>
    import pcbnew
  File "/Applications/Kicad/kicad.app/Contents/Frameworks/python/site-packages/pcbnew.py", line 31, in <module>
    import _pcbnew
ImportError: dlopen(/Applications/Kicad/kicad.app/Contents/Frameworks/python/site-packages/_pcbnew.so, 2): Library not loaded: @executable_path/../Frameworks/libboost_context-mt.dylib
  Referenced from: /Applications/Kicad/kicad.app/Contents/Frameworks/python/site-packages/_pcbnew.so
  Reason: unsafe use of @executable_path in /Applications/Kicad/kicad.app/Contents/Frameworks/python/site-packages/_pcbnew.so with restricted binary

So I tried this install_name_tool that @brainstorm suggested in that other post, but still no cigarr. I think probably the hardcoded file names might need to be updated, or that find/awk script needs fixing up to be usable. Trying that…

Yes, the script’s hardcoded file list was outdated. And the find script was just broken because doubly appending .dylib to each file. I fixed that up to be:

#!/bin/bash
# Inspired on: https://www.bountysource.com/issues/31269729-libwx_osx_cocoau-3-1-dylib-not-found

# KICAD_LIBS_TOFIX="libwx_osx_cocoau_gl-3.0.0 libwx_osx_cocoau_adv-3.0.0 libwx_osx_cocoau_aui-3.0.0 libwx_osx_cocoau_adv-3.0.0 libwx_osx_cocoau_html-3.0.0 libwx_osx_cocoau_core-3.0.0 libwx_osx_cocoau_stc-3.0.0 libkicad_3dsg.2.0.0 libGLEW.2.0.0 libcairo.2 libpixman-1.0 libwx_baseu_net-3.0.0 libwx_baseu-3.0.0 libwx_baseu_xml-3.0.0 libboost_context-mt libboost_date_time-mt"

KICAD_LIBS_TOFIX=`find /Applications/Kicad/kicad.app/Contents/Frameworks/ -iname *.dylib | xargs otool -L | grep executable_path | awk '{print $1}' | awk -F'/' '{print $4}'`

for kicadlib in $KICAD_LIBS_TOFIX;
do
	echo "Fixing ${kicadlib} broken path on pcbnew..."
	install_name_tool -change @executable_path/../Frameworks/${kicadlib} /Applications/Kicad/kicad.app/Contents/Frameworks/${kicadlib} /Applications/Kicad/pcbnew.app/Contents/Frameworks/python/site-packages/_pcbnew.so
done

echo "Done! All paths should be absolute now, no @executable_path in:"
otool -L /Applications/Kicad/kicad.app/Contents/Frameworks/python/site-packages/_pcbnew.so


# Brute force step
echo "Forcing absolute paths on all the dylibs and dependencies on KiCAD, this might take a while..."
for kicadlib in $KICAD_LIBS_TOFIX;
do
	for kicaddep in $KICAD_LIBS_TOFIX;
	do
		echo "Fixing ${kicadlib} referenced by ${kicaddep}..."
		install_name_tool -change @executable_path/../Frameworks/${kicadlib} /Applications/Kicad/kicad.app/Contents/Frameworks/${kicadlib} /Applications/Kicad/pcbnew.app/Contents/Frameworks/${kicaddep}
	done
done

which now works and I have running python.

So, to run external python scripts on OSX I need:

  • Put an actual python (3?) binary in /Applications/Kicad/pcbnew.app/Contents/MacOS/python. Softlinking doesn’t work.
  • Run the script above to fix relative paths
  • Change the top of each script to import like this:
import sys
sys.path.insert(0, "/Applications/Kicad/kicad.app/Contents/Frameworks/python/site-packages/")
import pcbnew
from pcbnew import *

Then I can run them like normal scripts in OSX.

Thanks @John_Pateman and @brainstorm!

1 Like

OMG, I’m so happy that my 10-min hacked-together library munging script actually helped someone :slight_smile:

Now for extra hero points: is there any developer reading this post that could include this OSX Python libraries fix as part of kicad’s release engineering? :smiley:

1 Like

Coming back to this now with some system updates on OSX I’m back at square one. I get this

Fatal Python error: PyThreadState_Get: no current thread

error message when trying to do any external scripting. Any tips highly appreciated. It’s python 2 I should have right, not 3?

https://github.com/INTI-CMNB/KiBot can generate this and much more!