KiCad PCB EDA Suite
Loading...
Searching...
No Matches
paths.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
20#include <wx/dir.h>
21#include <wx/filename.h>
22#include <wx/stdpaths.h>
23#include <wx/string.h>
24#include <wx/utils.h>
25#include <wx/msgdlg.h>
26
28#include <paths.h>
29#include <config.h>
30#include <build_version.h>
31#include <macros.h>
32#include <wx_filename.h>
33
34
35void PATHS::getUserDocumentPath( wxFileName& aPath )
36{
37 wxString envPath;
38
39 if( wxGetEnv( wxT( "KICAD_DOCUMENTS_HOME" ), &envPath ) )
40 aPath.AssignDir( envPath );
41 else
42 aPath.AssignDir( KIPLATFORM::ENV::GetDocumentsPath() );
43
44 aPath.AppendDir( KICAD_PATH_STR );
45 aPath.AppendDir( GetMajorMinorVersion().ToStdString() );
46}
47
48
50{
51 wxFileName tmp;
53
54 tmp.AppendDir( wxT( "plugins" ) );
55
56 return tmp.GetPath();
57}
58
59
61{
62 wxFileName tmp;
64
65 tmp.AppendDir( wxT( "scripting" ) );
66
67 return tmp.GetPath();
68}
69
70
72{
73 wxFileName tmp;
75
76 tmp.AppendDir( wxT( "template" ) );
77
78 return tmp.GetPathWithSep();
79}
80
81
83{
84 wxFileName tmp;
86
87 tmp.AppendDir( wxT( "symbols" ) );
88
89 return tmp.GetPath();
90}
91
92
94{
95 wxFileName tmp;
97
98 tmp.AppendDir( wxT( "footprints" ) );
99
100 return tmp.GetPath();
101}
102
103
105{
106 wxFileName tmp;
107 getUserDocumentPath( tmp );
108
109 tmp.AppendDir( wxT( "blocks" ) );
110
111 return tmp.GetPath();
112}
113
114
116{
117 wxFileName tmp;
118 getUserDocumentPath( tmp );
119
120 tmp.AppendDir( wxT( "3dmodels" ) );
121
122 return tmp.GetPath();
123}
124
125
127{
128 wxFileName tmp;
129 getUserDocumentPath( tmp );
130
131 tmp.AppendDir( wxT( "3rdparty" ) );
132
133 return tmp.GetAbsolutePath();
134}
135
136
138{
139 wxFileName tmp;
140 getUserDocumentPath( tmp );
141
142 tmp.AppendDir( wxT( "projects" ) );
143
144 return tmp.GetPath();
145}
146
147
148#if defined( __WXMAC__ )
154static wxString getOSXBundleRoot()
155{
156 static wxString bundleRoot;
157
158 if( bundleRoot.empty() )
159 {
160 wxFileName fn( wxStandardPaths::Get().GetExecutablePath() );
162 fn.SetFullName( wxEmptyString ); // Remove binary name
163
164 // Navigate from .../Contents/MacOS/ up to the .app bundle root
165 // e.g., /Applications/KiCad/KiCad.app/Contents/MacOS -> /Applications/KiCad/KiCad.app
166 if( fn.GetDirCount() >= 2 && fn.GetDirs().Last() == wxT( "MacOS" ) )
167 {
168 fn.RemoveLastDir(); // MacOS
169 fn.RemoveLastDir(); // Contents
170 }
171
172 // Handle aux binaries inside main bundle
173 // From: .../main.app/Contents/Applications/standalone.app
174 // To: .../main.app
175 const wxArrayString dirs = fn.GetDirs();
176 if( dirs.GetCount() >= 4 && dirs[dirs.GetCount() - 2] == wxT( "Applications" )
177 && dirs[dirs.GetCount() - 4].Lower().EndsWith( wxT( "app" ) ) )
178 {
179 fn.RemoveLastDir(); // standalone.app
180 fn.RemoveLastDir(); // Applications
181 fn.RemoveLastDir(); // Contents
182 }
183
184 bundleRoot = fn.GetPath();
185 }
186
187 return bundleRoot;
188}
189#endif
190
191
192wxString PATHS::GetStockDataPath( bool aRespectRunFromBuildDir )
193{
194 wxString path;
195
196 if( aRespectRunFromBuildDir && RunningFromBuildDir() )
197 {
198 // Allow debugging from build dir by placing relevant files/folders in the build root
199#if defined( __WXMAC__ )
200 wxFileName fn;
201 fn.AssignDir( getOSXBundleRoot() );
202 fn.RemoveLastDir(); // Above the .app bundle
203 fn.RemoveLastDir(); // Above the target subdirectory to build root
204 path = fn.GetPath();
205#elif defined( __WXMSW__ )
206 path = getWindowsKiCadRoot();
207#else
208 path = GetBuildRoot();
209
210 wxASSERT_MSG( !path.IsEmpty(), wxString::Format( wxT( "Could not find build root directory above %s" ),
211 GetExecutablePath() ) );
212#endif
213 }
214 else if( wxGetEnv( wxT( "KICAD_STOCK_DATA_HOME" ), &path ) && !path.IsEmpty() )
215 {
216 return path;
217 }
218 else
219 {
220#if defined( __WXMAC__ )
221 path = GetOSXKicadDataDir();
222#elif defined( __WXMSW__ )
223 path = getWindowsKiCadRoot() + wxT( "share/kicad" );
224#else
225 path = wxString::FromUTF8Unchecked( KICAD_DATA );
226#endif
227 }
228
229 return path;
230}
231
232
233#ifdef _WIN32
234
235wxString PATHS::GetWindowsBaseSharePath()
236{
237 return getWindowsKiCadRoot() + wxT( "share\\" );
238}
239
240#endif
241
242
244{
245 wxString path;
246
247#if defined( __WXMAC__ )
248 path = GetOSXKicadMachineDataDir();
249#elif defined( __WXMSW__ )
250 path = GetStockDataPath( false );
251#else
252 if( wxGetEnv( wxT( "APPDIR" ), &path ) )
253 path += wxT( "/share/kicad" );
254 else
255 path = wxString::FromUTF8Unchecked( KICAD_LIBRARY_DATA );
256#endif
257
258 return path;
259}
260
261
263{
264 wxFileName fn;
265
266 fn.AssignDir( GetStockEDALibraryPath() );
267 fn.AppendDir( "symbols" );
268
269 return fn.GetPathWithSep();
270}
271
272
274{
275 wxFileName fn;
276
277 fn.AssignDir( GetStockEDALibraryPath() );
278 fn.AppendDir( "footprints" );
279
280 return fn.GetPathWithSep();
281}
282
283
285{
286 wxFileName fn;
287
288 fn.AssignDir( GetStockEDALibraryPath() );
289 fn.AppendDir( "blocks" );
290
291 return fn.GetPathWithSep();
292}
293
294
296{
297 wxFileName fn;
298
299 fn.AssignDir( GetStockEDALibraryPath() );
300 fn.AppendDir( "3dmodels" );
301
302 return fn.GetPathWithSep();
303}
304
305
307{
308 wxFileName fn;
309
310 fn.AssignDir( GetStockDataPath() );
311 fn.AppendDir( "scripting" );
312
313 return fn.GetPathWithSep();
314}
315
316
318{
319 wxFileName fn;
320
321 fn.AssignDir( GetStockEDALibraryPath() );
322 fn.AppendDir( "template" );
323
324 return fn.GetPathWithSep();
325}
326
327
329{
330 wxFileName fn;
331
332 fn.AssignDir( GetStockDataPath() );
333 fn.AppendDir( "internat" );
334
335 return fn.GetPathWithSep();
336}
337
338
340{
341 wxFileName fn;
342
343#if defined( __WXMSW__ )
344 fn.AssignDir( GetExecutablePath() );
345 fn.AppendDir( wxT( "scripting" ) );
346#else
347 fn.AssignDir( PATHS::GetStockDataPath( false ) );
348#endif
349 fn.AppendDir( wxT( "plugins" ) );
350
351 return fn.GetPathWithSep();
352}
353
354
356{
357 wxFileName fn;
358
359#if defined( __WXMSW__ )
360 if( RunningFromBuildDir() )
361 {
362 fn.AssignDir( getWindowsKiCadRoot() );
363 }
364 else
365 {
366 fn.AssignDir( GetExecutablePath() );
367 }
368
369 fn.AppendDir( wxT( "plugins" ) );
370#elif defined( __WXMAC__ )
371 fn.AssignDir( getOSXBundleRoot() );
372 fn.AppendDir( wxT( "Contents" ) );
373 fn.AppendDir( wxT( "PlugIns" ) );
374#else
375 wxString envPath;
376
377 if( RunningFromBuildDir() )
378 {
379 fn.Assign( wxStandardPaths::Get().GetExecutablePath() );
380 fn.AppendDir( wxT( ".." ) );
381 fn.AppendDir( wxT( "plugins" ) );
382 }
383 // AppImages have a different path to the plugins, otherwise we end up with host system
384 // plugins being loaded.
385 else if( wxGetEnv( wxT( "APPDIR" ), &envPath ) )
386 {
387 fn.Assign( envPath, wxEmptyString );
388 fn.AppendDir( wxT( "usr" ) );
389 fn.AppendDir( wxT( "lib" ) );
390 fn.AppendDir( wxT( "x86_64-linux-gnu" ) );
391 fn.AppendDir( wxT( "kicad" ) );
392 fn.AppendDir( wxT( "plugins" ) );
393 }
394 else
395 {
396 // KICAD_PLUGINDIR = CMAKE_INSTALL_FULL_LIBDIR path is the absolute path
397 // corresponding to the install path used for constructing KICAD_USER_PLUGIN
398 wxString tfname = wxString::FromUTF8Unchecked( KICAD_PLUGINDIR );
399 fn.Assign( tfname, "" );
400 fn.AppendDir( wxT( "kicad" ) );
401 fn.AppendDir( wxT( "plugins" ) );
402 }
403#endif
404
405 fn.AppendDir( wxT( "3d" ) );
406
407 return fn.GetPathWithSep();
408}
409
410
412{
413 wxFileName fn;
414
415 fn.AssignDir( PATHS::GetStockDataPath( false ) );
416 fn.AppendDir( wxT( "demos" ) );
417
418 return fn.GetPathWithSep();
419}
420
421
423{
424 wxString envPath;
425 wxFileName tmp;
426
427 tmp.AssignDir( KIPLATFORM::ENV::GetUserCachePath() );
428
429 // Use KICAD_CACHE_HOME to allow the user to force a specific cache path.
430 if( wxGetEnv( wxT( "KICAD_CACHE_HOME" ), &envPath ) && !envPath.IsEmpty() )
431 {
432 // Override the assignment above with KICAD_CACHE_HOME
433 tmp.AssignDir( envPath );
434 }
435
436 tmp.AppendDir( KICAD_PATH_STR );
437 tmp.AppendDir( GetMajorMinorVersion().ToStdString() );
438
439 return tmp.GetPathWithSep();
440}
441
442
444{
445 wxString path;
446
447#if defined( __WXMAC__ )
448 path = GetOSXKicadDataDir();
449#elif defined( __WXMSW__ )
450 path = getWindowsKiCadRoot() + wxT( "share/doc/kicad" );
451#else
452 path = wxString::FromUTF8Unchecked( KICAD_DOCS );
453#endif
454
455 return path;
456}
457
458
460{
461 wxFileName tmp;
462 getUserDocumentPath( tmp );
463
464 tmp.AppendDir( wxT( "logs" ) );
465
466 return tmp.GetPath();
467}
468
469
470bool PATHS::EnsurePathExists( const wxString& aPath, bool aPathToFile )
471{
472 wxString pathString = aPath;
473 if( !aPathToFile )
474 {
475 // ensures the path is treated fully as directory
476 pathString += wxFileName::GetPathSeparator();
477 }
478
479 wxFileName path( pathString );
480 if( !path.MakeAbsolute() )
481 {
482 return false;
483 }
484
485 if( !wxFileName::DirExists( path.GetPath() ) )
486 {
487 if( !wxFileName::Mkdir( path.GetPath(), wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL ) )
488 {
489 return false;
490 }
491 }
492
493 return true;
494}
495
496
498{
508
509#ifdef _WIN32
510 // Warn about Controlled folder access
511 wxFileName tmp;
512 getUserDocumentPath( tmp );
513
514 if( !tmp.DirExists() )
515 {
516 wxString msg = wxString::Format(
517 _( "KiCad was unable to use '%s'.\n"
518 "\n"
519 "1. Disable 'Controlled folder access' in Windows settings or Group Policy\n"
520 "2. Make sure no other antivirus software interferes with KiCad\n"
521 "3. Make sure you have correct permissions set up" ),
522 tmp.GetPath() );
523
524 wxMessageBox( msg, _( "Warning" ), wxICON_WARNING );
525 }
526#endif
527}
528
529
530#ifdef __WXMAC__
531wxString PATHS::GetOSXKicadUserDataDir()
532{
533 // According to wxWidgets documentation for GetUserDataDir:
534 // Mac: ~/Library/Application Support/appname
535 wxFileName udir( wxStandardPaths::Get().GetUserDataDir(), wxEmptyString );
536
537 // Since appname is different if started via launcher or standalone binary
538 // map all to "kicad" here
539 udir.RemoveLastDir();
540 udir.AppendDir( wxT( "kicad" ) );
541
542 return udir.GetPath();
543}
544
545
546wxString PATHS::GetOSXKicadMachineDataDir()
547{
548 // 6.0 forward: Same as the main data dir
549 return GetOSXKicadDataDir();
550}
551
552
553wxString PATHS::GetOSXKicadDataDir()
554{
555 wxFileName ddir;
556 ddir.AssignDir( getOSXBundleRoot() );
557 ddir.AppendDir( wxT( "Contents" ) );
558 ddir.AppendDir( wxT( "SharedSupport" ) );
559 return ddir.GetPath();
560}
561#endif
562
563
564#ifdef _WIN32
565wxString PATHS::GetWindowsFontConfigDir()
566{
567 wxFileName fn;
568 fn.AssignDir( getWindowsKiCadRoot() );
569 fn.AppendDir( wxS( "etc" ) );
570 fn.AppendDir( wxS( "fonts" ) );
571
572 return fn.GetPathWithSep();
573}
574
575
576wxString PATHS::getWindowsKiCadRoot()
577{
578 wxFileName root( GetExecutablePath() + wxT( "/../" ) );
579 root.MakeAbsolute();
580
581 return root.GetPathWithSep();
582}
583#endif
584
585
587{
588 static wxString user_settings_path;
589
590 if( user_settings_path.empty() )
591 user_settings_path = CalculateUserSettingsPath();
592
593 return user_settings_path;
594}
595
596
597wxString PATHS::CalculateUserSettingsPath( bool aIncludeVer, bool aUseEnv )
598{
599 wxFileName cfgpath;
600
601 // http://docs.wxwidgets.org/3.0/classwx_standard_paths.html#a7c7cf595d94d29147360d031647476b0
602
603 wxString envstr;
604 if( aUseEnv && wxGetEnv( wxT( "KICAD_CONFIG_HOME" ), &envstr ) && !envstr.IsEmpty() )
605 {
606 // Override the assignment above with KICAD_CONFIG_HOME
607 cfgpath.AssignDir( envstr );
608 }
609 else
610 {
611 cfgpath.AssignDir( KIPLATFORM::ENV::GetUserConfigPath() );
612
613 cfgpath.AppendDir( TO_STR( KICAD_CONFIG_DIR ) );
614 }
615
616 if( aIncludeVer )
617 cfgpath.AppendDir( GetMajorMinorVersion().ToStdString() );
618
619 return cfgpath.GetPath();
620}
621
622
624{
625 static wxString exe_path;
626
627 if( exe_path.empty() )
628 {
629#ifdef __WXMAC__
630 // Use bundle root helper which handles symlink resolution and aux binaries
631 exe_path = getOSXBundleRoot() + wxT( "/" );
632#else
633 wxString envPath;
634
635 // When running inside an AppImage, the bundled ld-linux is invoked as a wrapper
636 // which causes /proc/self/exe to resolve to the dynamic linker rather than the
637 // actual binary. Use APPDIR to construct the correct executable path.
638 if( wxGetEnv( wxT( "APPDIR" ), &envPath ) )
639 {
640 envPath.Replace( WIN_STRING_DIR_SEP, UNIX_STRING_DIR_SEP );
641
642 if( !envPath.EndsWith( wxT( "/" ) ) )
643 envPath += wxT( "/" );
644
645 exe_path = envPath + wxT( "usr/bin/" );
646 }
647 else
648 {
649 wxString bin_dir = wxStandardPaths::Get().GetExecutablePath();
650
651 // Use unix notation for paths. I am not sure this is a good idea,
652 // but it simplifies compatibility between Windows and Unices.
653 // However it is a potential problem in path handling under Windows.
654 bin_dir.Replace( WIN_STRING_DIR_SEP, UNIX_STRING_DIR_SEP );
655
656 // Remove file name form command line:
657 while( bin_dir.Last() != '/' && !bin_dir.IsEmpty() )
658 bin_dir.RemoveLast();
659
660 exe_path = bin_dir;
661 }
662#endif
663 }
664
665 return exe_path;
666}
667
668
669wxString PATHS::ResolveSiblingExecutable( const wxString& aBaseName )
670{
671#ifdef __WXMAC__
672 // GetExecutablePath() returns the bundle root on macOS, but sibling binaries
673 // live next to the running executable in Contents/MacOS.
674 wxFileName sibling( wxFileName( wxStandardPaths::Get().GetExecutablePath() ).GetPath(), aBaseName );
675#else
676 wxFileName sibling( GetExecutablePath(), aBaseName );
677#endif
678
679#ifdef _WIN32
680 sibling.SetExt( wxT( "exe" ) );
681#endif
682
683 if( !sibling.FileExists() )
684 return wxEmptyString;
685
686 return sibling.GetFullPath();
687}
688
689
690const wxString& PATHS::GetBuildRoot()
691{
692 static const wxString buildRoot = FindKiCadBuildRoot( GetExecutablePath() );
693
694 return buildRoot;
695}
696
697
699{
700 return wxGetEnv( wxT( "KICAD_RUN_FROM_BUILD_DIR" ), nullptr ) || !GetBuildRoot().IsEmpty();
701}
702
703
704wxString PATHS::FindKiCadBuildRoot( const wxString& aExecutablePath )
705{
706#if !defined( __WXMAC__ ) && !defined( __WXMSW__ )
707 if( aExecutablePath.IsEmpty() )
708 return wxEmptyString;
709
710 // We don't have a perfect way to spot a build directory (e.g. when archived as artifacts in
711 // CI) but we can assume that the build directory will have a schemas directory that contains
712 // JSON files, as that's one of the things that we use this path for.
713 const auto looksLikeBuildDir = []( const wxFileName& aPath ) -> bool
714 {
715 const wxDir schemaDir( aPath.GetPathWithSep() + wxT( "schemas" ) );
716
717 if( !schemaDir.IsOpened() )
718 return false;
719
720 wxString filename;
721 return schemaDir.GetFirst( &filename, wxT( "*.json" ), wxDIR_FILES );
722 };
723
724 wxFileName fn;
725
726 if( aExecutablePath.EndsWith( wxT( "/" ) ) || aExecutablePath.EndsWith( wxT( "\\" ) ) )
727 fn.AssignDir( aExecutablePath );
728 else
729 fn.Assign( aExecutablePath );
730
731 while( fn.GetDirCount() > 0 && !looksLikeBuildDir( fn ) )
732 fn.RemoveLastDir();
733
734 if( fn.GetDirCount() == 0 )
735 return wxEmptyString;
736
737 return fn.GetPath();
738#else
739 wxUnusedVar( aExecutablePath );
740 return wxEmptyString;
741#endif
742}
wxString GetMajorMinorVersion()
Get only the major and minor version in a string major.minor.
static bool RunningFromBuildDir()
True when KiCad runs from its build tree or KICAD_RUN_FROM_BUILD_DIR is set.
Definition paths.cpp:698
static wxString GetUserPluginsPath()
Gets the user path for plugins.
Definition paths.cpp:49
static wxString GetStockSymbolsPath()
Gets the stock (install) symbols path.
Definition paths.cpp:262
static wxString ResolveSiblingExecutable(const wxString &aBaseName)
Resolve a sibling executable alongside the running process.
Definition paths.cpp:669
static wxString GetDefaultUser3DModelsPath()
Gets the default path we point users to create projects.
Definition paths.cpp:115
static wxString GetUserTemplatesPath()
Gets the user path for custom templates.
Definition paths.cpp:71
static void getUserDocumentPath(wxFileName &aPath)
Gets the user path for the current kicad version which acts as the root for other user paths.
Definition paths.cpp:35
static wxString GetStockEDALibraryPath()
Gets the stock (install) EDA library data path, which is the base path for templates,...
Definition paths.cpp:243
static wxString CalculateUserSettingsPath(bool aIncludeVer=true, bool aUseEnv=true)
Determines the base path for user settings files.
Definition paths.cpp:597
static wxString GetDefaultUserProjectsPath()
Gets the default path we point users to create projects.
Definition paths.cpp:137
static wxString GetStockPluginsPath()
Gets the stock (install) plugins path.
Definition paths.cpp:339
static wxString GetLogsPath()
Gets a path to use for user-visible log files.
Definition paths.cpp:459
static void EnsureUserPathsExist()
Ensures/creates user default paths.
Definition paths.cpp:497
static wxString GetDocumentationPath()
Gets the documentation path, which is the base path for help files.
Definition paths.cpp:443
static wxString GetDefaultUserDesignBlocksPath()
Gets the default path we point users to create projects.
Definition paths.cpp:104
static wxString GetDefault3rdPartyPath()
Gets the default path for PCM packages.
Definition paths.cpp:126
static const wxString & GetBuildRoot()
The build root of the running executable, or empty outside a KiCad build tree.
Definition paths.cpp:690
static bool EnsurePathExists(const wxString &aPath, bool aPathToFile=false)
Attempts to create a given path if it does not exist.
Definition paths.cpp:470
static wxString GetStockPlugins3DPath()
Gets the stock (install) 3d viewer plugins path.
Definition paths.cpp:355
static wxString FindKiCadBuildRoot(const wxString &aExecutablePath)
Return the CMake build root for a KiCad executable path, or an empty string outside a build tree.
Definition paths.cpp:704
static wxString GetStockDataPath(bool aRespectRunFromBuildDir=true)
Gets the stock (install) data path, which is the base path for things like scripting,...
Definition paths.cpp:192
static wxString GetDefaultUserFootprintsPath()
Gets the default path we point users to create projects.
Definition paths.cpp:93
static wxString GetStock3dmodelsPath()
Gets the stock (install) 3dmodels path.
Definition paths.cpp:295
static wxString GetStockTemplatesPath()
Gets the stock (install) templates path.
Definition paths.cpp:317
static wxString GetUserCachePath()
Gets the stock (install) 3d viewer plugins path.
Definition paths.cpp:422
static wxString GetUserScriptingPath()
Gets the user path for python scripts.
Definition paths.cpp:60
static wxString GetDefaultUserSymbolsPath()
Gets the default path we point users to create projects.
Definition paths.cpp:82
static wxString GetStockDemosPath()
Gets the stock (install) demos path.
Definition paths.cpp:411
static wxString GetLocaleDataPath()
Gets the locales translation data path.
Definition paths.cpp:328
static wxString GetUserSettingsPath()
Return the user configuration path used to store KiCad's configuration files.
Definition paths.cpp:586
static wxString GetStockDesignBlocksPath()
Gets the stock (install) footprints path.
Definition paths.cpp:284
static wxString GetStockFootprintsPath()
Gets the stock (install) footprints path.
Definition paths.cpp:273
static const wxString & GetExecutablePath()
Definition paths.cpp:623
static wxString GetStockScriptingPath()
Gets the stock (install) scripting path.
Definition paths.cpp:306
static void ResolvePossibleSymlinks(wxFileName &aFilename)
static std::string ToStdString(const wxString &aStr)
#define _(s)
This file contains miscellaneous commonly used macros and functions.
#define TO_STR(x)
Definition macros.h:90
wxString GetDocumentsPath()
Retrieves the operating system specific path for a user's documents.
wxString GetUserConfigPath()
Retrieves the operating system specific path for a user's configuration store.
wxString GetUserCachePath()
Retrieves the operating system specific path for user's application cache.
#define KICAD_PATH_STR
Definition paths.h:38
#define WIN_STRING_DIR_SEP
Definition paths.h:31
#define UNIX_STRING_DIR_SEP
Definition paths.h:30
std::string path