← Back to team overview

kicad-developers team mailing list archive

CMake better variable handling

 

Hello,

I would like to hear some comments about a patch I wrote today.
Earlier today I discovered that if you run CMake without setting a
CMAKE_INSTALL_PREFIX during first run the variabls
DEFAULT_INSTALL_PATH and for example KICAD_BIN are set only during
this run. If you later change CMAKE_INSTALL_PREFIX none of the
variables is updated. This leads to not running KiCad from within
installed directory. So I digged into the code and came up with the
following solution:

If none variable is set, set default values as before. Otherwise the
paths are evaluated again. On the other hand if some user input was
done these are kept.

I'm quite not happy with the naming of the macro so maybe someone has
a better idea, let me know. Would be fine if someone could try the
attached test under other environments.

Looking forward to some comments.
Greetings
Tobias

====================================================================

This commit adds support for a macro called 'set_kicad_cache'
which allow to prefer user input over default value.
This patch leads to the behaviour that KiCads advanced variables
are stored within internal cache. If for example the CMAKE_INSTALL_PREFIX
changes after first run the old behaviour does not lead to an new evaluation
of depending variables. With the help of 'set_kicad_cache' it is possible
to renew variables after first run.

Signed-off-by: Tobias Kohlbau <tobias.kohlbau@xxxxxxxxx>
---
 CMakeLists.txt | 96 +++++++++++++++++++++++++++++++++-------------------------
 1 file changed, 54 insertions(+), 42 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7ac2a10..537b84f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -107,16 +107,28 @@ elseif( MINGW )
 endif()
 mark_as_advanced( KICAD_USER_CONFIG_DIR )
 
+# Add macro for prefering user input over cached input. This leads to the behaviour that
+# a change of an variable within default refreshes the set.
+# This macro avoids setting force value when user input is present.
+macro( set_kicad_cache set default type doc )
+    if ( NOT ${set} )
+        set( ${set} "${default}" CACHE "${type}" "${doc}" )
+        set( ${set}_CACHE "${${set}}" CACHE INTERNAL "${doc}" )
+    else()
+        if ( ${set} MATCHES "^${set}_CACHE$" )
+            set( ${set} "${default}" CACHE "${type}" "${doc}" FORCE )
+            set( ${set}_CACHE "${${set}}" CACHE INTERNAL "${doc}" )
+        endif()
+    endif()
+endmacro()
+
 # Set default data file path to CMAKE_INSTALL_PREFIX if it wasn't specified during the
 # CMake configuration.  The value of DEFAULT_INSTALL_PATH is expanded in config.h and
 # used in the source code to define the base path for kicad search paths and environment
 # variables.
-if( NOT DEFAULT_INSTALL_PATH )
-    set( DEFAULT_INSTALL_PATH "${CMAKE_INSTALL_PREFIX}"
-         CACHE
-         PATH
-         "Location of KiCad data files." )
-endif()
+set_kicad_cache( DEFAULT_INSTALL_PATH ${CMAKE_INSTALL_PREFIX}
+    PATH
+    "Location of KiCad data files." )
 
 message( STATUS "Kicad install dir: <${DEFAULT_INSTALL_PATH}>" )
 
@@ -286,37 +298,37 @@ set( KIFACE_PREFIX  "_" )
 #================================================
 if( NOT APPLE )
     # Everything without leading / is relative to CMAKE_INSTALL_PREFIX.
-    set( KICAD_BIN ${CMAKE_INSTALL_PREFIX}/bin
-        CACHE PATH "Location of KiCad binaries." )
+    set_kicad_cache( KICAD_BIN ${CMAKE_INSTALL_PREFIX}/bin
+        PATH "Location of KiCad binaries." )
 
     if( WIN32 )
-        set( KICAD_PLUGINS ${KICAD_BIN}/scripting/plugins
-            CACHE PATH "Location of KiCad plugins." )
+        set_kicad_cache( KICAD_PLUGINS ${KICAD_BIN}/scripting/plugins
+            PATH "Location of KiCad plugins." )
 
-        set( KICAD_LIB ${KICAD_BIN}
-            CACHE PATH "Location of KiCad shared objects" )
+        set_kicad_cache( KICAD_LIB ${KICAD_BIN}
+            PATH "Location of KiCad shared objects" )
 
-        set( KICAD_USER_PLUGIN ${KICAD_BIN}/plugins
-            CACHE PATH "Location of KiCad user-loaded plugins" )
+        set_kicad_cache( KICAD_USER_PLUGIN ${KICAD_BIN}/plugins
+            PATH "Location of KiCad user-loaded plugins" )
     else()
