KiCad PCB EDA Suite
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
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 along
17 * with this program. If not, see <http://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
27#include <paths.h>
28#include <config.h>
29#include <build_version.h>
30#include <macros.h>
31#include <wx_filename.h>
32
33// lowercase or pretty case depending on platform
34#if defined( __WXMAC__ ) || defined( __WXMSW__ )
35#define KICAD_PATH_STR wxT( "KiCad" )
36#else
37#define KICAD_PATH_STR wxT( "kicad" )
38#endif
39
40
41void PATHS::getUserDocumentPath( wxFileName& aPath )
42{
43 wxString envPath;
44
45 if( wxGetEnv( wxT( "KICAD_DOCUMENTS_HOME" ), &envPath ) )
46 aPath.AssignDir( envPath );
47 else
48 aPath.AssignDir( KIPLATFORM::ENV::GetDocumentsPath() );
49
50 aPath.AppendDir( KICAD_PATH_STR );
51 aPath.AppendDir( GetMajorMinorVersion().ToStdString() );
52}
53
54
56{
57 wxFileName tmp;
59
60 tmp.AppendDir( wxT( "plugins" ) );
61
62 return tmp.GetPath();
63}
64
65
67{
68 wxFileName tmp;
70
71 tmp.AppendDir( wxT( "scripting" ) );
72
73 return tmp.GetPath();
74}
75
76
78{
79 wxFileName tmp;
81
82 tmp.AppendDir( wxT( "template" ) );
83
84 return tmp.GetPathWithSep();
85}
86
87
89{
90 wxFileName tmp;
92
93 tmp.AppendDir( wxT( "symbols" ) );
94
95 return tmp.GetPath();
96}
97
98
100{
101 wxFileName tmp;
102 getUserDocumentPath( tmp );
103
104 tmp.AppendDir( wxT( "footprints" ) );
105
106 return tmp.GetPath();
107}
108
109
111{
112 wxFileName tmp;
113 getUserDocumentPath( tmp );
114
115 tmp.AppendDir( wxT( "blocks" ) );
116
117 return tmp.GetPath();
118}
119
120
122{
123 wxFileName tmp;
124 getUserDocumentPath( tmp );
125
126 tmp.AppendDir( wxT( "3dmodels" ) );
127
128 return tmp.GetPath();
129}
130
131
133{
134 wxFileName tmp;
135 getUserDocumentPath( tmp );
136
137 tmp.AppendDir( wxT( "3rdparty" ) );
138
139 return tmp.GetPath();
140}
141
142
144{
145 wxFileName tmp;
146 getUserDocumentPath( tmp );
147
148 tmp.AppendDir( wxT( "projects" ) );
149
150 return tmp.GetPath();
151}
152
153
161static wxString getBuildDirectoryRoot()
162{
163 // We don't have a perfect way to spot a build directory (e.g. when archived as artifacts in
164 // CI) but we can assume that the build directory will have a schemas directory that contains
165 // JSON files, as that's one of the things that we use this path for.
166 const auto looksLikeBuildDir = []( const wxFileName& aPath ) -> bool
167 {
168 const wxDir schema_dir( aPath.GetPathWithSep() + wxT( "schemas" ) );
169
170 if( !schema_dir.IsOpened() )
171 return false;
172
173 wxString filename;
174 const bool found = schema_dir.GetFirst( &filename, wxT( "*.json" ), wxDIR_FILES );
175 return found;
176 };
177
178 const wxString execPath = PATHS::GetExecutablePath();
179 wxFileName fn = execPath;
180
181 // Climb the directory tree until we find a directory that looks like a build directory
182 // Normally we expect to climb one or two levels only.
183 while( fn.GetDirCount() > 0 && !looksLikeBuildDir( fn ) )
184 {
185 fn.RemoveLastDir();
186 }
187
188 wxASSERT_MSG(
189 fn.GetDirCount() > 0,
190 wxString::Format( wxT( "Could not find build root directory above %s" ), execPath ) );
191
192 return fn.GetPath();
193}
194
195
196wxString PATHS::GetStockDataPath( bool aRespectRunFromBuildDir )
197{
198 wxString path;
199
200 if( aRespectRunFromBuildDir && wxGetEnv( wxT( "KICAD_RUN_FROM_BUILD_DIR" ), nullptr ) )
201 {
202 // Allow debugging from build dir by placing relevant files/folders in the build root
203#if defined( __WXMAC__ )
204 wxFileName fn = wxStandardPaths::Get().GetExecutablePath();
205
206 fn.RemoveLastDir();
207 fn.RemoveLastDir();
208 fn.RemoveLastDir();
209 fn.RemoveLastDir();
210 path = fn.GetPath();
211#elif defined( __WXMSW__ )
212 path = getWindowsKiCadRoot();
213#else
215#endif
216 }
217 else if( wxGetEnv( wxT( "KICAD_STOCK_DATA_HOME" ), &path ) && !path.IsEmpty() )
218 {
219 return path;
220 }
221 else
222 {
223#if defined( __WXMAC__ )
224 path = GetOSXKicadDataDir();
225#elif defined( __WXMSW__ )
226 path = getWindowsKiCadRoot() + wxT( "share/kicad" );
227#else
228 path = wxString::FromUTF8Unchecked( KICAD_DATA );
229#endif
230 }
231
232 return path;
233}
234
235
236#ifdef _WIN32
237
238wxString PATHS::GetWindowsBaseSharePath()
239{
240 return getWindowsKiCadRoot() + wxT( "share\\" );
241}
242
243#endif
244
245
247{
248 wxString path;
249
250#if defined( __WXMAC__ )
251 path = GetOSXKicadMachineDataDir();
252#elif defined( __WXMSW__ )
253 path = GetStockDataPath( false );
254#else
255 path = wxString::FromUTF8Unchecked( KICAD_LIBRARY_DATA );
256#endif
257
258 return path;
259}
260
261
263{
264 wxString path;
265
266 path = GetStockEDALibraryPath() + wxT( "/symbols" );
267
268 return path;
269}
270
271
273{
274 wxString path;
275
276 path = GetStockEDALibraryPath() + wxT( "/footprints" );
277
278 return path;
279}
280
281
283{
284 wxString path;
285
286 path = GetStockEDALibraryPath() + wxT( "/blocks" );
287
288 return path;
289}
290
291
293{
294 wxString path;
295
296 path = GetStockEDALibraryPath() + wxT( "/3dmodels" );
297
298 return path;
299}
300
301
303{
304 wxString path;
305
306 path = GetStockDataPath() + wxT( "/scripting" );
307
308 return path;
309}
310
311
313{
314 wxString path;
315
316 path = GetStockEDALibraryPath() + wxT( "/template" );
317
318 return path;
319}
320
321
323{
324 wxString path;
325
326 path = GetStockDataPath() + wxT( "/internat" );
327
328 return path;
329}
330
331
333{
334 wxFileName fn;
335
336#if defined( __WXMSW__ )
337 fn.AssignDir( GetExecutablePath() );
338 fn.AppendDir( wxT( "scripting" ) );
339#else
340 fn.AssignDir( PATHS::GetStockDataPath( false ) );
341#endif
342 fn.AppendDir( wxT( "plugins" ) );
343
344 return fn.GetPathWithSep();
345}
346
347
349{
350 wxFileName fn;
351
352#if defined( __WXMSW__ )
353 if( wxGetEnv( wxT( "KICAD_RUN_FROM_BUILD_DIR" ), nullptr ) )
354 {
355 fn.AssignDir( getWindowsKiCadRoot() );
356 }
357 else
358 {
359 fn.AssignDir( GetExecutablePath() );
360 }
361
362 fn.AppendDir( wxT( "plugins" ) );
363#elif defined( __WXMAC__ )
364 fn.Assign( wxStandardPaths::Get().GetPluginsDir(), wxEmptyString );
365
366 // This must be mapped to main bundle for everything but kicad.app
367 const wxArrayString dirs = fn.GetDirs();
368
369 // Check if we are the main kicad binary. in this case, the path will be
370 // /path/to/bundlename.app/Contents/PlugIns
371 // If we are an aux binary, the path will be something like
372 // /path/to/bundlename.app/Contents/Applications/<standalone>.app/Contents/PlugIns
373 if( dirs.GetCount() >= 6 &&
374 dirs[dirs.GetCount() - 4] == wxT( "Applications" ) &&
375 dirs[dirs.GetCount() - 6].Lower().EndsWith( wxT( "app" ) ) )
376 {
377 fn.RemoveLastDir();
378 fn.RemoveLastDir();
379 fn.RemoveLastDir();
380 fn.RemoveLastDir();
381 fn.AppendDir( wxT( "PlugIns" ) );
382 }
383#else
384 wxString envPath;
385
386 // AppImages have a different path to the plugins, otherwise we end up with host sytem
387 // plugins being loaded.
388 if( wxGetEnv( wxT( "APPDIR" ), &envPath ) )
389 {
390 fn.Assign( envPath, wxEmptyString );
391 fn.AppendDir( wxT( "usr" ) );
392 fn.AppendDir( wxT( "lib" ) );
393 fn.AppendDir( wxT( "x86_64-linux-gnu" ) );
394 }
395 else
396 {
397 // KICAD_PLUGINDIR = CMAKE_INSTALL_FULL_LIBDIR path is the absolute path
398 // corresponding to the install path used for constructing KICAD_USER_PLUGIN
399 wxString tfname = wxString::FromUTF8Unchecked( KICAD_PLUGINDIR );
400 fn.Assign( tfname, "" );
401 }
402
403 fn.AppendDir( wxT( "kicad" ) );
404 fn.AppendDir( wxT( "plugins" ) );
405#endif
406
407 fn.AppendDir( wxT( "3d" ) );
408
409 return fn.GetPathWithSep();
410}
411
412
414{
415 wxFileName fn;
416
417 fn.AssignDir( PATHS::GetStockDataPath( false ) );
418 fn.AppendDir( wxT( "demos" ) );
419
420 return fn.GetPathWithSep();
421}
422
423
425{
426 wxString envPath;
427 wxFileName tmp;
428
429 tmp.AssignDir( KIPLATFORM::ENV::GetUserCachePath() );
430
431 // Use KICAD_CACHE_HOME to allow the user to force a specific cache path.
432 if( wxGetEnv( wxT( "KICAD_CACHE_HOME" ), &envPath ) && !envPath.IsEmpty() )
433 {
434 // Override the assignment above with KICAD_CACHE_HOME
435 tmp.AssignDir( envPath );
436 }
437
438 tmp.AppendDir( KICAD_PATH_STR );
439 tmp.AppendDir( GetMajorMinorVersion().ToStdString() );
440
441 return tmp.GetPathWithSep();
442}
443
444
446{
447 wxString path;
448
449#if defined( __WXMAC__ )
450 path = GetOSXKicadDataDir();
451#elif defined( __WXMSW__ )
452 path = getWindowsKiCadRoot() + wxT( "share/doc/kicad" );
453#else
454 path = wxString::FromUTF8Unchecked( KICAD_DOCS );
455#endif
456
457 return path;
458}
459
460
462{
463 wxFileName path;
464 path.AssignDir( wxStandardPaths::Get().GetTempDir() );
465 path.AppendDir( "org.kicad.kicad" );
466 path.AppendDir( "instances" );
467 return path.GetPathWithSep();
468}
469
470
472{
473 wxFileName tmp;
474 getUserDocumentPath( tmp );
475
476 tmp.AppendDir( wxT( "logs" ) );
477
478 return tmp.GetPath();
479}
480
481
482bool PATHS::EnsurePathExists( const wxString& aPath, bool aPathToFile )
483{
484 wxString pathString = aPath;
485 if( !aPathToFile )
486 {
487 // ensures the path is treated fully as directory
488 pathString += wxFileName::GetPathSeparator();
489 }
490
491 wxFileName path( pathString );
492 if( !path.MakeAbsolute() )
493 {
494 return false;
495 }
496
497 if( !wxFileName::DirExists( path.GetPath() ) )
498 {
499 if( !wxFileName::Mkdir( path.GetPath(), wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL ) )
500 {
501 return false;
502 }
503 }
504
505 return true;
506}
507
508
510{
520}
521
522
523#ifdef __WXMAC__
524wxString PATHS::GetOSXKicadUserDataDir()
525{
526 // According to wxWidgets documentation for GetUserDataDir:
527 // Mac: ~/Library/Application Support/appname
528 wxFileName udir( wxStandardPaths::Get().GetUserDataDir(), wxEmptyString );
529
530 // Since appname is different if started via launcher or standalone binary
531 // map all to "kicad" here
532 udir.RemoveLastDir();
533 udir.AppendDir( wxT( "kicad" ) );
534
535 return udir.GetPath();
536}
537
538
539wxString PATHS::GetOSXKicadMachineDataDir()
540{
541 // 6.0 forward: Same as the main data dir
542 return GetOSXKicadDataDir();
543}
544
545
546wxString PATHS::GetOSXKicadDataDir()
547{
548 // According to wxWidgets documentation for GetDataDir:
549 // Mac: appname.app/Contents/SharedSupport bundle subdirectory
550 wxFileName ddir( wxStandardPaths::Get().GetDataDir(), wxEmptyString );
551
552 // This must be mapped to main bundle for everything but kicad.app
553 const wxArrayString dirs = ddir.GetDirs();
554
555 // Check if we are the main kicad binary. in this case, the path will be
556 // /path/to/bundlename.app/Contents/SharedSupport
557 // If we are an aux binary, the path will be something like
558 // /path/to/bundlename.app/Contents/Applications/<standalone>.app/Contents/SharedSupport
559 if( dirs.GetCount() >= 6 &&
560 dirs[dirs.GetCount() - 4] == wxT( "Applications" ) &&
561 dirs[dirs.GetCount() - 6].Lower().EndsWith( wxT( "app" ) ) )
562 {
563 ddir.RemoveLastDir();
564 ddir.RemoveLastDir();
565 ddir.RemoveLastDir();
566 ddir.RemoveLastDir();
567 ddir.AppendDir( wxT( "SharedSupport" ) );
568 }
569
570 return ddir.GetPath();
571}
572#endif
573
574
575#ifdef _WIN32
576wxString PATHS::GetWindowsFontConfigDir()
577{
578 wxFileName fn;
579 fn.AssignDir( getWindowsKiCadRoot() );
580 fn.AppendDir( wxS( "etc" ) );
581 fn.AppendDir( wxS( "fonts" ) );
582
583 return fn.GetPathWithSep();
584}
585
586
587wxString PATHS::getWindowsKiCadRoot()
588{
589 wxFileName root( GetExecutablePath() + wxT( "/../" ) );
590 root.MakeAbsolute();
591
592 return root.GetPathWithSep();
593}
594#endif
595
596
598{
599 static wxString user_settings_path;
600
601 if( user_settings_path.empty() )
602 user_settings_path = CalculateUserSettingsPath();
603
604 return user_settings_path;
605}
606
607
608wxString PATHS::CalculateUserSettingsPath( bool aIncludeVer, bool aUseEnv )
609{
610 wxFileName cfgpath;
611
612 // http://docs.wxwidgets.org/3.0/classwx_standard_paths.html#a7c7cf595d94d29147360d031647476b0
613
614 wxString envstr;
615 if( aUseEnv && wxGetEnv( wxT( "KICAD_CONFIG_HOME" ), &envstr ) && !envstr.IsEmpty() )
616 {
617 // Override the assignment above with KICAD_CONFIG_HOME
618 cfgpath.AssignDir( envstr );
619 }
620 else
621 {
622 cfgpath.AssignDir( KIPLATFORM::ENV::GetUserConfigPath() );
623
624 cfgpath.AppendDir( TO_STR( KICAD_CONFIG_DIR ) );
625 }
626
627 if( aIncludeVer )
628 cfgpath.AppendDir( GetMajorMinorVersion().ToStdString() );
629
630 return cfgpath.GetPath();
631}
632
633
635{
636 static wxString exe_path;
637
638 if( exe_path.empty() )
639 {
640 wxString bin_dir = wxStandardPaths::Get().GetExecutablePath();
641
642#ifdef __WXMAC__
643 // On OSX GetExecutablePath() will always point to main
644 // bundle directory, e.g., /Applications/kicad.app/
645
646 wxFileName fn( bin_dir );
648
649 if( fn.GetName() == wxT( "kicad" ) || fn.GetName() == wxT( "kicad-cli" ) )
650 {
651 // kicad launcher, so just remove the Contents/MacOS part
652 fn.RemoveLastDir();
653 fn.RemoveLastDir();
654 }
655 else
656 {
657 // standalone binaries live in Contents/Applications/<standalone>.app/Contents/MacOS
658 fn.RemoveLastDir();
659 fn.RemoveLastDir();
660 fn.RemoveLastDir();
661 fn.RemoveLastDir();
662 fn.RemoveLastDir();
663 }
664
665 bin_dir = fn.GetPath() + wxT( "/" );
666#else
667 // Use unix notation for paths. I am not sure this is a good idea,
668 // but it simplifies compatibility between Windows and Unices.
669 // However it is a potential problem in path handling under Windows.
670 bin_dir.Replace( WIN_STRING_DIR_SEP, UNIX_STRING_DIR_SEP );
671
672 // Remove file name form command line:
673 while( bin_dir.Last() != '/' && !bin_dir.IsEmpty() )
674 bin_dir.RemoveLast();
675#endif
676 exe_path = bin_dir;
677 }
678
679 return exe_path;
680}
wxString GetMajorMinorVersion()
Get only the major and minor version in a string major.minor.
static wxString GetUserPluginsPath()
Gets the user path for plugins.
Definition: paths.cpp:55
static wxString GetStockSymbolsPath()
Gets the stock (install) symbols path.
Definition: paths.cpp:262
static wxString GetDefaultUser3DModelsPath()
Gets the default path we point users to create projects.
Definition: paths.cpp:121
static wxString GetInstanceCheckerPath()
Gets the path used for wxSingleInstanceChecker lock files.
Definition: paths.cpp:461
static wxString GetUserTemplatesPath()
Gets the user path for custom templates.
Definition: paths.cpp:77
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:41
static wxString GetStockEDALibraryPath()
Gets the stock (install) EDA library data path, which is the base path for templates,...
Definition: paths.cpp:246
static wxString CalculateUserSettingsPath(bool aIncludeVer=true, bool aUseEnv=true)
Determines the base path for user settings files.
Definition: paths.cpp:608
static wxString GetDefaultUserProjectsPath()
Gets the default path we point users to create projects.
Definition: paths.cpp:143
static wxString GetStockPluginsPath()
Gets the stock (install) plugins path.
Definition: paths.cpp:332
static wxString GetLogsPath()
Gets a path to use for user-visible log files.
Definition: paths.cpp:471
static void EnsureUserPathsExist()
Ensures/creates user default paths.
Definition: paths.cpp:509
static wxString GetDocumentationPath()
Gets the documentation path, which is the base path for help files.
Definition: paths.cpp:445
static wxString GetDefaultUserDesignBlocksPath()
Gets the default path we point users to create projects.
Definition: paths.cpp:110
static wxString GetDefault3rdPartyPath()
Gets the default path for PCM packages.
Definition: paths.cpp:132
static bool EnsurePathExists(const wxString &aPath, bool aPathToFile=false)
Attempts to create a given path if it does not exist.
Definition: paths.cpp:482
static wxString GetStockPlugins3DPath()
Gets the stock (install) 3d viewer plugins path.
Definition: paths.cpp:348
static wxString GetStockDataPath(bool aRespectRunFromBuildDir=true)
Gets the stock (install) data path, which is the base path for things like scripting,...
Definition: paths.cpp:196
static wxString GetDefaultUserFootprintsPath()
Gets the default path we point users to create projects.
Definition: paths.cpp:99
static wxString GetStock3dmodelsPath()
Gets the stock (install) 3dmodels path.
Definition: paths.cpp:292
static wxString GetStockTemplatesPath()
Gets the stock (install) templates path.
Definition: paths.cpp:312
static wxString GetUserCachePath()
Gets the stock (install) 3d viewer plugins path.
Definition: paths.cpp:424
static wxString GetUserScriptingPath()
Gets the user path for python scripts.
Definition: paths.cpp:66
static wxString GetDefaultUserSymbolsPath()
Gets the default path we point users to create projects.
Definition: paths.cpp:88
static wxString GetStockDemosPath()
Gets the stock (install) demos path.
Definition: paths.cpp:413
static wxString GetLocaleDataPath()
Gets the locales translation data path.
Definition: paths.cpp:322
static wxString GetUserSettingsPath()
Return the user configuration path used to store KiCad's configuration files.
Definition: paths.cpp:597
static wxString GetStockDesignBlocksPath()
Gets the stock (install) footprints path.
Definition: paths.cpp:282
static wxString GetStockFootprintsPath()
Gets the stock (install) footprints path.
Definition: paths.cpp:272
static const wxString & GetExecutablePath()
Definition: paths.cpp:634
static wxString GetStockScriptingPath()
Gets the stock (install) scripting path.
Definition: paths.cpp:302
static void ResolvePossibleSymlinks(wxFileName &aFilename)
Definition: wx_filename.cpp:91
This file contains miscellaneous commonly used macros and functions.
#define TO_STR(x)
Definition: macros.h:94
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.
static wxString getBuildDirectoryRoot()
Get the CMake build root directory for the current executable (which assumes the executable is in a b...
Definition: paths.cpp:161
#define KICAD_PATH_STR
Definition: paths.cpp:37
#define WIN_STRING_DIR_SEP
Definition: paths.h:31
#define UNIX_STRING_DIR_SEP
Definition: paths.h:30