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// 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 // KICAD_PLUGINDIR = CMAKE_INSTALL_FULL_LIBDIR path is the absolute path
385 // corresponding to the install path used for constructing KICAD_USER_PLUGIN
386 wxString tfname = wxString::FromUTF8Unchecked( KICAD_PLUGINDIR );
387 fn.Assign( tfname, "" );
388 fn.AppendDir( wxT( "kicad" ) );
389 fn.AppendDir( wxT( "plugins" ) );
390#endif
391
392 fn.AppendDir( wxT( "3d" ) );
393
394 return fn.GetPathWithSep();
395}
396
397
399{
400 wxFileName fn;
401
402 fn.AssignDir( PATHS::GetStockDataPath( false ) );
403 fn.AppendDir( wxT( "demos" ) );
404
405 return fn.GetPathWithSep();
406}
407
408
410{
411 wxString envPath;
412 wxFileName tmp;
413
414 tmp.AssignDir( KIPLATFORM::ENV::GetUserCachePath() );
415
416 // Use KICAD_CACHE_HOME to allow the user to force a specific cache path.
417 if( wxGetEnv( wxT( "KICAD_CACHE_HOME" ), &envPath ) && !envPath.IsEmpty() )
418 {
419 // Override the assignment above with KICAD_CACHE_HOME
420 tmp.AssignDir( envPath );
421 }
422
423 tmp.AppendDir( KICAD_PATH_STR );
424 tmp.AppendDir( GetMajorMinorVersion().ToStdString() );
425
426 return tmp.GetPathWithSep();
427}
428
429
431{
432 wxString path;
433
434#if defined( __WXMAC__ )
435 path = GetOSXKicadDataDir();
436#elif defined( __WXMSW__ )
437 path = getWindowsKiCadRoot() + wxT( "share/doc/kicad" );
438#else
439 path = wxString::FromUTF8Unchecked( KICAD_DOCS );
440#endif
441
442 return path;
443}
444
445
447{
448 wxFileName path;
449 path.AssignDir( wxStandardPaths::Get().GetTempDir() );
450 path.AppendDir( "org.kicad.kicad" );
451 path.AppendDir( "instances" );
452 return path.GetPathWithSep();
453}
454
455
457{
458 wxFileName tmp;
459 getUserDocumentPath( tmp );
460
461 tmp.AppendDir( wxT( "logs" ) );
462
463 return tmp.GetPath();
464}
465
466
467bool PATHS::EnsurePathExists( const wxString& aPath, bool aPathToFile )
468{
469 wxString pathString = aPath;
470 if( !aPathToFile )
471 {
472 // ensures the path is treated fully as directory
473 pathString += wxFileName::GetPathSeparator();
474 }
475
476 wxFileName path( pathString );
477 if( !path.MakeAbsolute() )
478 {
479 return false;
480 }
481
482 if( !wxFileName::DirExists( path.GetPath() ) )
483 {
484 if( !wxFileName::Mkdir( path.GetPath(), wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL ) )
485 {
486 return false;
487 }
488 }
489
490 return true;
491}
492
493
495{
505}
506
507
508#ifdef __WXMAC__
509wxString PATHS::GetOSXKicadUserDataDir()
510{
511 // According to wxWidgets documentation for GetUserDataDir:
512 // Mac: ~/Library/Application Support/appname
513 wxFileName udir( wxStandardPaths::Get().GetUserDataDir(), wxEmptyString );
514
515 // Since appname is different if started via launcher or standalone binary
516 // map all to "kicad" here
517 udir.RemoveLastDir();
518 udir.AppendDir( wxT( "kicad" ) );
519
520 return udir.GetPath();
521}
522
523
524wxString PATHS::GetOSXKicadMachineDataDir()
525{
526 // 6.0 forward: Same as the main data dir
527 return GetOSXKicadDataDir();
528}
529
530
531wxString PATHS::GetOSXKicadDataDir()
532{
533 // According to wxWidgets documentation for GetDataDir:
534 // Mac: appname.app/Contents/SharedSupport bundle subdirectory
535 wxFileName ddir( wxStandardPaths::Get().GetDataDir(), wxEmptyString );
536
537 // This must be mapped to main bundle for everything but kicad.app
538 const wxArrayString dirs = ddir.GetDirs();
539
540 // Check if we are the main kicad binary. in this case, the path will be
541 // /path/to/bundlename.app/Contents/SharedSupport
542 // If we are an aux binary, the path will be something like
543 // /path/to/bundlename.app/Contents/Applications/<standalone>.app/Contents/SharedSupport
544 if( dirs.GetCount() >= 6 &&
545 dirs[dirs.GetCount() - 4] == wxT( "Applications" ) &&
546 dirs[dirs.GetCount() - 6].Lower().EndsWith( wxT( "app" ) ) )
547 {
548 ddir.RemoveLastDir();
549 ddir.RemoveLastDir();
550 ddir.RemoveLastDir();
551 ddir.RemoveLastDir();
552 ddir.AppendDir( wxT( "SharedSupport" ) );
553 }
554
555 return ddir.GetPath();
556}
557#endif
558
559
560#ifdef _WIN32
561wxString PATHS::GetWindowsFontConfigDir()
562{
563 wxFileName fn;
564 fn.AssignDir( getWindowsKiCadRoot() );
565 fn.AppendDir( wxS( "etc" ) );
566 fn.AppendDir( wxS( "fonts" ) );
567
568 return fn.GetPathWithSep();
569}
570
571
572wxString PATHS::getWindowsKiCadRoot()
573{
574 wxFileName root( GetExecutablePath() + wxT( "/../" ) );
575 root.MakeAbsolute();
576
577 return root.GetPathWithSep();
578}
579#endif
580
581
583{
584 static wxString user_settings_path;
585
586 if( user_settings_path.empty() )
587 user_settings_path = CalculateUserSettingsPath();
588
589 return user_settings_path;
590}
591
592
593wxString PATHS::CalculateUserSettingsPath( bool aIncludeVer, bool aUseEnv )
594{
595 wxFileName cfgpath;
596
597 // http://docs.wxwidgets.org/3.0/classwx_standard_paths.html#a7c7cf595d94d29147360d031647476b0
598
599 wxString envstr;
600 if( aUseEnv && wxGetEnv( wxT( "KICAD_CONFIG_HOME" ), &envstr ) && !envstr.IsEmpty() )
601 {
602 // Override the assignment above with KICAD_CONFIG_HOME
603 cfgpath.AssignDir( envstr );
604 }
605 else
606 {
607 cfgpath.AssignDir( KIPLATFORM::ENV::GetUserConfigPath() );
608
609 cfgpath.AppendDir( TO_STR( KICAD_CONFIG_DIR ) );
610 }
611
612 if( aIncludeVer )
613 cfgpath.AppendDir( GetMajorMinorVersion().ToStdString() );
614
615 return cfgpath.GetPath();
616}
617
618
620{
621 static wxString exe_path;
622
623 if( exe_path.empty() )
624 {
625 wxString bin_dir = wxStandardPaths::Get().GetExecutablePath();
626
627#ifdef __WXMAC__
628 // On OSX GetExecutablePath() will always point to main
629 // bundle directory, e.g., /Applications/kicad.app/
630
631 wxFileName fn( bin_dir );
633
634 if( fn.GetName() == wxT( "kicad" ) || fn.GetName() == wxT( "kicad-cli" ) )
635 {
636 // kicad launcher, so just remove the Contents/MacOS part
637 fn.RemoveLastDir();
638 fn.RemoveLastDir();
639 }
640 else
641 {
642 // standalone binaries live in Contents/Applications/<standalone>.app/Contents/MacOS
643 fn.RemoveLastDir();
644 fn.RemoveLastDir();
645 fn.RemoveLastDir();
646 fn.RemoveLastDir();
647 fn.RemoveLastDir();
648 }
649
650 bin_dir = fn.GetPath() + wxT( "/" );
651#else
652 // Use unix notation for paths. I am not sure this is a good idea,
653 // but it simplifies compatibility between Windows and Unices.
654 // However it is a potential problem in path handling under Windows.
655 bin_dir.Replace( WIN_STRING_DIR_SEP, UNIX_STRING_DIR_SEP );
656
657 // Remove file name form command line:
658 while( bin_dir.Last() != '/' && !bin_dir.IsEmpty() )
659 bin_dir.RemoveLast();
660#endif
661 exe_path = bin_dir;
662 }
663
664 return exe_path;
665}
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:446
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:593
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:456
static void EnsureUserPathsExist()
Ensures/creates user default paths.
Definition: paths.cpp:494
static wxString GetDocumentationPath()
Gets the documentation path, which is the base path for help files.
Definition: paths.cpp:430
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:467
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:409
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:398
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:582
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:619
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