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 if( wxGetEnv( wxT( "APPDIR" ), &path ) )
291 path += wxT( "/share/kicad" );
292 else
293 path = wxString::FromUTF8Unchecked( KICAD_LIBRARY_DATA );
294#endif
295
296 return path;
297}
298
299
301{
302 wxFileName fn;
303
304 fn.AssignDir( GetStockEDALibraryPath() );
305 fn.AppendDir( "symbols" );
306
307 return fn.GetPathWithSep();
308}
309
310
312{
313 wxFileName fn;
314
315 fn.AssignDir( GetStockEDALibraryPath() );
316 fn.AppendDir( "footprints" );
317
318 return fn.GetPathWithSep();
319}
320
321
323{
324 wxFileName fn;
325
326 fn.AssignDir( GetStockEDALibraryPath() );
327 fn.AppendDir( "blocks" );
328
329 return fn.GetPathWithSep();
330}
331
332
334{
335 wxFileName fn;
336
337 fn.AssignDir( GetStockEDALibraryPath() );
338 fn.AppendDir( "3dmodels" );
339
340 return fn.GetPathWithSep();
341}
342
343
345{
346 wxFileName fn;
347
348 fn.AssignDir( GetStockDataPath() );
349 fn.AppendDir( "scripting" );
350
351 return fn.GetPathWithSep();
352}
353
354
356{
357 wxFileName fn;
358
359 fn.AssignDir( GetStockEDALibraryPath() );
360 fn.AppendDir( "template" );
361
362 return fn.GetPathWithSep();
363}
364
365
367{
368 wxFileName fn;
369
370 fn.AssignDir( GetStockDataPath() );
371 fn.AppendDir( "internat" );
372
373 return fn.GetPathWithSep();
374}
375
376
378{
379 wxFileName fn;
380
381#if defined( __WXMSW__ )
382 fn.AssignDir( GetExecutablePath() );
383 fn.AppendDir( wxT( "scripting" ) );
384#else
385 fn.AssignDir( PATHS::GetStockDataPath( false ) );
386#endif
387 fn.AppendDir( wxT( "plugins" ) );
388
389 return fn.GetPathWithSep();
390}
391
392
394{
395 wxFileName fn;
396
397#if defined( __WXMSW__ )
398 if( wxGetEnv( wxT( "KICAD_RUN_FROM_BUILD_DIR" ), nullptr ) )
399 {
400 fn.AssignDir( getWindowsKiCadRoot() );
401 }
402 else
403 {
404 fn.AssignDir( GetExecutablePath() );
405 }
406
407 fn.AppendDir( wxT( "plugins" ) );
408#elif defined( __WXMAC__ )
409 fn.AssignDir( getOSXBundleRoot() );
410 fn.AppendDir( wxT( "Contents" ) );
411 fn.AppendDir( wxT( "PlugIns" ) );
412#else
413 wxString envPath;
414
415 if( wxGetEnv( wxT( "KICAD_RUN_FROM_BUILD_DIR" ), nullptr ) )
416 {
417 fn.Assign( wxStandardPaths::Get().GetExecutablePath() );
418 fn.AppendDir( wxT( ".." ) );
419 fn.AppendDir( wxT( "plugins" ) );
420 }
421 // AppImages have a different path to the plugins, otherwise we end up with host system
422 // plugins being loaded.
423 else if( wxGetEnv( wxT( "APPDIR" ), &envPath ) )
424 {
425 fn.Assign( envPath, wxEmptyString );
426 fn.AppendDir( wxT( "usr" ) );
427 fn.AppendDir( wxT( "lib" ) );
428 fn.AppendDir( wxT( "x86_64-linux-gnu" ) );
429 fn.AppendDir( wxT( "kicad" ) );
430 fn.AppendDir( wxT( "plugins" ) );
431 }
432 else
433 {
434 // KICAD_PLUGINDIR = CMAKE_INSTALL_FULL_LIBDIR path is the absolute path
435 // corresponding to the install path used for constructing KICAD_USER_PLUGIN
436 wxString tfname = wxString::FromUTF8Unchecked( KICAD_PLUGINDIR );
437 fn.Assign( tfname, "" );
438 fn.AppendDir( wxT( "kicad" ) );
439 fn.AppendDir( wxT( "plugins" ) );
440 }
441#endif
442
443 fn.AppendDir( wxT( "3d" ) );
444
445 return fn.GetPathWithSep();
446}
447
448
450{
451 wxFileName fn;
452
453 fn.AssignDir( PATHS::GetStockDataPath( false ) );
454 fn.AppendDir( wxT( "demos" ) );
455
456 return fn.GetPathWithSep();
457}
458
459
461{
462 wxString envPath;
463 wxFileName tmp;
464
465 tmp.AssignDir( KIPLATFORM::ENV::GetUserCachePath() );
466
467 // Use KICAD_CACHE_HOME to allow the user to force a specific cache path.
468 if( wxGetEnv( wxT( "KICAD_CACHE_HOME" ), &envPath ) && !envPath.IsEmpty() )
469 {
470 // Override the assignment above with KICAD_CACHE_HOME
471 tmp.AssignDir( envPath );
472 }
473
474 tmp.AppendDir( KICAD_PATH_STR );
475 tmp.AppendDir( GetMajorMinorVersion().ToStdString() );
476
477 return tmp.GetPathWithSep();
478}
479
480
482{
483 wxString path;
484
485#if defined( __WXMAC__ )
486 path = GetOSXKicadDataDir();
487#elif defined( __WXMSW__ )
488 path = getWindowsKiCadRoot() + wxT( "share/doc/kicad" );
489#else
490 path = wxString::FromUTF8Unchecked( KICAD_DOCS );
491#endif
492
493 return path;
494}
495
496
498{
499 wxFileName path;
500 path.AssignDir( wxStandardPaths::Get().GetTempDir() );
501 path.AppendDir( "org.kicad.kicad" );
502 path.AppendDir( "instances" );
503 return path.GetPathWithSep();
504}
505
506
508{
509 wxFileName tmp;
510 getUserDocumentPath( tmp );
511
512 tmp.AppendDir( wxT( "logs" ) );
513
514 return tmp.GetPath();
515}
516
517
518bool PATHS::EnsurePathExists( const wxString& aPath, bool aPathToFile )
519{
520 wxString pathString = aPath;
521 if( !aPathToFile )
522 {
523 // ensures the path is treated fully as directory
524 pathString += wxFileName::GetPathSeparator();
525 }
526
527 wxFileName path( pathString );
528 if( !path.MakeAbsolute() )
529 {
530 return false;
531 }
532
533 if( !wxFileName::DirExists( path.GetPath() ) )
534 {
535 if( !wxFileName::Mkdir( path.GetPath(), wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL ) )
536 {
537 return false;
538 }
539 }
540
541 return true;
542}
543
544
546{
556
557#ifdef _WIN32
558 // Warn about Controlled folder access
559 wxFileName tmp;
560 getUserDocumentPath( tmp );
561
562 if( !tmp.DirExists() )
563 {
564 wxString msg = wxString::Format(
565 _( "KiCad was unable to use '%s'.\n"
566 "\n"
567 "1. Disable 'Controlled folder access' in Windows settings or Group Policy\n"
568 "2. Make sure no other antivirus software interferes with KiCad\n"
569 "3. Make sure you have correct permissions set up" ),
570 tmp.GetPath() );
571
572 wxMessageBox( msg, _( "Warning" ), wxICON_WARNING );
573 }
574#endif
575}
576
577
578#ifdef __WXMAC__
579wxString PATHS::GetOSXKicadUserDataDir()
580{
581 // According to wxWidgets documentation for GetUserDataDir:
582 // Mac: ~/Library/Application Support/appname
583 wxFileName udir( wxStandardPaths::Get().GetUserDataDir(), wxEmptyString );
584
585 // Since appname is different if started via launcher or standalone binary
586 // map all to "kicad" here
587 udir.RemoveLastDir();
588 udir.AppendDir( wxT( "kicad" ) );
589
590 return udir.GetPath();
591}
592
593
594wxString PATHS::GetOSXKicadMachineDataDir()
595{
596 // 6.0 forward: Same as the main data dir
597 return GetOSXKicadDataDir();
598}
599
600
601wxString PATHS::GetOSXKicadDataDir()
602{
603 wxFileName ddir;
604 ddir.AssignDir( getOSXBundleRoot() );
605 ddir.AppendDir( wxT( "Contents" ) );
606 ddir.AppendDir( wxT( "SharedSupport" ) );
607 return ddir.GetPath();
608}
609#endif
610
611
612#ifdef _WIN32
613wxString PATHS::GetWindowsFontConfigDir()
614{
615 wxFileName fn;
616 fn.AssignDir( getWindowsKiCadRoot() );
617 fn.AppendDir( wxS( "etc" ) );
618 fn.AppendDir( wxS( "fonts" ) );
619
620 return fn.GetPathWithSep();
621}
622
623
624wxString PATHS::getWindowsKiCadRoot()
625{
626 wxFileName root( GetExecutablePath() + wxT( "/../" ) );
627 root.MakeAbsolute();
628
629 return root.GetPathWithSep();
630}
631#endif
632
633
635{
636 static wxString user_settings_path;
637
638 if( user_settings_path.empty() )
639 user_settings_path = CalculateUserSettingsPath();
640
641 return user_settings_path;
642}
643
644
645wxString PATHS::CalculateUserSettingsPath( bool aIncludeVer, bool aUseEnv )
646{
647 wxFileName cfgpath;
648
649 // http://docs.wxwidgets.org/3.0/classwx_standard_paths.html#a7c7cf595d94d29147360d031647476b0
650
651 wxString envstr;
652 if( aUseEnv && wxGetEnv( wxT( "KICAD_CONFIG_HOME" ), &envstr ) && !envstr.IsEmpty() )
653 {
654 // Override the assignment above with KICAD_CONFIG_HOME
655 cfgpath.AssignDir( envstr );
656 }
657 else
658 {
659 cfgpath.AssignDir( KIPLATFORM::ENV::GetUserConfigPath() );
660
661 cfgpath.AppendDir( TO_STR( KICAD_CONFIG_DIR ) );
662 }
663
664 if( aIncludeVer )
665 cfgpath.AppendDir( GetMajorMinorVersion().ToStdString() );
666
667 return cfgpath.GetPath();
668}
669
670
672{
673 static wxString exe_path;
674
675 if( exe_path.empty() )
676 {
677#ifdef __WXMAC__
678 // Use bundle root helper which handles symlink resolution and aux binaries
679 exe_path = getOSXBundleRoot() + wxT( "/" );
680#else
681 wxString envPath;
682
683 // When running inside an AppImage, the bundled ld-linux is invoked as a wrapper
684 // which causes /proc/self/exe to resolve to the dynamic linker rather than the
685 // actual binary. Use APPDIR to construct the correct executable path.
686 if( wxGetEnv( wxT( "APPDIR" ), &envPath ) )
687 {
688 envPath.Replace( WIN_STRING_DIR_SEP, UNIX_STRING_DIR_SEP );
689
690 if( !envPath.EndsWith( wxT( "/" ) ) )
691 envPath += wxT( "/" );
692
693 exe_path = envPath + wxT( "usr/bin/" );
694 }
695 else
696 {
697 wxString bin_dir = wxStandardPaths::Get().GetExecutablePath();
698
699 // Use unix notation for paths. I am not sure this is a good idea,
700 // but it simplifies compatibility between Windows and Unices.
701 // However it is a potential problem in path handling under Windows.
702 bin_dir.Replace( WIN_STRING_DIR_SEP, UNIX_STRING_DIR_SEP );
703
704 // Remove file name form command line:
705 while( bin_dir.Last() != '/' && !bin_dir.IsEmpty() )
706 bin_dir.RemoveLast();
707
708 exe_path = bin_dir;
709 }
710#endif
711 }
712
713 return exe_path;
714}
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:300
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:497
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:645
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:377
static wxString GetLogsPath()
Gets a path to use for user-visible log files.
Definition paths.cpp:507
static void EnsureUserPathsExist()
Ensures/creates user default paths.
Definition paths.cpp:545
static wxString GetDocumentationPath()
Gets the documentation path, which is the base path for help files.
Definition paths.cpp:481
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:518
static wxString GetStockPlugins3DPath()
Gets the stock (install) 3d viewer plugins path.
Definition paths.cpp:393
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:333
static wxString GetStockTemplatesPath()
Gets the stock (install) templates path.
Definition paths.cpp:355
static wxString GetUserCachePath()
Gets the stock (install) 3d viewer plugins path.
Definition paths.cpp:460
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:449
static wxString GetLocaleDataPath()
Gets the locales translation data path.
Definition paths.cpp:366
static wxString GetUserSettingsPath()
Return the user configuration path used to store KiCad's configuration files.
Definition paths.cpp:634
static wxString GetStockDesignBlocksPath()
Gets the stock (install) footprints path.
Definition paths.cpp:322
static wxString GetStockFootprintsPath()
Gets the stock (install) footprints path.
Definition paths.cpp:311
static const wxString & GetExecutablePath()
Definition paths.cpp:671
static wxString GetStockScriptingPath()
Gets the stock (install) scripting path.
Definition paths.cpp:344
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