parent
d880606e72
commit
bdef682d4d
|
@ -29,13 +29,6 @@ if( DOXYGEN_FOUND )
|
|||
COMMENT "building doxygen docs into directory Documentation/doxygen/html"
|
||||
)
|
||||
|
||||
add_custom_target( dev-docs
|
||||
${CMAKE_COMMAND} -E remove_directory Documentation/development/doxygen
|
||||
COMMAND ${DOXYGEN_EXECUTABLE}
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/Documentation/development
|
||||
COMMENT "building developer's resource docs into directory Documentation/development/doxygen/html"
|
||||
)
|
||||
|
||||
# Add the docset targets
|
||||
add_subdirectory( docset )
|
||||
else()
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
|
||||
KIWAY Build Symbols, Definitions and Intentions
|
||||
|
||||
|
||||
COMPILING_DLL:
|
||||
|
||||
This is a signal to import_export.h, and when present, toggles the
|
||||
interpretation of the #defines in that file. Its purpose should not be
|
||||
extended beyond this.
|
||||
|
||||
|
||||
USE_KIWAY_DLLS:
|
||||
|
||||
Comes from CMake as a user configuration variable, settable in the Cmake
|
||||
user interface. It decides if KiCad will be built with the *.kiface program
|
||||
modules.
|
||||
|
||||
|
||||
BUILD_KIWAY_DLL:
|
||||
|
||||
Comes from CMake, but at the 2nd tier, not the top tier. By 2nd tier,
|
||||
something like pcbnew/CMakeLists.txt, not /CMakeLists.txt is meant. It is
|
||||
not a user configuration variable. Instead, the 2nd tier CMakeLists.txt file
|
||||
looks at the top level USE_KIWAY_DLLS and decides how the object files under
|
||||
the 2nd tier's control will be built. If it decides it wants to march in
|
||||
lockstep with USE_KIWAY_DLLS, then this local CMakeLists.txt file may pass a
|
||||
defined BUILD_KIWAY_DLL (singular) on the compiler command line to the
|
||||
pertinent set of compilation steps under its control.
|
||||
|
|
@ -1,243 +0,0 @@
|
|||
Proposed Plan for adding Nano Meters into PCBNEW as the Board Internal Unit
|
||||
===========================================================================
|
||||
|
||||
Author: Dick Hollenbeck November 25, 2011
|
||||
|
||||
Introduction:
|
||||
============
|
||||
|
||||
This document sketches out a plan to move KiCad's PCBNEW program from deci-mil
|
||||
internal units to nanometer internal units. The changes to the code are
|
||||
significant enough to describe the basic process before the work is started.
|
||||
|
||||
Definitions:
|
||||
===========
|
||||
|
||||
*) Board Internal Units (BIU). This is a pseudonym for the engineering units
|
||||
used by a BOARD when it is in RAM, and only when it is in RAM. BIU is
|
||||
essentially equal to nanometers in the future, and equal to deci-mils currently.
|
||||
A BIU refers typically to a measurement or a position on an XY grid, and this is
|
||||
because this grid is dimensioned in BIUs along both its X and Y axes. Both X and
|
||||
Y can be either positive or negative on this grid. In the case of measurements
|
||||
or scalars, there can be a radius, a diameter, a distance (length), and all of
|
||||
these can and should be expressed in BIUs, so long we are in RAM and so long as
|
||||
we are talking about the objects within the class BOARD instance. One special
|
||||
feature of XY points within the BIU coordinate system is that they will always
|
||||
be integers. In contrast, distances and other forms of measurements are not
|
||||
subject to the same limitation by the very nature of physics. Coordinates are
|
||||
always integers because we used signed whole numbers to represent these BIU
|
||||
coordinates.
|
||||
|
||||
*) Snap grid. A snap grid is a subset of the full set of possible XY coordinates
|
||||
in the BIU coordinate system. Points falling on the snap grid are evenly spaced
|
||||
in X and Y directions and are some integer multiple apart in this 2D space,
|
||||
greater than one BIU.
|
||||
|
||||
Assumptions:
|
||||
===========
|
||||
|
||||
a) It is ok to modify the board file format in order to handle the BIU change.
|
||||
|
||||
b) Boards saved on disk in the new format will not be readable using old software.
|
||||
|
||||
c) Since we have no backwards compatibility obligation (see b) above), we can
|
||||
make significant changes to the file format while we have this disruption
|
||||
opportunity.
|
||||
|
||||
General:
|
||||
=======
|
||||
|
||||
With nano meters as the Board Internal Unit (BIU), a 32 bit signed integer can
|
||||
only hold about 2 meters of positive length and 2 meters of negative length.
|
||||
Moreover, because most of the bits within a 32 bit integer can be "used up" to
|
||||
hold a typical length within a board, it is very likely that if pure 32 bit
|
||||
integer math is done, such as the multiplication of two integers in order to
|
||||
calculate a hypotenuse, then there will be an overflow within the 32 bit
|
||||
integer. (Another way to think of the BIU acronym is "Board Integer Unit" instead
|
||||
of as Board Internal Unit, to pave the way for the BFU, discussed below.)
|
||||
|
||||
Therefore all intermediate products, quotients, trig, and exponential
|
||||
calculations should be done using some larger floating point type. By larger,
|
||||
bitness or number of bits is meant. Distances that do not have to be rounded
|
||||
back to integer immediately can and should stay in the larger floating point
|
||||
"value container" for as long as possible. The typedef name of this floating
|
||||
point type is BFU (Board Float Unit). The engineering units on a BFU are the
|
||||
same as on a BIU. A typedef is nice so that we can toggle between double and
|
||||
"long double" for various compilations, and so that when performing casts, these
|
||||
are brief textual expressions.
|
||||
|
||||
Format Strings:
|
||||
==============
|
||||
|
||||
Because all our save to disk functions use printf() style format strings, we
|
||||
discuss how to construct a format string in the most usable way. There should be
|
||||
a printf() style format string like "%.6g" for the BFU (cast to a hard coded
|
||||
double) enclosed within a #define and its name should be FMT_ENG. This format
|
||||
string will be used at least for saving BOARD and MODULE files, and perhaps
|
||||
more.
|
||||
|
||||
FMT_ENG stands for "format string for ENGineering units used out in the file". A
|
||||
define is needed simply to provide consistency across many sites of usage. BIUs
|
||||
will be scaled before being written to disk in most every case, and since
|
||||
scaling is a multiplication, it means casting one of the factors to BFU, and
|
||||
then this product is output with a printf() style function using the FMT_ENG
|
||||
string segment.
|
||||
|
||||
That is, the FMT_ENG will be suitable for use with a BFU type. When BFU is set
|
||||
to double, then FMT_ENG will be set to "%.6g". When BFU is set to long double
|
||||
then FMT_ENG will be set to "%.6Lg". For example:
|
||||
|
||||
#if USE_DOUBLE_BFU
|
||||
typedef double BFU;
|
||||
#define FMT_ENG ".%10g"
|
||||
#else
|
||||
typedef long double BFU;
|
||||
#define FMT_ENG ".%10Lg"
|
||||
#endif
|
||||
|
||||
A format string can then be built up using compile time concatenation of
|
||||
strings, like this:
|
||||
|
||||
fprintf( fp, "Value: " FMT_ENG " " FMT_ENG "\n", BFU( biu1 * scale), BFU( biu2 * scale ) );
|
||||
|
||||
The 3rd and 4th arguments are BFUs, and the casting is done after the multiply
|
||||
since the scaling factor is already a double or perhaps even a long double. The
|
||||
final argument needs to match the format string, so the final product is wrapped
|
||||
in a BFU, which could actually be a truncation down to 64 bit float from 80 bit
|
||||
float. The key points are: the calculation must be done in a float type at least
|
||||
as bit-wide as BFU, and that the value actually passed to fprintf() must match
|
||||
the format string.
|
||||
|
||||
Choosing BIU Units:
|
||||
==================
|
||||
|
||||
BIUs are only used when a BOARD or MODULE is in RAM. A BIU is equivalent to
|
||||
either a 1) deci-mil or 2) nanometer, depending on how the source code is
|
||||
compiled. It is not a runtime decision. Form 1) is needed only during the
|
||||
preparation phase of the source code transition to nanometers. After the
|
||||
transition, only nanometers will be used in the compilation. No runtime
|
||||
switching is needed or wanted. Again, BIUs can only be one or the other for a
|
||||
given compilation, and this will swing based on a single #define.
|
||||
|
||||
Eventually we may want to actually use "BIU" as our integer type in source code
|
||||
for those lengths which pertain to the board coordinate space. This would give
|
||||
us the ability to easily modify it, go to a larger bitness, make the source code
|
||||
more readable, and keep the type information out of the variable name. This
|
||||
would mean having a point and/or size class based on BIU as the contained
|
||||
integer types. This is a nice to have, but not immediately mandatory.
|
||||
|
||||
There will be a number of places within the source code which will have to be
|
||||
doctored up to use the BFU casting. It will take some time to find all these
|
||||
sites. During this time it should be possible to continue using deci-mils as the
|
||||
BIU for source compilation.
|
||||
|
||||
There are a quite a number of path ways in and out of BOARDs and MODULEs. Most
|
||||
everyone of these pathways involve conversion or scaling of BIUs. An example of
|
||||
a pathway in is a BOARD disk file loading function. An example of a pathway out
|
||||
of a BOARD is a disk file saving function. Likewise for MODULEs. We can
|
||||
characterize the load and save functions by their source and destination
|
||||
representations of lengths.
|
||||
|
||||
BOARDs and MODULEs will soon have a new format, which is basically the existing
|
||||
format expressed in um or nm (TBD) rather than in deci-mils. For discussion, we
|
||||
will say this new format is in mm, even though it may end up being in um. In
|
||||
another year or two we will switch to s-expressions, or sooner if there is a
|
||||
volunteer.
|
||||
|
||||
Here are the required immediate need BOARD load functions:
|
||||
|
||||
1) Legacy to deci-mil loader. This loader uses a floating point scaling factor
|
||||
of unity, since destination is a RAM BOARD using deci-mils as its BIU.
|
||||
|
||||
2) Legacy to nanometer loader. This loader uses a floating point scaling factor
|
||||
of 2540, since destination is a RAM BOARD using nanometers as its BIU, and
|
||||
the source format is using deci-mils.
|
||||
|
||||
3) mm to nanometer loader. This loader uses a floating point scaling factor
|
||||
of 1000000, since the destination is a RAM BOARD using nanometers as its BIU.
|
||||
|
||||
There is no need for a nm to deci-mil loader. (Once somebody saves a file in the
|
||||
new format, that format is used going forward, or its backup in the old format.)
|
||||
|
||||
Now duplicate the above 3 loader types for MODULEs.
|
||||
|
||||
Here are the required immediate need BOARD save functions:
|
||||
|
||||
1) deci-mil to deci-mil, using a floating point scaling factor of unity. It
|
||||
should be possible to use trailing zero suppression on the deci-mils to get a
|
||||
BOARD that is identical to an old BOARD, and this can be used to test the new
|
||||
save function, using "diff" with whitespace ignore. This saver is only in play
|
||||
when the BIU is compiled to be deci-mils.
|
||||
|
||||
2) nanometer to mm, using a floating point scaling factor of 1/1000000. This
|
||||
saver is only in play when the BIU is compiled to be nanometers.
|
||||
|
||||
Now duplicate the above 3 saver types for MODULEs.
|
||||
|
||||
New BOARD and MODULE files will have a new field in them identifying the
|
||||
engineering units used, say mm.
|
||||
|
||||
In actuality, the source code to all 3 loaders, and to all 3 savers can be the
|
||||
same source code with a single variable in each case for scaling.
|
||||
|
||||
All 6 loaders and all 6 savers should be written in parallel with existing
|
||||
loaders and savers, so that we can toggle usage back and forth between the two
|
||||
for awhile. This means we do not gut existing savers and loaders until the new
|
||||
ones are debugged and stable.
|
||||
|
||||
The new savers and loaders are to be done in the context of a plug-in
|
||||
architecture, described elsewhere.
|
||||
|
||||
Angles and Rotations:
|
||||
====================
|
||||
|
||||
Internally we are switching from using an int to hold 1/10 of degrees angle to a
|
||||
typedef called DEGREES. The allowed values that DEGREES can hold will be
|
||||
enforced by the user interface policy, decided elsewhere. The engineering units
|
||||
in the DEGREES type is degrees, no longer tenths of degrees.
|
||||
|
||||
/// a value used to hold rotations or angles.
|
||||
typedef double DEGREES;
|
||||
|
||||
|
||||
User Interface Changes:
|
||||
======================
|
||||
|
||||
All these changes have to be done in a way where they hinge on one #ifdef.
|
||||
|
||||
*) The grid dimension choices will have to be changed.
|
||||
|
||||
*) The drawing routines will have to be changed to handle the case that BIU is
|
||||
compiled to be nm. Work towards getting legacy drawing code capable of handling
|
||||
a compile time #define to control a single scaling factor. Only the scaling
|
||||
factor should need be changed in the final state. Up until then, the work
|
||||
required is to inject the BFU casting where needed along with the scaling
|
||||
factor(s).
|
||||
|
||||
*) Remove any funky imperial to metric conversion functions which tried to hide/mask
|
||||
problems with lack of BIU precision.
|
||||
|
||||
*) There may be some fix ups pertaining to "near enough" type testing involving
|
||||
the user's mouse position, other than bounding box hit testing which should take
|
||||
care of itself (in BIUs). This has more to do with near-ness to a line type
|
||||
tests, and these are thought to best be done in screen coordinates anyway, not
|
||||
BIUs.
|
||||
|
||||
Work Tasks:
|
||||
==========
|
||||
|
||||
*) Within PCBNEW, find math expressions involving BIUs and cast them to BFUs
|
||||
early enough so that the compiler generates code in the BFU realm.
|
||||
|
||||
*) Find a way to consistently round values from BFUs back to BIUs, and put that
|
||||
code in place. This could be done using a set accessor on a BIU, or other way.
|
||||
|
||||
*) Fix the User Interface issues mentioned above, and more found later.
|
||||
|
||||
*) Write the 4 new load and save functions. Vladimir recently committed code
|
||||
which can be a starting point for some of these functions, except that the new
|
||||
ones should reside within a PLUGIN object where we can save the scaling factor
|
||||
variable as a member field of the plugin. In order to meet the requirements
|
||||
of all 3 board loaders, we may have to dynamically change the scaling factor
|
||||
depending on what we find in the *.brd file and how the plugin is compiled.
|
||||
|
|
@ -1,141 +0,0 @@
|
|||
Symbols used to create makefiles and compil Kicad:
|
||||
Definitions and usage
|
||||
|
||||
KICAD_SCRIPTING
|
||||
Build the Python scripting support inside KiCad binaries.
|
||||
Default ON.
|
||||
|
||||
KICAD_SCRIPTING_MODULES
|
||||
Build native portion of the pcbnew Python module: _pcbnew.{pyd,so} for OS command line use of Python.
|
||||
Default ON
|
||||
|
||||
KICAD_SCRIPTING_PYTHON3
|
||||
Build for Python 3 instead of 2.
|
||||
If using WXPYTHON, the python version must be the same as the version used to build wxPython
|
||||
Default OFF.
|
||||
|
||||
KICAD_SCRIPTING_WXPYTHON
|
||||
Build wxPython implementation for wx interface building in Python and py.shell.
|
||||
Default ON.
|
||||
|
||||
KICAD_SCRIPTING_WXPYTHON_PHOENIX
|
||||
Use new wxPython binding.
|
||||
Default OFF.
|
||||
|
||||
KICAD_SCRIPTING_ACTION_MENU
|
||||
Build a tools menu with registered python plugins: actions plugins.
|
||||
Default ON.
|
||||
|
||||
KICAD_USE_OCE
|
||||
Build tools and plugins related to OpenCascade Community Edition.
|
||||
Needed to support import/export STEP
|
||||
Default ON.
|
||||
|
||||
KICAD_USE_OCC
|
||||
Build tools and plugins related to OpenCascade Technology.
|
||||
Overrides KICAD_USE_OCE
|
||||
Default OFF.
|
||||
|
||||
KICAD_INSTALL_DEMOS
|
||||
Install KiCad demos and examples.
|
||||
Default ON.
|
||||
|
||||
KICAD_BUILD_QA_TESTS
|
||||
Build software Quality assurance unit tests.
|
||||
Default ON.
|
||||
|
||||
KICAD_SPICE
|
||||
Build KiCad with internal Spice simulator.
|
||||
Default ON.
|
||||
|
||||
KICAD_USE_FONT_REDUCED_SET
|
||||
Build KiCad with a reduced font set, without CKJ font.
|
||||
Avoid out of memory issue with some graphic cards on OpenGL.
|
||||
Default OFF.
|
||||
|
||||
BUILD_SMALL_DEBUG_FILES
|
||||
In debug build: create smaller binaries.
|
||||
|
||||
On Windows, binaries created by link option -g3 are *very large*
|
||||
(more than 1Gb for pcbnew, and more than 3Gb for the full kicad suite)
|
||||
This option create binaries using link option -g1 that create much smaller files, but
|
||||
there are less info in debug (However the file names and line numbers are available)
|
||||
Default OFF.
|
||||
|
||||
MAINTAIN_PNGS
|
||||
Allow build/rebuild bitmap icons used in menus from the corresponding .svg file.
|
||||
Set to true if you are a PNG maintainer and have the required tools given
|
||||
in the bitmaps_png/CMakeLists.txt file
|
||||
Default OFF.
|
||||
|
||||
|
||||
# Not supported by all platforms (for instance mingw)
|
||||
KICAD_SANITIZE
|
||||
Build KiCad with sanitizer options.
|
||||
WARNING: Not compatible with gold linker.
|
||||
Default OFF.
|
||||
|
||||
KICAD_STDLIB_DEBUG
|
||||
Build KiCad with libstdc++ debug flags enabled.
|
||||
Default OFF.
|
||||
|
||||
option( KICAD_STDLIB_LIGHT_DEBUG
|
||||
Build KiCad with libstdc++ with -Wp,-D_GLIBCXX_ASSERTIONS flag enabled.
|
||||
Not as intrusive as KICAD_STDLIB_DEBUG
|
||||
Default OFF.
|
||||
|
||||
KICAD_BUILD_PARALLEL_CL_MP
|
||||
Build in parallel using the /MP compiler option (Default OFF for safety reasons).
|
||||
Default OFF.
|
||||
|
||||
option( KICAD_USE_VALGRIND
|
||||
Build KiCad with valgrind stack tracking enabled.
|
||||
Default OFF.
|
||||
|
||||
When option KICAD_SCRIPTING OR KICAD_SCRIPTING_MODULES is enabled:
|
||||
PYTHON_EXECUTABLE can be defined when invoking cmake
|
||||
( use -DPYTHON_EXECUTABLE=<python path>/python.exe or python2 )
|
||||
when not defined by user, the Default is python.exe under Windows and python2 for others
|
||||
python binary file should be in exec path.
|
||||
|
||||
Note 1:
|
||||
KICAD_SCRIPTING controls the entire python scripting system.
|
||||
If it is off, no other scripting is allowed
|
||||
|
||||
Therefore, if KICAD_SCRIPTING is OFF, these other option are forced to OFF:
|
||||
KICAD_SCRIPTING_MODULES, KICAD_SCRIPTING_ACTION_MENU,KICAD_SCRIPTING_PYTHON3
|
||||
KICAD_SCRIPTING_WXPYTHON, KICAD_SCRIPTING_WXPYTHON_PHOENIX
|
||||
|
||||
Note 2:
|
||||
KICAD_SCRIPTING_WXPYTHON_PHOENIX requires enabling the KICAD_SCRIPTING_WXPYTHON flag
|
||||
so that the wxWidgets library is properly versioned
|
||||
|
||||
|
||||
Note 3
|
||||
These Symbols are always defined, and are not an option for cmake invocation:
|
||||
|
||||
|
||||
COMPILING_DLL:
|
||||
|
||||
This is a signal to import_export.h, and when present, toggles the
|
||||
interpretation of the #defines in that file. Its purpose should not be
|
||||
extended beyond this.
|
||||
|
||||
|
||||
USE_KIWAY_DLLS:
|
||||
|
||||
Comes from CMake as a user configuration variable, settable in the Cmake
|
||||
user interface. It decides if KiCad will be built with the *.kiface program
|
||||
modules.
|
||||
|
||||
|
||||
BUILD_KIWAY_DLL:
|
||||
|
||||
Comes from CMake, but at the 2nd tier, not the top tier. By 2nd tier,
|
||||
something like pcbnew/CMakeLists.txt, not /CMakeLists.txt is meant. It is
|
||||
not a user configuration variable. Instead, the 2nd tier CMakeLists.txt file
|
||||
looks at the top level USE_KIWAY_DLLS and decides how the object files under
|
||||
the 2nd tier's control will be built. If it decides it wants to march in
|
||||
lockstep with USE_KIWAY_DLLS, then this local CMakeLists.txt file may pass a
|
||||
defined BUILD_KIWAY_DLL (singular) on the compiler command line to the
|
||||
pertinent set of compilation steps under its control.
|
File diff suppressed because it is too large
Load Diff
|
@ -1,950 +0,0 @@
|
|||
# KiCad C++ Source Code Style Guide #
|
||||
|
||||
Latest Publishing: February 2017
|
||||
|
||||
First Published: September 2010
|
||||
|
||||
written by
|
||||
|
||||
Wayne Stambaugh \<<stambaughw@gmail.com>\>
|
||||
and
|
||||
Dick Hollenbeck \<<dick@softplc.com>\>
|
||||
|
||||
[TOC]
|
||||
|
||||
# 1. Introduction # {#csp_intro}
|
||||
The purpose of this document is to provide a reference guide for KiCad
|
||||
developers about how source code should be styled and formatted in
|
||||
KiCad. It is not a comprehensive programming guide because it does not
|
||||
discuss many things such as software engineering strategies, source
|
||||
directories, existing classes, or how to internationalize text. The goal
|
||||
is to make all of the KiCad source conform to this guide.
|
||||
|
||||
## 1.1 Why Coding Style Matters ## {#why}
|
||||
You may be thinking to yourself that using the style defined in this
|
||||
document will not make you a good programmer and you would be correct.
|
||||
Any given coding style is no substitute for experience. However, any
|
||||
experienced coder will tell that the only thing worse than looking at
|
||||
code that is not in your preferred coding style, is looking at twenty
|
||||
different coding styles that are not your preferred coding style.
|
||||
Consistency makes a) problems easier to spot, and b) looking at code for
|
||||
long periods of time more tolerable.
|
||||
|
||||
## 1.2 Enforcement ## {#enforcement}
|
||||
The KiCad coding police are not going to break down your door and beat
|
||||
you with your keyboard if you don't follow these guidelines (although
|
||||
there are those who would argue that they should). However, there are
|
||||
some very sound reasons why you should follow them. If you are
|
||||
contributing patches, you are much more likely to be taken seriously by
|
||||
the primary developers if your patches are formatted correctly. Busy
|
||||
developers don't have the time to go back and reformat your code. If you
|
||||
have a desire to become a regular KiCad developer with commit access to
|
||||
the development branch, you're not likely to get a glowing
|
||||
recommendation by the lead developers if you will not follow these
|
||||
guidelines. It is just good programming courtesy to follow this policy
|
||||
because it is respectful of the investment already made by the existing
|
||||
developers. The other KiCad developers will appreciate your effort.
|
||||
|
||||
**Warning**
|
||||
|
||||
**Do not modify this document without the consent of the project
|
||||
leader. All changes to this document require approval.**
|
||||
|
||||
## 1.3 Tools ## {#tools}
|
||||
|
||||
There are some tools that can help you format your code easily.
|
||||
|
||||
[`clang-format`][clang-format] is a formatting tool that can both be used to
|
||||
provide code-style automation to your editor of choice, as well as allow git to
|
||||
check formatting when committing (using a "Git hook"). You should install this
|
||||
program to be able to use the Git hooks.
|
||||
|
||||
The style config file is `_clang-format`, and should be picked up automatically
|
||||
by `clang-format` when the `--style=file` option is set.
|
||||
|
||||
To enable the Git hooks (only needs to be done once per Git repo):
|
||||
|
||||
git config core.hooksPath .githooks
|
||||
|
||||
Set the `git clang-format` tool to use the provided `_clang-format` file:
|
||||
|
||||
git config clangFormat.style file
|
||||
|
||||
Then, to enable the format checker, set the `kicad.check-format` Git config
|
||||
to "true" for the KiCad repo:
|
||||
|
||||
git config kicad.check-format true
|
||||
|
||||
Without this config, the format checker will not run on commit, but you can
|
||||
still check files staged for commit manually (see below).
|
||||
|
||||
If the hook is enabled, when you commit a change, you will be told if you
|
||||
have caused any style violations (only in your changed code). You can then fix
|
||||
the errors, either manually, or with the tools below.
|
||||
|
||||
If you are warned about formatting errors, but you are sure your style is correct,
|
||||
you can still commit:
|
||||
|
||||
git commit --no-verify
|
||||
|
||||
### 1.3.1 Correcting Formatting Errors ### {#correcting-formatting-errors}
|
||||
|
||||
There is a Git aliases file that provides the right commands to show and correct
|
||||
formatting errors. Add to your repository config by running this command from
|
||||
the source directory:
|
||||
|
||||
git config --add include.path $(pwd)/helpers/git/format_alias
|
||||
|
||||
Then you can use the following aliases:
|
||||
|
||||
* `git check-format`: show any formatting warnings (but make no changes)
|
||||
* `git fix-format`: correct formatting (you will need to `git add` afterwards)
|
||||
|
||||
These aliases use a script, `tools/check-coding.sh`, which takes care of only
|
||||
checking the formatting for files that should be formatted. This script has
|
||||
other uses:
|
||||
|
||||
* Make (or see only) violations in files modified in the previous commit (useful
|
||||
when interactive-rebasing):
|
||||
* `check_coding.sh --amend [--diff]`
|
||||
|
||||
|
||||
# 2. Naming Conventions # {#naming_conventions}
|
||||
Before delving into anything as esoteric as indentation and formatting,
|
||||
naming conventions need to be addressed. This section does not attempt
|
||||
to define what names you use for your code. Rather, it defines the style
|
||||
for naming. See the references section for links to some excellent
|
||||
coding references. When defining multiple word names use the following
|
||||
conventions for improved readability:
|
||||
|
||||
- Use underscores for all upper and all lower case variables to make
|
||||
multiple word names more readable.
|
||||
- Use camel case for mixed case variable names.
|
||||
|
||||
Avoid mixing camel case and underscores.
|
||||
|
||||
**Examples**
|
||||
~~~~~~~~~~~~~{.cpp}
|
||||
CamelCaseName // if camelcase, then no underscores
|
||||
all_lower_case_name
|
||||
ALL_UPPER_CASE_NAME
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
## 2.1 Class, Type Definitions, Name Space, and Macro Names ## {#definitions}
|
||||
Class, typedef, enum, name space, and macro names should be comprised of
|
||||
all capital letters.
|
||||
|
||||
**Examples**
|
||||
~~~~~~~~~~~~~{.cpp}
|
||||
class SIMPLE
|
||||
#define LONG_MACRO_WITH_UNDERSCORES
|
||||
typedef boost::ptr_vector<PIN> PIN_LIST;
|
||||
enum KICAD_T {...};
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
## 2.2 Local, Private and Automatic Variables ## {#local_variables}
|
||||
The first character of automatic, static local, and private variable
|
||||
names should be lower case. This indicates that the variable will not be
|
||||
“visible” outside of the function, file, or class where they are
|
||||
defined, respectively. The limited visibility is being acknowledged with
|
||||
the lowercase starting letter, where lowercase is considered to be less
|
||||
boisterous than uppercase.
|
||||
|
||||
**Examples**
|
||||
~~~~~~~~~~~~~{.cpp}
|
||||
int i;
|
||||
double aPrivateVariable;
|
||||
static char* static_variable = NULL;
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
## 2.3 Public and Global Variables ## {#global_variables}
|
||||
The first character of public and global variable names are to be
|
||||
uppercase. This indicates that the variable is visible outside the class
|
||||
or file in which it was defined. (An exception is the use of prefix `g_`
|
||||
which is also sometimes used to indicate a global variable.)
|
||||
|
||||
**Example**
|
||||
~~~~~~~~~~~~~{.cpp}
|
||||
char* GlobalVariable;
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
## 2.4 Local, Private and Static Functions ## {#functions}
|
||||
The first character of local, private, and static functions should be
|
||||
lower case. This indicates that the function is not visible outside the
|
||||
class or file where it is defined.
|
||||
|
||||
**Example**
|
||||
~~~~~~~~~~~~~{.cpp}
|
||||
bool isModified();
|
||||
static int buildList( int* list );
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
## 2.5 Function Arguments ## {#function_arguments}
|
||||
Function arguments are prefixed with an 'a' to indicate these are
|
||||
arguments to a function. The 'a' stands for “argument”, and it also
|
||||
enables clever and concise Doxygen comments.
|
||||
|
||||
**Example**
|
||||
~~~~~~~~~~~~~{.cpp}
|
||||
/*/** */*
|
||||
* Copy aFoo into this instance.
|
||||
*/
|
||||
void SetFoo( int aFoo );
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
Notice how the reader can say “a Foo” to himself when reading this.
|
||||
|
||||
## 2.6 Pointers ## {#pointers}
|
||||
It is not desired to identify a pointer by building a 'p' into the
|
||||
variable name. The pointer aspect of the variable pertains to type, not
|
||||
purpose.
|
||||
|
||||
**Example**
|
||||
~~~~~~~~~~~~~{.cpp}
|
||||
MODULE* module;
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
The purpose of the variable is that it represents a MODULE. Something
|
||||
like `p_module` would only make that harder to discern.
|
||||
|
||||
## 2.7 Accessing Member Variables and Member Functions ## {#accessing_members}
|
||||
We do not use `this->` to access either member variables or member
|
||||
functions from within the containing class. We let C++ perform this for
|
||||
us.
|
||||
|
||||
## 2.8 Use of 'auto' ##
|
||||
We do -not- use `auto` to reduce repetition. We do use it to increase
|
||||
readability. This generally means -only- use `auto` where std::lib gets
|
||||
overly verbose (such as iterators or `std::make_shared`), or when not using
|
||||
`auto` would cause line-wraps that can't otherwise be avoided.
|
||||
|
||||
|
||||
# 3. Commenting # {#commenting}
|
||||
Comments in KiCad typically fall into two categories: in line code
|
||||
comments and Doxygen comments. In line comments have no set formatting
|
||||
rules other than they should have the same indent level as the code if
|
||||
they do not follow a statement. In line comments that follow statements
|
||||
should not exceed 99 columns unless absolutely necessary. The prevents
|
||||
word wrapping in an editor when the viewable columns is set to 100. In
|
||||
line comments can use either the C++ or the C commenting style, but C++
|
||||
comments are preferred for single line comments or comments consisting
|
||||
of only a few lines.
|
||||
|
||||
## 3.1 Blank Lines Above Comments ## {#blank_lines_above_comments}
|
||||
If a comment is the first thing on a line, then that comment should have
|
||||
one or more blank lines above them. One blank line is preferred.
|
||||
|
||||
## 3.2 Doxygen ## {#doxygen}
|
||||
Doxygen is a C++ source code documenting tool used by the project. Descriptive
|
||||
*.html files can be generated from the source code by installing Doxygen and
|
||||
building the target named **doxygen-docs** and **dev-docs** that include this
|
||||
document.
|
||||
|
||||
$ cd <kicad_build_base>
|
||||
$ make doxygen-docs
|
||||
|
||||
The generated source \*.html files will be placed into
|
||||
\<kicad\_project\_base\>/Documentation/doxygen/html/ and the developer's
|
||||
\*.html files will be placed into
|
||||
\<kicad\_project\_base\>/Documentation/development/doxygen/html/
|
||||
|
||||
Doxygen comments are used to build developer documentation from the
|
||||
source code. They should normally be only placed in header files and not
|
||||
in \*.cpp files. This eliminates the obligation to keep two comments in
|
||||
agreement with each other. If the class, function, or enum, etc. is
|
||||
only defined in a \*.cpp source file and not present in any header file,
|
||||
in which case the Doxygen comments should go into the \*.cpp source file.
|
||||
Again, avoid duplicating the Doxygen comments in both the header and
|
||||
\*.cpp source files.
|
||||
|
||||
KiCad uses the JAVADOC comment style defined in the [“Documenting the
|
||||
code”][doccode] section of the Doxygen [manual][manual]. Don't forget
|
||||
to use the special Doxygen tags: bug, todo, deprecated, etc., so other
|
||||
developers can quickly get useful information about your code. It is
|
||||
good practice to actually generate the Doxygen \*.html files by
|
||||
building target doxygen-docs, and then to review the quality of your
|
||||
Doxygen comments with a web browser before submitting a patch.
|
||||
|
||||
[doccode]: http://www.doxygen.nl/manual/docblocks.html
|
||||
[manual]: http://www.doxygen.nl/manual
|
||||
|
||||
### 3.2.1 Function Comments ### {#function_comments}
|
||||
These go into a header file, unless the function is a private (i.e.
|
||||
static) function known only to a \*.cpp file. The format of a function
|
||||
comment is chosen to serve a dual purpose role: delineation of the
|
||||
function declaration within the source code and to create a consistent
|
||||
leading sentence in the doxygen html output. The chosen format is
|
||||
to use a descriptive single line sentence, followed by a blank line,
|
||||
followed by an optional detailed description as the shown in the example
|
||||
below.
|
||||
|
||||
**Example**
|
||||
~~~~~~~~~~~~~{.cpp}
|
||||
/*/** */*
|
||||
* Format and write text to an output stream.
|
||||
*
|
||||
* A really detailed description goes here if it's needed.
|
||||
*
|
||||
* @param aMestLevel is the multiple of spaces to precede the output with.
|
||||
* @param aFmt is a printf() style format string.
|
||||
* @param ... is a variable list of parameters that will get blended into
|
||||
* the output under control of the format string.
|
||||
* @return the number of characters output.
|
||||
* @throw IO_ERROR, if there is a problem outputting.
|
||||
*/
|
||||
int PRINTF_FUNC Print( int aNestLevel, const char* aFmt, ... );
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
The single line description goes on the 2nd line of the comment. The
|
||||
\@return keyword if present, should describe the return value followed
|
||||
by a hyphen. The \@param keyword names a function parameter and the text
|
||||
following should flow like a normal English sentence.
|
||||
|
||||
### 3.2.2 Class Comments ### {#class_comments}
|
||||
A class comment describes a class declaration by giving the purpose and
|
||||
use of the class. Its format is similar to a function comment. Doxygen
|
||||
can use the html \<p\> (paragraph designation) to begin a new paragraph
|
||||
in its output. So if the text of the comment is large, break it put into
|
||||
multiple paragraphs.
|
||||
|
||||
**Example**
|
||||
~~~~~~~~~~~~~{.cpp}
|
||||
/*/** */*
|
||||
* An interface (abstract) class used to output UTF8 text in a
|
||||
* convenient way.
|
||||
*
|
||||
* The primary interface is "printf() like" but with support for
|
||||
* indentation control. The destination of the 8 bit wide text is
|
||||
* up to the implementer.
|
||||
* <p>
|
||||
* The implementer only has to implement the write() function, but
|
||||
* can also optionally re-implement GetQuoteChar().
|
||||
* <p>
|
||||
* If you want to output a wxString, then use CONV_TO_UTF8() on it
|
||||
* before passing it as an argument to Print().
|
||||
* <p>
|
||||
* Since this is an abstract interface, only classes derived from
|
||||
* this one may actually be used.
|
||||
*/
|
||||
class OUTPUTFORMATTER
|
||||
{
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
|
||||
# 4. Formatting # {#formatting}
|
||||
This section defines the formatting style used in the KiCad source.
|
||||
|
||||
## 4.1 Indentation ## {#indentation}
|
||||
The indentation level for the KiCad source code is defined as four
|
||||
spaces. Please do not use tabs.
|
||||
|
||||
### 4.1.1 Defines ### {#defines}
|
||||
There should be only one space after a \#define statement.
|
||||
|
||||
### 4.1.2 Column Alignment ### {#column_alignment}
|
||||
Please try to align multiple consecutive similar lines into consistent
|
||||
columns when possible, such as \#define lines which can be thought of as
|
||||
containing 4 columns: \#define, symbol, value, and comment. Notice how
|
||||
all 4 columns are aligned in the example below.
|
||||
|
||||
**Example**
|
||||
~~~~~~~~~~~~~{.cpp}
|
||||
#define LN_RED 12 // my favorite
|
||||
#define LN_GREEN 13 // eco friendly
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
Another common case is the declaration of automatic variables. These are
|
||||
preferably shown in columns of type and variable name.
|
||||
|
||||
## 4.2 Blank Lines ## {#blank_lines}
|
||||
|
||||
### 4.2.1 Function Declarations ### {#function_declarations}
|
||||
There should be 1 blank line above a function declaration in a class
|
||||
file if that function declaration is presented with a Javadoc comment.
|
||||
This is consist with the statement above about blank lines above
|
||||
comments.
|
||||
|
||||
### 4.2.2 Function Definitions ### {#function_definitions}
|
||||
Function definitions in *.cpp files will not typically be accompanied by
|
||||
any comment, since those are normally only in the header file. It is
|
||||
desirable to set off the function definition within the *.cpp file by
|
||||
leaving two blank lines above the function definition.
|
||||
|
||||
### 4.2.3 Control Statements ### {#control_statements}
|
||||
There should be one blank line before the opening statement and after
|
||||
the closing curly brace or statement for all control statement blocks
|
||||
so that it is easy to see where control blocks begin and end. This
|
||||
includes `if`, `for`, `while`, `do`, and `switch` control blocks.
|
||||
|
||||
## 4.3 Line Length ### {#line_length}
|
||||
The maximum line width is 99 columns. An exception to this is a long
|
||||
quoted string such as the internationalized text required to satisfy
|
||||
MSVC++, described below.
|
||||
|
||||
## 4.4 Strings ## {#strings}
|
||||
The KiCad project team no longer supports compiling with Microsoft
|
||||
Visual C++. When you need to break long strings into smaller substrings,
|
||||
please use the C99 compliant method for improved readability. Using
|
||||
any of previously accepted methods defined below for breaking
|
||||
long internationalized strings will no longer be accepted.
|
||||
|
||||
**Examples**
|
||||
~~~~~~~~~~~~~{.cpp}
|
||||
// This works with C99 compliant compilers is the **only** accepted method:
|
||||
wxChar* foo = _( “this is a long string broken ”
|
||||
“into pieces for readability.” );
|
||||
|
||||
// This works with MSVC, breaks POEdit, and is **not** acceptable:
|
||||
wxChar* foo = _( “this is a long string broken ”
|
||||
L“into pieces for readability” );
|
||||
|
||||
// This works with MSVC, is ugly, and is **not** accepted:
|
||||
wxChar* foo = _( “this is a long string \
|
||||
broken into pieces for readability” );
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
A second acceptable solution is to simply put the text all on one
|
||||
line, even if it exceeds the 99 character line length limit. However,
|
||||
the preferred method is to break strings within the 99 character limit
|
||||
whenever possible to prevent wrapping.
|
||||
|
||||
## 4.5 Trailing Whitespace ## {#trailing_whitespace}
|
||||
Many programming editors conveniently indent your code for you. Some of
|
||||
them do it rather poorly and leave trailing whitespace. Thankfully, most
|
||||
editors come with a remove trailing whitespace macro or at least a
|
||||
setting to make trailing whitespace visible so you can see it and
|
||||
manually remove it. Trailing whitespace is known to break some text
|
||||
parsing tools. It also leads to unnecessary diffs in the version control
|
||||
system. Please remove trailing whitespace.
|
||||
|
||||
## 4.6 Multiple Statements per Line ## {#multiple_statements_per_line}
|
||||
It is generally preferred that each statement be placed on its own line.
|
||||
This is especially true for statements without keywords.
|
||||
|
||||
~~~~~~~~~~~~~{.cpp}
|
||||
x=1; y=2; z=3; // Bad, should be on separate lines.
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
## 4.7 Braces ## {#braces}
|
||||
Braces should be placed on the line proceeding the keyword and indented
|
||||
to the same level. It is not necessary to use braces if there is only a
|
||||
single line statement after the keyword. In the case of if..else
|
||||
if..else, indent all to the same level.
|
||||
|
||||
~~~~~~~~~~~~~{.cpp}
|
||||
void function()
|
||||
{
|
||||
if( foo )
|
||||
{
|
||||
statement1;
|
||||
statement2;
|
||||
}
|
||||
else if( bar )
|
||||
{
|
||||
statement3;
|
||||
statement4;
|
||||
}
|
||||
else
|
||||
statement5;
|
||||
}
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
## 4.8 Parenthesis ## {#parenthesis}
|
||||
Parenthesis should be placed immediately after function names and
|
||||
keywords. Spaces should be placed after the opening parenthesis, before
|
||||
the closing parenthesis, and between the comma and the next argument in
|
||||
functions. No space is needed if a function has no arguments.
|
||||
|
||||
~~~~~~~~~~~~~{.cpp}
|
||||
void Function( int aArg1, int aArg2 )
|
||||
{
|
||||
while( busy )
|
||||
{
|
||||
if( a || b || c )
|
||||
doSomething();
|
||||
else
|
||||
doSomethingElse();
|
||||
}
|
||||
}
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
## 4.9 Switch Formatting ## {#switch}
|
||||
The case statement is to be indented to the same level as the switch.
|
||||
|
||||
~~~~~~~~~~~~~{.cpp}
|
||||
switch( foo )
|
||||
{
|
||||
case 1:
|
||||
doOne();
|
||||
break;
|
||||
case 2:
|
||||
doTwo();
|
||||
// Fall through.
|
||||
default:
|
||||
doDefault();
|
||||
}
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
It is preferred to place all cases on a single line when that makes the
|
||||
code more readable. This is often done for look-ups or mapping functions. In
|
||||
this case, you will have to manually align for readability as appropriate and
|
||||
reject clang-format's suggested changes, if you use it:
|
||||
|
||||
~~~~~~~~~~~~~{.cpp}
|
||||
switch( m_orientation )
|
||||
{
|
||||
case PIN_RIGHT: m_orientation = PIN_UP; break;
|
||||
case PIN_UP: m_orientation = PIN_LEFT; break;
|
||||
case PIN_LEFT: m_orientation = PIN_DOWN; break;
|
||||
case PIN_DOWN: m_orientation = PIN_RIGHT; break;
|
||||
}
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
## 4.10 Lamdas ## {#lamda_formatting}
|
||||
The braces and statements of the body should be indented as you would a method,
|
||||
with the braces lined up under the capture block:
|
||||
|
||||
~~~~~~~~~~~~~{.cpp}
|
||||
auto belowCondition = []( const SELECTION& aSel )
|
||||
{
|
||||
return g_CurrentSheet->Last() != g_RootSheet;
|
||||
};
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
or:
|
||||
|
||||
~~~~~~~~~~~~~{.cpp}
|
||||
auto belowCondition =
|
||||
[]( const SELECTION& aSel )
|
||||
{
|
||||
return g_CurrentSheet->Last() != g_RootSheet;
|
||||
};
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
## 4.11 Class Definition Layout ## {#class_defs}
|
||||
When defining classes member variables should be placed at the bottom
|
||||
and methods should be placed above the member variables. The scope
|
||||
ordering of the class should be public, protect, then private. Do not
|
||||
redefine the same scope multiple times in a row. Here is an example
|
||||
class definition:
|
||||
|
||||
~~~~~~~~~~~~~{.cpp}
|
||||
class FOO
|
||||
{
|
||||
public:
|
||||
FOO();
|
||||
void FooPublicMethod();
|
||||
|
||||
protected:
|
||||
void fooProtectedMethod();
|
||||
|
||||
private:
|
||||
void fooPrivateMethod();
|
||||
|
||||
// Private not redefined here unless no private methods.
|
||||
int m_privateMemberVariable;
|
||||
};
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
|
||||
# 5. License Statement # {#license_statement}
|
||||
There is a the file copyright.h which you can copy into the top of
|
||||
your new source files and edit the \<author\> field. KiCad depends on
|
||||
the copyright enforcement capabilities of copyright law, and this
|
||||
means that source files must be copyrighted and not be released into
|
||||
the public domain. Each source file has one or more owners.
|
||||
|
||||
|
||||
# 6. Debugging Output {#debugging_output}
|
||||
Debugging output is a common method for validating code. However, it
|
||||
should not always active in debug builds. This makes it difficult for
|
||||
other developers to see their debugging output and can have a significant
|
||||
impact on the performance of debug builds. I you need to use debugging
|
||||
output, use [wxLogDebug] instead of `printf` or C++ output stream. If
|
||||
you accidentally leave the debugging output in the source, it will expand
|
||||
to nothing on release builds. All debugging output code should be removed
|
||||
from the source tree before pushing changes to the main KiCad repo. Do not
|
||||
comment out debugging output. This just adds more cruft to the code base.
|
||||
If you need to leave debugging output for, future testing, use tracing
|
||||
output (see 6.1).
|
||||
|
||||
## 6.1 Using Tracing for Debugging Output {#tracing_output}
|
||||
There are occasions when you want to see debugging output to ensure
|
||||
existing code performs as expected. In this case, use [wxLogTrace] which
|
||||
allows debugging output to be controlled by the `WXTRACE` environment
|
||||
variable. When using [wxLogTrace][wxLogTrace], the trace environment
|
||||
variable string should be documented by either adding it to the
|
||||
`trace_helper.{h/cpp}` source files or locally using the [Doxygen][Doxygen]
|
||||
comment `\ingroup trace_env_vars`.
|
||||
|
||||
# 7. Header Files # {#header_files}
|
||||
Project \*.h source files should:
|
||||
|
||||
- contain a license statement
|
||||
- contain a nested include \#ifndef
|
||||
- be fully self standing and not depend on other headers that are not
|
||||
included within it.
|
||||
|
||||
The license statement was described above.
|
||||
|
||||
## 7.1 Nested Include #ifndef ## {#nested_include}
|
||||
Each header file should include an \#ifndef which is commonly used to
|
||||
prevent compiler errors in the case where the header file is seen
|
||||
multiple times in the code stream presented to the compiler. Just
|
||||
after the license statement, at the top of the file there should be
|
||||
lines similar to these (but with a file name specific token other than
|
||||
`RICHIO_H_`):
|
||||
|
||||
~~~~~~~~~~~~~{.cpp}
|
||||
#ifndef RICHIO_H_
|
||||
#define RICHIO_H_
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
And at the very bottom of the header file, use a line like this one:
|
||||
|
||||
~~~~~~~~~~~~~{.cpp}
|
||||
#endif // RICHIO_H_
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
The \#ifndef wrapper begins after the license statement, and ends at
|
||||
the very bottom of the file. It is important that it wrap any nested
|
||||
\#include statements, so that the compiler can skip them if the
|
||||
\#ifndef evaluates to false, which will reduce compilation time.
|
||||
|
||||
## 7.2 Headers Without Unsatisfied Dependencies ## {#header_depends}
|
||||
Any header file should include other headers that it depends on. (Note:
|
||||
KiCad is not at this point now, but this section is a goal of the
|
||||
project.)
|
||||
|
||||
It should be possible to run the compiler on any header file within the
|
||||
project, and with proper include paths being passed to the compiler, the
|
||||
header file should compile without error.
|
||||
|
||||
**Example**
|
||||
|
||||
$ cd /svn/kicad/testing.checkout/include
|
||||
$ g++ wx-config --cxxflags -I . xnode.h -o /tmp/junk
|
||||
|
||||
Such structuring of the header files removes the need within a client
|
||||
\*.cpp file to include some project header file before some other project
|
||||
header file. (A client \*.cpp file is one that intends to **use, not
|
||||
implement,** the public API exposed within the header file.)
|
||||
|
||||
Client code should not have to piece together things that a header file
|
||||
wishes to expose. The exposing header file should be viewed as a fully
|
||||
sufficient **ticket to use** the public API of that header file.
|
||||
|
||||
This is not saying anything about how much to expose, only that that
|
||||
which is exposed needs to be fully usable merely by including the header
|
||||
file that exposes it, with no additional includes.
|
||||
|
||||
For situations where there is a class header file and an
|
||||
implementation \*.cpp file, it is desirable to hide as much of the
|
||||
private implementation as is practical and any header file that is not
|
||||
needed as part of the public API can and should be included only in
|
||||
the implementation \*.cpp file. However, the number one concern of
|
||||
this section is that client (using) code can use the public API which
|
||||
is exposed in the header file, merely by including that one header
|
||||
file.
|
||||
|
||||
|
||||
# 8. When in Doubt... # {#when_in_doubt}
|
||||
When editing existing source code files and there are multiple acceptable
|
||||
code formatting options or no formatting is defined, follow the existing
|
||||
formatting in the file.
|
||||
|
||||
|
||||
# 9. I Wrote X Lines of Code Before I Read This Document # {#x_lines}
|
||||
It's OK. We all make mistakes. Fortunately, KiCad provides a
|
||||
configuration file for the code beautifier uncrustify. Uncrustify won't
|
||||
fix your naming problems but it does a pretty decent job of formatting
|
||||
your source code. There are a few places where uncrustify makes some
|
||||
less than ideal indentation choices. It struggles with the string
|
||||
declaration macros wxT(“”) and \_(“”) and functions used as arguments to
|
||||
other functions. After you uncrustify your source code, please review the
|
||||
indentation for any glaring errors and manually fix them. See the
|
||||
uncrustify [website][uncrustify] for more information.
|
||||
|
||||
[uncrustify]: http://uncrustify.sourceforge.net/
|
||||
|
||||
|
||||
# 10. Show Me an Example # {#show_me_an_example}
|
||||
Nothing drives the point home like an example. The source file richio.h
|
||||
below was taken directly from the KiCad source.
|
||||
|
||||
~~~~~~~~~~~~~{.cpp}
|
||||
/*
|
||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2007-2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
|
||||
* Copyright (C) 2007 KiCad Developers, see change_log.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef RICHIO_H_
|
||||
#define RICHIO_H_
|
||||
|
||||
|
||||
// This file defines 3 classes useful for working with DSN text files and is named
|
||||
// "richio" after its author, Richard Hollenbeck, aka Dick Hollenbeck.
|
||||
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
// I really did not want to be dependent on wxWidgets in richio
|
||||
// but the errorText needs to be wide char so wxString rules.
|
||||
#include <wx/wx.h>
|
||||
#include <cstdio> // FILE
|
||||
|
||||
|
||||
|
||||
/*/** */*
|
||||
* A class used to hold an error message and may be used to throw exceptions
|
||||
* containing meaningful error messages.
|
||||
*/
|
||||
struct IOError
|
||||
{
|
||||
wxString errorText;
|
||||
|
||||
IOError( const wxChar* aMsg ) :
|
||||
errorText( aMsg )
|
||||
{
|
||||
}
|
||||
|
||||
IOError( const wxString& aMsg ) :
|
||||
errorText( aMsg )
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/*/** */*
|
||||
* Read single lines of text into a buffer and increments a line number counter.
|
||||
*/
|
||||
class LINE_READER
|
||||
{
|
||||
protected:
|
||||
|
||||
FILE* fp;
|
||||
int lineNum;
|
||||
unsigned maxLineLength;
|
||||
unsigned length;
|
||||
char* line;
|
||||
unsigned capacity;
|
||||
|
||||
public:
|
||||
|
||||
/*/** */*
|
||||
* @param aFile is an open file in "ascii" mode, not binary mode.
|
||||
* @param aMaxLineLength is the number of bytes to use in the line buffer.
|
||||
*/
|
||||
LINE_READER( FILE* aFile, unsigned aMaxLineLength );
|
||||
|
||||
~LINE_READER()
|
||||
{
|
||||
delete[] line;
|
||||
}
|
||||
|
||||
/*
|
||||
int CharAt( int aNdx )
|
||||
{
|
||||
if( (unsigned) aNdx < capacity )
|
||||
return (char) (unsigned char) line[aNdx];
|
||||
return -1;
|
||||
}
|
||||
*/
|
||||
|
||||
/*/** */*
|
||||
* Read a line of text into the buffer and increments the line number
|
||||
* counter.
|
||||
*
|
||||
* @return is the number of bytes read, 0 at end of file.
|
||||
* @throw IO_ERROR when a line is too long.
|
||||
*/
|
||||
int ReadLine();
|
||||
|
||||
operator char* ()
|
||||
{
|
||||
return line;
|
||||
}
|
||||
|
||||
int LineNumber()
|
||||
{
|
||||
return lineNum;
|
||||
}
|
||||
|
||||
unsigned Length()
|
||||
{
|
||||
return length;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*/** */*
|
||||
* An interface (abstract class) used to output ASCII text in a convenient way.
|
||||
*
|
||||
* The primary interface is printf() like with support for indentation control.
|
||||
* The destination of the 8 bit wide text is up to the implementer. If you want
|
||||
* to output a wxString, then use CONV_TO_UTF8() on it before passing it as an
|
||||
* argument to Print().
|
||||
* <p>
|
||||
* Since this is an abstract interface, only classes derived from this one
|
||||
* will be the implementations.
|
||||
* </p>
|
||||
*/
|
||||
class OUTPUTFORMATTER
|
||||
{
|
||||
|
||||
#if defined(__GNUG__) // The GNU C++ compiler defines this
|
||||
|
||||
// When used on a C++ function, we must account for the "this" pointer,
|
||||
// so increase the STRING-INDEX and FIRST-TO_CHECK by one.
|
||||
// See http://docs.freebsd.org/info/gcc/gcc.info.Function_Attributes.html
|
||||
// Then to get format checking during the compile, compile with -Wall or -Wformat
|
||||
#define PRINTF_FUNC __attribute__ ((format (printf, 3, 4)))
|
||||
|
||||
#else
|
||||
#define PRINTF_FUNC // nothing
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
||||
/*/** */*
|
||||
* Format and write text to the output stream.
|
||||
*
|
||||
* @param nestLevel is the multiple of spaces to preceed the output with.
|
||||
* @param fmt is a printf() style format string.
|
||||
* @param ... is a variable list of parameters that will get blended into
|
||||
* the output under control of the format string.
|
||||
* @return the number of characters output.
|
||||
* @throw IO_ERROR if there is a problem outputting, such as a full disk.
|
||||
*/
|
||||
virtual int PRINTF_FUNC Print( int nestLevel, const char* fmt, ... ) = 0;
|
||||
|
||||
/*/** */*
|
||||
* Return the quoting character required for aWrapee.
|
||||
*
|
||||
* Return the quote character as a single character string for a given
|
||||
* input wrapee string. If the wrappee does not need to be quoted,
|
||||
* the return value is "" (the null string), such as when there are no
|
||||
* delimiters in the input wrapee string. If you want the quote character
|
||||
* to be assuredly not "", then pass in "(" as the wrappee.
|
||||
* <p>
|
||||
* Implementations are free to override the default behavior, which is to
|
||||
* call the static function of the same name.
|
||||
* </p>
|
||||
*
|
||||
* @param aWrapee is a string that might need wrapping on each end.
|
||||
* @return the quote character as a single character string, or ""
|
||||
* if the wrapee does not need to be wrapped.
|
||||
*/
|
||||
virtual const char* GetQuoteChar( const char* aWrapee ) = 0;
|
||||
|
||||
virtual ~OUTPUTFORMATTER() {}
|
||||
|
||||
/*/** */*
|
||||
* Get the quote character according to the Specctra DSN specification.
|
||||
*
|
||||
* @param aWrapee is a string that might need wrapping on each end.
|
||||
* @param aQuoteChar is a single character C string which provides the current
|
||||
* quote character, should it be needed by the wrapee.
|
||||
*
|
||||
* @return the quote_character as a single character string, or ""
|
||||
* if the wrapee does not need to be wrapped.
|
||||
*/
|
||||
static const char* GetQuoteChar( const char* aWrapee, const char* aQuoteChar );
|
||||
};
|
||||
|
||||
|
||||
/*/** */*
|
||||
* Implement an OUTPUTFORMATTER to a memory buffer.
|
||||
*/
|
||||
class STRINGFORMATTER : public OUTPUTFORMATTER
|
||||
{
|
||||
std::vector<char> buffer;
|
||||
std::string mystring;
|
||||
|
||||
int sprint( const char* fmt, ... );
|
||||
int vprint( const char* fmt, va_list ap );
|
||||
|
||||
public:
|
||||
|
||||
/*/** */*
|
||||
* Reserve space in the buffer
|
||||
*/
|
||||
STRINGFORMATTER( int aReserve = 300 ) :
|
||||
buffer( aReserve, '\0' )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*/** */*
|
||||
* Clears the buffer and empties the internal string.
|
||||
*/
|
||||
void Clear()
|
||||
{
|
||||
mystring.clear();
|
||||
}
|
||||
|
||||
/*/** */*
|
||||
* Remove whitespace, '(', and ')' from the internal string.
|
||||
*/
|
||||
void StripUseless();
|
||||
|
||||
|
||||
std::string GetString()
|
||||
{
|
||||
return mystring;
|
||||
}
|
||||
|
||||
|
||||
//-----<OUTPUTFORMATTER>------------------------------------------------
|
||||
int PRINTF_FUNC Print( int nestLevel, const char* fmt, ... );
|
||||
const char* GetQuoteChar( const char* wrapee );
|
||||
//-----</OUTPUTFORMATTER>-----------------------------------------------
|
||||
};
|
||||
|
||||
|
||||
#endif // RICHIO_H_
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
|
||||
# 11. Resources # {#resources}
|
||||
There are plenty of excellent resources on the Internet on C++ coding
|
||||
styles and coding do's and don'ts. Here are a few useful ones. In most
|
||||
cases, the coding styles do not follow the KiCad coding style but there
|
||||
is plenty of other good information here. Besides, most of them have
|
||||
some great humor in them enjoyable to read. Who knows, you might even
|
||||
learn something new.
|
||||
|
||||
- [C++ Coding Standard][cppstandard]
|
||||
- [Linux Kernel Coding Style][kernel]
|
||||
- [C++ Operator Overloading Guidelines][overloading]
|
||||
- [Wikipedia's Programming Style Page][style]
|
||||
|
||||
[clang-format]: https://clang.llvm.org/docs/ClangFormat.html
|
||||
[cppstandard]:http://www.possibility.com/Cpp/CppCodingStandard.html
|
||||
[kernel]:https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/Documentation/process/coding-style.rst
|
||||
[overloading]:http://www.cs.caltech.edu/courses/cs11/material/cpp/donnie/cpp-ops.html
|
||||
[style]:http://en.wikipedia.org/wiki/Programming_style
|
||||
[wxLogDebug]:https://docs.wxwidgets.org/3.0/group__group__funcmacro__log.html#ga9c530ae20eb423744f90874d2c97d02b
|
||||
[wxLogTrace]:https://docs.wxwidgets.org/3.0/group__group__funcmacro__log.html#gae28a46b220921cd87a6f75f0842294c5
|
||||
[Doxygen]:https://www.doxygen.nl/index.html
|
|
@ -1,99 +0,0 @@
|
|||
# Commit Message Format Policy # {#commit_messages}
|
||||
|
||||
[TOC]
|
||||
|
||||
Commit messages should begin with a brief subject line. Try to limit this
|
||||
to no more than 72 characters. The body of the message should be separated
|
||||
from the subject line by a blank line and wrapped at 72 characters. The body
|
||||
of a commit message should explain what the commit does and why. Do not
|
||||
explain *how* the changes work as the code itself should do that.
|
||||
|
||||
# Linking a commit to an issue # {#commit_bug_link}
|
||||
|
||||
If your commit fixes an issue that has been reported in the [issue
|
||||
tracker](https://gitlab.com/kicad/code/kicad/issues), add a line indicating the
|
||||
fixed issue number to your commit message. In such case, Gitlab will
|
||||
automatically close the issue and add a link to your commit in the issue.
|
||||
|
||||
For example, the following line will automatically close issue #1234567:
|
||||
|
||||
Fixes https://gitlab.com/kicad/code/kicad/issues/1234567
|
||||
|
||||
There is an [alias](#commit_fixes_alias) to simplify this step.
|
||||
You can read more about automatic issue closing in the
|
||||
[Gitlab documentation](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically).
|
||||
|
||||
# Changelog tags {#commit_changelog_tag}
|
||||
|
||||
To facilitate following the code changes, you should include a changelog tag
|
||||
to indicate modifications noticeable by the users. There are three types of
|
||||
changelog tags:
|
||||
|
||||
- `ADDED` to denote a new feature
|
||||
- `CHANGED` to indicate a modification of an existing feature
|
||||
- `REMOVED` to inform about removal of an existing feature
|
||||
|
||||
There is no need to add changelog tags for commits that do not modify the way
|
||||
the users interact with the software, such as code refactoring or a bugfix for
|
||||
unexpected behavior. The main purpose of the changelog tags is to generate the
|
||||
release notes and notify the documentation maintainers about changes. Keep that
|
||||
in mind when deciding whether to add a changelog tag.
|
||||
|
||||
## Making the Documentation Developers Aware of Changes {#commit_let_doc_team_know}
|
||||
|
||||
When a commit with changelog tag is pushed, the committer should create a new
|
||||
issue in the [documentation
|
||||
repository](http://github.com/KiCad/kicad-doc/issues) to notify the
|
||||
documentation maintainers. You should include a link to the commit containing
|
||||
the reported changes.
|
||||
|
||||
## Extracting changelog {#commit_extract_changelog}
|
||||
|
||||
Thanks to the changelog tags, it is easy to extract the changelog using git
|
||||
commands:
|
||||
|
||||
git log -E --grep="ADD[ED]?:|REMOVE[D]?:|CHANGE[D]?:" --since="1 Jan 2017"
|
||||
git log -E --grep="ADD[ED]?:|REMOVE[D]?:|CHANGE[D]?:" <commit hash>
|
||||
|
||||
KiCad provides an [alias](#commit_changelog_alias) to shorten the changelog
|
||||
extraction commands.
|
||||
|
||||
# Example # {#commit_example}
|
||||
|
||||
Following is an example of a properly formatted commit message:
|
||||
|
||||
Eeschema: Adding line styling options
|
||||
|
||||
ADDED: Add support in Eeschema for changing the default line style,
|
||||
width and color on a case-by-case basis.
|
||||
|
||||
CHANGED: "Wire" lines now optionally include data on the line style,
|
||||
width and color if they differ from the default.
|
||||
|
||||
Fixes https://gitlab.com/kicad/code/kicad/issues/594059
|
||||
Fixes https://gitlab.com/kicad/code/kicad/issues/1405026
|
||||
|
||||
# Git aliases file # {#commit_git_aliases}
|
||||
|
||||
There is a file containing helpful git aliases located at
|
||||
`helpers/git/fixes_alias`. To install it, run in the source repository:
|
||||
|
||||
git config --add include.path $(pwd)/helpers/git/fixes_alias
|
||||
|
||||
## 'fixes' alias # {#commit_fixes_alias}
|
||||
|
||||
Once the alias configuration file is installed, it may be used to amend the
|
||||
most recent commit to include the bug report link:
|
||||
|
||||
git fixes 1234567
|
||||
|
||||
For example, the command below will append a line to the last commit message:
|
||||
|
||||
Fixes https://gitlab.com/kicad/code/kicad/issues/1234567
|
||||
|
||||
## 'changelog' alias # {#commit_changelog_alias}
|
||||
|
||||
With the alias configuration file installed, you get an alias to extract the changelog:
|
||||
|
||||
git changelog --since="1 Jan 2017"
|
||||
git changelog <commit hash>
|
|
@ -1,676 +0,0 @@
|
|||
# Building KiCad from Source #
|
||||
If you are a user and not a developer, please consider using one of the prebuilt packages
|
||||
of KiCad which can be found at the [download][] page on the [KiCad website][]. Building KiCad
|
||||
from source is not for the faint of heart and is not recommended unless you have reasonable
|
||||
software development experience. This document contains the instructions on how to build KiCad
|
||||
from source on the supported platforms. It is not intended as a guide for installing or building
|
||||
[library dependencies](#library_dependencies). Please consult your platforms documentation for
|
||||
installing packages or the source code when building the library dependencies. Currently the
|
||||
supported platforms are Windows Versions 7-10, just about any version of Linux, and macOS
|
||||
10.9-10.13. You may be able to build KiCad on other platforms but it is not supported. On
|
||||
Windows and Linux the [GNU GCC][] is the only supported compiler and on macOS [Clang][] is the
|
||||
only supported compiler.
|
||||
|
||||
[TOC]
|
||||
|
||||
# Development Tools # {#development_tools}
|
||||
|
||||
Before you begin building KiCad, there are a few tools required in addition to your compiler.
|
||||
Some of these tools are required to build from source and some are optional.
|
||||
|
||||
## CMake Build Configuration Tool ## {#cmake}
|
||||
|
||||
[CMake][] is the build configuration and makefile generation tool used by KiCad. It is required.
|
||||
|
||||
|
||||
## Git Version Control System ## {#git}
|
||||
|
||||
The official source code repository is hosted on [GitLab][] and requires [git][] to get
|
||||
the latest source. If you prefer to use [GitHub][] there is a read only mirror of the official
|
||||
KiCad repository. The previous official hosting location at [Launchpad][] is still active as
|
||||
a mirror. Changes should be submitted as [merge requests][] via GitLab. The development team
|
||||
will not review changes submitted on GitHub or Launchpad as those platforms are mirrors only.
|
||||
|
||||
## Doxygen Code Documentation Generator ## {#doxygen_section}
|
||||
|
||||
The KiCad source code is documented using [Doxygen][] which parses the KiCad source code files
|
||||
and builds a dependency tree along with the source documentation into HTML. Doxygen is only
|
||||
required if you are going to build the KiCad documentation.
|
||||
|
||||
## SWIG Simplified Wrapper and Interface Generator ## {#swig}
|
||||
|
||||
[SWIG][] is used to generate the Python scripting language extensions for KiCad. SWIG is not
|
||||
required if you are not going to build the KiCad scripting extension.
|
||||
|
||||
|
||||
# Library Dependencies # {#library_dependencies}
|
||||
|
||||
This section includes a list of library dependencies required to build KiCad. It does not
|
||||
include any dependencies of the libraries. Please consult the library's documentation for any
|
||||
additional dependencies. Some of these libraries are optional depending on you build
|
||||
configuration. This is not a guide on how to install the library dependencies using you systems
|
||||
package management tools or how to build the library from source. Consult the appropriate
|
||||
documentation to perform these tasks.
|
||||
|
||||
## wxWidgets Cross Platform GUI Library## {#wxwidgets}
|
||||
|
||||
[wxWidgets][] is the graphical user interface (GUI) library used by KiCad. The current minimum
|
||||
version is 3.0.0. However, 3.0.2 should be used whenever possible as there are some known bugs
|
||||
in prior versions that can cause problems on some platforms. Please note that there are also
|
||||
some platform specific patches that must be applied before building wxWidgets from source. These
|
||||
patches can be found in the [patches folder][] in the KiCad source. These patches are named by
|
||||
the wxWidgets version and platform name they should be applied against. wxWidgets must be built
|
||||
with the --with-opengl option. If you installed the packaged version of wxWidgets on your system,
|
||||
verify that it was built with this option.
|
||||
|
||||
## Boost C++ Libraries ## {#boost}
|
||||
|
||||
The [Boost][] C++ library is required only if you intend to build KiCad with the system installed
|
||||
version of Boost instead of the default internally built version. If you use the system installed
|
||||
version of Boost, version 1.56 or greater is required. Please note there are some platform
|
||||
specific patches required to build a working Boost library. These patches can be found in the
|
||||
[patches folder][] in the KiCad source. These patches are named by the platform name they should
|
||||
be applied against.
|
||||
|
||||
## GLEW OpenGL Extension Wrangler Library ## {#glew}
|
||||
|
||||
The [OpenGL Extension Wrangler][GLEW] is an OpenGL helper library used by the KiCad graphics
|
||||
abstraction library [GAL] and is always required to build KiCad.
|
||||
|
||||
## ZLib Library ## {#zlib}
|
||||
|
||||
The [ZLib][] development library is used by KiCad to handle compressed 3d models (.stpz and .wrz files)
|
||||
and is always required to build KiCad.
|
||||
|
||||
## GLM OpenGL Mathematics Library ## {#glm}
|
||||
|
||||
The [OpenGL Mathematics Library][GLM] is an OpenGL helper library used by the KiCad graphics
|
||||
abstraction library [GAL] and is always required to build KiCad.
|
||||
|
||||
## GLUT OpenGL Utility Toolkit Library ## {#glut}
|
||||
|
||||
The [OpenGL Utility Toolkit][GLUT] is an OpenGL helper library used by the KiCad graphics
|
||||
abstraction library [GAL] and is always required to build KiCad.
|
||||
|
||||
## Cairo 2D Graphics Library ## {#cairo}
|
||||
|
||||
The [Cairo][] 2D graphics library is used as a fallback rendering canvas when OpenGL is not
|
||||
available and is always required to build KiCad.
|
||||
|
||||
## Python Programming Language ## {#python}
|
||||
|
||||
The [Python][] programming language is used to provide scripting support to KiCad. It needs
|
||||
to be installed unless the [KiCad scripting](#kicad_scripting) build configuration option is
|
||||
disabled.
|
||||
|
||||
## wxPython Library ## {#wxpython}
|
||||
|
||||
The [wxPython][] library is used to provide a scripting console for Pcbnew. It needs to be
|
||||
installed unless the [wxPython scripting](#wxpython_scripting) build configuration option is
|
||||
disabled. When building KiCad with wxPython support, make sure the version of the wxWidgets
|
||||
library and the version of wxPython installed on your system are the same. Mismatched versions
|
||||
have been known to cause runtime issues.
|
||||
|
||||
## Curl Multi-Protocol File Transfer Library ## {#curl}
|
||||
|
||||
The [Curl Multi-Protocol File Transfer Library][libcurl] is used to provide secure internet
|
||||
file transfer access for the [GitHub][] plug in. This library needs to be installed unless
|
||||
the GitHub plug build option is disabled.
|
||||
|
||||
## OpenCascade Library ## {#oce}
|
||||
|
||||
The [OpenCascade Community Edition (OCE)][liboce] is used to provide support for loading and saving
|
||||
3D model file formats such as STEP. This library needs to be installed unless the OCE build
|
||||
option is disabled.
|
||||
|
||||
[Open CASCSADE Technology (OCC)][libocc] should also work as an alternative to OCE. Selection of
|
||||
library Cascade library can be specified at build time. See the [STEP/IGES support](#oce_opt)
|
||||
section. When building OCC using the option BUILD_MODULE_Draw=OFF make building more easy
|
||||
|
||||
## Ngspice Library ## {#ngspice}
|
||||
|
||||
The [Ngspice Library][libngspice] is used to provide Spice simulation support in the schematic
|
||||
editor. Make sure the the version of ngspice library used was built with the--with-ngshared
|
||||
option. This library needs to be installed unless the Spice build option is disabled.
|
||||
|
||||
# KiCad Build Configuration Options # {#build_opts}
|
||||
|
||||
KiCad has many build options that can be configured to build different options depending on
|
||||
the availability of support for each option on a given platform. This section documents
|
||||
these options and their default values.
|
||||
|
||||
## Scripting Support ## {#scripting_opt}
|
||||
|
||||
The KICAD_SCRIPTING option is used to enable building the Python scripting support into Pcbnew.
|
||||
This options is enabled by default, and will disable all other KICAD_SCRIPTING_* options when
|
||||
it is disabled.
|
||||
|
||||
## Python 3 Scripting Support ## {#python3}
|
||||
|
||||
The KICAD_SCRIPTING_PYTHON3 option is used to enable using Python 3 for the scripting support
|
||||
instead of Python 2. This option is disabled by default and only is relevant if
|
||||
[KICAD_SCRIPTING](#scripting_opt) is enabled.
|
||||
|
||||
## Scripting Module Support ## {#scripting_mod_opt}
|
||||
|
||||
The KICAD_SCRIPTING_MODULES option is used to enable building and installing the Python modules
|
||||
supplied by KiCad. This option is enabled by default, but will be disabled if
|
||||
[KICAD_SCRIPTING](#scripting_opt) is disabled.
|
||||
|
||||
## wxPython Scripting Support ## {#wxpython_opt}
|
||||
|
||||
The KICAD_SCRIPTING_WXPYTHON option is used to enable building the wxPython interface into
|
||||
Pcbnew including the wxPython console. This option is enabled by default, but will be disabled if
|
||||
[KICAD_SCRIPTING](#scripting_opt) is disabled.
|
||||
|
||||
## wxPython Phoenix Scripting Support ## {#wxpython_phoenix}
|
||||
|
||||
The KICAD_SCRIPTING_WXPYTHON_PHOENIX option is used to enable building the wxPython interface with
|
||||
the new Phoenix binding instead of the legacy one. This option is disabled by default, and
|
||||
enabling it requires [KICAD_SCRIPTING](#scripting_opt) to be enabled.
|
||||
|
||||
## Python Scripting Action Menu Support ## {#python_action_menu_opt}
|
||||
|
||||
The KICAD_SCRIPTING_ACTION_MENU option allows Python scripts to be added directly to the Pcbnew
|
||||
menu. This option is enabled by default, but will be disabled if
|
||||
[KICAD_SCRIPTING](#scripting_opt) is disabled. Please note that this option is highly
|
||||
experimental and can cause Pcbnew to crash if Python scripts create an invalid object state
|
||||
within Pcbnew.
|
||||
|
||||
## Integrated Spice simulator ## {#spice_opt}
|
||||
|
||||
The KICAD_SPICE option is used to control if the Spice simulator interface for Eeschema is
|
||||
built. When this option is enabled, it requires [ngspice][] to be available as a shared
|
||||
library. This option is enabled by default.
|
||||
|
||||
## STEP/IGES support for the 3D viewer ## {#oce_opt}
|
||||
|
||||
The KICAD_USE_OCE is used for the 3D viewer plugin to support STEP and IGES 3D models. Build tools
|
||||
and plugins related to OpenCascade Community Edition (OCE) are enabled with this option. When
|
||||
enabled it requires [liboce][] to be available, and the location of the installed OCE library to be
|
||||
passed via the OCE_DIR flag. This option is enabled by default.
|
||||
|
||||
Alternatively KICAD_USE_OCC can be used instead of OCE. Both options are not supposed to be enabled
|
||||
at the same time.
|
||||
|
||||
## Wayland EGL support ## {#egl_opt}
|
||||
|
||||
The KICAD_USE_EGL option switches the OpenGL backend from using X11 bindings to Wayland EGL bindings.
|
||||
This option is only relevant on Linux when running wxWidgets 3.1.5+ with the EGL backend of
|
||||
the wxGLCanvas (which is the default option, but can be disabled in the wxWidgets build).
|
||||
|
||||
By default, setting KICAD_USE_EGL will use a in-tree version of the GLEW library (that is compiled with
|
||||
the additional flags needed to run on an EGL canvas) staticly linked into KiCad. If the system
|
||||
version of GLEW supports EGL (it must be compiled with the GLEW_EGL flag), then it can be used instead
|
||||
by setting KICAD_USE_BUNDLED_GLEW to OFF.
|
||||
|
||||
## Windows HiDPI Support ## {#msw_hidpi_opt}
|
||||
|
||||
The KICAD_WIN32_DPI_AWARE option makes the Windows manifest file for KiCad use a DPI aware version, which
|
||||
tells Windows that KiCad wants Per Monitor V2 DPI awareness (requires Windows 10 version 1607 and later).
|
||||
|
||||
## Development Analysis Tools ## {#dev_tools}
|
||||
|
||||
KiCad can be compiled with support for several features to aid in the catching and debugging of
|
||||
runtime memory issues
|
||||
|
||||
### Valgrind support
|
||||
|
||||
The KICAD_USE_VALGRIND option is used to enable Valgrind's stack annotation feature in the tool framework.
|
||||
This provides the ability for Valgrind to trace memory allocations and accesses in the tool framework
|
||||
and reduce the number of false positives reported. This option is disabled by default.
|
||||
|
||||
### C++ standard library debugging
|
||||
|
||||
KiCad provides two options to enable debugging assertions contained in the GCC C++ standard library:
|
||||
KICAD_STDLIB_DEBUG and KICAD_STDLIB_LIGHT_DEBUG. Both these options are disabled by default, and only
|
||||
one should be turned on at a time with KICAD_STDLIB_DEBUG taking precedence.
|
||||
|
||||
The KICAD_STDLIB_LIGHT_DEBUG option enables the light-weight standard library assertions by passing
|
||||
`_GLIBCXX_ASSERTIONS ` into CXXFLAGS. This enables things such as bounds checking on strings, arrays
|
||||
and vectors, as well as null pointer checks for smart pointers.
|
||||
|
||||
The KICAD_STDLIB_DEBUG option enables the full set of standard library assertions by passing
|
||||
`_GLIBCXX_DEBUG` into CXXFLAGS. This enables full debugging support for the standard library.
|
||||
|
||||
### Address Sanitizer support
|
||||
|
||||
The KICAD_SANITIZE option enables Address Sanitizer support to trace memory allocations and
|
||||
accesses to identify problems. This option is disabled by default. The Address Sanitizer
|
||||
contains several runtime options to tailor its behavior that are described in more detail in its
|
||||
[documentation](https://github.com/google/sanitizers/wiki/AddressSanitizerFlags).
|
||||
|
||||
This option is not supported on all build systems, and is known to have problems when using
|
||||
mingw.
|
||||
|
||||
## Demos and Examples ## {#demo_install_opt}
|
||||
|
||||
The KiCad source code includes some demos and examples to showcase the program. You can choose
|
||||
whether install them or not with the KICAD_INSTALL_DEMOS option. You can also select where to
|
||||
install them with the KICAD_DEMOS variable. On Linux the demos are installed in
|
||||
$PREFIX/share/kicad/demos by default.
|
||||
|
||||
## Quality assurance (QA) unit tests ## {#quality_assurance_tests_opt}
|
||||
|
||||
The KICAD_BUILD_QA_TESTS option allows building unit tests binaries for quality assurance as part
|
||||
of the default build. This option is enabled by default.
|
||||
|
||||
If this option is disabled, the QA binaries can still be built by manually specifying the target.
|
||||
For example, with `make`:
|
||||
|
||||
* Build all QA binaries: `make qa_all`
|
||||
* Build a specific test: `make qa_pcbnew`
|
||||
* Build all unit tests: `make qa_all_tests`
|
||||
* Build all test tool binaries: `make qa_all_tools`
|
||||
|
||||
For more information about testing KiCad, see [this page](testing.md).
|
||||
|
||||
## KiCad Build Version ## {#build_version_opt}
|
||||
|
||||
The KiCad version string is defined by the output of `git describe --dirty` when git is available
|
||||
or the version string defined in CMakeModules/KiCadVersion.cmake with the value of
|
||||
KICAD_VERSION_EXTRA appended to the former. If the KICAD_VERSION_EXTRA variable is not defined,
|
||||
it is not appended to the version string. If the KICAD_VERSION_EXTRA variable is defined it
|
||||
is appended along with a leading '-' to the full version string as follows:
|
||||
|
||||
(KICAD_VERSION[-KICAD_VERSION_EXTRA])
|
||||
|
||||
The build script automatically creates the version string information from the [git][] repository
|
||||
information as follows:
|
||||
|
||||
(5.0.0-rc2-dev-100-g5a33f0960)
|
||||
|
|
||||
output of `git describe --dirty` if git is available.
|
||||
|
||||
|
||||
## KiCad Config Directory ## {#config_dir_opt}
|
||||
|
||||
The default KiCad configuration directory is `kicad`. On Linux this is located at
|
||||
`~/.config/kicad`, on MSW, this is `C:\Documents and Settings\username\Application Data\kicad` and
|
||||
on MacOS, this is `~/Library/Preferences/kicad`. If the installation package would like to, it may
|
||||
specify an alternate configuration name instead of `kicad`. This may be useful for versioning
|
||||
the configuration parameters and allowing the use of, e.g. `kicad5` and `kicad6` concurrently without
|
||||
losing configuration data.
|
||||
|
||||
This is set by specifying the KICAD_CONFIG_DIR string at compile time.
|
||||
|
||||
# Getting the KiCad Source Code ## {#getting_src}
|
||||
|
||||
There are several ways to get the KiCad source. If you want to build the stable version you
|
||||
can down load the source archive from the [GitLab][] repository. Use tar or some
|
||||
other archive program to extract the source on your system. If you are using tar, use the
|
||||
following command:
|
||||
|
||||
tar -xaf kicad_src_archive.tar.xz
|
||||
|
||||
If you are contributing directly to the KiCad project on GitLab, you can create a local
|
||||
copy on your machine by using the following command:
|
||||
|
||||
git clone https://gitlab.com/kicad/code/kicad.git
|
||||
|
||||
Here is a list of source links:
|
||||
|
||||
Stable release archives: https://kicad.org/download/source/
|
||||
|
||||
Development branch: https://gitlab.com/kicad/code/kicad/tree/master
|
||||
|
||||
GitHub mirror: https://github.com/KiCad/kicad-source-mirror
|
||||
|
||||
# Building KiCad on Linux # {#build_linux}
|
||||
|
||||
To perform a full build on Linux, run the following commands:
|
||||
|
||||
cd <your kicad source mirror>
|
||||
mkdir -p build/release
|
||||
mkdir build/debug # Optional for debug build.
|
||||
cd build/release
|
||||
cmake -DCMAKE_BUILD_TYPE=Release \
|
||||
../../
|
||||
make
|
||||
sudo make install
|
||||
|
||||
If the CMake configuration fails, determine the missing dependencies and install them on your
|
||||
system. By default, CMake sets the install path on Linux to /usr/local. Use the
|
||||
CMAKE_INSTALL_PREFIX option to specify a different install path.
|
||||
|
||||
# Building KiCad on Windows # {#build_windows}
|
||||
|
||||
The preferred Windows build environment is currently [MSYS2][].
|
||||
[Visual Studio][] with [vcpkg][] is also a supported build environment
|
||||
but does not yet fully support all KiCad features.
|
||||
|
||||
|
||||
## Building using MSYS2 ## {#msys2_build}
|
||||
|
||||
### Setup
|
||||
|
||||
The [MSYS2][] project
|
||||
provides packages for all of the require dependencies to build KiCad. To setup the [MSYS2][]
|
||||
build environment, depending on your system download and run either the [MSYS2 32-bit Installer][]
|
||||
or the [MSYS2 64-bit Installer][]. After the installer is finished, update to the latest
|
||||
package versions by running the `msys2_shell.cmd` file located in the MSYS2 install path and
|
||||
running the command `pacman -Syu`. If the msys2-runtime package is updated, close the shell
|
||||
and run `msys2_shell.cmd`.
|
||||
|
||||
### Building
|
||||
The following commands assume you are building for 64-bit Windows, and that you already have
|
||||
the KiCad source code in a folder called `kicad-source` in your home directory. See below
|
||||
for changes if you need to build for 32-bit instead. Run `mingw64.exe` from the MSYS2
|
||||
install path. At the command prompt run the the following commands:
|
||||
|
||||
pacman -S base-devel \
|
||||
git \
|
||||
mingw-w64-x86_64-cmake \
|
||||
mingw-w64-x86_64-doxygen \
|
||||
mingw-w64-x86_64-gcc \
|
||||
mingw-w64-x86_64-python2 \
|
||||
mingw-w64-x86_64-pkg-config \
|
||||
mingw-w64-x86_64-swig \
|
||||
mingw-w64-x86_64-boost \
|
||||
mingw-w64-x86_64-cairo \
|
||||
mingw-w64-x86_64-glew \
|
||||
mingw-w64-x86_64-curl \
|
||||
mingw-w64-x86_64-wxPython \
|
||||
mingw-w64-x86_64-wxWidgets \
|
||||
mingw-w64-x86_64-toolchain \
|
||||
mingw-w64-x86_64-glm \
|
||||
mingw-w64-x86_64-oce \
|
||||
mingw-w64-x86_64-ngspice \
|
||||
mingw-w64-x86_64-zlib
|
||||
cd kicad-source
|
||||
mkdir -p build/release
|
||||
mkdir build/debug # Optional for debug build.
|
||||
cd build/release
|
||||
cmake -DCMAKE_BUILD_TYPE=Release \
|
||||
-G "MSYS Makefiles" \
|
||||
-DCMAKE_PREFIX_PATH=/mingw64 \
|
||||
-DCMAKE_INSTALL_PREFIX=/mingw64 \
|
||||
-DDEFAULT_INSTALL_PATH=/mingw64 \
|
||||
../../
|
||||
make -j N install # Where N is the number of concurrent threads that your system can handle
|
||||
|
||||
For 32-bit builds, run `mingw32.exe` and change `x86_64` to `i686` in the package names and
|
||||
change the paths in the cmake configuration from `/mingw64` to `/mingw32`.
|
||||
|
||||
For debug builds, run the cmake command with `-DCMAKE_BUILD_TYPE=Debug` from the `build/debug` folder.
|
||||
|
||||
### MSYS2 with CLion
|
||||
KiCad in combiation with MSYS2 can be configured to be used with CLion to provide a nice IDE experience.
|
||||
|
||||
#### Toolchain Setup
|
||||
First you must register MSYS2 as a toolchain, or namely, the compiler.
|
||||
|
||||
File > Preferences to open the Settings window.
|
||||
|
||||
Navigate to Build, Execution, Development and then the Toolchains page.
|
||||
|
||||
Add a new toolchain, and configure it as such
|
||||
|
||||
* Name: `MSYS2-MinGW64`
|
||||
* Environment Path: `<your msys2 install folder>\mingw64\`
|
||||
* CMake: `<your msys2 install folder>\mingw64\bin\cmake.exe`
|
||||
|
||||
All other fields will become automatically populated.
|
||||
|
||||
|
||||
#### Project Setup
|
||||
File > Open and select the folder containing the kicad source.
|
||||
CLion may attempt to start CMake generation and fail, this is ok.
|
||||
|
||||
Open the Settings window again.
|
||||
Navigate to Build, Execution, Development and then the CMake page.
|
||||
These settings are saved to the project.
|
||||
|
||||
You want to create a Debug configuration as such
|
||||
|
||||
* Name: `Debug-MSYS2`
|
||||
* Build-Type: `Debug`
|
||||
* Toolchain: `MSYS2-MinGW64`
|
||||
* CMake options:
|
||||
```
|
||||
-G "MinGW Makefiles"
|
||||
-DCMAKE_PREFIX_PATH=/mingw64
|
||||
-DCMAKE_INSTALL_PREFIX=/mingw64
|
||||
-DDEFAULT_INSTALL_PATH=/mingw64
|
||||
```
|
||||
* Build-directory: `build/debug-msys2`
|
||||
|
||||
|
||||
You may now trigger the "Reload CMake Cache" option in CLion to generate the cmake project
|
||||
You should delete the "junk" build folder (usually name cmake-build-debug-xxxx) it may have created in the source before it was changed above.
|
||||
We change the build folder because we have a gitignore for `/build`
|
||||
|
||||
Warning: Receiving warning messages about Boost versions is normal.
|
||||
|
||||
|
||||
### Known MSYS2 Build Issues ## {#known_issues_msys2}
|
||||
|
||||
There are some known issues that are specific to MSYS2. This section provides a list of the
|
||||
currently known issues when building KiCad using MSYS2.
|
||||
|
||||
#### Building with Boost 1.70 ### {#ki_msys2_boost_1_70}
|
||||
|
||||
There is an issue building KiCad with Boost version 1.70 due to CMake not defining the proper
|
||||
link libraries during configuration. Boost 1.70 can be used but `-DBoost_NO_BOOST_CMAKE=ON`
|
||||
needs to be added during CMake configuration to insure the link libraries are properly generated.
|
||||
|
||||
#### Building OCE from source
|
||||
|
||||
KiCad requires OCE by default, and the version installed by `pacman` can cause build errors in
|
||||
x86_64 systems as of March 2018. In order to work around this, you can build OCE from source on
|
||||
these systems. Building OCE on Windows requires that you place the source code in a very short
|
||||
directory path, otherwise you will run into errors caused by the maximum path length on Windows.
|
||||
In the example below, the `MINGW-packages` repository is cloned to `/c/mwp`, which is equivalent to
|
||||
`C:\mwp` in Windows path terminology. You may wish to change the destination of the `git clone`
|
||||
command if you do not want to place it on the root of your C drive, but if you run in to strange
|
||||
compilation errors about missing files, it is probably because your path is too long.
|
||||
|
||||
git clone https://github.com/Alexpux/MINGW-packages /c/mwp
|
||||
cd /c/mwp/mingw-w64-oce
|
||||
makepkg-mingw -is
|
||||
|
||||
## Building using Visual Studio (2019) ## {#vs_build}
|
||||
|
||||
### Environment Setup ## {#env_setup_vs}
|
||||
|
||||
#### Visual Studio
|
||||
You must first install [Visual Studio][] with the **Desktop development with C++** feature set installed.
|
||||
|
||||
|
||||
#### vcpkg
|
||||
**If you are new to vcpkg** you must, pick a spot on your system to put it.
|
||||
Then run these three commands
|
||||
|
||||
```
|
||||
git clone https://github.com/microsoft/vcpkg
|
||||
.\vcpkg\bootstrap-vcpkg.bat
|
||||
.\vcpkg\vcpkg integrate install
|
||||
```
|
||||
|
||||
which will give you a vcpkg install ready to use with the next steps
|
||||
|
||||
### KiCad Specific Setup ## {#vs_setup_steps}
|
||||
|
||||
vcpkg defaults to x86-windows even on 64-bit machines,
|
||||
it is advised for ease of use you set a **USER** or **SYSTEM** environment variable
|
||||
with the name **VCPKG_DEFAULT_TRIPLET** and value **x64-windows**
|
||||
|
||||
KiCad still supports 32-bit builds for now but may not in the future, thus 64-bit is preferred.
|
||||
|
||||
#### 1. Install vcpkg packages
|
||||
The following packages are required for vcpkg
|
||||
```
|
||||
.\vcpkg install boost
|
||||
.\vcpkg install cairo
|
||||
.\vcpkg install curl
|
||||
.\vcpkg install glew
|
||||
.\vcpkg install gettext
|
||||
.\vcpkg install glm
|
||||
.\vcpkg install icu
|
||||
.\vcpkg install ngspice
|
||||
.\vcpkg install opencascade
|
||||
.\vcpkg install opengl
|
||||
.\vcpkg install openssl
|
||||
.\vcpkg install python3
|
||||
.\vcpkg install wxwidgets
|
||||
.\vcpkg install zlib
|
||||
```
|
||||
|
||||
If you did not set the **VCPKG_DEFAULT_TRIPLET** environment variable, you will have to append
|
||||
:x64-windows to end of each packages name, `boost:x64-windows` for example.
|
||||
|
||||
#### 2. CMakeSettings.json
|
||||
Contained in the build root is a `CMakeSettings.json.sample`, copy and rename this file to `CMakeSettings.json`
|
||||
Edit `CMakeSettings.json` update the VcPkgDir environment variable up top to match the location of your vcpkg clone.
|
||||
```
|
||||
{ "VcPkgDir": "D:/vcpkg/" },
|
||||
```
|
||||
|
||||
#### 3. "Open Folder" in Visual Studio
|
||||
Launch Visual Studio (only after completing the above steps).
|
||||
|
||||
When the initial wizard launches, select to **Open a local folder**
|
||||
This is the correct way to make Visual Studio directly handle *CMake* projects.
|
||||
|
||||
|
||||
# Building KiCad on macOS # {#build_osx}
|
||||
|
||||
As of V5, building and packaging for macOS can be done using [kicad-mac-builder][],
|
||||
which downloads, patches, builds, and packages for macOS. It is used to create the official
|
||||
releases and nightlies, and it reduces the complexity of setting up a build environment to a command
|
||||
or two. Usage of kicad-mac-builder is detailed at on its website.
|
||||
|
||||
If you wish to build without kicad-mac-builder, please use the following and its source code
|
||||
as reference. Building on macOS requires building dependency libraries that require patching
|
||||
in order to work correctly.
|
||||
|
||||
In the following set of commands, replace the macOS version number (i.e. 10.11) with the desired
|
||||
minimum version. It may be easiest to build for the same version you are running.
|
||||
|
||||
KiCad currently won't work with a stock version of wxWidgets that can be downloaded or
|
||||
installed by package managers like MacPorts or Homebrew. To avoid having to deal with
|
||||
patches a [KiCad fork of wxWidgets][] is being maintained on GitHub. All the needed patches
|
||||
and some other fixes/improvements are contained in the `kicad/macos-wx-3.0` branch.
|
||||
|
||||
To perform a wxWidgets build, execute the following commands:
|
||||
|
||||
cd <your wxWidgets build folder>
|
||||
git clone -b kicad/macos-wx-3.0 https://gitlab.com/kicad/code/wxWidgets.git
|
||||
mkdir wx-build
|
||||
cd wx-build
|
||||
../wxWidgets/configure \
|
||||
--prefix=`pwd`/../wx-bin \
|
||||
--with-opengl \
|
||||
--enable-aui \
|
||||
--enable-html \
|
||||
--enable-stl \
|
||||
--enable-richtext \
|
||||
--with-libjpeg=builtin \
|
||||
--with-libpng=builtin \
|
||||
--with-regex=builtin \
|
||||
--with-libtiff=builtin \
|
||||
--with-zlib=builtin \
|
||||
--with-expat=builtin \
|
||||
--without-liblzma \
|
||||
--with-macosx-version-min=10.11 \
|
||||
--enable-universal-binary=i386,x86_64 \
|
||||
CC=clang \
|
||||
CXX=clang++
|
||||
make
|
||||
make install
|
||||
|
||||
If everything works you will find the wxWidgets binaries in `<your wxWidgets build folder>/wx-bin`.
|
||||
Now, build a basic KiCad without Python scripting using the following commands:
|
||||
|
||||
cd <your kicad source mirror>
|
||||
mkdir -p build/release
|
||||
mkdir build/debug # Optional for debug build.
|
||||
cd build/release
|
||||
cmake -DCMAKE_C_COMPILER=clang \
|
||||
-DCMAKE_CXX_COMPILER=clang++ \
|
||||
-DCMAKE_OSX_DEPLOYMENT_TARGET=10.11 \
|
||||
-DwxWidgets_CONFIG_EXECUTABLE=<your wxWidgets build folder>/wx-bin/bin/wx-config \
|
||||
-DKICAD_SCRIPTING=OFF \
|
||||
-DKICAD_SCRIPTING_MODULES=OFF \
|
||||
-DKICAD_SCRIPTING_WXPYTHON=OFF \
|
||||
-DCMAKE_INSTALL_PREFIX=../bin \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
../../
|
||||
make
|
||||
make install
|
||||
|
||||
If the CMake configuration fails, determine the missing dependencies and install them on your
|
||||
system or disable the corresponding KiCad feature. If everything works you will get self-contained
|
||||
application bundles in the `build/bin` folder.
|
||||
|
||||
Building KiCad with Python scripting is more complex and won't be covered in detail here.
|
||||
You will have to build wxPython against the wxWidgets source of the KiCad fork - a stock wxWidgets
|
||||
that might be bundled with the wxPython package won't work. Please see wxPython documentation
|
||||
or [macOS bundle build scripts][] (`compile_wx.sh`) on how to do this. Then, use a CMake
|
||||
configuration as follows to point it to your own wxWidgets/wxPython:
|
||||
|
||||
cmake -DCMAKE_C_COMPILER=clang \
|
||||
-DCMAKE_CXX_COMPILER=clang++ \
|
||||
-DCMAKE_OSX_DEPLOYMENT_TARGET=10.9 \
|
||||
-DwxWidgets_CONFIG_EXECUTABLE=<your wxWidgets build folder>/wx-bin/bin/wx-config \
|
||||
-DPYTHON_EXECUTABLE=<path-to-python-exe>/python \
|
||||
-DPYTHON_SITE_PACKAGE_PATH=<your wxWidgets build folder>/wx-bin/lib/python2.7/site-packages \
|
||||
-DCMAKE_INSTALL_PREFIX=../bin \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
../../
|
||||
|
||||
# Known Issues # {#known_issues}
|
||||
|
||||
There are some known issues that effect all platforms. This section provides a list of the
|
||||
currently known issues when building KiCad on any platform.
|
||||
|
||||
## Boost C++ Library Issues ## {#boost_issue}
|
||||
|
||||
As of version 5 of [GNU GCC][], using the default configuration of downloading, patching, and
|
||||
building of Boost 1.54 will cause the KiCad build to fail. Therefore a newer version of Boost
|
||||
must be used to build KiCad. If your system has Boost 1.56 or greater installed, you job is
|
||||
straight forward. If your system does not have Boost 1.56 or greater installed, you will have
|
||||
to download and [build Boost][] from source. If you are building Boost on windows using [MinGW][]
|
||||
you will have to apply the Boost patches in the KiCad source [patches folder][].
|
||||
|
||||
|
||||
[download]: https://kicad.org/download/
|
||||
[KiCad website]: https://kicad.org/
|
||||
[GNU GCC]: https://gcc.gnu.org/
|
||||
[Clang]: http://clang.llvm.org/
|
||||
[CMake]: https://cmake.org/
|
||||
[Launchpad]: https://code.launchpad.net/kicad/
|
||||
[GIT]: https://git-scm.com/
|
||||
[GitHub]: https://github.com/KiCad/kicad-source-mirror
|
||||
[GitLab]: https://gitlab.com/kicad/code/kicad
|
||||
[ngspice]: http://ngspice.sourceforge.net/
|
||||
[Doxygen]: http://www.doxygen.nl
|
||||
[mailing list]: https://launchpad.net/~kicad-developers
|
||||
[SWIG]: http://www.swig.org/
|
||||
[wxWidgets]: http://wxwidgets.org/
|
||||
[patches folder]: http://bazaar.launchpad.net/~kicad-product-committers/kicad/product/files/head:/patches/
|
||||
[Boost]: http://www.boost.org/
|
||||
[GLEW]: http://glew.sourceforge.net/
|
||||
[GLUT]: https://www.opengl.org/resources/libraries/glut/
|
||||
[Cairo]: http://cairographics.org/
|
||||
[Python]: https://www.python.org/
|
||||
[wxPython]: http://wxpython.org/
|
||||
[merge requests]: https://gitlab.com/kicad/code/kicad/merge_requests
|
||||
[MSYS2]: http://www.msys2.org/
|
||||
[MSYS2 32-bit Installer]: http://repo.msys2.org/distrib/i686/msys2-i686-20161025.exe
|
||||
[MSYS2 64-bit Installer]: http://repo.msys2.org/distrib/x86_64/msys2-x86_64-20161025.exe
|
||||
[PKGBUILD]: https://github.com/Alexpux/MINGW-packages/blob/master/mingw-w64-kicad-git/PKGBUILD
|
||||
[kicad-mac-builder]:https://github.com/KiCad/kicad-mac-builder
|
||||
[KiCad fork of wxWidgets]:https://github.com/KiCad/wxWidgets
|
||||
[MinGW]: http://mingw.org/
|
||||
[build Boost]: http://www.boost.org/doc/libs/1_59_0/more/getting_started/index.html
|
||||
[MSYS2 64-bit SourceForge repo]: http://sourceforge.net/projects/msys2/files/REPOS/MINGW/x86_64/
|
||||
[libcurl]: http://curl.haxx.se/libcurl/
|
||||
[GLM]: http://glm.g-truc.net/
|
||||
[git]: https://git-scm.com/
|
||||
[liboce]: https://github.com/tpaviot/oce
|
||||
[libocc]: https://www.opencascade.com/content/overview
|
||||
[libngspice]: https://sourceforge.net/projects/ngspice/
|
||||
[ZLib]: http://www.zlib.net/
|
||||
[vcpkg]: https://github.com/microsoft/vcpkg
|
||||
[Visual Studio]: https://visualstudio.microsoft.com/vs/
|
|
@ -1,10 +0,0 @@
|
|||
\ingroup config
|
||||
\defgroup config Configuration strings
|
||||
|
||||
This page documents keys used in the KiCad configuration files.
|
||||
|
||||
\defgroup develconfig Development configuration settings
|
||||
|
||||
The keys documented on this page are for development use. There is no GUI option
|
||||
to configure them; a developer can set them by manually editing the configuration
|
||||
files.
|
|
@ -1,182 +0,0 @@
|
|||
# Python Plugin Development for Pcbnew #
|
||||
|
||||
[TOC]
|
||||
|
||||
# Introduction # {#ppi_intro}
|
||||
KiCad implements a Python plugin interface so that external Python plugins can
|
||||
be run from within Pcbnew. The interface is generated using the `Simplified
|
||||
Wrapper and Interface Generator` or [SWIG](http://www.swig.org). SWIG is
|
||||
instructed to translate specific C/C++ header files into other languages using
|
||||
`interface` files. These files ultimately decide what C/C++ functions, classes
|
||||
and other declarations are exported and can be found in `pcbnew/swig/`.
|
||||
|
||||
During build-time the SWIG interface files are used to generate the
|
||||
corresponding .py files. These files are installed into Python's system-wide
|
||||
`dist-packages` repository, thus they can be imported by any Python 2
|
||||
interpreter installed on the system.
|
||||
|
||||
# Existing Pcbnew Python API documentation # {#ppi_api_docs}
|
||||
The Pcbnew Python API can be used stand-alone, i.e. no instance of Pcbnew is
|
||||
running and the board project to be manipulated is loaded and saved from and to
|
||||
file. This approach is shown with some examples in the [user's
|
||||
documentation](https://docs.kicad.org/master/en/pcbnew/pcbnew.html#kicad_scripting_reference).
|
||||
|
||||
Another documentation source is the auto-generated Doxygen reference of the
|
||||
API. It can be found
|
||||
[here](http://docs.kicad.org/doxygen-python/namespacepcbnew.html).
|
||||
|
||||
# \`Action Plugin\` Support # {#ppi_action_pi}
|
||||
Besides the stand-alone usage of the generated Python plugin interface,
|
||||
additional support regarding online manipulation of board projects is available
|
||||
for Pcbnew. Plugins using this feature are called `Action Plugins` and they are
|
||||
accessible using a Pcbnew menu entry that can be found under `Tools->External
|
||||
Plugins`. KiCad plugins that follow the `Action Plugin` conventions can be made
|
||||
to show up as external plugins in that menu and optionally as top toolbar button.
|
||||
The user can run the plugin resulting in calling a defined entry function in the
|
||||
Python plugin's code.
|
||||
This function can then be used to access and manipulate the currently loaded
|
||||
board from the Python script environment.
|
||||
|
||||
## Typical Plugin Structure ## {#ppi_pi_struct}
|
||||
The `Action Plugin` support is implemented in Pcbnew by discovering Python
|
||||
packages and Python script files in specific directories on startup.
|
||||
In order for the discovery process to work, the following requirements must be met.
|
||||
|
||||
* The plugin must be installed in the KiCad plugins search paths as documented
|
||||
in `scripting/kicadplugins.i`. You can always discover the search path for your
|
||||
setup by opening the scripting console and entering the command:
|
||||
|
||||
`import pcbnew; print pcbnew.PLUGIN_DIRECTORIES_SEARCH`
|
||||
|
||||
Currently on a Linux Installation the plugins search path is
|
||||
|
||||
* /usr/share/kicad/scripting/plugins/
|
||||
* ~/.kicad/scripting/plugins
|
||||
* ~/.kicad_plugins/
|
||||
|
||||
On Windows
|
||||
|
||||
* \%KICAD_INSTALL_PATH%/share/kicad/scripting/plugins
|
||||
* \%APPDATA%/Roaming/kicad/scripting/plugins
|
||||
|
||||
On macOS, there is a security feature that makes it easier to add scripting plugins
|
||||
to the ~/Library... path than to kicad.app, but the search path is
|
||||
|
||||
* /Applications/kicad/Kicad/Contents/SharedSupport/scripting/plugins
|
||||
* ~/Library/Application Support/kicad/scripting/plugins
|
||||
|
||||
* Alternatively a symbolic link can be created in the KiCad plugin path link to
|
||||
the plugin file/folder in another location of the file system. This can be
|
||||
useful for development.
|
||||
* The plugin must be written as a simple Python script (*.py) located in the
|
||||
plugin search path. Note that this method is preferred for small plugins
|
||||
consisting of a single .py file.
|
||||
* Alternatively the plugin must be implemented as a Python package conforming to
|
||||
the Python package standard definitions (See
|
||||
[6.4. Packages](https://docs.python.org/2/tutorial/modules.html#packages)).
|
||||
Note that this method is preferred for larger plugin projects consisting of
|
||||
multiple .py files and resource files such as dialogs or images.
|
||||
* The Python plugin must contain a class derived from `pcbnew.ActionPlugin` and
|
||||
it's `register()` method must be called within the plugin.
|
||||
|
||||
The following examples demonstrate the plugin requirements.
|
||||
|
||||
## Simple Plugin Example ## {#ppi_simple_example}
|
||||
The folder structure of the simple plugin is fairly straight forward.
|
||||
A single Python script file is placed into a directory that is present in the
|
||||
KiCad plugin path.
|
||||
|
||||
+ ~/.kicad_plugins/ # A folder in the KiCad plugin path
|
||||
- simple_plugin.py
|
||||
- simple_plugin.png (optional)
|
||||
|
||||
The file `simple_plugin.py` contains the following.
|
||||
|
||||
import pcbnew
|
||||
import os
|
||||
|
||||
class SimplePlugin(pcbnew.ActionPlugin):
|
||||
def defaults(self):
|
||||
self.name = "Plugin Name as shown in Pcbnew: Tools->External Plugins"
|
||||
self.category = "A descriptive category name"
|
||||
self.description = "A description of the plugin and what it does"
|
||||
self.show_toolbar_button = False # Optional, defaults to False
|
||||
self.icon_file_name = os.path.join(os.path.dirname(__file__), 'simple_plugin.png') # Optional, defaults to ""
|
||||
|
||||
def Run(self):
|
||||
# The entry function of the plugin that is executed on user action
|
||||
print("Hello World")
|
||||
|
||||
SimplePlugin().register() # Instantiate and register to Pcbnew
|
||||
|
||||
Note that if specified `icon_file_name` must contain absolute path to the plugin icon.
|
||||
It must be png file, recommended size is 26x26 pixels. Alpha channel for opacity is supported.
|
||||
If icon is not specified a generic tool icon will be used.
|
||||
|
||||
`show_toolbar_button` only defines a default state for plugin toolbar button. Users can override
|
||||
it in pcbnew preferences.
|
||||
|
||||
## Complex Plugin Example ## {#ppi_complex_example}
|
||||
The complex plugin example represents a single Python package that is imported
|
||||
on Pcbnew startup. When the Python package is imported, the `__init__.py` file
|
||||
is executed and is thus a perfect place to instantiate and register the plugin
|
||||
to Pcbnew.
|
||||
The big advantage here is, that you can modularize your plugin much better and
|
||||
include other files without cluttering the KiCad plugin directory.
|
||||
Additionally, the same plugin can be executed standalone using `python -m`
|
||||
e.g. to perform tests on the Python code.
|
||||
The following folder structure shows how complex plugins are implemented:
|
||||
|
||||
+ ~/.kicad_plugins/ # this directory has to be in the plugin path
|
||||
+ complex_plugin/ # The plugin directory (A Python package)
|
||||
- __init__.py # This file is executed when the package is imported (on Pcbnew startup)
|
||||
- __main__.py # This file is optional. See below
|
||||
- complex_plugin_action.py # The ActionPlugin derived class lives here
|
||||
- complex_plugin_utils.py # Other Python parts of the plugin
|
||||
- icon.png
|
||||
+ otherstuff/
|
||||
- otherfile.png
|
||||
- misc.txt
|
||||
|
||||
It is recommended to name the file containing the ActionPlugin derived class as
|
||||
`<package-name>_action.py`.
|
||||
In this case the file is named `complex_plugin_action.py` with the following
|
||||
contents:
|
||||
|
||||
import pcbnew
|
||||
import os
|
||||
|
||||
class ComplexPluginAction(pcbnew.ActionPlugin)
|
||||
def defaults(self):
|
||||
self.name = "A complex action plugin"
|
||||
self.category = "A descriptive category name"
|
||||
self.description "A description of the plugin"
|
||||
self.show_toolbar_button = True # Optional, defaults to False
|
||||
self.icon_file_name = os.path.join(os.path.dirname(__file__), 'icon.png') # Optional
|
||||
|
||||
def Run(self):
|
||||
# The entry function of the plugin that is executed on user action
|
||||
print("Hello World")
|
||||
|
||||
The `__init__.py` file is then used to instantiate and register the plugin to
|
||||
Pcbnew as follows.
|
||||
|
||||
from .complex_plugin_action import ComplexPluginAction # Note the relative import!
|
||||
ComplexPluginAction().register() # Instantiate and register to Pcbnew
|
||||
|
||||
As described in [PEP 338](https://www.python.org/dev/peps/pep-0338/) Python can
|
||||
execute packages (or modules) as scripts. This can be useful to implement a
|
||||
command-line stand-alone version of your KiCad plugin with minimum effort.
|
||||
In order to implement this feature, a `__main__.py` file is created in the
|
||||
package directory.
|
||||
This file can be executed by running the following command.
|
||||
|
||||
python -m <package_name>
|
||||
|
||||
Make sure that your current directory is the parent directory of the package
|
||||
directory when running the command.
|
||||
In these examples, this would be `~/.kicad_plugins`.
|
||||
When running the command the Python interpreter runs
|
||||
`/complex_plugin/__init__.py` followed by `/complex_plugin/__main__.py`.
|
||||
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
# Version 6 Road Map
|
||||
|
||||
The road map has been moved to the
|
||||
[GitLab Wiki](https://gitlab.com/kicad/code/kicad/-/wikis/KiCad-6.0-Roadmap).
|
||||
This document is no longer maintained.
|
|
@ -1,105 +0,0 @@
|
|||
# Road Map #
|
||||
|
||||
This document is the KiCad Developer's road map document. It is a living
|
||||
document that should be maintained as the project progresses. The goal of
|
||||
this document is to provide an overview for developers of where the project
|
||||
is headed beyond the current development cycle road map (currently
|
||||
[version 6](./v6_road_map.html) to prevent resource conflicts and endless
|
||||
rehashing of previously discussed topics. It is broken into sections for
|
||||
each major component of the KiCad source code and documentation. It defines
|
||||
tasks that developers an use to contribute to the project and provides updated
|
||||
status information. Tasks should define clear objectives and avoid vague
|
||||
generalizations so that a new developer can complete the task. It is not a
|
||||
place for developers to add their own personal wish list It should only be
|
||||
updated with approval of the project manager after discussion with the lead
|
||||
developers.
|
||||
|
||||
Each entry in the road map is made up of four sections. The goal should
|
||||
be a brief description of the what the road map entry will accomplish. The
|
||||
task section should be a list of deliverable items that are specific enough
|
||||
hat they can be documented as completed. The dependencies sections is a list
|
||||
of requirements that must be completed before work can begin on any of the
|
||||
tasks. The status section should include a list of completed tasks or marked
|
||||
as complete as when the goal is met.
|
||||
|
||||
[TOC]
|
||||
|
||||
# Project # {#project}
|
||||
This section defines the tasks for the project related goals that are not
|
||||
related to coding or documentation. It is a catch all for issues such as
|
||||
developer and user relations, dissemination of information on websites,
|
||||
policies, etc.
|
||||
|
||||
|
||||
# General # {#general}
|
||||
This section defines the tasks that affect all or most of KiCad or do not
|
||||
fit under as specific part of the code such as the board editor or the
|
||||
schematic editor.
|
||||
|
||||
|
||||
# Build Tools # {#build_tools}
|
||||
This section covers build tools for both the KiCad source as well as the
|
||||
custom dependency builds required to build KiCad.
|
||||
|
||||
|
||||
# Common Library # {#common_lib}
|
||||
This section covers the source code shared between all of the KiCad
|
||||
applications
|
||||
|
||||
|
||||
# KiCad: Application Launcher # {#kicad}
|
||||
This section applies to the source code for the KiCad application launcher.
|
||||
|
||||
|
||||
# Eeschema: Schematic Editor # {#eeschema}
|
||||
This section applies to the source code for the Eeschema schematic editor.
|
||||
|
||||
|
||||
# CvPcb: Footprint Association Tool # {#cvpcb}
|
||||
This section covers the source code of the footprint assignment tool CvPcb.
|
||||
|
||||
|
||||
# Pcbnew: Circuit Board Editor # {#pcbnew}
|
||||
This section covers the source code of the board editing application Pcbnew.
|
||||
|
||||
|
||||
# GerbView: Gerber File Viewer # {#gerbview}
|
||||
|
||||
This section covers the source code for the GerbView gerber file viewer.
|
||||
|
||||
|
||||
# Documentation # {#documentation}
|
||||
This section defines the tasks for both the user and developer documentation.
|
||||
|
||||
## Maintenance ## {#doc_maintenance}
|
||||
**Task:**
|
||||
- Keep screen shots current with the source changes.
|
||||
|
||||
**Dependencies:**
|
||||
- None.
|
||||
|
||||
**Status:**
|
||||
- No progress.
|
||||
|
||||
|
||||
# Unit Testing # {#unittest}
|
||||
**Goal:**
|
||||
|
||||
Improve the quality of KiCad and ensure changes do no break existing
|
||||
capabilities.
|
||||
|
||||
**Task:**
|
||||
- Explore the possibility of including a C++ unit test framework in addition
|
||||
to the existing Python framework.
|
||||
- Create robust enough test coverage to determine if code changes break any
|
||||
core functionality.
|
||||
|
||||
**Dependencies:**
|
||||
- Completion of the initial release of this document.
|
||||
|
||||
**Status:**
|
||||
- In progress.
|
||||
|
||||
|
||||
[kicad-website]:https://kicad.org/
|
||||
[kicad-docs]:https://docs.kicad.org/doxygen/
|
|
@ -1,134 +0,0 @@
|
|||
# Settings Framework
|
||||
|
||||
The settings framework manages application settings, as well as projects. This document explains
|
||||
how to make use of the framework as well as some of its inner workings.
|
||||
|
||||
[TOC]
|
||||
|
||||
## Source Code Guide
|
||||
|
||||
Most of the relevant code is in `common/settings` and `common/project`.
|
||||
|
||||
C++ Class | Description
|
||||
:------------------------|:-------------
|
||||
`SETTINGS_MANAGER` | Loads and unloads settings files and projects
|
||||
`JSON_SETTINGS` | The base class for all settings objects. Represents a single JSON file.
|
||||
`NESTED_SETTINGS` | A `JSON_SETTINGS` object stored within another (i.e. without its own file)
|
||||
`PARAM` | A parameter: helper class for storing data inside a `JSON_SETTINGS`
|
||||
`APP_SETTINGS_BASE` | Base class for application (frame) settings
|
||||
`COLOR_SETTINGS` | A subclass of `JSON_SETTINGS` designed for storing color themes
|
||||
`COMMON_SETTINGS` | The settings available to every part of KiCad
|
||||
`PROJECT_FILE` | A `JSON_SETTINGS` representing a project (`.kicad_pro`) file
|
||||
`PROJECT_LOCAL_SETTINGS` | A `JSON_SETTINGS` representing a project local state (`.kicad_prl`) file
|
||||
|
||||
## Where Settings are Stored
|
||||
|
||||
There are four main places a setting might be stored:
|
||||
|
||||
1) In `COMMON_SETTINGS`: this is a setting that is shared between all parts of KiCad.
|
||||
2) In an application settings object (subclass of `APP_SETTINGS_BASE`). These objects, such as
|
||||
`EESCHEMA_SETTINGS` and `PCBNEW_SETTINGS`, store settings that are specific to a portion of
|
||||
KiCad. In particular, these objects are compiled inside the context of their respective
|
||||
application, so they have access to data types that may not be part of `common`.
|
||||
3) In the `PROJECT_FILE`, where they will be specific to a loaded project. This is true of most of
|
||||
the settings found in the Board / Schematic Setup dialogs. Currently, KiCad only supports having
|
||||
one project loaded at a time, and a number of places in the code expect that a `PROJECT` object
|
||||
will always be available. Because of this, the `SETTINGS_MANAGER` will always ensure that a
|
||||
"dummy" `PROJECT_FILE` is available even when no project has been loaded by the user. This dummy
|
||||
project can be modified in memory but not saved to disk.
|
||||
4) In the `PROJECT_LOCAL_SETTINGS` object, where they will be specific to a loaded project. This
|
||||
file is for settings that are "local state", such as which board layers are visible, that should
|
||||
(for many users, at least) not be checked in to source control. Any setting here should be
|
||||
transient, meaning there will be no ill effect if the entire file is deleted.
|
||||
|
||||
## JSON_SETTINGS
|
||||
|
||||
The `JSON_SETTINGS` class is the backbone of the settings infrastructure. It is a subclass of the
|
||||
`nlohmann::json::basic_json` class provided by `thirdparty/nlohmann_json/nlohmann/json.hpp`. As
|
||||
such, anytime raw manipulation of the underlying JSON data is needed, you can use the [standard
|
||||
`nlohmann::json` API](https://nlohmann.github.io/json/api/basic_json/). The JSON contents represent
|
||||
the **state of the file on disk**, not the state of the data exposed to C++. Synchronization
|
||||
between the two is done via parameters (see below) and takes place right after loading from disk and
|
||||
right before saving to disk.
|
||||
|
||||
## Parameters
|
||||
|
||||
Parameters establish the link between C++ data and content in the JSON file. In general, parameters
|
||||
consist of a **path**, **pointer**, and **default value**. The path is a string of the form
|
||||
`"x.y.z"`, where each component represents a nested JSON dictionary key. The pointer is a pointer
|
||||
to the C++ member variable that holds the data accessible to consumers of the `JSON_SETTINGS`. The
|
||||
default value is used to update the pointer when the data is missing from the JSON file.
|
||||
|
||||
Parameters are subclasses of `PARAM_BASE` in `include/settings/parameters.h`. There are a number of
|
||||
helpful subclasses created to make it easier to store complex data in JSON files.
|
||||
|
||||
The basic `PARAM` class is templated and is useful for storing any data type can be serialized to
|
||||
JSON automatically. A basic instantiation of a `PARAM` might look like:
|
||||
|
||||
m_params.emplace_back( new PARAM<int>( "appearance.icon_scale",
|
||||
&m_Appearance.icon_scale, 0 ) );
|
||||
|
||||
Here, `m_Appearance.icon_scale` is a public member of the settings object (an `int` inside a
|
||||
`struct`). `"appearance.icon_scale"` is the **path** to store the value in the JSON file, and `0`
|
||||
is the default value. This would result in JSON looking like this:
|
||||
|
||||
{
|
||||
"appearance": {
|
||||
"icon_scale": 0
|
||||
}
|
||||
}
|
||||
|
||||
Note that it is possible to use custom types with `PARAM<>` as long as they have a `to_json` and
|
||||
`from_json` defined. See `COLOR4D` for an example of this.
|
||||
|
||||
For storing complex data types, it is sometimes easiest to use `PARAM_LAMBDA<>`, which allows you
|
||||
to define a "getter" and "setter" as part of the parameter definition. You can use this to build
|
||||
a `nlohmann::json` object and store it as the "value" of your parameter. For examples of how this
|
||||
is done, see `NET_SETTINGS`.
|
||||
|
||||
## NESTED_SETTINGS
|
||||
|
||||
The `NESTED_SETTINGS` class is like a `JSON_SETTINGS` but instead of a file for a backing store, it
|
||||
uses another `JSON_SETTINGS` object. The entire contents of a `NESTED_SETTINGS` are stored as the
|
||||
value of a particular key in the parent file. This has two key benefits:
|
||||
|
||||
1) You can split up large sets of settings in to more manageable pieces
|
||||
2) You can hide knowledge about the nested settings from the parent settings object
|
||||
|
||||
For example, many portions of the project file are stored as `NESTED_SETTINGS` objects inside the
|
||||
`PROJECT_FILE`. These objects, including `SCHEMATIC_SETTINGS`, `NET_SETTINGS`, and
|
||||
`BOARD_DESIGN_SETTINGS`, are compiled as part of eeschema or pcbnew, so they have access to data
|
||||
types not available in common (where `PROJECT_FILE` is compiled).
|
||||
|
||||
When the outer file is loaded, all of the data for the nested settings is there in the underlying
|
||||
`nlohmann::json` data store -- it's just not used until the appropriate `NESTED_SETTINGS` is loaded.
|
||||
|
||||
`NESTED_SETTINGS` objects can have shorter lifecycles than the parent. This is required because in
|
||||
some cases (such as with the project file), the parent can stay resident in one frame (the KiCad
|
||||
manager, for example) while a frame that uses a nested settings inside it can be created and
|
||||
destroyed. When the nested settings is destroyed, it ensures that its data is stored to the JSON
|
||||
data of the parent. The parent `JSON_SETTINGS` can then be saved to disk, if desired.
|
||||
|
||||
## Schema Version and Migrations
|
||||
|
||||
Settings objects have a **schema version**, which is a const integer that can be incremented when a
|
||||
migration is needed. The schema version in the code is compared to that in the loaded file, and if
|
||||
the file version is lower (older), **migrations** are run to bring the data in the file up to date.
|
||||
|
||||
**Migrations** are functions that are responsible for making the necessary changes from one schema
|
||||
version to another. They act on the **underlying JSON data**, before parameter loading has taken
|
||||
place.
|
||||
|
||||
Migrations are not always needed when changing a settings file. You are free to add or remove
|
||||
parameters without changing the schema version or writing migrations. If you add parameters, they
|
||||
will be added to the JSON file and initialized to their default value. If you remove parameters,
|
||||
they will be silently dropped from the JSON file the next time the settings are saved. Migration is
|
||||
only needed when you need to make changes to the JSON file that depend on the current state. For
|
||||
example, if you decide to rename a settings key, but want to preserve the user's present setting.
|
||||
|
||||
If you need to make a "breaking change" to a settings file:
|
||||
|
||||
1) Increment the schema version
|
||||
2) Write a migration that makes the necessary changes to the underlying `nlohmann::json` object
|
||||
3) Call `JSON_SETTINGS::registerMigration` in the constructor for the object
|
||||
|
|
@ -1,80 +0,0 @@
|
|||
# Stable Release Policy #
|
||||
|
||||
This document defines the project requirements that must be satisfied in order to create a new
|
||||
stable release of the KiCad project. It is designed to be a reference for developers and user's
|
||||
so that both groups expectations are understood. This document is only to be modified by the
|
||||
project leader or at the request of the project leader. It should be noted that this policy is
|
||||
not cast in stone and at any time in the future, should the decision be made by the project at
|
||||
large that it can be revised to suit the ongoing needs of the project and it's users.
|
||||
|
||||
The current release policy is to support the concept of a lightweight stable release. The goal
|
||||
is to provide regular stable releases of KiCad without the burden of trying to provide long term
|
||||
support of a full stable release branch. Therefore, once a new release is created, the only
|
||||
patches that will be made to the stable release branch will be for bugs that cause KiCad to crash
|
||||
or possible corruption and/or loss of data. No other changes from the current development branch
|
||||
will be backported to the last stable release by the project.
|
||||
|
||||
[TOC]
|
||||
|
||||
# Stable Release Interval # {#stable_release_interval}
|
||||
|
||||
The criteria required for new stable releases is based on the developers decision that enough
|
||||
new features and/or improvements have been made to the current development branch to justify a
|
||||
new stable release. This decision is completely discretionary and can be proposed at any time
|
||||
by any developer on the KiCad developers mailing list. Once a request for a new stable release
|
||||
is made, a consensus must be reached by the primary developers to proceed with the release with
|
||||
the final decision and announcement being made by the project leader.
|
||||
|
||||
|
||||
# Feature Freeze # {#feature_freeze}
|
||||
|
||||
Once the announcement has been made that a new stable release is in effect, the current
|
||||
development branch is frozen. No new features or potentially disruptive core code changes can
|
||||
be committed with out approval of the primary developers and/or the project leader.
|
||||
|
||||
# Bug Fixing # {#bug_fixing}
|
||||
|
||||
After the development branch has been frozen, work will continue to fix bugs reported against
|
||||
the development branch. Bugs will be prioritized based on their severity. All bugs that cause
|
||||
KiCad to crash or cause loss and/or corruption of data must be fixed. All other bugs must be
|
||||
evaluated to see if they fit into the scope of the stable release. All bugs that fit into the
|
||||
scope of the stable release will be tagged and must be fixed. All other bugs will be tagged for
|
||||
the next stable release and fixed when it is convenient. Once the stable release is officially
|
||||
announced, the bugs tagged as "Fix Committed" that are relevant to the stable release will be
|
||||
changed to "Fix Released".
|
||||
|
||||
# User Documentation # {#user_docs}
|
||||
|
||||
The user documentation will be updated to reflect the current changes in the code. This includes
|
||||
all new features, any behavioral changes to existing features, and all screen shots as required.
|
||||
Completion of the English version of the user documentation is minimum that is required for
|
||||
release. Foreign language translations can be released at any time as the become available.
|
||||
|
||||
# Stable Release Series Branch # {#stable_branch}
|
||||
|
||||
Once the primary developers decide that the stable release criteria has been met, a new series
|
||||
branch will be created from the current product branch on Launchpad. At this time the freeze
|
||||
will be removed from the product branch and normal development can resume. The stable release
|
||||
version will be incremented from the previous stable release and tagged in the stable release
|
||||
branch build configuration.
|
||||
|
||||
# System Installers # {#system_installers}
|
||||
|
||||
To proved the best user experience for platforms that do not have package managers, full system
|
||||
installers will be provided. Currently this only pertains to Windows and OSX. The full system
|
||||
installers will include all KiCad binary files, all binary library dependencies, user
|
||||
documentation, component libraries, 3D model libraries, demo project files, and project template
|
||||
files. Optionally, the footprint libraries can be included for users who prefer not us use the
|
||||
GitHub plugin.
|
||||
|
||||
# Source Archives # {#source_archives}
|
||||
|
||||
To provide a convenient method for system packagers to build KiCad from known stable sources,
|
||||
source archives in the most common formats along with the resulting md5sum checksum will be
|
||||
added to either the KiCad developer's site on Launchpad or the main website at www.kicad.org.
|
||||
|
||||
# Stable Release Announcement # {#announcement}
|
||||
|
||||
Once all of the above tasks have been completed, the project leader will post an announcement on
|
||||
the developers mailing list and the Launchpad site. This announcement should include a list of
|
||||
new features and improvements made since the previous stable release.
|
|
@ -1,182 +0,0 @@
|
|||
# Technical To-Do List {#technical_todo}
|
||||
|
||||
Some work is blocked for technical reasons, and can only be done once
|
||||
certain other criteria are met (e.g. library versions).
|
||||
|
||||
Because KiCad supports distributions with relatively long support cycles,
|
||||
many of these workarounds will be required for some time, so they are easily
|
||||
forgotten.
|
||||
|
||||
This section collects these so they can be dealt with when the project's
|
||||
minimum version for that dependency is met. This kind of code should always be
|
||||
documented in detail at the place of use, so that it's clear what action should
|
||||
be taken in future.
|
||||
|
||||
[TOC]
|
||||
|
||||
# C++ Versions {#todo_cpp_version}
|
||||
|
||||
Newer C++ versions include features that make some of our current code unnecessary.
|
||||
|
||||
## C++11 {#todo_cpp_11}
|
||||
|
||||
This C++ standard version is already used by KiCad, but much code that pre-dates
|
||||
the version switch exists and can be tidied.
|
||||
|
||||
* [`std::auto_ptr`](https://en.cppreference.com/w/cpp/memory/auto_ptr)
|
||||
should be changed to [`std::unique_ptr`](https://en.cppreference.com/w/cpp/memory/unique_ptr).
|
||||
`auto_ptr` is removed entirely in C++17.
|
||||
|
||||
## C++14 {#todo_cpp_14}
|
||||
|
||||
This C++ standard version is already used by KiCad on the development branch, but much code
|
||||
that pre-dates this version can be tidied.
|
||||
|
||||
Compiler support:
|
||||
|
||||
* GCC: complete by GCC 5: [GCC C++14 support](https://gcc.gnu.org/projects/cxx-status.html#cxx14).
|
||||
|
||||
## C++17 {#todo_cpp_17}
|
||||
|
||||
Compiler support:
|
||||
|
||||
* GCC: from GCC 5 to 7: [GCC C++17 support](https://gcc.gnu.org/projects/cxx-status.html#cxx17).
|
||||
|
||||
Provides:
|
||||
|
||||
* `OPT<>` can be replaced with [`std::optional`](https://en.cppreference.com/w/cpp/utility/optional).
|
||||
Header `core/optional.h` can be removed and replaced with the built-in `<optional>`.
|
||||
Needs [GCC 7][].
|
||||
* [`std::filesystem`](https://en.cppreference.com/w/cpp/filesystem)
|
||||
can replace `boost::filesystem` and the Boost dependency can be dropped entirely
|
||||
from the CMake files.
|
||||
* `[[fallthrough]]` attribute can be used to indicate switch statements intentionally fallthrough.
|
||||
Then Clang -Wimplicit-fallthrough warnings can be enabled.
|
||||
|
||||
|
||||
## C++20 {#todo_cpp_20}
|
||||
|
||||
Compiler support:
|
||||
* TBD (Yet to be released)
|
||||
|
||||
Provides:
|
||||
|
||||
* `constexpr std::string` and `constexpr std::vector` can be used to initialize items:
|
||||
* File extensions in `wildcards_and_files_ext.h`
|
||||
|
||||
# Compilers {#compilers}
|
||||
|
||||
Some compilers have bugs or limitations to C++ standard support.
|
||||
|
||||
## GCC {#todo_gcc}
|
||||
|
||||
Current versions:
|
||||
|
||||
* Debian Stretch: [6.3.0](https://packages.debian.org/stretch/gcc)
|
||||
* Debian Buster: [8.3.0](https://packages.debian.org/buster/gcc)
|
||||
* Ubuntu 14.04: [4.8.2](https://packages.ubuntu.com/trusty/gcc)
|
||||
* Ubuntu 16.04: [5.3.1](https://packages.ubuntu.com/xenial/gcc)
|
||||
* Ubuntu 18.04: [7.3.0](https://packages.ubuntu.com/bionic/gcc)
|
||||
|
||||
### GCC 7 {#todo_gcc_7}
|
||||
|
||||
* Fixes [bug #56480](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56480)
|
||||
(Explicit specialization in a different namespace). This
|
||||
means the `BOOST_TEST_PRINT_NAMESPACE_OPEN` macro is not required, a namespace
|
||||
alias can be used instead.
|
||||
|
||||
# 3rd Party Libraries # {#todo_third_party}
|
||||
|
||||
There are several places in KiCad where workarounds exist for defects in 3rd
|
||||
party library limitations or defects.
|
||||
|
||||
## Boost ## {#todo_boost}
|
||||
|
||||
Current versions:
|
||||
|
||||
* Debian Stretch: [1.62](https://packages.debian.org/stretch/libboost-dev)
|
||||
* Ubuntu 14.04: [1.54](https://packages.ubuntu.com/trusty/libboost-dev)
|
||||
* Ubuntu 16.04: [1.58](https://packages.ubuntu.com/xenial/libboost-dev)
|
||||
* Ubuntu 18.04: [1.65](https://packages.ubuntu.com/bionic/libboost-dev)
|
||||
|
||||
### 1.59 {#boost_1_59}
|
||||
|
||||
* Boost 1.59 brings a major overhaul of the [Boost test][] library.
|
||||
* Many "Polyfills" un `unit_test_utils.h` can be removed:
|
||||
* `BOOST_TEST_CONTEXT` and `BOOST_TEST_INFO` are available, remove the
|
||||
polyfill macros.
|
||||
* `boost::unit_test::expected_failures` is available, so can remove the
|
||||
`HAVE_EXPECTED_FAILURES` guard macro.
|
||||
* `BOOST_TEST_PRINT_NAMESPACE_OPEN` doesn't need to switch the namespace
|
||||
|
||||
### 1.64 #### {#todo_boost_1_64}
|
||||
|
||||
* [Boost test][]
|
||||
* Boost test print helper for `nullptr_t` exists, can remove our polyfill
|
||||
* The [`boost_test_print_type`](https://www.boost.org/doc/libs/master/libs/test/doc/html/boost_test/test_output/test_tools_support_for_logging/testing_tool_output_disable.html)
|
||||
customisation point exists and the old code using `BOOST_TEST_PRINT_NAMESPACE_OPEN`
|
||||
can be converted to use that.
|
||||
|
||||
## CMake ### {#todo_cmake}
|
||||
|
||||
Current versions:
|
||||
|
||||
* Debian Stretch: [3.7.2](https://packages.debian.org/stretch/cmake)
|
||||
* Ubuntu 14.04: [2.8.12](https://packages.ubuntu.com/trusty/cmake)
|
||||
* Ubuntu 16.04: [3.5.1](https://packages.ubuntu.com/xenial/cmake)
|
||||
* Ubuntu 18.04: [3.10.2](https://packages.ubuntu.com/bionic/cmake)
|
||||
|
||||
### 3.1 {#todo_cmake_3_1}
|
||||
|
||||
* Can remove [CMake policy CMP0025](https://cmake.org/cmake/help/v3.0/policy/CMP0025.html)
|
||||
from root CMake
|
||||
|
||||
### 3.3 {#todo_cmake_3_3}
|
||||
|
||||
* Can remove check for [CMake policy CMP0063](https://cmake.org/cmake/help/git-stage/policy/CMP0063.html)
|
||||
entirely (the policy exists as of v3.3 and the default is correct).
|
||||
|
||||
### 3.5 {#todo_cmake_3_5}
|
||||
|
||||
* Can use `target_link_libraries(foo Boost::boost)` for Boost header-only libraries,
|
||||
rather than `${Boost_INCLUDE_DIRS}`.
|
||||
C.f. [Github commit](https://github.com/Kitware/CMake/commit/3f9b081f6ee85e0691c36496d989edbe8382589d)
|
||||
|
||||
## OpenSSL {#todo_openssl}
|
||||
|
||||
Current versions:
|
||||
|
||||
* Debian Stretch: [1.0.1](https://packages.debian.org/stretch/openssl)
|
||||
* Ubuntu 14.04: [1.0.1](https://packages.ubuntu.com/trusty/openssl)
|
||||
* Ubuntu 16.04: [1.0.2](https://packages.ubuntu.com/xenial/openssl)
|
||||
* Ubuntu 18.04: [1.1.0](https://packages.ubuntu.com/bionic/openssl)
|
||||
|
||||
### 1.1.0 {#todo_openssl_1_1_0}
|
||||
|
||||
* Can remove all locking code from `kicad_curl.cpp`. From v1.1.0, this is no
|
||||
longer required. C.f. [OpenSSL issue 1260](https://github.com/openssl/openssl/issues/1260)
|
||||
|
||||
## wxWidgets {#todo_wx}
|
||||
|
||||
Current versions:
|
||||
|
||||
* Debian Stretch: [3.0.2](https://packages.debian.org/stretch/wx-common)
|
||||
* Ubuntu 14.04: [3.0.0](https://packages.ubuntu.com/trusty/wx-common)
|
||||
* Ubuntu 16.04: [3.0.2](https://packages.ubuntu.com/xenial/wx-common)
|
||||
* Ubuntu 18.04: [3.0.4](https://packages.ubuntu.com/bionic/wx-common)
|
||||
|
||||
### 3.1 {#todo_wx_3_1}
|
||||
|
||||
This is a development release, but it brings its own set of features and fixes.
|
||||
Most of these will not be available in general distributions until v3.2.
|
||||
|
||||
* DPI scaling on GTK+ available (also needs GTK+ 3.10).
|
||||
C.f. [this commit](https://github.com/wxWidgets/wxWidgets/commit/f95fd11e08482697c3b0c0a9d2ccd661134480ee)
|
||||
`dpi_scaling.cpp` should continue to work normally, but the config should
|
||||
no longer be required and the scaling should auto-detect.
|
||||
* Once the minimum version is greater than 3.1.3, the code inside the constructor of the `HIDPI_GL_CANVAS`
|
||||
should be removed, since the default behavior of a `wxGLCanvas` was changed in 3.1.3 to always want the
|
||||
best resolution.
|
||||
|
||||
[Boost test]: https://github.com/boostorg/test
|
||||
[GCC 7]: https://gcc.gnu.org/gcc-7/changes.html
|
|
@ -1,334 +0,0 @@
|
|||
# Testing KiCad #
|
||||
|
||||
[TOC]
|
||||
|
||||
# Unit tests {#unit-tests}
|
||||
|
||||
KiCad has a limited number of unit tests, which can be used to
|
||||
check that certain functionality works.
|
||||
|
||||
Tests are registered using [CTest][], part of CMake. CTest gathers all the
|
||||
disparate test programs and runs them. Most C++ unit
|
||||
tests are written using the [Boost Unit Test framework][], but this is not
|
||||
required to add a test to the testing suite.
|
||||
|
||||
The test CMake targets generally start with `qa_`, the names of the tests
|
||||
within CTest are the same but without the `qa_` prefix.
|
||||
|
||||
## Running tests {#running-tests}
|
||||
|
||||
You can run all tests after building with `make test` or `ctest`. The latter
|
||||
option allows many CTest options which can be useful, especially in automated
|
||||
or CI environments.
|
||||
|
||||
### Running specific tests {#running-specific-tests}
|
||||
|
||||
To run a specific test executable, you can just run with `ctest` or run
|
||||
the executable directly. Running directly is often the simplest way when
|
||||
working on a specific test and you want access to the test executable's
|
||||
arguments. For example:
|
||||
|
||||
# run the libcommon tests
|
||||
cd /path/to/kicad/build
|
||||
qa/common/qa_common [parameters]
|
||||
|
||||
For Boost unit tests, you can see the options for the test with `<test> --help`.
|
||||
Common useful patterns:
|
||||
|
||||
* `<test> -t "Utf8/*"` runs all tests in the `Utf8` test suite.
|
||||
* `<test> -t "Utf8/UniIterNull"` runs only a single test in a specific suite.
|
||||
* `<test> -l all` adds more verbose debugging to the output.
|
||||
* `<test> --list_content` lists the test suites and test cases within the
|
||||
test program. You can use these for arguments to `-t`.
|
||||
|
||||
You can rebuild just a specific test with CMake to avoid rebuilding
|
||||
everything when working on a small area, e.g. `make qa_common`.
|
||||
|
||||
### Automated testing {#automated-testing}
|
||||
|
||||
The unit tests can be run on automated Continuous Integration (CI) systems.
|
||||
|
||||
By default, tests output human-readable results, which is useful when
|
||||
developing or debugging, but not so useful for automated test reporting.
|
||||
Systems that can parse XML test results can enable these by setting the
|
||||
`KICAD_TEST_XML_OUTPUT` option to `ON`. The test results are then output
|
||||
as files ending in `.xml` in the `qa` subdirectory.
|
||||
|
||||
Test results are written to the build directory as follows:
|
||||
|
||||
* Boost units tests: one XML file per test with the extension `.boost-results.xml`
|
||||
* Python unit tests: one directory per test with the extension `.xunit-results.xml`.
|
||||
These directories contain one `.xml` file per Python test case file.
|
||||
|
||||
## Writing Boost tests {#writing-boost-tests}
|
||||
|
||||
Boost unit tests are straightforward to write. Individual test cases can be
|
||||
registered with:
|
||||
|
||||
BOOST_AUTO_TEST_CASE( SomeTest )
|
||||
{
|
||||
BOOST_CHECK_EQUAL( 1, 1 );
|
||||
}
|
||||
|
||||
There is a range of functions like `BOOST_CHECK`, which are documented
|
||||
[here][boost-test-functions]. Using the most specific function is preferred, as that
|
||||
allows Boost to provide more detailed failures: `BOOST_CHECK( foo == bar )` only
|
||||
reports a mismatch, `BOOST_CHECK_EQUAL( foo, bar )` will show the values of
|
||||
each.
|
||||
|
||||
To output debug messages, you can use `BOOST_TEST_MESSAGE` in the unit tests,
|
||||
which will be visible only if you set the `-l` parameter to `message` or higher.
|
||||
This colours the text differently to make it stand out from other testing
|
||||
messages and standard output.
|
||||
|
||||
You can also use `std::cout`, `printf`, `wxLogDebug` and so on for debug
|
||||
messages inside tested functions (i.e. where you don't have access to the Boost
|
||||
unit test headers). These will always be printed, so take care
|
||||
to remove them before committing, or they'll show up when KiCad runs normally!
|
||||
|
||||
### Expected failures {#expected-failures}
|
||||
|
||||
Sometimes, it is helpful to check in tests that do not pass. However, it is bad
|
||||
practise to intentionally check in commits that break builds (which is what
|
||||
happens if you cause `make test` to fail).
|
||||
|
||||
Boost provides a method of declaring that some specific tests are allowed to fail.
|
||||
This syntax is not consistently available in all supported Boost versions, so you
|
||||
should use the following construct:
|
||||
|
||||
```
|
||||
#include <unit_test_utils/unit_test_utils.h>
|
||||
|
||||
// On platforms with older boosts, the test will be excluded entirely
|
||||
#ifdef HAVE_EXPECTED_FAILURES
|
||||
|
||||
// Declare a test case with 1 "allowed" failure (out of 2, in this case)
|
||||
BOOST_AUTO_TEST_CASE( SomeTest, *boost::unit_test::expected_failures( 1 ) )
|
||||
{
|
||||
BOOST_CHECK_EQUAL( 1, 1 );
|
||||
|
||||
// This check fails, but does not cause a test suite failure
|
||||
BOOST_CHECK_EQUAL( 1, 2 );
|
||||
|
||||
// Further failures *would* be a test suit failure
|
||||
}
|
||||
|
||||
#endif
|
||||
```
|
||||
|
||||
When run, this produces output somewhat like this:
|
||||
|
||||
```
|
||||
qa/common/test_mytest.cpp(123): error: in "MyTests/SomeTest": check 1 == 2 has failed [1 != 2
|
||||
*** No errors detected
|
||||
```
|
||||
|
||||
And the unit test executable returns `0` (success).
|
||||
|
||||
Checking in a failing test is a strictly temporary situation, used to illustrate
|
||||
the triggering of a bug prior to fixing it. This is advantageous, not only from
|
||||
a "project history" perspective, but also to ensure that the test you write to
|
||||
catch the bug in question does, in fact, catch the bug in the first place.
|
||||
|
||||
### Assertions {#test-assertions}
|
||||
|
||||
It is possible to check for assertions in unit tests. When running the unit
|
||||
tests, `wxASSERT` calls are caught and re-thrown as exceptions. You can then use
|
||||
the `CHECK_WX_ASSERT` macro to check this is called in Debug builds. In Release
|
||||
builds, the check is not run, as `wxASSERT` is disabled in these builds.
|
||||
|
||||
You can use this to ensure that code rejects invalid input correctly.
|
||||
|
||||
## Python modules {#python-tests}
|
||||
|
||||
The Pcbnew Python modules have some test programs in the `qa` directory.
|
||||
You must have the `KICAD_SCRIPTING_MODULES` option on in CMake to
|
||||
build the modules and enable this target.
|
||||
|
||||
The main test script is `qa/test.py` and the test units are in
|
||||
`qa/testcases`. All the test units can by run using `ctest python`, which
|
||||
runs `test.py`.
|
||||
|
||||
You can also run an individual case manually, by making sure the
|
||||
modules are built, adding them to `PYTHONPATH` and running the test
|
||||
from the source tree:
|
||||
|
||||
make pcbnew_python_module
|
||||
export PYTHONPATH=/path/to/kicad/build/pcbnew
|
||||
cd /path/to/kicad/source/qa
|
||||
python2 testcase/test_001_pcb_load.py
|
||||
|
||||
### Diagnosing segfaults {#python-segfaults}
|
||||
|
||||
Although the module is Python, it links against a C++ library
|
||||
(the same one used by KiCad Pcbnew), so it can segfault if the library
|
||||
has a defect.
|
||||
|
||||
You can run the tests in GDB to trace this:
|
||||
|
||||
$ gdb
|
||||
|
||||
(gdb) file python2
|
||||
(gdb) run testcases/test_001_pcb_load.py
|
||||
|
||||
If the test segfaults, you will get a familiar backtrace, just like
|
||||
if you were running pcbnew under GDB.
|
||||
|
||||
# Utility programs {#utility-programs}
|
||||
|
||||
KiCad includes some utility programs that can be used for debugging, profiling,
|
||||
analysing or developing certain parts of the code without having to invoke the full
|
||||
GUI program.
|
||||
|
||||
Generally, they are part of the `qa_*_tools` QA executables, each one containing
|
||||
the relevant tools for that library. To list the tools in a given program, pass
|
||||
the `-l` parameter. Most tools provide help with the `-h` argument.
|
||||
To invoke a program:
|
||||
|
||||
qa_<lib>_tools <tool name> [-h] [tool arguments]
|
||||
|
||||
Below is a brief outline of some available tools. For full information and command-line
|
||||
parameters, refer to the tools' usage test (`-h`).
|
||||
|
||||
* `common_tools` (the common library and core functions):
|
||||
* `coroutine`: A simple coroutine example
|
||||
* `io_benchmark`: Show relative speeds of reading files using various IO techniques.
|
||||
* `qa_pcbnew_tools` (pcbnew-related functions):
|
||||
* `drc`: Run and benchmark certain DRC functions on a user-provided `.kicad_pcb` files
|
||||
* `pcb_parser`: Parse user-provided `.kicad_pcb` files
|
||||
* `polygon_generator`: Dump polygons found on a PCB to the console
|
||||
* `polygon_triangulation`: Perform triangulation of zone polygons on PCBs
|
||||
|
||||
# Fuzz testing {#fuzz-testing}
|
||||
|
||||
It is possible to run fuzz testing on some parts of KiCad. To do this for a
|
||||
generic function, you need to be able to pass some kind of input from the fuzz
|
||||
testing tool to the function under test.
|
||||
|
||||
For example, to use the [AFL fuzzing tool][], you will need:
|
||||
|
||||
* A test executable that can:
|
||||
* Receive input from `stdin` to be run by `afl-fuzz`.
|
||||
* Optional: process input from a filename to allow `afl-tmin` to minimise the
|
||||
input files.
|
||||
* To compile this executable with an AFL compiler, to enable the instrumentation
|
||||
that allows the fuzzer to detect the fuzzing state.
|
||||
|
||||
For example, the `qa_pcbnew_tools` executable (which contains `pcb_parser`,
|
||||
a fuzz testing tool for `.kicad_pcb` file parsing) can be compiled like this:
|
||||
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DCMAKE_CXX_COMPILER=/usr/bin/afl-clang-fast++ -DCMAKE_C_COMPILER=/usr/bin/afl-clang-fast ../kicad_src
|
||||
make qa_pcbnew_tools
|
||||
|
||||
You may need to disable core dumps and CPU frequency scaling on your system (AFL
|
||||
will warn you if you should do this). For example, as root:
|
||||
|
||||
# echo core >/proc/sys/kernel/core_pattern
|
||||
# echo performance | tee cpu*/cpufreq/scaling_governor
|
||||
|
||||
To fuzz, run the executable via `afl-fuzz`:
|
||||
|
||||
afl-fuzz -i fuzzin -o fuzzout -m500 qa/pcbnew_tools/qa_pcbnew_tools pcb_parser
|
||||
|
||||
where:
|
||||
|
||||
* `-i` is a directory of files to use as fuzz input "seeds"
|
||||
* `-o` is a directory to write the results (including inputs that provoke crashes
|
||||
or hangs)
|
||||
* `-t` is the maximum time that a run is allowed to take before being declared a "hang"
|
||||
* `-m` is the memory allowed to use (this often needs to be bumped, as KiCad code
|
||||
tends to use a lot of memory to initialise)
|
||||
|
||||
The AFL TUI will then display the fuzzing progress, and you can use the hang- or
|
||||
crash-provoking inputs to debug code as needed.
|
||||
|
||||
# Run-time debugging {#run-time}
|
||||
|
||||
KiCad can be debugged at run-time, either under a full debugger
|
||||
such as GDB, or using simple methods like logging debug to the
|
||||
console.
|
||||
|
||||
## Printing debug {#print-debug}
|
||||
|
||||
If you are compiling KiCad yourself, you can simply add debugging statements to
|
||||
relevant places in the code, for example:
|
||||
|
||||
wxLogDebug( "Value of variable: %d", my_int );
|
||||
|
||||
This produces debug output that can only be seen when compiling
|
||||
in Debug mode.
|
||||
|
||||
You can also use `std::cout` and `printf`.
|
||||
|
||||
Ensure you do not leave this kind of debugging in place when
|
||||
submitting code.
|
||||
|
||||
## Printing trace {#trace-debug}
|
||||
|
||||
Some parts of the code have "trace" that can be enabled selectively according to
|
||||
a "mask", for example:
|
||||
|
||||
wxLogTrace( "TRACEMASK", "My trace, value: %d", my_int );
|
||||
|
||||
This will not be printed by default. To show it, set the `WXTRACE` environment
|
||||
variable when you run KiCad to include the masks you wish to enable:
|
||||
|
||||
$ WXTRACE="TRACEMASK,OTHERMASK" kicad
|
||||
|
||||
When printed, the debug will be prefixed with a timestamp and the trace mask:
|
||||
|
||||
11:22:33: Trace: (TRACEMASK) My trace, value: 42
|
||||
|
||||
If you add a trace mask, define and document the mask as a variable in
|
||||
`include/trace_helpers.h`. This will add it to the [trace mask documentation][].
|
||||
|
||||
Some available masks:
|
||||
|
||||
* Core KiCad functions:
|
||||
* `KICAD_KEY_EVENTS`
|
||||
* `KicadScrollSettings`
|
||||
* `KICAD_FIND_ITEM`
|
||||
* `KICAD_FIND_REPLACE`
|
||||
* `KICAD_NGSPICE`
|
||||
* `KICAD_PLUGINLOADER`
|
||||
* `GAL_PROFILE`
|
||||
* `GAL_CACHED_CONTAINER`
|
||||
* `PNS`
|
||||
* `CN`
|
||||
* `SCROLL_ZOOM` - for the scroll-wheel zooming logic in GAL
|
||||
* Plugin-specific (including "standard" KiCad formats):
|
||||
* `3D_CACHE`
|
||||
* `3D_SG`
|
||||
* `3D_RESOLVER`
|
||||
* `3D_PLUGIN_MANAGER`
|
||||
* `KI_TRACE_CCAMERA`
|
||||
* `PLUGIN_IDF`
|
||||
* `PLUGIN_VRML`
|
||||
* `KICAD_SCH_LEGACY_PLUGIN`
|
||||
* `KICAD_GEDA_PLUGIN`
|
||||
* `KICAD_PCB_PLUGIN`
|
||||
|
||||
# Advanced configuration {#advanced-configuration}
|
||||
|
||||
There are some advance configuration options, which are mostly used for
|
||||
development or testing purposes.
|
||||
|
||||
To set these options, you can create the file `kicad_advanced` and set the keys
|
||||
as desired (the [advanced config documentation][] for a current list. You should
|
||||
never need to set these keys for normal usage - if you do, that's a bug.
|
||||
|
||||
Any features enabled though the advanced configuration system are
|
||||
considered experimental and therefore unsuitable for production use. These
|
||||
features are explicitly not supported or considered fully tested.
|
||||
Issues are still welcome for defects discovered.
|
||||
|
||||
|
||||
[CTest]: https://cmake.org/cmake/help/latest/module/CTest.html
|
||||
[Boost Unit Test framework]: https://www.boost.org/doc/libs/1_68_0/libs/test/doc/html/index.html
|
||||
[boost-test-functions]: https://www.boost.org/doc/libs/1_68_0/libs/test/doc/html/boost_test/utf_reference/testing_tool_ref.html
|
||||
[AFL fuzzing tool]: http://lcamtuf.coredump.cx/afl/
|
||||
[trace mask documentation]: http://docs.kicad.org/doxygen/group__trace__env__vars.html
|
||||
[trace mask documentation]: http://docs.kicad.org/doxygen/group__trace__env__vars.html
|
||||
[advanced config documentation]: http://docs.kicad.org/doxygen/namespaceAC__KEYS.html
|
|
@ -1,570 +0,0 @@
|
|||
# Tool Framework #
|
||||
|
||||
This document briefly outlines the structure of the tool system in the
|
||||
GAL canvases.
|
||||
|
||||
[TOC]
|
||||
|
||||
# Introduction # {#intro}
|
||||
|
||||
The GAL (Graphics Abstraction Layer) framework provides a powerful
|
||||
method of easily adding tools to KiCad. Compared to the older "legacy"
|
||||
canvas, GAL tools are more flexible, powerful and much easier to write.
|
||||
|
||||
A GAL "tool" is a class which provides one or more "actions"
|
||||
to perform. An action can be a simple one-off action (e.g. "zoom in"
|
||||
or "flip object"), or an interactive process (e.g. "manually edit
|
||||
polygon points").
|
||||
|
||||
Some examples of tools in the Pcbnew GAL are:
|
||||
|
||||
* The selection tool - the "normal" tool. This tool enters a state where
|
||||
items can be added to a list of selected objects, which are then made
|
||||
available for other tools to act on.
|
||||
(pcbnew/tools/selection_tool.cpp, pcbnew/tools/selection_tool.h)
|
||||
* The edit tool - this tool is active when a component is "picked up",
|
||||
and tracks the mouse position to allow the user to move a component.
|
||||
Aspects of editing (e.g. flip) are also make available for use by
|
||||
hotkeys or other tools.
|
||||
(pcbnew/tools/edit_tool.cpp,pcbnew/tools/edit_tool.h)
|
||||
* The drawing tool - this tool controls the process of drawing graphics
|
||||
elements such as line segments and circles.
|
||||
(pcbnew/tools/drawing_tool.cpp,pcbnew/tools/drawing_tool.h)
|
||||
* The zoom tool - allows the user to zoom in and out.
|
||||
|
||||
# Major parts of a tool # {#major-parts}
|
||||
|
||||
There are two main aspects to tools: the actions and the the tool class.
|
||||
|
||||
## Tool actions {#tool-actions}
|
||||
|
||||
The `TOOL_ACTION` class acts as a handle for the GAL framework to
|
||||
call on actions provided by tools. Generally, every action, interactive
|
||||
or not, has a `TOOL_ACTION` instance. This provides:
|
||||
|
||||
* A "name", which is of the format `pcbnew.ToolName.actionName`, which
|
||||
is used internally to dispatch the action
|
||||
* A "scope", which determines when the tools is available:
|
||||
* `AS_CONTEXT`, when the action is specific to a particular tool. For
|
||||
example, `pcbnew.InteractiveDrawing.incWidth` increases the width
|
||||
of a line while the line is still being drawn.
|
||||
* `AS_GLOBAL`, when the tool can always be invoked, by a hotkey, or
|
||||
during the execution of a different tool. For example, the zoom
|
||||
actions can be accessed from the selection tool's menu during the
|
||||
interactive selection process.
|
||||
* A "default hotkey", which is used if the user doesn't provide their
|
||||
own configuration.
|
||||
* A "menu item", which is the (translatable) string shown when this tool
|
||||
is accessed from a menu.
|
||||
* A "menu description", which is the string shown in the menu item's
|
||||
tooltip and provides a more detailed description if needed.
|
||||
* An "icon", which is shown in menus and on buttons for the action
|
||||
* "Flags" which include:
|
||||
* `AF_ACTIVATE` which indicates that the tool enters an active state. When
|
||||
a tool is active it will keep receiving UI events, such as mouse clicks
|
||||
or key presses, which are normally handled in an event loop (see
|
||||
TOOL_INTERACTIVE::Wait()).
|
||||
* A parameter, which allows different actions to call the same function
|
||||
with different effects, for example "step left" and "step right".
|
||||
|
||||
## The tool class {#tool-class}
|
||||
|
||||
GAL tools inherit the `TOOL_BASE` class. A Pcbnew tool will generally
|
||||
inherit from `PCB_TOOL`, which is a `TOOL_INTERACTIVE`, which is
|
||||
a `TOOL_BASE`. Eeschema tools inherit directly from `TOOL_INTERACTIVE`.
|
||||
|
||||
The tool class for a tool can be fairly lightweight - much of the
|
||||
functionality is inherited from the tool's base classes. These base
|
||||
classes provide access to several things, particularly:
|
||||
|
||||
* Access to the parent frame (a `wxWindow`, which can be used to
|
||||
modify the viewport, set cursors and status bar content, etc.
|
||||
* Use the function `getEditFrame<T>()`, where `T` is the frame
|
||||
subclass you want. In `PCB_TOOL`, this is likely `PCB_EDIT_FRAME`.
|
||||
* Access to the `TOOL_MANAGER` which can be used to access other tools'
|
||||
actions.
|
||||
* Access to the "model" (some sort of `EDA_ITEM`) which backs the tool.
|
||||
* Access with `getModel<T>()`. In `PCB_TOOL`, the model type `T` is
|
||||
`BOARD`, which can be used to access and modify the PCB content.
|
||||
* Access to the `KIGFX::VIEW` and `KIGFX::VIEW_CONTROLS`, which are
|
||||
used to manipulate the GAL canvas.
|
||||
|
||||
The major parts of tool's implementation are the functions used by the
|
||||
`TOOL_MANAGER` to set up and manage the tool:
|
||||
|
||||
* Constructor and destructor to establish whatever class members are
|
||||
required.
|
||||
* The TOOL_BASE class requires a string to be passed for the
|
||||
tool name, which normally looks like `pcbnew.ToolName`.
|
||||
* `Init()` function (optional), which is commonly used to fill in
|
||||
a context menu, either belonging to this tool, or access another
|
||||
tool's menu and add items to that. This function is called once, when
|
||||
the tool is registered with the tool manager.
|
||||
* `Reset()` function, called when the model (e.g. the `BOARD`) is reloaded,
|
||||
when the GAL canvas is switched, and also just after tool registration.
|
||||
Any resource claimed from the GAL view or the model must be released
|
||||
in this function, as they could become invalid.
|
||||
* `setTransitions()` function, which maps tool actions to functions
|
||||
within the tool class.
|
||||
* One or more functions to call when actions are invoked. Many actions
|
||||
can invoke the same function if desired. The functions have the
|
||||
following signature:
|
||||
* int TOOL_CLASS::FunctionName( const TOOL_EVENT& aEvent )
|
||||
* Returning 0 means success.
|
||||
* These functions are called by the `TOOL_MANAGER` in case an associated
|
||||
event arrives (association is created with TOOL_INTERACTIVE::Go() function).
|
||||
* These can generally be private, as they are not called directly
|
||||
by any other code, but are invoked by the tool manager's coroutine
|
||||
framework according to the `setTransitions()` map.
|
||||
|
||||
### Interactive actions {#interactive-actions}
|
||||
|
||||
The action handlers for an interactive actions handle repeated actions
|
||||
from the tool manager in a loop, until an action indicating that the
|
||||
tool should exit.
|
||||
|
||||
Interactive tools also normally indicate that they are active with
|
||||
a cursor change and by setting a status string.
|
||||
|
||||
int TOOL_NAME::someAction( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
auto& frame = *getEditFrame<PCB_EDIT_FRAME>();
|
||||
|
||||
// set tool hint and cursor (actually looks like a crosshair)
|
||||
frame.SetToolID( ID_LOCAL_RATSNEST_BUTT,
|
||||
wxCURSOR_PENCIL, _( "Select item to move left" ) );
|
||||
getViewControls()->ShowCursor( true );
|
||||
|
||||
// activate the tool, now it will be the first one to receive events
|
||||
// you can skip this, if you are writing a handler for a single action
|
||||
// (e.g. zoom in), opposed to interactive tool that requires further
|
||||
// events to operate (e.g. dragging a component)
|
||||
Activate();
|
||||
|
||||
// the main event loop
|
||||
while( OPT_TOOL_EVENT evt = Wait() )
|
||||
{
|
||||
if( evt->IsCancel() || evt->IsActivate() )
|
||||
{
|
||||
// end of interactive tool
|
||||
break;
|
||||
}
|
||||
else if( evt->IsClick( BUT_LEFT ) )
|
||||
{
|
||||
// do something here
|
||||
}
|
||||
// other events...
|
||||
}
|
||||
|
||||
// reset the PCB frame to how it was when we got it
|
||||
frame.SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString );
|
||||
getViewControls()->ShowCursor( false );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
## The tool menu {#tool-menu}
|
||||
|
||||
Top level tools, i.e. tools that the user enters directly, usually
|
||||
provide their own context menu. Tools that are called only from other
|
||||
tools' interactive modes add their menu items to those tools' menus.
|
||||
|
||||
To use a `TOOL_MENU` in a top level tool, simply add one as a member
|
||||
and initialize it with a reference to the tools at construction time:
|
||||
|
||||
TOOL_NAME: public PCB_TOOL
|
||||
{
|
||||
public:
|
||||
TOOL_NAME() :
|
||||
PCB_TOOL( "pcbnew.MyNewTool" ),
|
||||
m_menu( *this )
|
||||
{}
|
||||
|
||||
private:
|
||||
TOOL_MENU m_menu;
|
||||
}
|
||||
|
||||
You can then add a menu accessor, or provide a custom function to
|
||||
allow other tools to add any other actions, or a subset that you
|
||||
think appropriate.
|
||||
|
||||
You can then invoke the menu from an interactive tool loop by
|
||||
calling `m_menu.ShowContextMenu()`. Clicking on the tool's entry in
|
||||
this menu will trigger the action - there is no further action
|
||||
needed in your tool's event loop.
|
||||
|
||||
|
||||
## Commit objects {#commits}
|
||||
|
||||
The `COMMIT` class manages changes to `EDA_ITEMS`, which combines
|
||||
changes on any number of items into a single undo/redo action.
|
||||
When editing PCBs, changes to the PCB are managed by the derived
|
||||
`BOARD_COMMIT` class.
|
||||
|
||||
This class takes either a `PCB_BASE_FRAME` or a `PCB_TOOL` as an
|
||||
argument. Using `PCB_TOOL` is more appropriate for a GAL tool, since
|
||||
there's no need to go though a frame class if not required.
|
||||
|
||||
The procedure of a commit is:
|
||||
|
||||
* Construct an appropriate `COMMIT` object
|
||||
* Before modifying any item, add it to the commit with `Modify( item )`
|
||||
so that the current item state can be stored as an undo point.
|
||||
* When adding a new item, call `Add( item )`. Do not delete the added item,
|
||||
unless you are going to abort the commit.
|
||||
* When removing an item, call `Remove( item )`. You should not delete the
|
||||
removed item, it will be stored in the undo buffer.
|
||||
* Finalize the commit with `Push( "Description" )`. If you performed
|
||||
no modifications, additions or removals, this is a no-op, so you
|
||||
don't need to check if you made any changes before pushing.
|
||||
|
||||
If you want to abort a commit, you can just destruct it, without
|
||||
calling `Push()`. The underlying model won't be updated.
|
||||
|
||||
As an example:
|
||||
|
||||
// Construct commit from current PCB_TOOL
|
||||
BOARD_COMMIT commit( this );
|
||||
|
||||
BOARD_ITEM* modifiedItem = getSomeItemToModify();
|
||||
|
||||
// tell the commit we're going to change the item
|
||||
commit.Modify( modifiedItem );
|
||||
|
||||
// update the item
|
||||
modifiedItem->Move( x, y );
|
||||
|
||||
// create a new item
|
||||
PCB_SHAPE* newItem = new PCB_SHAPE;
|
||||
|
||||
// ... set up item here
|
||||
|
||||
// add to commit
|
||||
commit.Add( newItem );
|
||||
|
||||
// update the model and add the undo point
|
||||
commit.Push( "Modified one item, added another" );
|
||||
|
||||
|
||||
# Tutorial: Adding a new tool {#tutorial}
|
||||
|
||||
Without getting too heavily into the details of how the GAL tool framework
|
||||
is implemented under the surface, let's look at how you could add a
|
||||
brand new tool to Pcbnew. Our tool will have the following (rather
|
||||
useless) functions:
|
||||
|
||||
* An interactive tool which will allow the user to select a point,
|
||||
choose from the items at that point and then move that item 10mm to
|
||||
the left.
|
||||
* While in this mode, the context menu will have more options:
|
||||
* Use of the "normal" canvas zoom and grid options
|
||||
* A non-interactive tool which will add a fixed circle at a fixed point.
|
||||
* A way to invoke the non-interactive "unfill all zones" tool from
|
||||
the PCB_EDITOR_CONTROL tool.
|
||||
|
||||
## Declare tool actions {#declare-actions}
|
||||
|
||||
The first step is to add tool actions. We will implement two actions
|
||||
named:
|
||||
|
||||
* `Pcbnew.UselessTool.MoveItemLeft` - the interactive tool
|
||||
* `Pcbnew.UselessTool.FixedCircle` - the non-interactive tool.
|
||||
|
||||
The "unfill tool" already exists with the name
|
||||
`pcbnew.EditorControl.zoneUnfillAll`.
|
||||
|
||||
This guide assumes we will be adding a tool to Pcbnew, but the
|
||||
procedure for other GAL-capable canvases will be similar.
|
||||
|
||||
In `pcbnew/tools/pcb_actions.h`, we add the following to the
|
||||
`PCB_ACTIONS` class, which declares our tools:
|
||||
|
||||
static TOOL_ACTION uselessMoveItemLeft;
|
||||
static TOOL_ACTION uselessFixedCircle;
|
||||
|
||||
Definitions of actions generally happen in the .cpp of the relevant tool.
|
||||
It doesn't actually matter where the definition occurs (the declaration
|
||||
is enough to use the action), as long as it's linked in the end.
|
||||
Similar tools should always be defined together.
|
||||
|
||||
In our case, since we're making a new tool, this will be in
|
||||
`pcbnew/tools/useless_tool.cpp`. If adding actions to existing tools,
|
||||
the prefix of the tool string (e.g. `"Pcbnew.UselessTool"`) will
|
||||
be a strong indicator as to where to define the tool.
|
||||
|
||||
The tools definitions look like this:
|
||||
|
||||
TOOL_ACTION COMMON_ACTIONS::uselessMoveItemLeft(
|
||||
"pcbnew.UselessTool.MoveItemLeft",
|
||||
AS_GLOBAL, MD_CTRL + MD_SHIFT + int( 'L' ),
|
||||
_( "Move item left" ), _( "Select and move item left" ) );
|
||||
|
||||
TOOL_ACTION COMMON_ACTIONS::uselessFixedCircle(
|
||||
"pcbnew.UselessTool.FixedCircle",
|
||||
AS_GLOBAL, MD_CTRL + MD_SHIFT + int( 'C' ),
|
||||
_( "Fixed circle" ), _( "Add a fixed size circle in a fixed place" ),
|
||||
add_circle_xpm );
|
||||
|
||||
We have defined hotkeys for each action, and they are both global. This
|
||||
means you can use `Shift+Ctrl+L` and `Shift-Ctrl-C` to access each tool
|
||||
respectively.
|
||||
|
||||
We defined an icon for one of the tools, which should appear in any
|
||||
menu the item is added to, along with the given label and explanatory
|
||||
tooltip.
|
||||
|
||||
We now have two actions defined, but they are not connected to anything.
|
||||
We need to define a functions which implement the right actions.
|
||||
You can add these to an existing tool (for example `PCB_EDITOR_CONTROL`,
|
||||
which deals with many general PCB modification operation like zone
|
||||
filling), or you can write a whole new tool to keep things separate
|
||||
and give you more scope for adding tool state.
|
||||
|
||||
We will write our own tool to demonstrate the process.
|
||||
|
||||
## Add tool class declaration {#declare-tool-class}
|
||||
|
||||
Add a new tool class header `pcbnew/tools/useless_tool.h` containing
|
||||
the following class:
|
||||
|
||||
class USELESS_TOOL : public PCB_TOOL
|
||||
{
|
||||
public:
|
||||
USELESS_TOOL();
|
||||
~USELESS_TOOL();
|
||||
|
||||
///> React to model/view changes
|
||||
void Reset( RESET_REASON aReason ) override;
|
||||
|
||||
///> Basic initialization
|
||||
bool Init() override;
|
||||
|
||||
///> Bind handlers to corresponding TOOL_ACTIONs
|
||||
void setTransitions() override;
|
||||
|
||||
private:
|
||||
///> 'Move selected left' interactive tool
|
||||
int moveLeft( const TOOL_EVENT& aEvent );
|
||||
|
||||
///> Internal function to perform the move left action
|
||||
void moveLeftInt();
|
||||
|
||||
///> Add a fixed size circle
|
||||
int fixedCircle( const TOOL_EVENT& aEvent );
|
||||
|
||||
///> Menu model displayed by the tool.
|
||||
TOOL_MENU m_menu;
|
||||
};
|
||||
|
||||
## Implement tool class methods {#implement-tool}
|
||||
|
||||
In the `pcbnew/tools/useless_tool.cpp`, implement the required methods.
|
||||
In this file, you might also add free function helpers, other classes,
|
||||
and so on.
|
||||
|
||||
You will need to add this file to the `pcbnew/CMakeLists.txt` to
|
||||
build it.
|
||||
|
||||
Below you will find the contents of useless_tool.cpp:
|
||||
|
||||
#include "useless_tool.h"
|
||||
|
||||
#include <class_draw_panel_gal.h>
|
||||
#include <view/view_controls.h>
|
||||
#include <view/view.h>
|
||||
#include <tool/tool_manager.h>
|
||||
#include <board_commit.h>
|
||||
|
||||
// For frame ToolID values
|
||||
#include <pcbnew_id.h>
|
||||
|
||||
// For action icons
|
||||
#include <bitmaps.h>
|
||||
|
||||
// Items tool can act on
|
||||
#include <class_board_item.h>
|
||||
#include <class_drawsegment.h>
|
||||
|
||||
// Access to other PCB actions and tools
|
||||
#include "pcb_actions.h"
|
||||
#include "selection_tool.h"
|
||||
|
||||
|
||||
/*
|
||||
* Tool-specific action definitions
|
||||
*/
|
||||
TOOL_ACTION PCB_ACTIONS::uselessMoveItemLeft(
|
||||
"pcbnew.UselessTool.MoveItemLeft",
|
||||
AS_GLOBAL, MD_CTRL + MD_SHIFT + int( 'L' ),
|
||||
_( "Move item left" ), _( "Select and move item left" ) );
|
||||
|
||||
TOOL_ACTION PCB_ACTIONS::uselessFixedCircle(
|
||||
"pcbnew.UselessTool.FixedCircle",
|
||||
AS_GLOBAL, MD_CTRL + MD_SHIFT + int( 'C' ),
|
||||
_( "Fixed circle" ), _( "Add a fixed size circle in a fixed place" ),
|
||||
add_circle_xpm );
|
||||
|
||||
/*
|
||||
* USELESS_TOOL implementation
|
||||
*/
|
||||
|
||||
USELESS_TOOL::USELESS_TOOL() :
|
||||
PCB_TOOL( "pcbnew.UselessTool" ),
|
||||
m_menu( *this )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
USELESS_TOOL::~USELESS_TOOL()
|
||||
{}
|
||||
|
||||
|
||||
void USELESS_TOOL::Reset( RESET_REASON aReason )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool USELESS_TOOL::Init()
|
||||
{
|
||||
auto& menu = m_menu.GetMenu();
|
||||
|
||||
// add our own tool's action
|
||||
menu.AddItem( PCB_ACTIONS::uselessFixedCircle );
|
||||
// add the PCB_EDITOR_CONTROL's zone unfill all action
|
||||
menu.AddItem( PCB_ACTIONS::zoneUnfillAll );
|
||||
|
||||
// Add standard zoom and grid tool actions
|
||||
m_menu.AddStandardSubMenus( *getEditFrame<PCB_BASE_FRAME>() );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void USELESS_TOOL::moveLeftInt()
|
||||
{
|
||||
// we will call actions on the selection tool to get the current
|
||||
// selection. The selection tools will handle item disambiguation
|
||||
PCB_SELECTION_TOOL* selectionTool = m_toolMgr->GetTool<PCB_SELECTION_TOOL>();
|
||||
assert( selectionTool );
|
||||
|
||||
// call the actions
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::selectionCursor, true );
|
||||
selectionTool->SanitizeSelection();
|
||||
|
||||
const SELECTION& selection = selectionTool->GetSelection();
|
||||
|
||||
// nothing selected, return to event loop
|
||||
if( selection.Empty() )
|
||||
return;
|
||||
|
||||
BOARD_COMMIT commit( this );
|
||||
|
||||
// iterate BOARD_ITEM* container, moving each item
|
||||
for( auto item : selection )
|
||||
{
|
||||
commit.Modify( item );
|
||||
item->Move( wxPoint( -5 * IU_PER_MM, 0 ) );
|
||||
}
|
||||
|
||||
// push commit - if selection were empty, this is a no-op
|
||||
commit.Push( "Move left" );
|
||||
}
|
||||
|
||||
int USELESS_TOOL::moveLeft( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
auto& frame = *getEditFrame<PCB_EDIT_FRAME>();
|
||||
|
||||
// set tool hint and cursor (actually looks like a crosshair)
|
||||
frame.SetToolID( ID_NO_TOOL_SELECTED,
|
||||
wxCURSOR_PENCIL, _( "Select item to move left" ) );
|
||||
|
||||
getViewControls()->ShowCursor( true );
|
||||
|
||||
Activate();
|
||||
|
||||
// handle tool events for as long as the tool is active
|
||||
while( OPT_TOOL_EVENT evt = Wait() )
|
||||
{
|
||||
if( evt->IsCancel() || evt->IsActivate() )
|
||||
{
|
||||
// end of interactive tool
|
||||
break;
|
||||
}
|
||||
else if( evt->IsClick( BUT_RIGHT ) )
|
||||
{
|
||||
m_menu.ShowContextMenu();
|
||||
}
|
||||
else if( evt->IsClick( BUT_LEFT ) )
|
||||
{
|
||||
// invoke the main action logic
|
||||
moveLeftInt();
|
||||
|
||||
// keep showing the edit cursor
|
||||
getViewControls()->ShowCursor( true );
|
||||
}
|
||||
}
|
||||
|
||||
// reset the PCB frame to how it was we got it
|
||||
frame.SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString );
|
||||
getViewControls()->ShowCursor( false );
|
||||
|
||||
// exit action
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int USELESS_TOOL::fixedCircle( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
// new circle to add (ideally use a smart pointer)
|
||||
PCB_SHAPE* circle = new PCB_SHAPE;
|
||||
|
||||
// Set the circle attributes
|
||||
circle->SetShape( S_CIRCLE );
|
||||
circle->SetWidth( 5 * IU_PER_MM );
|
||||
circle->SetStart( wxPoint( 50 * IU_PER_MM, 50 * IU_PER_MM ) );
|
||||
circle->SetEnd( wxPoint( 80 * IU_PER_MM, 80 * IU_PER_MM ) );
|
||||
circle->SetLayer( LAYER_ID::F_SilkS );
|
||||
|
||||
// commit the circle to the BOARD
|
||||
BOARD_COMMIT commit( this );
|
||||
commit.Add( circle );
|
||||
commit.Push( _( "Draw a circle" ) );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void USELESS_TOOL::setTransitions()
|
||||
{
|
||||
Go( &USELESS_TOOL::fixedCircle, PCB_ACTIONS::uselessFixedCircle.MakeEvent() );
|
||||
Go( &USELESS_TOOL::moveLeft, PCB_ACTIONS::uselessMoveItemLeft.MakeEvent() );
|
||||
}
|
||||
|
||||
|
||||
## Register the tool {#register-tool}
|
||||
|
||||
The last step is to register the tool in the tool manager.
|
||||
|
||||
This is done in the frame's `setupTools()` function for whichever
|
||||
`EDA_DRAW_FRAME` support that tool.
|
||||
|
||||
## Build and run {#tutorial-summary}
|
||||
|
||||
When this is all done, you should have modified the following files:
|
||||
|
||||
* `pcbnew/tools/common_actions.h` - action declarations
|
||||
* `pcbnew/tools/useless_tool.h` - tool header
|
||||
* `pcbnew/tools/useless_tool.cpp` - action definitions and tool implementation
|
||||
* `pcbnew/tools/tools_common.cpp` - registration of the tool
|
||||
* `pcbnew/CMakeLists.txt` - for building the new .cpp files
|
||||
|
||||
When you run Pcbnew, you should be able to press `Shift+Ctrl+L` to
|
||||
enter the "move item left" tool - the cursor will change to a crosshair
|
||||
and "Select item to move left" appears in the bottom right corner.
|
||||
|
||||
When you right-click, you get a menu, which contains an entry for
|
||||
our "create fixed circle" tool and one for the existing "unfill all
|
||||
zones" tool which we added to the menu. You can also use `Shift+Ctrl+C`
|
||||
to access the fixed circle action.
|
||||
|
||||
Congratulations, you have just created your first KiCad tool!
|
|
@ -1,177 +0,0 @@
|
|||
# User Interface Guidelines #
|
||||
|
||||
This document defines the guidelines for user interface development in
|
||||
KiCad. Developers are expected to following these guidelines as closely
|
||||
as possible when contributing user interface code to the KiCad project.
|
||||
|
||||
[TOC]
|
||||
|
||||
# Text Capitalization # {#capitalization}
|
||||
For all visible text used within KiCad, follow recommendations in the
|
||||
capitalization section in the [writing style section of the GNOME User
|
||||
Interface Guidelines][gnome-ui-style]. This applies to all Menus, Titles,
|
||||
Labels, Tooltips, Buttons, etc.
|
||||
|
||||
The capitalization for the application names is KiCad, Eeschema, CvPcb,
|
||||
GerbView, and Pcbnew. All strings that have application names that are
|
||||
visible to the user should be capitalized this way. It's also a good
|
||||
idea use this capitalization in source code comments as well to prevent
|
||||
confusion of new contributors.
|
||||
|
||||
## Capitalization Styles ## {#cap-styles}
|
||||
There are two styles of capitalization are used in GNOME user interface
|
||||
elements: header capitalization and sentence capitalization. This
|
||||
section defines the capitalization style and when each type of capitalization
|
||||
should be used.
|
||||
|
||||
### Header Capitalization ### {#cap-header}
|
||||
|
||||
When using header capitalization all words are capitalized with the following
|
||||
exceptions:
|
||||
* Articles: a, an, the.
|
||||
* Conjunctions: and, but, for, not, so, yet ...
|
||||
* Prepositions of three or fewer letters: at, for, by, in, to ...
|
||||
|
||||
### Sentence Capitalization ### {#cap-sentence}
|
||||
When capitalizing sentences, capitalize the first letter of the first word,
|
||||
and any other words normally capitalized in sentences such as proper nouns.
|
||||
|
||||
## Capitalization Table ## {#cap-table}
|
||||
The following table indicates the capitalization style to use for each type
|
||||
of user interface element.
|
||||
|
||||
Element | Style
|
||||
------- | -------------------------------------------
|
||||
Check box labels | Sentence
|
||||
Command button labels | Header
|
||||
Column heading labels | Header
|
||||
Desktop background object labels | Header
|
||||
Dialog messages | Sentence
|
||||
Drop-down combination box labels | Sentence
|
||||
Drop-down list box labels | Sentence
|
||||
Field labels | Sentence
|
||||
Text on web pages | Sentence
|
||||
Group box and window frame labels | Header
|
||||
Items in drop-down and list controls | Sentence
|
||||
List box labels | Sentence
|
||||
Menu items | Header
|
||||
Menu items in applications | Header
|
||||
Menu titles in applications | Header
|
||||
Radio button labels | Sentence
|
||||
Slider labels | Sentence
|
||||
Spin box labels | Sentence
|
||||
Tabbed section titles | Header
|
||||
Text box labels | Sentence
|
||||
Titlebar labels | Header
|
||||
Toolbar button labels | Header
|
||||
Tooltips | Sentence
|
||||
Webpage titles and navigational elements | Header
|
||||
|
||||
# Dialogs # {#dialogs}
|
||||
|
||||
This section defines how dialog boxes should be designed. The KiCad project
|
||||
uses the [GNOME User Interface Guidelines][gnome-ui-guidelines] for laying out
|
||||
dialogs. When designing dialogs, follow the [visual layout section of the GNOME
|
||||
User Interface Guidelines][gnome-ui-layout]. KiCad's dialogs may either be
|
||||
designed with [wxFormBuilder][wxformbuilder] or created by hand. However,
|
||||
existing dialogs must be maintained in the same way as they have been
|
||||
implemented. Please use [wxFormBuilder v3.8.0 or later][wxformbuilder-releases]
|
||||
to avoid version mismatch between developers.
|
||||
|
||||
## Escape Key Termination ## {#dialogs-esc-key}
|
||||
Please note that the escape key termination only works properly if there is a
|
||||
dialog button defined with an ID of wxID_CANCEL or setting the escape button
|
||||
ID using [wxDialog::SetEscapeID( MY_ESCAPE_BUTTON_ID )][wxdialog-setescapeid]
|
||||
is called during dialog initialization. The former is the preferred method for
|
||||
handling escape key dialog termination. There is a checkbox in wxFormBuilder
|
||||
for setting the "default" control, and this is the one fired when the "enter"
|
||||
key is pressed.
|
||||
|
||||
## Dialog Layout with Sizers ## {#dialogs-sizers}
|
||||
Use wxWidgets "sizers" in all dialogs, no matter how simple they are. Using
|
||||
absolute sizing in dialogs is forbidden in KiCad. See the [wxWidgets sizer
|
||||
overview][wxwidgets-sizers] for more information on using sizers. Configure
|
||||
the sizers so that as the dialog window is expanded, the most sensible use of
|
||||
the increased dialog window occurs automatically by the sizers. For example,
|
||||
in the DRC dialog of Pcbnew, sizers should be used to expand the text control
|
||||
to use the full available free window area, so that the user's view of the
|
||||
items in the text control is maximized as he/she expands the dialog window,
|
||||
making it easier to read more DRC error messages. In other dialogs without
|
||||
one component more important than the others, the sizers might be configured
|
||||
to position the controls to sensible positions near the perimeter of the
|
||||
increasingly larger dialog box, not necessarily leaving them all bundled
|
||||
tightly together. The dialog box should look nice at any size large enough
|
||||
to show all the user interface elements.
|
||||
|
||||
Avoid defining initial dialog sizes if possible. Let the sizers do their
|
||||
job. After the dialog is fit to the sizers, set the minimum size to the
|
||||
current size to prevent the dialog controls from being obscured when
|
||||
resizing the dialog. If the labels or text of the dialog controls are,
|
||||
set or changed at run time. Rerun wxWindow::Fit() to allow the dialog to
|
||||
re-size and adjust for the new control widths. This can all be done after
|
||||
the dialog is created but before it is shown or use class methods to
|
||||
re-size the dialog as required. Reset the minimum size to the updated
|
||||
dialog size.
|
||||
|
||||
Dialog windows should not exceed 1024 x 768 when displayed in a 13 point font.
|
||||
Note that the font used by end users is not something that you control from
|
||||
within the dialog, but for testing purposes please do not exceed this dialog
|
||||
size should the user have selected a font size of 13 points. If your dialog
|
||||
exceeds this limit, please redesign the dialog using tabs or some other
|
||||
paging method to reduce the size of the dialog.
|
||||
|
||||
## Dialog Base Class ## {#dialog-base}
|
||||
The KiCad project has a base class which most if not all dialogs should be
|
||||
derived from. When using wxFormBuilder, please add the following settings
|
||||
to the "Dialog" tab:
|
||||
|
||||
* subclass.name <- DIALOG_SHIM
|
||||
* subclass.header <- dialog_shim.h
|
||||
|
||||
This will provide for an override of the Show( bool ) wxWindow() function
|
||||
and provide retentive size and position for the session. For more information,
|
||||
see the [DIALOG_SHIM class source code][kicad-src-dialog-shim].
|
||||
|
||||
Use tooltips to explain the functionality of each non-obvious control.
|
||||
This is important because the help files and the wiki often lag behind
|
||||
the source code.
|
||||
|
||||
## Transferring Data To and From Controls ## {#dialogs-xfer}
|
||||
|
||||
Dialog data must be transferred to the dialog controls on dialog initialization
|
||||
and transferred from controls when the dialog is dismissed by the default
|
||||
affirmative action (typically clicking the wxID_OK button) or the clicking the
|
||||
wxID_APPLY button. The wxWidgets dialog framework has support for this by
|
||||
using validators. Please read the [wxValidator Overview][wxwidgets-validator]
|
||||
in the [wxWidgets documentation][wxwidgets-doc]. In the past, data transfer
|
||||
was handled in various default button handlers virtually all of which were
|
||||
broken. Do not implement default button handlers in your dialog code. Use
|
||||
validators to transfer data to and from controls and allow the default dialog
|
||||
button handlers work the way they were designed.
|
||||
|
||||
## Internationalization ## {#dialog-i18n}
|
||||
|
||||
To generate a list of strings occurring in a dialog, one needs to enable
|
||||
'internationalize' checkbox in the project properties. Otherwise, it will not
|
||||
be possible to translate the dialog.
|
||||
|
||||
# String Quoting # {#quoting}
|
||||
Often text strings will be quoted for display which use may used in controls
|
||||
that render HTML. Using angle brackets will cause grief for HTML rendering
|
||||
controls so text should be quoted with single quotes ''. e.g.:
|
||||
|
||||
* 'filename.kicad_pcb'
|
||||
* 'longpath/subdir'
|
||||
* 'FOOTPRINTNAME'
|
||||
* 'anything else'
|
||||
|
||||
[gnome-ui-guidelines]:https://developer.gnome.org/hig/stable/
|
||||
[gnome-ui-layout]:https://developer.gnome.org/hig/stable/visual-layout.html.en
|
||||
[gnome-ui-style]:https://developer.gnome.org/hig/stable/writing-style.html.en
|
||||
[wxformbuilder]:https://github.com/wxFormBuilder/wxFormBuilder
|
||||
[wxformbuilder-releases]:https://github.com/wxFormBuilder/wxFormBuilder/releases
|
||||
[wxwidgets-doc]:http://docs.wxwidgets.org/3.0/
|
||||
[wxdialog-setescapeid]:http://docs.wxwidgets.org/3.0/classwx_dialog.html#a585869988e308f549128a6a065f387c6
|
||||
[wxwidgets-sizers]:http://docs.wxwidgets.org/3.0/overview_sizer.html
|
||||
[wxwidgets-validator]:http://docs.wxwidgets.org/3.0/overview_validator.html
|
||||
[kicad-src-dialog-shim]:http://bazaar.launchpad.net/~kicad-product-committers/kicad/product/view/head:/common/dialog_shim.cpp
|
|
@ -1,89 +0,0 @@
|
|||
|
||||
S-Expression Support in Kicad
|
||||
============================================================================
|
||||
Author: Dick Hollenbeck
|
||||
Date: Jan 2011
|
||||
|
||||
|
||||
An s-expression is a text stream or string, in the same vain as XML, consisting
|
||||
of a sequence of elements. Each element is either an atom or list. An atom
|
||||
corresponds to a string, while a list corresponds to an s-expression. The
|
||||
following grammar represents our definition of an s-expression:
|
||||
|
||||
sexpr ::= ( sx )
|
||||
sx ::= atom sxtail | sexpr sxtail | NULL
|
||||
sxtail ::= sx | NULL
|
||||
atom :: quoted | value
|
||||
quoted :: "ws_string"
|
||||
value :: nws_string
|
||||
|
||||
An atom can either be a quoted string, which is a string containing whitespace
|
||||
surrounded by double quotes, or a non-whitespace string that does not require
|
||||
surrounding quotes.
|
||||
|
||||
The s-expression syntax used in Kicad uses two quoting/syntax strategies, given
|
||||
by the needs of the Specctra DSN specification and of our own non-specctra
|
||||
needs. The Specctra DSN specification is not very clear with regard to quoting
|
||||
and on top of that there is Freerouter's interpretation, which would actually
|
||||
supercede anything in the Specctra DSN spec anyway, due to a desire to be
|
||||
compatible with Freerouter.
|
||||
|
||||
We have our own needs, which go beyond those of the Specctra DSN spec, so we
|
||||
support the two syntaxes or quoting protocols for quoted atoms:
|
||||
|
||||
1) Specctra quoting protocol (specctraMode)
|
||||
2) Kicad quoting protocol (non-specctraMode)
|
||||
|
||||
We can control our own destiny better by having a separately defined mode for
|
||||
non Specctra DSN files.
|
||||
|
||||
To summarize, in specctraMode Freerouter dictates to us what we need to do. In
|
||||
non-specctraMode, which can be thought of as Kicad mode, we have our own quoting
|
||||
protocol and can make changes without breaking the specctraMode.
|
||||
|
||||
There needs to be agreement between how a file is saved, and how a file is read
|
||||
back in, in either mode, to fulfill the round-tripping requirements. A file
|
||||
written using one mode may not necessarily be readable using the other mode,
|
||||
although it might be. Just don't count on it.
|
||||
|
||||
|
||||
In Kicad mode:
|
||||
|
||||
OUTPUTFORMATTER::Quoted() is the tool to wrap s-expression atoms.
|
||||
DSNLEXER::NexTok() is basically the inverse function, and reads tokens back in.
|
||||
These two must agree, so that what is written out comes back in un-altered.
|
||||
|
||||
The decision to wrap the string or not is left to the Quoted() function. If the
|
||||
string is wrapped, it will also escape internal double quotes, \n's and \r's.
|
||||
Any null string is wrapped in quotes, and so is any string which starts with
|
||||
'#', so that it is not confused with an s-expression comment.
|
||||
|
||||
|
||||
Kicad S-expression Syntax and Quoting Protocol (non-specctraMode):
|
||||
==================================================================
|
||||
|
||||
*) Some atoms are considered keywords, and constitute a grammar superimposed on
|
||||
the s-expressions. All keywords are ASCII and lowercase. International characters
|
||||
are not to be used here.
|
||||
|
||||
*) All Kicad s-expression files are saved using a UTF8 encoding and should
|
||||
support any international characters in the atoms which are not keywords.
|
||||
|
||||
*) DSNLEXER::NextTok() requires that any token be on a single line of input. If
|
||||
you want to save a multi-line string, Quoted() will automatically escape the \n
|
||||
or \r for you and put the output on a single line. It should round-trip fine.
|
||||
|
||||
*) There can be escape sequences in a quoted string only. Escape sequences allow
|
||||
foreign tools to generate byte patterns in the input stream. C style 2 byte hex
|
||||
codes are supported, and so are 3 byte octal escape sequences. See
|
||||
DSNLEXER::NextTok() for the full list of escape sequences, by searching file
|
||||
dsnlexer.cpp for the string "ESCAPE SEQUENCES". Any use of the escape mechanism
|
||||
must still produce UTF-8 encoded text after the escape handling is applied.
|
||||
|
||||
*) Just because an escape sequence is supported on input, does not mean that
|
||||
OUTPUTFORMATTER::Quoted() must generate such an escape sequence for output. For
|
||||
example, having true tabs in the s-expression file is OK. So that will not be
|
||||
escaped on output. Other similar cases exist.
|
||||
|
||||
*) Backslash is the escape byte.
|
||||
|
Loading…
Reference in New Issue