Remove documentation now moved to http://dev-docs.kicad.org/

Repo at
This commit is contained in:
Marek Roszko 2021-01-01 12:49:49 -05:00
parent d880606e72
commit bdef682d4d
20 changed files with 1 additions and 6458 deletions

View File

@ -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()

View File

@ -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.

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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>

View File

@ -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/

View File

@ -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.

View File

@ -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`.

View File

@ -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.

View File

@ -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/

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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!

View File

@ -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

View File

@ -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.

View File

@ -780,8 +780,7 @@ WARN_LOGFILE =
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
# Note: If this tag is empty the current directory is searched.
INPUT = Documentation/development \
3d-viewer \
INPUT = 3d-viewer \
bitmap2component \
bitmaps_png \
common \