{"id":1945,"date":"2013-10-17T17:28:06","date_gmt":"2013-10-17T05:28:06","guid":{"rendered":"https:\/\/www.deltics.co.nz\/blog\/?p=1945"},"modified":"2013-10-17T17:28:06","modified_gmt":"2013-10-17T05:28:06","slug":"unit-aliases-and-build-configurations","status":"publish","type":"post","link":"https:\/\/www.deltics.co.nz\/blog\/posts\/1945\/","title":{"rendered":"Unit Aliases and Build Configurations"},"content":{"rendered":"<span class=\"rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">[Estimated Reading Time: <\/span> <span class=\"rt-time\">3<\/span> <span class=\"rt-label rt-postfix\">minutes]<\/span><\/span><p>Over on stackoverflow, Ann Gossard had a <a href=\"http:\/\/stackoverflow.com\/questions\/19411055\/add-unit-to-project-is-removing-a-compiler-directive-from-the-project-source\">question about using an <strong>$ifdef<\/strong> in the project (DPR) <strong>uses<\/strong> list to use one unit in preference over another, specifically in debug builds<\/a>.  In this situation, it immediately occurred to me that unit aliases might be creatively deployed.<\/p>\n<p>What follows is a slightly expanded version of the answer I posted to that question.<\/p>\n<p><!--more--><\/p>\n<p>The problem Ann was experiencing is the well known issue of the DPR not respecting any <strong>$ifdef<\/strong>&#8216;s in the <strong>uses<\/strong> list, removing them if [<em>when &#8211; Ed<\/em>] it re-writes the <strong>uses<\/strong> list in response to certain IDE operations such as &#8220;<em>Add\/Remove Unit<\/em>&#8221; etc.<\/p>\n<p>As Rob suggested (and I echoed in my answer), one option is to avoid those IDE operations and to only ever manage the DPR uses list manually.  But occasionally you will likely slip up and have to reconstruct your <strong>uses<\/strong> list from time to time.<\/p>\n<p>If you are using a version of Delphi which supports build configurations (Delphi 2007 or later), a <strong>unit alias<\/strong> can be used to select a unit based on the selected build configuration without relying on an <strong>$ifdef<\/strong> in the uses list.<\/p>\n<p><em>If you are using a version of Delphi prior to Delphi 2007 then I have a vague recollection that there may have been 3rd party solutions that provided similar functionality before this official support was added but I didn&#8217;t use them myself and do not know if they included support for per-configuration unit aliases.  Google will have to be your friend if you fall into this camp I&#8217;m afraid.  \ud83d\ude41<br \/>\n<\/em><\/p>\n<p>But, if you do have Delphi 2007 or later&#8230;.<\/p>\n<h2>Alias Smith and Jones&#8230;<\/h2>\n<p>Consider two units where you wish to use either on or the other depending upon the build configuration (debug or release):<\/p>\n<ul>\n<li>DebugUnit.pas<\/li>\n<li>ReleaseUnit.pas<\/li>\n<\/ul>\n<p>In your project options add a <strong>Unit Alias<\/strong> for:<\/p>\n<p><strong>DEBUG<\/strong> configuration: <code>UnitToUse=DebugUnit<\/code><\/p>\n<p><strong>RELEASE<\/strong> configuration: <code>UnitToUse=ReleaseUnit<\/code><\/p>\n<figure id=\"attachment_1946\" aria-describedby=\"caption-attachment-1946\" style=\"width: 690px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Screen-Shot-2013-10-17-at-15.25.51.png?ssl=1\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Screen-Shot-2013-10-17-at-15.25.51.png?resize=640%2C222&#038;ssl=1\" alt=\"Build Specific Unit Aliases\" width=\"640\" height=\"222\" class=\"size-full wp-image-1946\" srcset=\"https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Screen-Shot-2013-10-17-at-15.25.51.png?w=690&amp;ssl=1 690w, https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Screen-Shot-2013-10-17-at-15.25.51.png?resize=300%2C103&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Screen-Shot-2013-10-17-at-15.25.51.png?resize=500%2C173&amp;ssl=1 500w\" sizes=\"(max-width: 640px) 100vw, 640px\" data-recalc-dims=\"1\" \/><\/a><figcaption id=\"caption-attachment-1946\" class=\"wp-caption-text\">Build Specific Unit Aliases<\/figcaption><\/figure>\n<p><em><strong>Note:<\/strong> This screen capture is taken from Delphi 2010.  Things worked slightly different in Delphi 2007 but unfortunately my Delphi 2007 installation seems to have a problem in this area, throwing an exception in <strong>delphicoreide100.bpl<\/strong> whenever I try to access the <strong>Configuration Manager<\/strong>, which is were the different option sets were managed in that version.  So I&#8217;m afraid I can&#8217;t show a working example from that version.<\/em> \ud83d\ude41<\/p>\n<p>But, if using Delphi 2009 or later (or you&#8217;ve got a working <strong>Configuration Manager<\/strong> in Delphi 2007) &#8230;<\/p>\n<p>In the DPR add an entry to the uses list for <\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">UnitToUse<\/pre>\n<p>Note that this entry in DPR cannot identify a filename using the <strong><code>in &#039;&lt;filename.pas&gt;&#039;<\/code><\/strong> syntax and must instead rely on the aliased units being on the project (or IDE) search path.<\/p>\n<p>Anywhere that you would normally use the <strong>DebugUnit<\/strong> or <strong>ReleaseUnit<\/strong>, refer instead to <strong>UnitToUse<\/strong>.  Obviously the name for the alias is entirely up to you.<\/p>\n<p>If the two units have the same interface &#8220;contracts&#8221; then your builds will seamlessly switch between these two units simply by changing the target configuration from <strong>Debug<\/strong> to <strong>Release<\/strong> or vice versa.<\/p>\n<p>If they have different interface contracts then you can still use <strong>$ifdef<\/strong> directives in your application code to work with the contents of whichever unit UnitToUse refers to, as appropriate, e.g.<\/p>\n<pre class=\"brush: delphi; title: ; notranslate\" title=\"\">\r\nuses\r\n  UnitToUse;\r\n\r\n\r\nprocedure DoSomethingInvolvingAliasedUnit;\r\nbegin\r\n  {$ifdef DEBUG}\r\n    \/\/ code which relies on the debug unit\r\n  {$else}\r\n    \/\/ code which relies on the release unit\r\n  {$endif}\r\nend;\r\n<\/pre>\n<h3>Caveat Developor<\/h3>\n<p>This technique has an admittedly narrow application.<\/p>\n<p>It only works where you need to select between one unit or another (or <strong>N<\/strong> units where there is a <em>1:1 correspondence<\/em> between <em>each<\/em> unit used in the <strong>DEBUG<\/strong> and <strong>RELEASE<\/strong> builds).<\/p>\n<p>It obviously cannot work if you needed to use more units in the <strong>DEBUG<\/strong> build than in the <strong>RELEASE<\/strong> build (or vice versa).<\/p>\n<p>In the case where you have one unit with no corresponding alternative, you could use an alias to select an entirely empty unit (consisting of empty <strong>interface<\/strong> and <strong>implementation<\/strong> sections), but arguably it would be simpler to just wrap an <strong>$ifdef<\/strong> around the contents of the <strong>interface<\/strong> and <strong>implementation<\/strong> sections of a consistently used unit in that case.<\/p>\n<p>But still, for Ann&#8217;s specific case of selecting one of an alternate pair of units, this struck me as a particularly elegant solution.  It&#8217;s not often that <strong>Unit Aliases<\/strong> find much purpose beyond that which they dutifully provide day in, day out, quietly and unobtrusively.<\/p>\n<p>Which is perhaps why they are sometimes overlooked.  \ud83d\ude42<\/p>\n","protected":false},"excerpt":{"rendered":"<p><span class=\"rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">[Estimated Reading Time: <\/span> <span class=\"rt-time\">3<\/span> <span class=\"rt-label rt-postfix\">minutes]<\/span><\/span> Over on stackoverflow, Ann Gossard had a question about using an $ifdef in the project (DPR) uses list to use one unit in preference over another, specifically in debug builds. In this situation, it immediately occurred to me that unit aliases might be creatively deployed. What follows is a slightly expanded version of the answer [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"jetpack_publicize_message":"","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":[]},"categories":[4],"tags":[292,246],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p1TKYv-vn","jetpack_sharing_enabled":true,"jetpack-related-posts":[{"id":1954,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/1954\/","url_meta":{"origin":1945,"position":0},"title":"Hands Off My Application! (Another DPR Trick)","date":"18 Oct 2013","format":false,"excerpt":"In a comment on my previous post, David Heffernan noted that the IDE messes around with other parts of the application DPR in addition to the uses list. He is right. Another area that the IDE likes to muck about with is the code in the DPR begin .. end\u2026","rel":"","context":"In &quot;Delphi&quot;","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Screen-Shot-2013-10-18-at-09.01.47.png?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":1372,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/1372\/","url_meta":{"origin":1945,"position":1},"title":"DPROJ Woes","date":"23 Apr 2013","format":false,"excerpt":"I spent the best part of half a day last week trying to get to the bottom of a very strange issue on a project I was working on. I had just created a new unit in the project and had reached a point where I needed to add that\u2026","rel":"","context":"In &quot;Delphi&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1397,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/1397\/","url_meta":{"origin":1945,"position":2},"title":"Qualified Enum Reference That Fails to Compile in XE4 (and rightly so)","date":"01 May 2013","format":false,"excerpt":"Running through some of my code last night, putting them through the new XE4 compiler, threw up a real oddity: Some code that used to compile just fine, which no longer compiles in XE4 and which should not have compiled before! It's an odd one, because the code previously compiled\u2026","rel":"","context":"In &quot;Delphi&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":2144,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/2144\/","url_meta":{"origin":1945,"position":3},"title":"Smoketest 1.0 &#8211; Release and Be Damned!","date":"14 Nov 2013","format":false,"excerpt":"As I have been promising for some time (quite literally 5 years (!), I am ashamed to admit) I am finally unclenching and releasing the Smoketest framework into the wild, ready or not. The code is published and will continue to be updated in a github repository. Documentation is still\u2026","rel":"","context":"In &quot;Delphi&quot;","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Screen-Shot-2013-11-14-at-19.51.57-.png?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":3019,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/3019\/","url_meta":{"origin":1945,"position":4},"title":"What&#8217;s in a Name[space] ?","date":"29 Oct 2019","format":false,"excerpt":"A recap of unit aliases and how they relate to namespace prefixes as a prelude to a more interesting examination of Scope Elevation.","rel":"","context":"In &quot;Delphi&quot;","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/niklaus-wirth-edit.jpg?fit=934%2C362&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]},{"id":1300,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/1300\/","url_meta":{"origin":1945,"position":5},"title":"What&#8217;s in a Name(space) ?","date":"28 Nov 2012","format":false,"excerpt":"The ever evolving DWScript project continues to advance the Pascal language at an impressive pace. Just today it was announced that this scripting version of Pascal now has \"namespace\" support. When I first read the details of the implementation, my initial reaction was that it \"felt a bit backwards\". The\u2026","rel":"","context":"In &quot;Delphi&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"_links":{"self":[{"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/posts\/1945"}],"collection":[{"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/comments?post=1945"}],"version-history":[{"count":7,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/posts\/1945\/revisions"}],"predecessor-version":[{"id":1953,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/posts\/1945\/revisions\/1953"}],"wp:attachment":[{"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/media?parent=1945"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/categories?post=1945"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/tags?post=1945"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}