zoukankan      html  css  js  c++  java
  • Debug vs. Release In Delphi Build Configurations

    http://delphi.about.com/od/objectpascalide/ss/debug-vs-release-in-delphi-build-configurations.htm

    The Project Manager window in your Delphi (RAD Studio) IDE displays and organizes
    the contents of your current project group and any projects it contains.
    It will list all the units that are part of your project
    as well as all the forms and resource files included.

    The Build Configurations section will list various build configurations you have for your project.

    Some more recent (to be correct: starting from Delphi 2007) Delphi versions
    have two (three) default build configurations: DEBUG and RELEASE.

    The Conditional Compilation 101 article does mention build configurations
    but does not explain the difference in details.

    Debug vs. Release

    Since you can activate each of the build configurations you see in the Project Manager,
    and build your project producing a different executable file, the question is 

    what is the difference between Debug and Release?

    The naming itself: "debug" and "release" should point you in the right direction.

    • Debug configuration should be active and used
      while we are developing and debugging and changing your application.
    • Release configuration should be activated
      when we are building your application so that the produced executable file
      to be sent to the users.

    Yet, the question remains:
    what's the difference?
    What can you do while "debug" is active and what is included in the final executable file vs.
    how does the executable look when "release" is applied?

    Build Configurations

    By default there are three (even though in the Project Manager you only see two) build configurations
    created by Delphi when you start a new project. Those are: Base, Debug and Release.

    The Base configuration acts as a base set of option values 
    that is used in all the configurations you subsequently create.

    The option values mentioned, are the compiling and linking and other set of options
    you can alter for your project using the Project Options dialog
    (main menu: Project - Options).

    The Debug configuration extends Base by disabling optimization
    and enabling debugging, as well as setting specific syntax options.

    The Release configuration extends Base to
    not produce symbolic debugging information, the code is not generated for TRACE and ASSERT calls,
    meaning the size of your executable is reduced.

    You can add your own build configurations, you can delete
    both the default Debug and Release configurations,
    but you cannot delete the Base one.

    Build configurations are saved in the project file (.dproj).
    The DPROJ is an XML file, here's how the section with build configurations:

    <PropertyGroup Condition="'$(Base)'!=''">
      <DCC_ImageBase>00400000</DCC_ImageBase>
      <DCC_DcuOutput>.\$(Config)\$(Platform)</DCC_DcuOutput>
      <DCC_UnitAlias>WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;$(DCC_UnitAlias)</DCC_UnitAlias>
      <DCC_ExeOutput>.\$(Config)\$(Platform)</DCC_ExeOutput>
    </PropertyGroup>
    <PropertyGroup Condition="'$(Cfg_1)'!=''">
      <DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
      <DCC_Optimize>false</DCC_Optimize>
      <DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
    </PropertyGroup>
    <PropertyGroup Condition="'$(Cfg_2)'!=''">
      <DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
      <DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
      <DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
      <DCC_DebugInformation>false</DCC_DebugInformation>
    </PropertyGroup>

    Of course, you will not alter the DPROJ file manually, it is maintained by Delphi.

    You *can* rename build configurations,
    you *can* alter the settings for each build configuration,
    you *can* make it so that "release" is for debugging and "debug" is optimized for your clients.
    Therefore you need t know what you are doing :)

    Compiling, Building, Running

    As you are working on your application, developing it,
    you can compile, build, and run the application directly from the IDE.
    Compiling, building and running will produce the executable file.

    Compiling will syntax check your code and will compile the application -
    taking into account only those files that have changed since the last Build.
    Compiling produces DCU files.

    Building is an extension to compiling where all the units (even those not altered) are compiled. 
    When you change project options you should build!

    Running compiles the code and runs the application.
    You can run with debugging (F9) or without debugging (Ctrl+Shift+F9).
    If run without debugging, the debugger built into the IDE will not be invoked -
    your debugging breakpoints will "not" work.

    Now that you know how and where the build configurations are saved,

    let's see the difference between the Debug and Release builds.

    The default build configuration Debug, you can locate in the Project Manager for your Delphi project,
    is created by Delphi when you created a new application/project.

    Debug configuration disables optimization and enables debugging.

    To edit the build configuration: right click the configuration name,
    select "Edit" from the context menu and you will find yourself looking at the Project Options dialog box.

    Debug Options

    Since debug extends the Base configuration build,
    those settings that have a different value will be displayed in bold.

    For Debug (and therefore debugging) the specific options are:

    • Delphi Compiler - Compiling - Code Generation - 
      Optimization OFF - the compiler will NOT perform a number of code optimizations,
      such as placing variables in CPU registers,
      eliminating common subexpressions,
      and generating induction variables.
    • Delphi Compiler - Compiling - Code Generation - 
      Stack Frames ON - stack frames are always generated for procedures and functions,
      even when they're not needed.
    • Delphi Compiler - Compiling - Debugging - 
      Debug Information ON - when a program or unit is compiled with this option enabled,
      the 
      integrated debugger lets you single-step and set breakpoints.
      Debug information being "on" does not affect the size or speed of the executable program -
      debug information is compiled into the DCUs and does not get linked into the executable.
    • Delphi Compiler - Compiling - Debugging - 
      Local symbols ON - When a program or unit is compiled with this option enabled,
      the 
      integrated debugger lets you examine and modify the module's local variables.
      Local symbols being "on" does not affect the size or speed of the executable program.

    NOTE: by default, the "use debug .dcus" option is OFF.
    Setting this option on enables you to 
    debug Delphi VCL source code (set a breakpoint in the VCL)

    Let's now see what "Release" is about...

    The default build configuration Release, you can locate in the Project Manager for your Delphi project,
    is created by Delphi when you created a new application/project.

    Release configuration enables optimization and disables debugging,
    the code is not generated for TRACE and ASSERT calls,
    meaning the size of your executable is reduced.

    To edit the build configuration: right click the configuration name,
    select "Edit" from the context menu and you will find yourself looking at the Project Options dialog box.

    Release Options

    Since release extends the Base configuration build, those settings that have a different value will be displayed in bold.

    For Release (the version to be used by the users of your application - not for debugging) the specific options are:

    • Delphi Compiler - Compiling - Code Generation - 
      Optimization ON - the compiler will perform a number of code optimizations,
      such as placing variables in CPU registers,
      eliminating common subexpressions,
      and generating induction variables.
    • Delphi Compiler - Compiling - Code Generation - 
      Stack Frames OFF - stack frames are NOT generated for procedures and functions.
    • Delphi Compiler - Compiling - Debugging - 
      Debug Information OFF - when a program or unit is compiled with this option disabled,
      the 
      integrated debugger does NOT let you single-step and set breakpoints.
    • Delphi Compiler - Compiling - Debugging - 
      Local symbols OFF - When a program or unit is compiled with this option disabled,
      the 
      integrated debugger does NOT let you examine and modify the module's local variables.

    Those are the default values set by Delphi for a new project.
    You can alter any of the Project options to make your own version of debug or release build configurations.

    http://delphi.about.com/od/objectpascalide/a/delphi-conditional-compilation-101.htm

    Have Two Applications In One Delphi Program
    (Conditional Compilation)

    When creating "normal" Delphi desktop applications (not services or web servers and similar),
    let's say using the VCL, you would start by selecting "New VCL Forms Application" from the IDE's main menu.
    This will create a program/application skeleton for you containing a single form.
    You 
    add more forms and units to build your application.

    Project Group, Project, Program, Application

    Now, the above action will actually create a new "project".
    Take a look at the Project Manager (somewhere in the IDE or make it visible
    by selecting View-Project Manager from the IDE's main menu).
    You'll see "ProjectX" (containing UnitX.pas) that is a part of what is called "ProjectGroupX".
    The X can be "1" or "2" or similar, depending on how many projects (sorry, applications)
    you started and saved, but did not change the default name.

    Therefore, the newly created "application" is actually a "project" in some project group.

    A complete, Delphi executable application consists of multiple units,
    all tied together by a single source code unit called a project file (like the One Ring).

    If you take a look at the projects file source code (DPR),
    you'll note the DPR unit starts with the reserved word "program".

    The program keyword, inside the DPR source file, identifies this unit as a program's main source unit.
    You can see that the unit name, ProjectX, follows the program keyword
    (Delphi gives the project a default name until you save the project with a more meaningful name).
    When you compile (or build) Delphi uses the name of the project file for the name of the EXE file that it creates.

    Again, normally, all the forms and units that are part of the project
    would be compiled/linked into the final executable file.

    For the sake of this article, and since in developers talking
    both "program" and "application" are used to describe the same thing,
    I will refer to "program" when I think of a project,
    and the "application" will be the final executable.

    Ok, all set and we can continue with the article main idea :)

    Two Applications In One Project (sorry, Program)

    Have you even wanted to have two executable versions for your application?
    Let's say one "trial" and one "normal"?

    Have you ever needed to include or not include pieces
    (some forms, units) of the project based on some criteria?

    Have you ever needed to have the same code base in one program
    but also have an option to build two (or more) different applications?

    If the answer to any of the above is "yes",
    then you are ready to learn about Delphi's conditional compilation.

    Conditional Compilation

    Now, before moving into a discussion how to have "here's how" for the above
    (and similar questions) let's see what conditional compilation is.

    Delphi component developers are certainly familiar with conditional compilation.

    However, if you plan on writing Delphi code that should work
    with several version of the Delphi compiler
    (as you are working in a team and not all members are using the same Delphi version, for a dummy example)
    you need to know under which versions your code gets compiled.

    The Delphi Compiler Version Directives article has some startup info on
    how conditional compilation is used to test the version of the Delphi compiler.

    Essentially, conditional compilation is based on the existence and evaluation of constants,
    the status of compiler switches, and the definition of conditional symbols.
    Such symbols are like boolean values.

    There's a set of pre-defined conditional symbols in Delphi like:
    "MSWINDOWS" (indicates that the operating environment is Windows),
    "CONSOLE" (defined if an application is being compiled as a console application),
    "WIN32" (use to distinguish between specific Windows platforms, such as 32-bit versus 64-bit)
    and alike (above mentioned VER symbols to indicate the compiler version).

    As stated, conditional symbols act like boolean values,
    they are either defined (true) or undefined (false).
    Any conditional symbol is treated as false until it has been defined.

    Since conditional symbols are like boolean values, to test for true or false,
    you would use the "special version" of the if then else statement.

    Here's an example:

    {$IFDEF DEBUG}
      Caption := '"DEBUG" is defined and "on"';
    {$ELSE}
      Caption := '"DEBUG" is not defined and "off"';
    {$ENDIF}

    Try placing the above code inside the OnCreate event handler for
    the (main) form of the application (program, project) created at the beginning of the article.

    Now, take a look at the Project Manager, the "Build Configurations" node.
    Either "Debug" or "Release" will be bold. That is the currently active build configurations.
    Double click one to activate it. Run (F9) the application.
    Note the different form caption depending on what the active build configuration is?
    Ha! Conditional compilation in action!!

    IFDEF, IFNDEF

    Just like normal if and else, the "$IFDEF" and "$IFNDEF" along with "$ELSE" and "$ENDIF"
    are used when you want to leverage conditional compilation.
    They get surrounded by "{" and "}".

    The "IFDEF" means "if defined" whatever comes after it.
    IFNDEF is for "not defined".
    In the above example the conditional symbol is "DEBUG" -
    a pre-defined symbol by Delphi used in "debug build configuration".

    You cannot use conditional symbols with normal if/then/else statements.

    Now, the question comes up: how do I define my own conditional symbols? How do I go with:

    {$IFDEF MY_CONDITIONAL_SYMBOL}
      Caption := 'This is a TRIAL version, buy the full one to have all the features!"';
    {$ENDIF}

    First, note that when a conditional symbol, like "MY_CONDITIONAL_SYMBOL",
    is NOT defined the above would always evaluate to false
    and the "Caption := ..." line of code would never execute.

    Build Configuration: Release + TRIAL

    The option to have different build configurations for your Delphi program
    allows you to have two (or more) different applications (executable files)
    being produced by the compiler/linker.
    For this purpose you would use a feature called conditional compilation.

    Conditional compilation let's you tell Delphi compiler
    to include or not include parts of your code
    depending on the existence of conditional symbols.

    As explained, some conditional symbols,
    like "DEBUG" and "WIN32" are pre-defined in Delphi.

    If you want to be able to easily have two different executable files for your program
    (therefore produce two different applications using the same code base),
    let's say "TRIAL" and "normal", you could define a conditional symbol
    "TRIAL_VERSION", then have lines of code like:

    {$IFDEF TRIAL_VERSION}
      Caption := 'This is a TRIAL version, buy the full one to have all the features!"';
    {$ENDIF}

    Therefore, the question is: how to define a custom conditional symbol (like "TRIAL_VERSION")?

    Build Configuration: Release + TRIAL

    For the sake of simplicity, let's say you want to have a special "RELEASE" version of your program.
    The normal RELEASE will build your normal application,
    the executable will have name as specified by the project (dpr) file.
    The, let's call it, TRIAL RELEASE will create a differently named executable
    that will be the trial version of your application where some features are not allowed.

    For the above, we want to have a special release version where our custom conditional symbol "TRIAL_VERSION" is defined.

    We will define the TRIAL_VERSION conditional symbol as a part of a special extension
    to the existing RELEASE build configuration. Here's how:

    1. Expand the "Build Configurations" node under "Project1" in "ProjectGroup1" inside the Project Manger,
    2. Right click the "Release" build configuration and select "New Configuration..." from the popup menu.
    3. Let the name for the new configuration build be "TRIAL" on the New Build Configuration dialog.
    4. The TRIAL is now a sub-node to the Release build configuration node.

    The TRIAL build configuration extends the Release configuration, and for the moment they are the same.

    Let's now see how to add our custom conditional symbol "TRIAL_VERSION" to the "TRIAL" build configuration.

    Once the custom TRIAL build configuration is created
    (extending the pre-defined Release configuration),
    you need to define a custom conditional symbol
    to ensure building your program as a trial build
    will create a different application - due to conditional compilation.

    Here's how to add/define your own conditional symbol "TRIAL_VERSION"
    for the custom "Trial" build configuration:

    1. Right click on the newly created build configuration
      (Trial, extends Release). Select Edit..
    2. Project Options dialog will get displayed.
      The Conditional defines will list "Release".
      Add "TRIAL_VERSION" (use a semicolon to separate multiple symbols).
      RELEASE;TRIAL_VERSION
      
    3. Click Ok on the Project Options dialog

    With the above our custom conditional symbol "TRIAL_VERSION"
    is defined for the "TRIAL" build configuration!

    Note: conditional symbols must start with a letter,
    followed by any combination of letters, digits, and underscores;
    they can be of any length, but only the first 255 characters are significant.

    Once a conditional symbol is defined we can use special conditional directives:
    $IFDEF, $IFNDEF, $ELSEIF, $ELSE, $ENDIF
    to code against the existence of a conditional symbol...

    Ok, let's now see how this works and how to take "TRIAL_VERSION" into consideration
    when coding and building our application.

    TRIAL_VERSION in Action!

    Have the next code inside the OnCreate event handler for the main form of the program:

    procedure TForm1.FormCreate(Sender: TObject);
    begin
    {$IFDEF TRIAL_VERSION}
      Caption := 'This is a TRIAL RELEASE version';
    {$ELSE}
      {$IFDEF DEBUG}
        Caption := 'This is a DEBUG version';
      {$ELSE}
        Caption := 'This is a RELEASE version';
      {$ENDIF}
    {$ENDIF}
    end;

    Double clicking the Debug, Release and Trial build configurations activate each configuration
    (in the Project Manager) and run the program.
    Note how the Caption of the form changes depending on the active build configuration!

    That's it: conditional compilation in action :)

    How could we now have different forms be a part of our program
    depending on the conditional symbols and compilation?

    Having seen how you can have your application respond to
    user action differently depending on the existence of conditional symbols
    and conditional compilation, let's now see how to include different forms.

    Suppose you have a splash screen and you want a different splash screen
    to appear for the trial and for the normal release of the application.

    Trial vs. Release Splash Screen

    A splash screen is a form which appears before your main form is displayed -
    maybe to show the title of the application, some additional data, whatever.

    For each build configuration (and therefore a different application),
    be it "release" or "trial" you can display a different splash screen.

    Here's how

    1. Add two more forms to the project.
    2. Name the forms: "TSplashFormTrial" (unit name: "SplashUnitTrial") and
      "TSplashFormRelease" (unit name: "SplashUnitRelease").
      Note that by design the two newly added forms will not be a part of those forms
      that get auto created by Delphi.
      Rather, they will be listed in the Project Options - Forms - Available Forms list.
      This means that you need to manually create and show and free the forms.
    3. Each of the splash forms will have a simple Execute class method -
      creating and displaying the form.
      class procedure TSplashFormRelease.Execute;
      begin
        with TSplashFormRelease.Create(nil) do
        try
          Show; Refresh;
          Sleep(1000);
        finally
          Free;
        end;
      end;
      The above code is for the "release" version.
      The TSplashFormTrial has the same method,
      the Sleep call is here only to mimic some workload.

    Now, open up the project's unit (dpr) source code and let it look like:

    program Project1;
    
    uses
      Forms,
      Unit1 in 'Unit1.pas' {Form1},
      {$IFDEF TRIAL_VERSION}
      SplashUnitTrial in 'SplashUnitTrial.pas' {SplashFormTrial};
      {$ELSE}
      SplashUnitRelease in 'SplashUnitRelease.pas' {SplashFormRelease};
      {$ENDIF}
    
    {$R *.res}
    
    begin
      Application.Initialize;
    
      {$IFDEF TRIAL_VERSION}
        TSplashFormTrial.Execute;
    
        Application.Title := 'myApplication TRIAL VERSION';
      {$ELSE}
        TSplashFormRelease.Execute;
    
        Application.Title := 'myApplication';
      {$ENDIF};
    
      Application.MainFormOnTaskbar := True;
      Application.CreateForm(TForm1, Form1);
      Application.Run;
    end.

    Depending on your active build configuration,
    either the TSplashFormTrial Execute (if TRIAL active) will get called
    or the one from TSplashFormRelease.

    Also, note that depending on the conditional symbol,
    only one of the two splash forms will actually be included in the final compiled application -
    as we are using conditional directives in the uses list also.

    WARNING: IDE Destroys Project's Code Containing Conditional Compilation!!

    Having conditional compilation in your project's unit - you need to be very careful.
    If you do something which would result in Delphi auto-maintaining the source code of the project's unit -
    your conditional directives will get messed up!

    For example: add one more unit (or form) to the project, the result is:

    program Project1;
    
    uses
      Forms,
      Unit1 in 'Unit1.pas' {Form1},
      SplashUnitRelease in 'SplashUnitRelease.pas' {SplashFormRelease},
      Unit2 in 'Unit2.pas';
    
    {$ENDIF}
    
    {$R *.res}
    ...

    The "SplashUnitTrial in 'SplashUnitTrial.pas' {SplashFormTrial};"
    is gone under the uses section. There's a leftover "{$ENDIF}".

    This problem will only happen to the uses section -
    not in-between the begin/end pair.

    Therefore, you should, again, manually fix this to:

    program Project1;
    
    uses
      Forms,
      Unit1 in 'Unit1.pas' {Form1},
      {$IFDEF TRIAL_VERSION}
      SplashUnitTrial in 'SplashUnitTrial.pas' {SplashFormTrial},
      {$ELSE}
      SplashUnitRelease in 'SplashUnitRelease.pas' {SplashFormRelease},
      {$ENDIF}
      Unit2 in 'Unit2.pas';
    
    {$R *.res}
    ...

    The last question is how to have a different exe name
    depending on the build configuration / conditional compilation
    .
    Answered on the next page...

    Now that you know how to have your own conditional symbols defined,
    to have Delphi's conditional compilation create different versions of your application,
    you might ask "
    how to change the exe name depending on the build configuration?"

    Yes, your IDE has the answer :)

    Please note that the name of the project's source unit (the DPR) defines
    what will be the name of the generated executable file.
    If your project is named "Project1", the executable will be named "Project1.exe".

    Since now you have a trial and a normal release build -
    you might want to create differently named executable files for your application.

    Build Events

    Take a look at the Project Options for your project.
    You should see a node named "Build Events".
    You can use the build events to create a list of events that occur
    in two stages of the build process:

    pre-build and post-build.

    The build, compile, and make commands available in the IDE
    call the new build engine from Microsoft:

    MSBuild.

    I will not go into many details, and will leave for you to explore MS Build :)

    So what the task was? To have a different name for the executable file
    when the "trial" build configuration is active!

    Where's the exe?
    First, note that the final executable file will, by design, created in a different -
    build configuration related folder.
    This is specified by the "Output Directory" option in the Project Options - Delphi Compiler.

    By design, the value is:

    .\$(Config)\$(Platform)
    

    This means that the "Project1.exe" will get generated inside the
    "\Release\Win32" folder (if running under Win32)
    when the "Release" build configuration is active.

    Our trial version is therefore generated in : "\Trial\Win32"

    Post-Build Event: Rename Exe

    Go to Project Options - Build Events and enter the following for the post-build command:

    IF $(Config) == TRIAL Move "$(OUTPUTDIR)$(OUTPUTFILENAME)" "$(OUTPUTDIR)$(OUTPUTNAME)_TRIAL_$(OUTPUTEXT)"
    

    The above msbuild commands will rename the generated executable file
    if the active build configuration is "trial".

    After building, the "Output" window will show:

    Target PreBuildEvent:
        echo TRIAL
        TRIAL
    Target _PasCoreCompile:
        c:\program files (x86)\embarcadero\rad studio\ ...
    Target PostBuildEvent:
        IF TRIAL == TRIAL  Move ".\TRIAL\Win32\Project1.exe" ".\TRIAL\Win32\Project1_TRIAL_.exe"
                1 file(s) moved.
    Build succeeded.
        0 Warning(s)
        0 Error(s)
    

    And that's it! Finally, all questions answered!! :)

    Note: the "download" section has the entire project available for download.

    http://delphi.about.com/library/code/conditional-compilation.zip

    Pre and Post-Build Automation in Delphi

    Extend the BDS IDE so that Pre-Build and
    Post-Build tasks can be automated

    http://delphi.about.com/od/devutilities/a/pre_post_build.htm

    This article describes a simple way to 
    extend the BDS IDE so that Pre-Build and Post-Build tasks
    can be automated without a single line of code.

    Why Pre or Post-Build?

    I’m trying to create my first shareware program in my free time.
    With that comes adding some security measures and so I chose Armadillo
    (now 
    SoftwarePassport). The way this protection works is
    by wrapping the program’s EXE which means it has to be done
    after building the main program.

    This protective wrapper needs to be in place even for development work,
    be that to test settings related to the protection itself or
    simply to avoid a large number of conditional defines to block code out.

    For the last few days I’ve been trying to automate the process
    which involves running a windows application with certain parameters.
    Because there is not much information on how to successfully accomplish this,
    I decided to write this article to share the workaround that I found to be very good,
    at least until Delphi gains a more customizable builder.

    The solution to Pre-Build and Post-Build in the BDS IDE

    The whole idea works around 2 concepts applied together: 

    using Build Tools and Project Groups.

    I’ll describe the process for the Post-Build situation in my particular case,
    but, by playing around with the build order, this can easily be adapted to Pre-Build too
    and you can even have several Pre and Post-Build tools being executed.

    Step-by-step instructions

    Let’s start by opening your project.

    1. Right-click on the Project Group and select "Add New Project…".
    2. Any type of project will do, I selected a console application and named it PostBuild,
      but again, any name will do. You can keep your project the Active one.
    3. Save all that and choose a proper name for the .bdsgroup file.
    4. Right-click on the PostBuild project in the project explorer
      and select "Dependencies": this is one of the most important steps
      because in here you can say that this project (PostBuild)
      depends on another one (your main project),
      so that it will always be built after your main one.

    Now for the tool configuration. In my particular case, I need to run the following command line:

     "C:\Program Files\SoftwarePassport\Armadillo.exe" "D:\Dev\My Prog\Prot.arm" /P 

    So, let’s do two things here:
    add the Prot.arm file to the Post-Build project and
    create a Build Tool to handle .arm files.

    The Build Tools dialog, or more specifically, the "Add…" sub-dialog,
    could use a bit more explanation in the help file
    but eventually I got it working as you might have guessed or
    I would not be writing this article!

    The key points in this dialog are:

    Title: Anything will do but using a descriptive title always helps

    Default Extensions: *.arm (this is for my case for the example command-line above)

    Command Line: This is the trickiest of them all, but after you get one working, they’re all easy.
    The trick here is not to use quotes on the program’s name
    but instead use the windows SFN (Short File Name).
    The reason is that, should you need to use quotes to enclose the path of your file,
    the IDE gets confused with too many quotes.
    So, these are the wrong ways of adding that command line above:

    C:\Program Files\SoftwarePassport\Armadillo.exe D:\Dev\My Prog\Prot.arm /P

    "C:\Program Files\SoftwarePassport\Armadillo.exe" D:\Dev\My Prog\Prot.arm /P

    C:\Program Files\SoftwarePassport\Armadillo.exe "D:\Dev\My Prog\Prot.arm" /P

    "C:\Program Files\SoftwarePassport\Armadillo.exe" "D:\Dev\My Prog\Prot.arm" /P

    This last one should work, if it were not for the IDE to be confused with it.
    So, what does work is either of these:

    C:\Progra~1\Softwa~1\Armadillo.exe "D:\Dev\My Prog\Prot.arm" /P

    C:\Progra~1\SoftwarePassport\Armadillo.exe "D:\Dev\My Prog\Prot.arm" /P

    The 1st one is a "true" SFN (if in doubt, run CMD.exe and do a dir /X "C:\";
    it's not critical that you use a "true SFN",
    the important thing is that no part of the full path + program name
    has spaces in it as you can see in the 2nd example,
    thus leaving the quotes available for use on the file name.
    Of course, we don’t want this exactly as it is as it would be hard coded.
    We can use some Macros to make it more generic,
    so here are the Add Build Tool contents for my case:

    Title: ArmProtect

    Default Extensions: *.arm

    Command Line: C:\Progra~1\SoftwarePassport\Armadillo.exe "$PATH$NAME" /P

    Using these Macros is also the reason why I used SFN on the program and not on the filename!
    In this case, "$PATH$NAME" gets expanded to "D:\Dev\My Prog\Prot.arm".

    Don't forget that this tool will only be used on the extensions indicated in this dialog.

    You can also, at any point in time, manually run this command by right-clicking
    any *.arm file on your project and selecting the tool from the menu.

    The final step to remember is to Build All Projects
    (you can give it a keyboard shortcut to make it easier to use and/or put it on your toolbar).

    Pre and Post-Build in Short

    1. Add a Post-Build "void" project to your project group;
    2. Right click that project, select Dependencies and make it depend on your main project
    3. Add the file you want to be processed after building your program to the PostBuild project
    4. Create a Build Tool to run the proper command-line and associate
      it with that file’s extension (don't forget about using SFN for the program name)
    5. Always load the .bdsgroup instead of the .bdsproj and use
      Project -> Build All Projects whenever you want the Pre/Post-Build to work.

    Final Notes

    You may need to exit and re-open the IDE for it to acknowledge changes to Build Tools,
    especially when you just added a new one.

    Adding a Pre-Build is also easy to achieve playing with the project’s dependencies:
    you will need to make your main project dependent on the PreBuild one.

    If you need to add some step that does not depend on any type of file,
    simply make up some extension (use 4 or more characters to avoid conflicts with existing extensions)
    and create a void file of that extension to associate with the Build Tool, for instance, "nothing.step1".

    If you want to customize the Build Current Project key to perform Build All Projects instead,
    take a look at the free GExperts Add-In.


  • 相关阅读:
    算法实现:在10个数中选6个数,显示所有组合
    转载:PostgreSQL和MySQL协议简介
    转载:国内外高精地图厂商一览
    使用带key访问iPortalREST服务
    cass启动提示Frame主框架程序没有加载
    设置Gridview单元格内容不换行
    Sql自定义编号唯一性问题
    关于EXCEL数据导入到SQLServer中字段存在NULL的问题
    Gridview显示网格线
    ComboBox自动匹配查找
  • 原文地址:https://www.cnblogs.com/shangdawei/p/3128110.html
Copyright © 2011-2022 走看看