{"id":301,"date":"2017-11-27T17:15:12","date_gmt":"2017-11-27T16:15:12","guid":{"rendered":"http:\/\/www.em-company.fr\/blog\/?p=301"},"modified":"2017-11-27T17:15:54","modified_gmt":"2017-11-27T16:15:54","slug":"static-library-version-check","status":"publish","type":"post","link":"https:\/\/www.em-company.fr\/blog\/index.php\/2017\/11\/27\/static-library-version-check\/","title":{"rendered":"Static version check of an un-versioned library"},"content":{"rendered":"<p>When you integrate an external partner delivery (Software Library), it is crucial to maintain version coherency. Say your partner is delivering library version 2.2.1, and you would integrate that together with your software from label Week30. You then need to make sure that:<!--more--><\/p>\n<ol>\n<li>Proper header files are included for this library. Header files for V2.2.1 are probably different than for V1.2.3.<\/li>\n<li>The software would not even compile with an older version of the library. What I mean is that, you want the whole build system preventing you to build the software.<\/li>\n<li>At runtime, you want to make sure the proper library version is actually used. If not, your software would typically <em>assert<\/em>, or handle this in a way or another.<\/li>\n<\/ol>\n<p>This sounds very basic requirements and any software engineer should be persuaded that these are the bare minimum requirements. However, more often than not, the reality is different (sounds familiar ?).<\/p>\n<p>I had this situation on one project where we were receiving regular drops of an algorithm library. The library was named &#8230; &#8220;library.a&#8221; and the header file &#8220;library.h&#8221;. No provision was made for a runtime revision querying, and it took several successive deliveries to agree upon an &#8220;<em>uint32 getVersion()<\/em> &#8221; entry point.<\/p>\n<p>Most important for me was to solve point 2. as all the libraries had the same name, nearly the same size and a very similar interface &#8230;. but radically different behaviors.<\/p>\n<p>So I ended doing the following:<\/p>\n<p>1. Use the Librarian tool to add a specific function to the library. This function would be named after the library version. The function does not need to do anything, just to be there.<\/p>\n<p>2. Call this function from our software.<\/p>\n<p>Then the magic operates: if the wrong function is called, then the linker would complain. This is preventing linking the wrong library, and it is correctly detected at compile time.<\/p>\n<h5>Steps in more details<\/h5>\n<p><span style=\"text-decoration: underline;\">Use of the librarian<\/span><\/p>\n<p>My environment was IAR for ARM, but it can be applied to a lot of others toolchains. In this toolchain, the compiler and librarian are<\/p>\n<pre>IAR_COMPILER=\"IAR Systems\\Embedded Workbench 7.0\\arm\\bin\\iccarm.exe\"\r\nIAR_LIBRARIAN=\"IAR Systems\\Embedded Workbench 7.0\\arm\\bin\\iarchive.exe\"<\/pre>\n<p>Using a small batch file, we can pre-process the libray as follows:<\/p>\n<pre>@echo void IchBinV%VERSION%(void){} &gt; %TEMPFILE%.c\r\n%IAR_COMPILER% -o %TEMPFILE%.o -c %TEMPFILE%.c\r\n%IAR_LIBRARIAN% -r %PARTNER_LIB% %TEMPFILE%.o<\/pre>\n<p>So I create an helper function named &#8220;IchBin&lt;version-number&gt;(void) &#8221; where version-number would hold the actual version. For example, for V1.05<\/p>\n<pre>IchBinV105(void) {}<\/pre>\n<p><span style=\"text-decoration: underline;\">Client software side<\/span><\/p>\n<p>The function is compiled &#8220;on-the-fly&#8221; and added to the partner library. Then, somewhere in my software, I would have<\/p>\n<pre>......\r\n#ifdef LIBRARY_V105\r\nint res = IchBinV105();\r\n#elif defined(LIBRARY_V106)\r\nint res = IchBinV106();\r\n#endif\r\n.....<\/pre>\n<p>(<em>example with 2 different versions checked<\/em>)<\/p>\n<p>In term of process, a simple batch file can be used (or bash), which would automate all this. For example, mine was (sanitized):<\/p>\n<pre>set PARTNER_LIB=%2%\r\n\r\n:process\r\nif \/I NOT \"%1\"==\"105\" if \/I NOT \"%1\"==\"201\" if \/I NOT \"%1\"==\"202\" goto wrong_rev\r\n\r\nset IAR_COMPILER=\"C:\\Program Files (x86)\\IAR Systems\\Embedded Workbench 7.0\\arm\\bin\\iccarm.exe\"\r\nset IAR_LIBRARIAN=\"C:\\Program Files (x86)\\IAR Systems\\Embedded Workbench 7.0\\arm\\bin\\iarchive.exe\"\r\nset TEMPFILE=%TEMP%\\libversion\r\nset VERSION=%1%\r\n\r\n:: Test the tools\r\n:: 1. Test compiler\r\n%IAR_COMPILER% 1&gt;nul 2&gt;nul\r\nif \"%ERRORLEVEL%\"==\"0\" goto :compiler_ok\r\n\r\necho could not find ICCARM compiler.\r\ngoto :end\r\n:compiler_ok\r\n@echo Found compiler iccarm.exe\r\n\r\n:: 2. Test librarian\r\n%IAR_LIBRARIAN% 1&gt;nul 2&gt;nul\r\nif \"%ERRORLEVEL%\"==\"0\" goto :librarian_ok\r\necho could not find Librarian compiler.\r\ngoto :end\r\n:librarian_ok\r\n@echo Found Librarian iarchive.exe\r\n@echo.\r\n@echo Processing library archiving process\r\npause\r\n\r\n@echo void IchBinV%VERSION%(void){} &gt; %TEMPFILE%.c\r\n%IAR_COMPILER% -o %TEMPFILE%.o -c %TEMPFILE%.c\r\n%IAR_LIBRARIAN% -r %PARTNER_LIB% %TEMPFILE%.o\r\n\r\n:: Verification\r\n@echo.\r\n@echo Library contains now the following entries\r\n%IAR_LIBRARIAN% --symbols %PARTNER_LIB%\r\ngoto :end\r\n\r\n:wrong_rev\r\n@echo Error: Bad revision\r\n@echo.\r\n\r\n:usage\r\n@echo prepares a lib for archiving\r\n@echo.\r\n@echo syntax:\r\n@echo \"prep_lib &lt;version&gt; &lt;lib_file_name&gt;\"\r\n@echo \"version = [105 | 201 | 202]\"\r\n@echo \"lib_file_name = file name [default = library.a]\"\r\n\r\n<\/pre>\n<p>The bulk of the script is checking the tools, the revs, the arguments, then runs the 2 lines described above.<\/p>\n<p>That is a very simple trick but once in place, it can save hours of debugging and nervous conference calls !<\/p>\n<p><em>PS: the strange name for the function &#8220;IchBin&#8221; was the result of a long running joke we had in the team, in relation with a famous ad at the french TV<\/em><\/p>\n<p><em> ( https:\/\/www.youtube.com\/watch?v=6ZsPBgjITNs).<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>When you integrate an external partner delivery (Software Library), it is crucial to maintain version coherency. Say your partner is delivering library version 2.2.1, and you would integrate that together with your software from label Week30. You then need to make sure that:<\/p>\n","protected":false},"author":4,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[26,1],"tags":[],"class_list":["post-301","post","type-post","status-publish","format-standard","hentry","category-methodology","category-uncategorized"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.7 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Static version check of an un-versioned library - Embedded<\/title>\n<meta name=\"description\" content=\"A very simple method to add static version verification of an un-versioned library. It uses the librarian and compiler to add an specific entry point.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.em-company.fr\/blog\/index.php\/2017\/11\/27\/static-library-version-check\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Static version check of an un-versioned library - Embedded\" \/>\n<meta property=\"og:description\" content=\"A very simple method to add static version verification of an un-versioned library. It uses the librarian and compiler to add an specific entry point.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.em-company.fr\/blog\/index.php\/2017\/11\/27\/static-library-version-check\/\" \/>\n<meta property=\"og:site_name\" content=\"Embedded\" \/>\n<meta property=\"article:published_time\" content=\"2017-11-27T16:15:12+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2017-11-27T16:15:54+00:00\" \/>\n<meta name=\"author\" content=\"kriko\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"kriko\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.em-company.fr\\\/blog\\\/index.php\\\/2017\\\/11\\\/27\\\/static-library-version-check\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.em-company.fr\\\/blog\\\/index.php\\\/2017\\\/11\\\/27\\\/static-library-version-check\\\/\"},\"author\":{\"name\":\"kriko\",\"@id\":\"https:\\\/\\\/www.em-company.fr\\\/blog\\\/#\\\/schema\\\/person\\\/fcb297f759038f0e8cb969c4c29742df\"},\"headline\":\"Static version check of an un-versioned library\",\"datePublished\":\"2017-11-27T16:15:12+00:00\",\"dateModified\":\"2017-11-27T16:15:54+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.em-company.fr\\\/blog\\\/index.php\\\/2017\\\/11\\\/27\\\/static-library-version-check\\\/\"},\"wordCount\":507,\"commentCount\":0,\"articleSection\":[\"methodology\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.em-company.fr\\\/blog\\\/index.php\\\/2017\\\/11\\\/27\\\/static-library-version-check\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.em-company.fr\\\/blog\\\/index.php\\\/2017\\\/11\\\/27\\\/static-library-version-check\\\/\",\"url\":\"https:\\\/\\\/www.em-company.fr\\\/blog\\\/index.php\\\/2017\\\/11\\\/27\\\/static-library-version-check\\\/\",\"name\":\"Static version check of an un-versioned library - Embedded\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.em-company.fr\\\/blog\\\/#website\"},\"datePublished\":\"2017-11-27T16:15:12+00:00\",\"dateModified\":\"2017-11-27T16:15:54+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/www.em-company.fr\\\/blog\\\/#\\\/schema\\\/person\\\/fcb297f759038f0e8cb969c4c29742df\"},\"description\":\"A very simple method to add static version verification of an un-versioned library. It uses the librarian and compiler to add an specific entry point.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.em-company.fr\\\/blog\\\/index.php\\\/2017\\\/11\\\/27\\\/static-library-version-check\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.em-company.fr\\\/blog\\\/index.php\\\/2017\\\/11\\\/27\\\/static-library-version-check\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.em-company.fr\\\/blog\\\/index.php\\\/2017\\\/11\\\/27\\\/static-library-version-check\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Accueil\",\"item\":\"https:\\\/\\\/www.em-company.fr\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Static version check of an un-versioned library\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.em-company.fr\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.em-company.fr\\\/blog\\\/\",\"name\":\"Embedded\",\"description\":\"(...but not only)\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.em-company.fr\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.em-company.fr\\\/blog\\\/#\\\/schema\\\/person\\\/fcb297f759038f0e8cb969c4c29742df\",\"name\":\"kriko\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Static version check of an un-versioned library - Embedded","description":"A very simple method to add static version verification of an un-versioned library. It uses the librarian and compiler to add an specific entry point.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.em-company.fr\/blog\/index.php\/2017\/11\/27\/static-library-version-check\/","og_locale":"en_US","og_type":"article","og_title":"Static version check of an un-versioned library - Embedded","og_description":"A very simple method to add static version verification of an un-versioned library. It uses the librarian and compiler to add an specific entry point.","og_url":"https:\/\/www.em-company.fr\/blog\/index.php\/2017\/11\/27\/static-library-version-check\/","og_site_name":"Embedded","article_published_time":"2017-11-27T16:15:12+00:00","article_modified_time":"2017-11-27T16:15:54+00:00","author":"kriko","twitter_card":"summary_large_image","twitter_misc":{"Written by":"kriko","Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.em-company.fr\/blog\/index.php\/2017\/11\/27\/static-library-version-check\/#article","isPartOf":{"@id":"https:\/\/www.em-company.fr\/blog\/index.php\/2017\/11\/27\/static-library-version-check\/"},"author":{"name":"kriko","@id":"https:\/\/www.em-company.fr\/blog\/#\/schema\/person\/fcb297f759038f0e8cb969c4c29742df"},"headline":"Static version check of an un-versioned library","datePublished":"2017-11-27T16:15:12+00:00","dateModified":"2017-11-27T16:15:54+00:00","mainEntityOfPage":{"@id":"https:\/\/www.em-company.fr\/blog\/index.php\/2017\/11\/27\/static-library-version-check\/"},"wordCount":507,"commentCount":0,"articleSection":["methodology"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.em-company.fr\/blog\/index.php\/2017\/11\/27\/static-library-version-check\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.em-company.fr\/blog\/index.php\/2017\/11\/27\/static-library-version-check\/","url":"https:\/\/www.em-company.fr\/blog\/index.php\/2017\/11\/27\/static-library-version-check\/","name":"Static version check of an un-versioned library - Embedded","isPartOf":{"@id":"https:\/\/www.em-company.fr\/blog\/#website"},"datePublished":"2017-11-27T16:15:12+00:00","dateModified":"2017-11-27T16:15:54+00:00","author":{"@id":"https:\/\/www.em-company.fr\/blog\/#\/schema\/person\/fcb297f759038f0e8cb969c4c29742df"},"description":"A very simple method to add static version verification of an un-versioned library. It uses the librarian and compiler to add an specific entry point.","breadcrumb":{"@id":"https:\/\/www.em-company.fr\/blog\/index.php\/2017\/11\/27\/static-library-version-check\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.em-company.fr\/blog\/index.php\/2017\/11\/27\/static-library-version-check\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.em-company.fr\/blog\/index.php\/2017\/11\/27\/static-library-version-check\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Accueil","item":"https:\/\/www.em-company.fr\/blog\/"},{"@type":"ListItem","position":2,"name":"Static version check of an un-versioned library"}]},{"@type":"WebSite","@id":"https:\/\/www.em-company.fr\/blog\/#website","url":"https:\/\/www.em-company.fr\/blog\/","name":"Embedded","description":"(...but not only)","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.em-company.fr\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.em-company.fr\/blog\/#\/schema\/person\/fcb297f759038f0e8cb969c4c29742df","name":"kriko"}]}},"_links":{"self":[{"href":"https:\/\/www.em-company.fr\/blog\/index.php\/wp-json\/wp\/v2\/posts\/301","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.em-company.fr\/blog\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.em-company.fr\/blog\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.em-company.fr\/blog\/index.php\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/www.em-company.fr\/blog\/index.php\/wp-json\/wp\/v2\/comments?post=301"}],"version-history":[{"count":2,"href":"https:\/\/www.em-company.fr\/blog\/index.php\/wp-json\/wp\/v2\/posts\/301\/revisions"}],"predecessor-version":[{"id":303,"href":"https:\/\/www.em-company.fr\/blog\/index.php\/wp-json\/wp\/v2\/posts\/301\/revisions\/303"}],"wp:attachment":[{"href":"https:\/\/www.em-company.fr\/blog\/index.php\/wp-json\/wp\/v2\/media?parent=301"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.em-company.fr\/blog\/index.php\/wp-json\/wp\/v2\/categories?post=301"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.em-company.fr\/blog\/index.php\/wp-json\/wp\/v2\/tags?post=301"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}