-        set( KICAD_PLUGINS lib/kicad/plugins
-            CACHE PATH "Location of KiCad plugins." )
+        set_kicad_cache( KICAD_PLUGINS lib/kicad/plugins
+            PATH "Location of KiCad plugins." )
 
-        set( KICAD_LIB ${CMAKE_INSTALL_PREFIX}/lib
-            CACHE PATH "Location of KiCad shared objects" )
+        set_kicad_cache( KICAD_LIB ${CMAKE_INSTALL_PREFIX}/lib
+            PATH "Location of KiCad shared objects" )
 
-        set( KICAD_USER_PLUGIN ${CMAKE_INSTALL_PREFIX}/lib/kicad/plugins
-            CACHE PATH "Location of KiCad user-loaded plugins" )
+        set_kicad_cache( KICAD_USER_PLUGIN ${CMAKE_INSTALL_PREFIX}/lib/kicad/plugins
+            PATH "Location of KiCad user-loaded plugins" )
     endif()
 
-    set( KICAD_DATA share/kicad
-        CACHE PATH "Location of KiCad data files." )
-    set( KICAD_DOCS share/doc/kicad
-        CACHE PATH "Location of KiCad documentation files." )
-    set( KICAD_DEMOS ${KICAD_DATA}/demos
-        CACHE PATH "Location of KiCad demo files." )
-    set( KICAD_TEMPLATE ${KICAD_DATA}/template
-        CACHE PATH "Location of KiCad template files." )
+    set_kicad_cache( KICAD_DATA share/kicad
+        PATH "Location of KiCad data files." )
+    set_kicad_cache( KICAD_DOCS share/doc/kicad
+        PATH "Location of KiCad documentation files." )
+    set_kicad_cache( KICAD_DEMOS ${KICAD_DATA}/demos
+        PATH "Location of KiCad demo files." )
+    set_kicad_cache( KICAD_TEMPLATE ${KICAD_DATA}/template
+        PATH "Location of KiCad template files." )
 else()
     # everything without leading / is relative to CMAKE_INSTALL_PREFIX.
     # CMAKE_INSTALL_PREFIX is root of .dmg image
@@ -344,20 +356,20 @@ else()
     # everything provided with the application bundle goes into
     # kicad.app/Contents/SharedSupport => accessible via GetDataDir()
     # everything else to the .dmg image
-    set( KICAD_DATA ${OSX_BUNDLE_INSTALL_DIR}/${OSX_BUNDLE_SUP_DIR}
-        CACHE PATH "Location of KiCad data files." FORCE )
-    set( KICAD_LIB ${OSX_BUNDLE_INSTALL_DIR}/${OSX_BUNDLE_LIB_DIR}
-        CACHE PATH "Location of KiCad shared objects" FORCE )
-    set( KICAD_USER_PLUGIN ${OSX_BUNDLE_INSTALL_PLUGIN_DIR}
-        CACHE PATH "Location of KiCad user-loaded plugins" FORCE )
-    set( KICAD_TEMPLATE ${KICAD_DATA}/template
-        CACHE PATH "Location of KiCad template files." FORCE )
-    set( KICAD_PLUGINS ${KICAD_DATA}/plugins
-        CACHE PATH "Location of KiCad plugins." FORCE )
-    set( KICAD_DOCS doc
-        CACHE PATH "Location of KiCad documentation files." FORCE )
-    set( KICAD_DEMOS demos
-        CACHE PATH "Location of KiCad demo files." FORCE )
+    set_kicad_cache( KICAD_DATA ${OSX_BUNDLE_INSTALL_DIR}/${OSX_BUNDLE_SUP_DIR}
+        PATH "Location of KiCad data files." FORCE )
+    set_kicad_cache( KICAD_LIB ${OSX_BUNDLE_INSTALL_DIR}/${OSX_BUNDLE_LIB_DIR}
+        PATH "Location of KiCad shared objects" FORCE )
+    set_kicad_cache( KICAD_USER_PLUGIN ${OSX_BUNDLE_INSTALL_PLUGIN_DIR}
+        PATH "Location of KiCad user-loaded plugins" FORCE )
+    set_kicad_cache( KICAD_TEMPLATE ${KICAD_DATA}/template
+        PATH "Location of KiCad template files." FORCE )
+    set_kicad_cache( KICAD_PLUGINS ${KICAD_DATA}/plugins
+        PATH "Location of KiCad plugins." FORCE )
+    set_kicad_cache( KICAD_DOCS doc
+        PATH "Location of KiCad documentation files." FORCE )
+    set_kicad_cache( KICAD_DEMOS demos
+        PATH "Location of KiCad demo files." FORCE )
 
     # RPATH setttings for building shared libraries
     set( CMAKE_MACOSX_RPATH FALSE )
-- 
2.9.0



Follow ups