{"id":383311,"date":"2024-06-29T04:50:14","date_gmt":"2024-06-29T04:50:14","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=383311"},"modified":"-0001-11-30T00:00:00","modified_gmt":"2024-06-29T04:50:14","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=383311","title":{"rendered":"<span>Using kconfig for own projects<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-1\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<h2 id=\"intro\">Intro<\/h2>\n<p>  <\/p>\n<p>Every Linux professional write scripts. Some\u0435imes light, linear. Sometimes complex script with functions and libs(yes, you can write your bash-library for use in other scripts). <\/p>\n<p>  <\/p>\n<p>But some of the scripts need a configuration file to work. For instance, I wrote a script that builds the ubuntu image for pxe, and I need to change the build process without build-script changes. The best way to resolve this task is to add configuration files.<\/p>\n<p><a name=\"habracut\"><\/a>  <\/p>\n<p>Writing this config by hands is not a great idea: <\/p>\n<p>  <\/p>\n<ul>\n<li>every user should know all available options <\/li>\n<li>hight risk of incorrect data entry <\/li>\n<li>uncomfortable <\/li>\n<li>maybe something else<\/li>\n<\/ul>\n<p>  <\/p>\n<p>Linux kernel gave us a great solution \u2014 KConfig. This system resolves all these troubles: <\/p>\n<p>  <\/p>\n<ul>\n<li>New config generated automatically <\/li>\n<li>You can set the default value<\/li>\n<li>The previous version of config saved automatically <\/li>\n<li>text\/graphical interface available<\/li>\n<\/ul>\n<p>  <\/p>\n<p>These are not all the benefits. You can see more <a href=\"https:\/\/www.kernel.org\/doc\/Documentation\/kbuild\/kconfig-language.txt\" rel=\"nofollow\">here<\/a>. <\/p>\n<p>  <\/p>\n<h2 id=\"how-it-works\">How it works<\/h2>\n<p>  <\/p>\n<p>Simplified schema:<\/p>\n<p>  <\/p>\n<ul>\n<li>All configuration parameters described in KConfig-format file (including available ones) <\/li>\n<li>Interpreter (mconf, gconf, qconf, others) reads this file, current config (if it exists), and shows the menu <\/li>\n<li>The user selects needed options and selects the SAVE option <\/li>\n<li>KConfig moves old config to .config.old and creates new config (default name .config)<\/li>\n<\/ul>\n<p>  <\/p>\n<p>After that, you get a ready-made config that can be used in scripts(or for project build).<\/p>\n<p>  <\/p>\n<h2 id=\"example-project\">Example project<\/h2>\n<p>  <\/p>\n<p>Now, I&#8217;ll show you the demo-project. I placed it on <a href=\"https:\/\/github.com\/skif-web\/demo-kbuild\" rel=\"nofollow\">github<\/a>.<\/p>\n<p>  <\/p>\n<h3 id=\"overview\">overview<\/h3>\n<p>  <\/p>\n<p>It&#8217;s a simple script that shows the information about the last logins. Available options: <\/p>\n<p>  <\/p>\n<ul>\n<li>Select destination (file or console) <\/li>\n<li>If the selected destination is a file, the user can set the filename <\/li>\n<li>Shows information about both all and only current users <\/li>\n<\/ul>\n<p>  <\/p>\n<p>Just clone this repo and go to its directory:<\/p>\n<p>  <\/p>\n<pre><code class=\"bash\">boozlachu@debian:~$ git clone https:\/\/github.com\/skif-web\/demo-kbuild.git Cloning into 'demo-kbuild'... remote: Enumerating objects: 8, done. remote: Counting objects: 100% (8\/8), done. remote: Compressing objects: 100% (6\/6), done. remote: Total 8 (delta 0), reused 5 (delta 0), pack-reused 0 Unpacking objects: 100% (8\/8), done. boozlachu@debian:~$ cd demo-kbuild\/ boozlachu@debian:~\/demo-kbuild$ ls getLast.sh  KConfig  README.md<\/code><\/pre>\n<p>  <\/p>\n<h3 id=\"kconfig-interpreter-notes\">KConfig interpreter notes<\/h3>\n<p>  <\/p>\n<p>KConfig is just a language. You have to use the interpreter to show the menu. In the Linux kernel, the interpreter is built when you run the &#171;make menuconfig&#187; command. But I&#8217;m a lazy potato and will use the kconfig-frontends package. It is available in Debian\/Ubuntu, and you can also build it from the source. Or add an interpreter build from source to your project.<\/p>\n<p>  <\/p>\n<h3 id=\"kconfig-file\">KConfig file<\/h3>\n<p>  <\/p>\n<p>The main file here is KConfig. KConfig supports a lot of operators, but I&#8217;ll use only some of them. <\/p>\n<p>  <\/p>\n<p>Various types of variables are available there. The most useful are:<\/p>\n<p>  <\/p>\n<ul>\n<li>string to save string data <\/li>\n<li>bool to save the bool value (y or commented string in config) <\/li>\n<li>tristate (*\/m\/commented)<\/li>\n<\/ul>\n<p>  <\/p>\n<pre><code class=\"bash\">boozlachu@debian:~\/demo-kbuild$ cat KConfig  choice SELECT_DESTINATION     prompt \"Select data destination\"     default DESTINATION_TTY  config SELECT_DESTINATION_TTY     bool \"show data in console\" config SELECT_DESTINATION_FILE     bool \"save data to file\" endchoice  config SELECT_DESTINATION_FILE_FILENAME     string \"destination file\"     depends on SELECT_DESTINATION_FILE     default \"last.log\"     help       Write destination file with relative or full path  config SHOW_ONLY_CURRENT_USER     bool \"show data only for current user\"     default y     help       script will get data only for current user<\/code><\/pre>\n<p>  <\/p>\n<p>Let&#8217;s see it. Choice-endchoice pair allows creating SELECT of variants. Inside these keywords, I set definition (prompt), default value (default), and added available variants (SELECT_DESTINATION_TTY, SELECT_DESTINATION_FILE). <\/p>\n<p>  <\/p>\n<p>The next option (SELECT_DESTINATION_FILE_FILENAME) will only be shown if the destination is the file. The keyword &#171;depends on&#187; allows us to do this. Also, the available keyword &#171;selects&#187; that works in the opposite direction. <\/p>\n<p>  <\/p>\n<p>Option SHOW_ONLY_CURRENT_USER will always be shown. <\/p>\n<p>  <\/p>\n<p>Run kconfig in text mode:<\/p>\n<p>  <\/p>\n<pre><code class=\"bash\">boozlachu@debian:~\/demo-kbuild$ kconfig-mconf KConfig <\/code><\/pre>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/jv\/0r\/_w\/jv0r_wzu-vdh5mftqy5ryohjppm.png\" data-src=\"https:\/\/habrastorage.org\/webt\/jv\/0r\/_w\/jv0r_wzu-vdh5mftqy5ryohjppm.png\"\/><br \/>  And with qt:<\/p>\n<p>  <\/p>\n<pre><code class=\"bash\">boozlachu@debian:~\/demo-kbuild$ kconfig-qconf KConfig<\/code><\/pre>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/mo\/as\/6b\/moas6betwo4mdzaje8ekllgzqw4.png\" data-src=\"https:\/\/habrastorage.org\/webt\/mo\/as\/6b\/moas6betwo4mdzaje8ekllgzqw4.png\"\/><\/p>\n<p>  <\/p>\n<h3 id=\"test-run\">Test run<\/h3>\n<p>  <\/p>\n<p>After configuring it, we get .config file with options:<\/p>\n<p>  <\/p>\n<pre><code class=\"bash\">boozlachu@debian:~\/demo-kbuild$ cat .config  # # Automatically generated file; DO NOT EDIT. # Configuration # CONFIG_SELECT_DESTINATION_TTY=y # CONFIG_SELECT_DESTINATION_FILE is not set CONFIG_SHOW_ONLY_CURRENT_USER=y<\/code><\/pre>\n<p>  <\/p>\n<p>As you can see, non-selected options are commented on. It&#8217;s useful for my script. <\/p>\n<p>  <\/p>\n<p>I run it with this config:<\/p>\n<p>  <\/p>\n<pre><code class=\"bash\">boozlachu@debian:~\/demo-kbuild$ .\/getLast.sh  boozlach pts\/0        192.168.2.4      Sun Jul 19 06:00   still logged in boozlach pts\/0        192.168.2.4      Sun Jul 19 05:58 - 05:58  (00:00)  wtmp begins Thu Apr 16 05:48:31 2020<\/code><\/pre>\n<p>  <\/p>\n<p>I changed the parameters via KConfig and got another result. Now the date was saved to a file, instead of being shown in the console:<\/p>\n<p>  <\/p>\n<pre><code class=\"bash\">boozlachu@debian:~\/demo-kbuild$ cat .config # # Automatically generated file; DO NOT EDIT. # Configuration # # CONFIG_SELECT_DESTINATION_TTY is not set CONFIG_SELECT_DESTINATION_FILE=y CONFIG_SELECT_DESTINATION_FILE_FILENAME=\"last.log\" CONFIG_SHOW_ONLY_CURRENT_USER=y boozlachu@debian:~\/demo-kbuild$ .\/getLast.sh  boozlachu@debian:~\/demo-kbuild$ cat last.log  boozlach pts\/0        192.168.2.4      Sun Jul 19 06:00   still logged in boozlach pts\/0        192.168.2.4      Sun Jul 19 05:58 - 05:58  (00:00)<\/code><\/pre>\n<p>  <\/p>\n<h2 id=\"conclusion\">Conclusion<\/h2>\n<p>  <\/p>\n<p>As you can see, KConfig is very powerful and friendly util for configuring. It can be used for scripts, package building, and other variants. <\/p>\n<p>  <\/p>\n<p>If you want to see an improved variant of KConfig using a makefile in the real project \u2014 write in comments.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/515398\/\"> https:\/\/habr.com\/ru\/articles\/515398\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-1\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<h2 id=\"intro\">Intro<\/h2>\n<p>  <\/p>\n<p>Every Linux professional write scripts. Some\u0435imes light, linear. Sometimes complex script with functions and libs(yes, you can write your bash-library for use in other scripts). <\/p>\n<p>  <\/p>\n<p>But some of the scripts need a configuration file to work. For instance, I wrote a script that builds the ubuntu image for pxe, and I need to change the build process without build-script changes. The best way to resolve this task is to add configuration files.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-383311","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/383311","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=383311"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/383311\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=383311"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=383311"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=383311"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}