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#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__ ) && !defined( __WXMSW__ )
156static wxString getBuildDirectoryRoot()
157{
158 // We don't have a perfect way to spot a build directory (e.g. when archived as artifacts in
159 // CI) but we can assume that the build directory will have a schemas directory that contains
160 // JSON files, as that's one of the things that we use this path for.
161 const auto looksLikeBuildDir = []( const wxFileName& aPath ) -> bool
162 {
163 const wxDir schema_dir( aPath.GetPathWithSep() + wxT( "schemas" ) );
164
165 if( !schema_dir.IsOpened() )
166 return false;
167
168 wxString filename;
169 const bool found = schema_dir.GetFirst( &filename, wxT( "*.json" ), wxDIR_FILES );
170 return found;
171 };
172
173 const wxString execPath = PATHS::GetExecutablePath();
174 wxFileName fn = execPath;
175
176 // Climb the directory tree until we find a directory that looks like a build directory
177 // Normally we expect to climb one or two levels only.
178 while( fn.GetDirCount() > 0 && !looksLikeBuildDir( fn ) )
179 {
180 fn.RemoveLastDir();
181 }
182
183 wxASSERT_MSG(
184 fn.GetDirCount() > 0,
185 wxString::Format( wxT( "Could not find build root directory above %s" ), execPath ) );
186
187 return fn.GetPath();
188}
189#elif defined( __WXMAC__ )
195static wxString getOSXBundleRoot()
196{
197 static wxString bundleRoot;
198
199 if( bundleRoot.empty() )
200 {
201 wxFileName fn( wxStandardPaths::Get().GetExecutablePath() );
203 fn.SetFullName( wxEmptyString ); // Remove binary name
204
205 // Navigate from .../Contents/MacOS/ up to the .app bundle root
206 // e.g., /Applications/KiCad/KiCad.app/Contents/MacOS -> /Applications/KiCad/KiCad.app
207 if( fn.GetDirCount() >= 2 && fn.GetDirs().Last() == wxT( "MacOS" ) )
208 {
209 fn.RemoveLastDir(); // MacOS
210 fn.RemoveLastDir(); // Contents
211 }
212
213 // Handle aux binaries inside main bundle
214 // From: .../main.app/Contents/Applications/standalone.app
215 // To: .../main.app
216 const wxArrayString dirs = fn.GetDirs();
217 if( dirs.GetCount() >= 4 && dirs[dirs.GetCount() - 2] == wxT( "Applications" )
218 && dirs[dirs.GetCount() - 4].Lower().EndsWith( wxT( "app" ) ) )
219 {
220 fn.RemoveLastDir(); // standalone.app
221 fn.RemoveLastDir(); // Applications
222 fn.RemoveLastDir(); // Contents
223 }
224
225 bundleRoot = fn.GetPath();
226 }
227
228 return bundleRoot;
229}
230#endif
231
232
233wxString PATHS::GetStockDataPath( bool aRespectRunFromBuildDir )
234{
235 wxString path;
236
237 if( aRespectRunFromBuildDir && wxGetEnv( wxT( "KICAD_RUN_FROM_BUILD_DIR" ), nullptr ) )
238 {
239 // Allow debugging from build dir by placing relevant files/folders in the build root
240#if defined( __WXMAC__ )
241 wxFileName fn;
242 fn.AssignDir( getOSXBundleRoot() );
243 fn.RemoveLastDir(); // Above the .app bundle
244 fn.RemoveLastDir(); // Above the target subdirectory to build root
245 path = fn.GetPath();
246#elif defined( __WXMSW__ )
247 path = getWindowsKiCadRoot();
248#else
250#endif
251 }
252 else if( wxGetEnv( wxT( "KICAD_STOCK_DATA_HOME" ), &path ) && !path.IsEmpty() )
253 {
254 return path;
255 }
256 else
257 {
258#if defined( __WXMAC__ )
259 path = GetOSXKicadDataDir();
260#elif defined( __WXMSW__ )
261 path = getWindowsKiCadRoot() + wxT( "share/kicad" );
262#else
263 path = wxString::FromUTF8Unchecked( KICAD_DATA );
264#endif
265 }
266
267 return path;
268}
269
270
271#ifdef _WIN32
272
273wxString PATHS::GetWindowsBaseSharePath()
274{
275 return getWindowsKiCadRoot() + wxT( "share\\" );
276}
277
278#endif
279
280
282{
283 wxString path;
284
285#if defined( __WXMAC__ )
286 path = GetOSXKicadMachineDataDir();
287#elif defined( __WXMSW__ )
288 path = GetStockDataPath( false );
289#else
290 path = wxString::FromUTF8Unchecked( KICAD_LIBRARY_DATA );
291#endif
292
293 return path;
294}
295
296
298{
299 wxString path;
300
301 path = GetStockEDALibraryPath() + wxT( "/symbols" );
302
303 return path;
304}
305
306
308{
309 wxString path;
310
311 path = GetStockEDALibraryPath() + wxT( "/footprints" );
312
313 return path;
314}
315
316
318{
319 wxString path;
320
321 path = GetStockEDALibraryPath() + wxT( "/blocks" );
322
323 return path;
324}
325
326
328{
329 wxString path;
330
331 path = GetStockEDALibraryPath() + wxT( "/3dmodels" );
332
333 return path;
334}
335
336
338{
339 wxString path;
340
341 path = GetStockDataPath() + wxT( "/scripting" );
342
343 return path;
344}
345
346
348{
349 wxString path;
350
351 path = GetStockEDALibraryPath() + wxT( "/template" );
352
353 return path;
354}
355
356
358{
359 wxString path;
360
361 path = GetStockDataPath() + wxT( "/internat" );
362
363 return path;
364}
365
366
368{
369 wxFileName fn;
370
371#if defined( __WXMSW__ )
372 fn.AssignDir( GetExecutablePath() );
373 fn.AppendDir( wxT( "scripting" ) );
374#else
375 fn.AssignDir( PATHS::GetStockDataPath( false ) );
376#endif
377 fn.AppendDir( wxT( "plugins" ) );
378
379 return fn.GetPathWithSep();
380}
381
382
384{
385 wxFileName fn;
386
387#if defined( __WXMSW__ )
388 if( wxGetEnv( wxT( "KICAD_RUN_FROM_BUILD_DIR" ), nullptr ) )
389 {
390 fn.AssignDir( getWindowsKiCadRoot() );
391 }
392 else
393 {
394 fn.AssignDir( GetExecutablePath() );
395 }
396
397 fn.AppendDir( wxT( "plugins" ) );
398#elif defined( __WXMAC__ )
399 fn.AssignDir( getOSXBundleRoot() );
400 fn.AppendDir( wxT( "Contents" ) );
401 fn.AppendDir( wxT( "PlugIns" ) );
402#else
403 wxString envPath;
404
405 if( wxGetEnv( wxT( "KICAD_RUN_FROM_BUILD_DIR" ), nullptr ) )
406 {
407 fn.Assign( wxStandardPaths::Get().GetExecutablePath() );
408 fn.AppendDir( wxT( ".." ) );
409 fn.AppendDir( wxT( "plugins" ) );
410 }
411 // AppImages have a different path to the plugins, otherwise we end up with host system
412 // plugins being loaded.
413 else if( wxGetEnv( wxT( "APPDIR" ), &envPath ) )
414 {
415 fn.Assign( envPath, wxEmptyString );
416 fn.AppendDir( wxT( "usr" ) );
417 fn.AppendDir( wxT( "lib" ) );
418 fn.AppendDir( wxT( "x86_64-linux-gnu" ) );
419 fn.AppendDir( wxT( "kicad" ) );
420 fn.AppendDir( wxT( "plugins" ) );
421 }
422 else
423 {
424 // KICAD_PLUGINDIR = CMAKE_INSTALL_FULL_LIBDIR path is the absolute path
425 // corresponding to the install path used for constructing KICAD_USER_PLUGIN
426 wxString tfname = wxString::FromUTF8Unchecked( KICAD_PLUGINDIR );
427 fn.Assign( tfname, "" );
428 fn.AppendDir( wxT( "kicad" ) );
429 fn.AppendDir( wxT( "plugins" ) );
430 }
431#endif
432
433 fn.AppendDir( wxT( "3d" ) );
434
435 return fn.GetPathWithSep();
436}
437
438
440{
441 wxFileName fn;
442
443 fn.AssignDir( PATHS::GetStockDataPath( false ) );
444 fn.AppendDir( wxT( "demos" ) );
445
446 return fn.GetPathWithSep();
447}
448
449
451{
452 wxString envPath;
453 wxFileName tmp;
454
455 tmp.AssignDir( KIPLATFORM::ENV::GetUserCachePath() );
456
457 // Use KICAD_CACHE_HOME to allow the user to force a specific cache path.
458 if( wxGetEnv( wxT( "KICAD_CACHE_HOME" ), &envPath ) && !envPath.IsEmpty() )
459 {
460 // Override the assignment above with KICAD_CACHE_HOME
461 tmp.AssignDir( envPath );
462 }
463
464 tmp.AppendDir( KICAD_PATH_STR );
465 tmp.AppendDir( GetMajorMinorVersion().ToStdString() );
466
467 return tmp.GetPathWithSep();
468}
469
470
472{
473 wxString path;
474
475#if defined( __WXMAC__ )
476 path = GetOSXKicadDataDir();
477#elif defined( __WXMSW__ )
478 path = getWindowsKiCadRoot() + wxT( "share/doc/kicad" );
479#else
480 path = wxString::FromUTF8Unchecked( KICAD_DOCS );
481#endif
482
483 return path;
484}
485
486
488{
489 wxFileName path;
490 path.AssignDir( wxStandardPaths::Get().GetTempDir() );
491 path.AppendDir( "org.kicad.kicad" );
492 path.AppendDir( "instances" );
493 return path.GetPathWithSep();
494}
495
496
498{
499 wxFileName tmp;
500 getUserDocumentPath( tmp );
501
502 tmp.AppendDir( wxT( "logs" ) );
503
504 return tmp.GetPath();
505}
506
507
508bool PATHS::EnsurePathExists( const wxString& aPath, bool aPathToFile )
509{
510 wxString pathString = aPath;
511 if( !aPathToFile )
512 {
513 // ensures the path is treated fully as directory
514 pathString += wxFileName::GetPathSeparator();
515 }
516
517 wxFileName path( pathString );
518 if( !path.MakeAbsolute() )
519 {
520 return false;
521 }
522
523 if( !wxFileName::DirExists( path.GetPath() ) )
524 {
525 if( !wxFileName::Mkdir( path.GetPath(), wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL ) )
526 {
527 return false;
528 }
529 }
530
531 return true;
532}
533
534
536{
546
547#ifdef _WIN32
548 // Warn about Controlled folder access
549 wxFileName tmp;
550 getUserDocumentPath( tmp );
551
552 if( !tmp.DirExists() )
553 {
554 wxString msg = wxString::Format(
555 _( "KiCad was unable to use '%s'.\n"
556 "\n"
557 "1. Disable 'Controlled folder access' in Windows settings or Group Policy\n"
558 "2. Make sure no other antivirus software interferes with KiCad\n"
559 "3. Make sure you have correct permissions set up" ),
560 tmp.GetPath() );
561
562 wxMessageBox( msg, _( "Warning" ), wxICON_WARNING );
563 }
564#endif
565}
566
567
568#ifdef __WXMAC__
569wxString PATHS::GetOSXKicadUserDataDir()
570{
571 // According to wxWidgets documentation for GetUserDataDir:
572 // Mac: ~/Library/Application Support/appname
573 wxFileName udir( wxStandardPaths::Get().GetUserDataDir(), wxEmptyString );
574
575 // Since appname is different if started via launcher or standalone binary
576 // map all to "kicad" here
577 udir.RemoveLastDir();
578 udir.AppendDir( wxT( "kicad" ) );
579
580 return udir.GetPath();
581}
582
583
584wxString PATHS::GetOSXKicadMachineDataDir()
585{
586 // 6.0 forward: Same as the main data dir
587 return GetOSXKicadDataDir();
588}
589
590
591wxString PATHS::GetOSXKicadDataDir()
592{
593 wxFileName ddir;
594 ddir.AssignDir( getOSXBundleRoot() );
595 ddir.AppendDir( wxT( "Contents" ) );
596 ddir.AppendDir( wxT( "SharedSupport" ) );
597 return ddir.GetPath();
598}
599#endif
600
601
602#ifdef _WIN32
603wxString PATHS::GetWindowsFontConfigDir()
604{
605 wxFileName fn;
606 fn.AssignDir( getWindowsKiCadRoot() );
607 fn.AppendDir( wxS( "etc" ) );
608 fn.AppendDir( wxS( "fonts" ) );
609
610 return fn.GetPathWithSep();
611}
612
613
614wxString PATHS::getWindowsKiCadRoot()
615{
616 wxFileName root( GetExecutablePath() + wxT( "/../" ) );
617 root.MakeAbsolute();
618
619 return root.GetPathWithSep();
620}
621#endif
622
623
625{
626 static wxString user_settings_path;
627
628 if( user_settings_path.empty() )
629 user_settings_path = CalculateUserSettingsPath();
630
631 return user_settings_path;
632}
633
634
635wxString PATHS::CalculateUserSettingsPath( bool aIncludeVer, bool aUseEnv )
636{
637 wxFileName cfgpath;
638
639 // http://docs.wxwidgets.org/3.0/classwx_standard_paths.html#a7c7cf595d94d29147360d031647476b0
640
641 wxString envstr;
642 if( aUseEnv && wxGetEnv( wxT( "KICAD_CONFIG_HOME" ), &envstr ) && !envstr.IsEmpty() )
643 {
644 // Override the assignment above with KICAD_CONFIG_HOME
645 cfgpath.AssignDir( envstr );
646 }
647 else
648 {
649 cfgpath.AssignDir( KIPLATFORM::ENV::GetUserConfigPath() );
650
651 cfgpath.AppendDir( TO_STR( KICAD_CONFIG_DIR ) );
652 }
653
654 if( aIncludeVer )
655 cfgpath.AppendDir( GetMajorMinorVersion().ToStdString() );
656
657 return cfgpath.GetPath();
658}
659
660
662{
663 static wxString exe_path;
664
665 if( exe_path.empty() )
666 {
667#ifdef __WXMAC__
668 // Use bundle root helper which handles symlink resolution and aux binaries
669 exe_path = getOSXBundleRoot() + wxT( "/" );
670#else
671 wxString bin_dir = wxStandardPaths::Get().GetExecutablePath();
672
673 // Use unix notation for paths. I am not sure this is a good idea,
674 // but it simplifies compatibility between Windows and Unices.
675 // However it is a potential problem in path handling under Windows.
676 bin_dir.Replace( WIN_STRING_DIR_SEP, UNIX_STRING_DIR_SEP );
677
678 // Remove file name form command line:
679 while( bin_dir.Last() != '/' && !bin_dir.IsEmpty() )
680 bin_dir.RemoveLast();
681
682 exe_path = bin_dir;
683#endif
684 }
685
686 return exe_path;
687}
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:49
static wxString GetStockSymbolsPath()
Gets the stock (install) symbols path.
Definition paths.cpp:297
static wxString GetDefaultUser3DModelsPath()
Gets the default path we point users to create projects.
Definition paths.cpp:115
static wxString GetInstanceCheckerPath()
Gets the path used for wxSingleInstanceChecker lock files.
Definition paths.cpp:487
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:281
static wxString CalculateUserSettingsPath(bool aIncludeVer=true, bool aUseEnv=true)
Determines the base path for user settings files.
Definition paths.cpp:635
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:367
static wxString GetLogsPath()
Gets a path to use for user-visible log files.
Definition paths.cpp:497
static void EnsureUserPathsExist()
Ensures/creates user default paths.
Definition paths.cpp:535
static wxString GetDocumentationPath()
Gets the documentation path, which is the base path for help files.
Definition paths.cpp:471
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 bool EnsurePathExists(const wxString &aPath, bool aPathToFile=false)
Attempts to create a given path if it does not exist.
Definition paths.cpp:508
static wxString GetStockPlugins3DPath()
Gets the stock (install) 3d viewer plugins path.
Definition paths.cpp:383
static wxString GetStockDataPath(bool aRespectRunFromBuildDir=true)
Gets the stock (install) data path, which is the base path for things like scripting,...
Definition paths.cpp:233
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:327
static wxString GetStockTemplatesPath()
Gets the stock (install) templates path.
Definition paths.cpp:347
static wxString GetUserCachePath()
Gets the stock (install) 3d viewer plugins path.
Definition paths.cpp:450
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:439
static wxString GetLocaleDataPath()
Gets the locales translation data path.
Definition paths.cpp:357
static wxString GetUserSettingsPath()
Return the user configuration path used to store KiCad's configuration files.
Definition paths.cpp:624
static wxString GetStockDesignBlocksPath()
Gets the stock (install) footprints path.
Definition paths.cpp:317
static wxString GetStockFootprintsPath()
Gets the stock (install) footprints path.
Definition paths.cpp:307
static const wxString & GetExecutablePath()
Definition paths.cpp:661
static wxString GetStockScriptingPath()
Gets the stock (install) scripting path.
Definition paths.cpp:337
static void ResolvePossibleSymlinks(wxFileName &aFilename)
#define _(s)
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:156
#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