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