Prev: software engineer required
Next: Safe Pointers
From: Hibou57 (Yannick Duchêne) on 1 Jan 2010 09:58 I've noticed a seaming trick with language files and compiler definitions files. With language files : when a kind of file does not make distinction between specification and implementation, the documentation suggest to use the element Extension instead of the two element Spec_Suffix and Body_Suffix. However, as I've noticed with AdaControl file, which was relying on the file zadactl.xml for its language definition, enabling the AdaControl language support in a project, was not showing up AdaControl files (*.aru) in the project view. This can be solved using either the Spec_Suffix or the Body_Suffix, instead of Extension, and unlike what the documentation suggest. Exemple of modification to be applied in zadactl.xml : <Name>AdaControl</Name> <Body_Suffix>.aru</Body_Suffix> Next, in the compiler configuration files now, the documentation point that if a language is not associated to a compiler (like AdaControl source files are), then the <executable> element in <compiler_description> should contains an empty string. Unfortunately, GPRConfig which is invoked prior to GPRBuild when building from GPS, does not seems to handle this properly, and simply do as if a compiler was to be found for AdaControl file and none was found, so finally, GPRBuild gives warning messages complaining no compiler could be found for AdaControl and all AdaControl source files were ignored. This is an erroneous warning message. There is luckily a work around : provid in <executable>, the name of an application which GPRConfig will be able to find, then, use an empty string in the package Compiler chunk for Driver. Exemple : <compiler_description> <name>AdaCtl</name> <!-- The name of the application --> <!-- associated with the AdaControl --> <!-- language --> <version>DummyVersion</version> <executable>adactl</executable> <!-- Trick here. See below --> ..... ..... package Compiler is for Driver ("AdaControl") use ""; end Compiler; </config> </configuration> I've applied this trick to have access to AdaControl files from GPS without getting any erroneous warnings at build time. The complete source of the adacontrol.xml file I use for the AdaControl dummy compiler definition I use, with a long comment at the end, is given below. <?xml version="1.0" ?> <gprconfig> <!-- This file is required to avoid messages of the kind --> <!-- warning: no compiler specified for language "Adacontrol", -- > <!-- ignoring all of its sources . --> <!-- Tell about the AdaCtl application --> <compiler_description> <name>AdaCtl</name> <!-- The name of the application --> <!-- associated with the AdaControl --> <!-- language --> <version>DummyVersion</version> <executable>adactl</executable> <!-- Trick here. See below --> <languages>AdaControl</languages> <!-- The language name which AdaCtl --> <!-- handles --> <target>i386-pc-mingw32</target> <!-- You may have to add some --> <!-- target-triplets here --> <target>i686-pc-mingw32</target> <target>pentium-mingw32msv</target> <target>i386-pc-linux</target> <target>i686-pc-linux</target> <target>pentium-linux</target> </compiler_description> <!-- This is needed to associate AdaControl files to a none- existing --> <!-- compiler. --> <configuration> <compilers> <compiler name="AdaCtl" language="AdaControl" /> </compilers> <config> package Naming is for Body_Suffix ("AdaControl") use ".aru"; end Naming; package Compiler is for Driver ("AdaControl") use ""; -- Use an empty string end Compiler; -- here, instead of in the Executable tag </config> <!-- See below to learn more --> </configuration> <!-- To understand this configuration file, have a look at --> <!-- http://www.adacore.com/wp-content/files/auto_update/gprbuild-docs/html/gprbuild_ug.html#The-GPRconfig-knowledge-base --> <!-- A trick is used to avoid GPRBuild warnings of the kind warning: no compiler specified for language "Adacontrol", ignoring all its sources when AdaControl is selected as one of the language in a project (which is a good choice if you want to have AdaControl files appearing in project view). Such a message can be confusing for a first time user, who may believe something is going wrong with either AdaCtl or GPS/GPRBuild. For a better user experience, this is nice to avoid such erroneous warning messages. In the compiler definition file in the gprconfig directory, use adactl instead of the blank string which is supposed to means not a compiler but which is not well handled by GPRBuild. The use of AdaCtl here, is just to be an application GPRConfig will be able to find. Then, in the package Compiler in the configuration section, use an empty string (at this place, not in the compiler definition). You may have to add some host-triplets where indicated if you want it to work. Keep in mind GPRConfig believes this is a compiler. More explanations : if you use an empty string in the compiler definition, GPRConfig is supposed to handle this as an indication that the corresponding language is on purpose not associated to any compiler. But it seems to forget about it, and warns you it did not find a suitable compiler for AdaControl files. So we must provide simething there, the name of an application GPRConfig will be able to find. This is AdaCtl dummy's role here. But for GPRConfig, a compiler definition is nothing without an associated project chunck. This takes place in the <configuration> node. There, we will have to provide an application a second time. This should be adactl as well, but it will then fail, as AdaCtl will be hungry with the parameters it will recieve then. Fortunately, there is a tip : we may use there, an application which is not the same as the one specified in the compiler definition (but both are still needed). And it appears it works fine to give an empty string here. GPRBuild, unlike GPRConfig which is invoked prior to GPRBuild, does not complains it did not find a compiler, and as there is no compiler, it simply does not attempt to apply a compiler on AdaControl files. This only works if given, may it be an empty string. Giving an empty string is not the same as giving nothing. In few words : when a language is not to be associated to a compiler, do not use an empty string in the compiler definition, but use a dummy application there, and use an empty string, instead, in the package Compiler chunck in the configuration node. Questions and comments : yannick_duchene(a)yahoo.fr --> </gprconfig>
From: Hibou57 (Yannick Duchêne) on 1 Jan 2010 10:51
Some other comments : When setting up a compiler definition, keep in mind that the name provided for the node <executable> is case sensitive, even on none- case-sensitive systems. Probably GPRConfig is doing a scan of all directories and doing so, use the names it gets as-is, with no canonical case conversion, when the system is not case sensitive. Still about this <executable> node : although GPRBuild will accept a script or a so called batch file (for Windows users) in the for Driver (language) use "..." , GPRConfig will not recognize any script there, if it is has an extention. If you provide Test.bat here, as the application, GPRConfig will not find it. At least on Windows, only real executables can be used there. Probably it will work on Unix- like, with script which does not use any file name extension. You have two things : a compiler definition, which seems to be intended to GPRConfig, and a project configuration chunk, which is intended to GPRBuild. Both expects a language name and an application name. These are two definition, which are related and unrelated in the mean time. These are related in the way if you do not provide a compiler definition, then the project configuration chunk will not be handled. But this is unrelated in the way the application you indicate as a compiler in the project configuration chunk, is not required to be same as the one given in the compiler definition. You may prodive "foo" for <executable> in the compiler definition for the language L, and provide "bar" in a for Driver ("L") use "bar"; in the project configuration chunk. No check is done here when you do so, and you must care about it. The compiler definition allow you do give an explicit version, or an external reference to a version (via invocation of an application and a regexp expression). This version number may be later used as a filter for the definition of project definition chunk. Always provide a version, even a dummy one : weither or not you use filtering based on version number, if you provide no version number, the compiler definition will be silently ignored by GPRConfig. The <target> element is mandatory as well, even if the application provided is not intended to produce any object file at all (see the exemple of adactl just given in a prior message). Even if you have provided a language definition file for GPS in one of its plug-ins directory, and this language definition file define a file extension for your language, you must explicitly recalls this file name extension in the projection configuration chunk. This is not done automatically. GPS uses its language definition file to know what it will allow you to select as files belonging to a project, but it must no information about what this file extensions are, neither to GPRConfig or GPRBuild. You must do it yourself, and take care to have the same in both place. Exemple : package Naming is for Body_Suffix ("AdaControl") use ".aru"; end Naming; in the adacontrol.xml file which I've put in share/gprconfig, and <Name>AdaControl</Name> <Body_Suffix>.aru</Body_Suffix> for the zadactl.xml file which is in one of the GPS plug-ins directory. Note : I've noticed GPRBuild seomtimes have troubles when XML comments are used in XML file parts standing for a project configuration chunk. Avoid using XML comments there, and use Ada comments instead. Another example case where it is required to use a different application in the compiler definition and the project configuration chunk : surprisingly to me, GPR configuration files, does not provide a way to build a commande line like some other IDE do. And indeed, I did not found any such things in the standard files which are provided in the gprconfig directory. You will not be able to say, as an example windres -i filename -o basename.o . GPRBuold seems to always add the filename as the last option of all the options you may provide in for Required_Switches (language) use ("..."); , and will simply expect the application to create basename.[target-object-extension] object file in the object directory, which is the current-working-directory GPRBuild gives to the compiler. There is no way, neither, to build a command line which will tell the compiler what the object output directory is. For these reasons, the wrapper introduced before with the example of the Windows Resources compiler, is still needed. If this wrapper is a script with an extension, you will not be able to specify it as the application in the compiler definition, but you will be able, and have to, use it in the project configuration chunk. This is another example case where the application specified in the compiler definition and the project configuration chunk are not the same. For my first question which was how do I setup a compiler for Windows Resources in GPS and GPR ? , here is finally the three file I used : windows-resources-language.xml in one of the GPS plugins directory (for language definition) : <?xml version="1.0" encoding="utf-8" ?> <!-- Provides Windows Resources language definition for the GPS IDE. This does not provide any definition for the GPR project manager, which requires another configuration file. This file provides syntax support, view of sources in the project view and its outline view (the one of the project view, not the standalone Outline View tab). You should put this file in either ${PREFIX}/share/gps/plug-ins/ for an all users installation or else in ${PROFILE}/.gps/plug-ins/ for a single user installation. Questions and comments : yannick_duchene(a)yahoo.fr --> <GPS> <Language> <Name>Windows Resources</Name> <Parent>C</Parent> <!-- Formally speaking, this should be CPP, but it is not available in standard GPS languages --> <Body_Suffix>.rc</Body_Suffix> <Extension>.rc</Extension> <Keywords>^(__DATE__|__FILE__|__LINE__|__STDC__|__TIME__| __TIMESTAMP__)\b</Keywords> <!-- RC predefined macros --> <Keywords>^(ACCELERATORS|BITMAP|CURSOR|DIALOG|DIALOGEX|FONT|HTML| ICON|MENU|MENUEX|MESSAGETABLE|POPUP|PLUGPLAY|RCDATA|STRINGTABLE| TEXTINCLUDE|TYPELIB|VERSIONINFO|VXD)\b</Keywords> <!-- Standard resources --> <Keywords>^(AUTO3STATE|AUTOCHECKBOX|AUTORADIOBUTTON|CHECKBOX| COMBOBOX|CONTROL|CTEXT|DEFPUSHBUTTON|EDITTEXT|GROUPBOX|ICON|LISTBOX| LTEXT|PUSHBOX|PUSHBUTTON|RADIOBUTTON|RTEXT|SCROLLBAR|STATE3)\b</ Keywords> <!-- Control resources --> <Keywords>^(CAPTION|CHARACTERISTICS|CLASS|EXSTYLE|FONT|LANGUAGE| MENU|MENUITEM|STYLE|VERSION)\b</Keywords> <!-- Statement resources --> <Keywords>^(RT_CURSOR|RT_BITMAP|RT_ICON|RT_MENU|RT_DIALOG| RT_STRING|RT_FONTDIR|RT_FONT|RT_ACCELERATORS|RT_RCDATA|RT_MESSAGETABLE| RT_GROUP_CURSOR|RT_GROUP_ICON|RT_VERSION|RT_DLGINCLUDE)\b</Keywords> <!-- Resource type IDs --> <Keywords>^(RT_MANIFEST)\b</Keywords> <!-- Others --> <Context> <Comment_Start>/*</Comment_Start> <Comment_End>*/</Comment_End> <New_Line_Comment_Start>//</New_Line_Comment_Start> <String_Delimiter>"</String_Delimiter> <Quote_Character>\</Quote_Character> <Constant_Character>'</Constant_Character> <Can_Indent>True</Can_Indent> <Syntax_Highlighting>True</Syntax_Highlighting> <Case_Sensitive>True</Case_Sensitive> </Context> <Categories> <Category> <Name>include</Name> <Pattern>^\s*(#include\s+\S+).*</Pattern> <!-- Ex. #include "resources.h" --> <Index>1</Index> </Category> <Category> <Name>statement</Name> <Pattern>^\s*((\w+|\d+)\s+(\w+)).*</Pattern> <!-- Ex. 1 RT_MANIFEST ".\\Manifest.xml". The name may be either an ID or a string --> <Index>1</Index> </Category> </Categories> </Language> </GPS> <!-- Reférences for Windows Resources source files : http://msdn.microsoft.com/en-us/library/aa381032(VS.85,lightweight).aspx http://msdn.microsoft.com/en-us/library/aa381043(VS.85).aspx http://msdn.microsoft.com/en-us/library/cc194804.aspx http://msdn.microsoft.com/en-us/library/ms997646.aspx References for GPS language configuration : http://www.adacore.com/wp-content/files/auto_update/gps-docs/Adding-support-for-new-languages.html --> windows-resources.xml in the share/gprconfig directory (for compiler and project configuration chunk definitions) : <?xml version="1.0" ?> <gprconfig> <compiler_description> <name>WindRes</name> <executable>windres</executable> <version>DummyVersion</version> <languages>Windows Resources</languages> <target>i686-pc-mingw32</target> </compiler_description> <configuration> <compilers> <compiler name="WindRes" language="Windows Resources" /> </compilers> <config> package Naming is for Body_Suffix ("Windows Resources") use ".rc"; -- for Casing ("Windows Resources") use "mixedcase"; end Naming; package Compiler is for Driver ("Windows Resources") use "windres-for- gps.bat"; <!-- for Required_Switches ("Windows Resources") use (""); --> end Compiler; </config> </configuration> </gprconfig> The wrapper batch windres-for-gps.bat file which have to be located in your shell ${PATH} : @echo off rem Compiles a Windows resource file (*.rc). It do so running windres from rem the directory where the resource file belong, just for windres to be rem able to resolve relative path the resource file may contains. rem The object file is produced in this same directory. Later, the object rem file is moved to the object directory, which is the one from where rem gnatmake will invok this batch. rem rem This batch script is to be invoked with the file name to compile as rem its first and unique argument. rem rem The argument is retrieved in %1 rem rem %1 is the full file name rem %~n1 is the base name rem %~dp1 is the parent directory name rem pushd <dir> goes to <dir> and remember of the actual directory rem popd comes back to the actual directory pushd %~dp1 windres.exe -i %1 -o %~n1.o popd if exist %~n1.o del %~n1.o if exist %~dp1\%~n1.o move %~dp1\%~n1.o . Or simply download the three files here : http://www.les-ziboux.rasama.org/download/windres-in-gpr-gps-on-windows-host.zip |