Difference between revisions of "The build process of Code::Blocks"

From Code::Blocks
m (making headings)
 
(4 intermediate revisions by 3 users not shown)
Line 1: Line 1:
== The build order, projects and targets ==
+
[[Category:User Documentation]]
Code::Blocks has a strict build order. According to the project setup the targets of a project are build in the order from top to bottom (unless the build of a target is disabled in the options). Within the focus of a workspace the projects that belong to a workspace are usually build according to the target that has been selected.
 
Let's assume all projects in a workspace have the targets "Debug" and "Release". Furthermore the checkbox "Build this target with all" in each project's target options is enabled for all "Release" targets. Thus if as build target "Debug" is selected, all "Debug" targets of all projects will be build in the order as they appear. If a project has no "Debug" target it will be skipped.
 
The same applied to the "Release" target. If "All" is selected this would be the same in this example because we had enabled "Build this target with all" only for the "Release" targets. If we had enabled this checkbox for the "Debug" targets, too then build "All" would build both, the "Debug" and the "Release" targets of each project.
 
Please notice that you are not limited to this kind of target. Another target philosophy could be additional libraries that are required to complete the build process of a project. But the libraries could also be setup as own project within a workspace.
 
  
== Dependencies between projects ==
+
In this page, the build process is explained in detail. What goes on behind the scenes and "when" is covered. I hope it makes an interesting read :).
Now we had said that the build order for projects is as they appear in the workspace. This is generally true unless you setup project dependencies. A project dependency can be setup in project options. You simply select for a project on which other projects it depends. Thus imagine in your workspace you have a library project and an executable project which depends on the library. Then you could (and should) enable the dependency checkbox in the project options of the executable project.
 
Please notice that this information is saved within the workspace file, not the project file as it is a dependency between two projects within a workspace.
 
This in addition changes the order of how your projects are build. It was said that the general order is from top to bottom (for the selected target(s)). With dependencies this might change. If your executable project is at the top and the library at the bottom and the executable has been setup to depend on the library then first the library will be build and second the executable.
 
  
== Starting the build process ==
 
Before the actual build process starts (i.e. the compiler/linker commands start executing), a preprocessing step runs which generates all required command-lines. This step is necessary because it also caches much information making subsequent builds faster.
 
  
== Using build scripts ==
+
= Build order =
Another way to influence the build process are build scripts that can be attached on project- and target-level within the project setup. These scripts are in Squirrel and have defined entry points that are required to be implemented. The build scripts run in the preprocessing step mentioned before. Build scripts usually alter project/target options which are then added to the command line (in this step).
+
As you have probably guessed, Code::Blocks does not launch build commands at random but rather as a well thought out and prepared sequence. But first let's see what components are the subject of the build:
  
== Using pre- and post build steps ==
+
* '''Workspace''': contains one or more projects
When this is done, Code::Blocks starts to actually execute build commands including so-called pre- and post-build steps. These commands that again can be setup on project- and target level. This could be scripts (or batch files if you prefer Windows) that e.g. copy files or any other operation you can do with a usual OS system script. So the command line has been computed, now the pre-build steps are executed, then the command line (the actual compile step) executes, after that the post-build steps are executed.
+
* '''Project''': contains one or more build targets. It also contains the project's files.
This happens for each file within each target and each projects whose compilation has been requested.
+
* '''Build target''': project files are assigned to it, which are built as a group and generate one binary output. This output can either be an executable, a dynamic library or a static library. ''NOTE: there is one kind of build target that does not produce a binary output directly but rather just runs its pre/post build steps (which may generate a binary output externally).''
 +
 
 +
Let's break these subjects in sections and explain them in more detail.
 +
 
 +
 
 +
== Workspace ==
 +
The workspace is the top-level container item for organizing your projects. Since there can be only one workspace open at a time, there really is no build order issue for them. It's only one, so it's just built ;).
 +
 
 +
Use the menu "Build->Build workspace" to build a workspace (i.e. all the projects contained in it).
 +
 
 +
 
 +
== Projects ==
 +
Here, things start getting interesting :).
 +
 
 +
Projects build order is different depending if the user has set project dependencies or not. Please read on.
 +
 
 +
 
 +
=== Without project dependencies ===
 +
In this case, projects are built in the order of appearence, from top to bottom.
 +
Most projects though (at least not the "hello world" ones), would want to setup project dependencies.
 +
 
 +
 
 +
=== Using project dependencies ===
 +
Project dependencies are a simple way to tell Code::Blocks that a given project "depends" on another (in the same workspace, always).
 +
 
 +
Thus imagine in your workspace you have a library project and an executable project which depends on the library. Then you could (and should) tell Code::Blocks about this dependency. To do this, you select "Project->Properties" and click the "Project's dependencies.." button.
 +
 
 +
''Please notice that the dependency information is saved within the workspace file, not the project file as it is a dependency between two projects within a workspace.''
 +
 
 +
 
 +
[[Image:Project_deps.png|frame|Setting up project dependencies]]
 +
 
 +
It is very easy to use this dialog. Select the project you want to add a dependency and then put a checkmark on all projects that this project depends on. This will ensure that all the projects you checked will be built before the project that depends on them, ensuring a synchronized build.
 +
 
 +
 
 +
'''Tip:''' You don't have to close this dialog and launch the other project's properties again to set their dependencies. You can set all projects dependencies from this same dialog. Just select a different project in the drop-down box :).
 +
 
 +
 
 +
Some things to note:
 +
* Dependencies are set directly or indirectly. If project A depends directly on project B and project B depends on project C, then project A indirectly depends on project C too.
 +
* Code::Blocks is smart enough to watch out for circular dependencies and prohibit them. A circular dependency is caused when project A depends directly or indirectly on project B and project B depends directly or indirectly on project A.
 +
* Dependencies take effect either if building the whole workspace or a single project. In this case, only the dependencies needed for the project you 're building will be built too.
 +
 
 +
 
 +
== Build targets ==
 +
Build targets build order depend on a couple of things.
 +
# If the user has selected a specific build target in the compiler toolbar's drop-down box, then only this build target is built. If project dependencies are setup for the project containing this target, all projects it depends on will also build their target with the same name. If no such target exists, that project is skipped.
 +
# If the virtual "All" target is selected, then all targets in the project (and all the projects it depends on) are built in order, top to bottom. There are a couple of exceptions to this:
 +
#* A target is not built with "All" if the target option (in project properties "Targets" page) "Build this target with All" is not selected.
 +
#* If no targets in the project have the above option selected, then no virtual "All" target appears in the list.
 +
 
 +
 
 +
 
 +
= Preprocessing phase =
 +
Before the actual build process starts (i.e. the compiler/linker commands start executing), a preprocessing step runs which generates all required command-lines for the entire build process.
 +
This step caches much of the information it generates, making subsequent builds faster in effect.
 +
 
 +
This step also runs any attached [[build scripts]].
 +
 
 +
 
 +
 
 +
= Actual commands execution =
 +
This is the stage that the build process actually starts, from the user's point of view. The files start getting compiled and finally linked to generate the various binary outputs the build targets define.
 +
 
 +
In this step, the pre-build and post-build steps are also executed.
 +
 
 +
 
 +
== Pre-build and post-build steps ==
 +
These are commands that can be setup on project and/or target level. They are shell commands that e.g. copy files around or any other operation you can do with a usual OS system shell.
 +
 
 +
The variables specified in the article [[Variable expansion]] can be used in the scripts to get things like target output directory, project directory, target type and others.
 +
 
 +
Here's a breakdown of the pre/post build steps execution order for an imaginary project with two targets (Debug/Release):
 +
 
 +
# Project pre-build steps
 +
## Target "Debug" pre-build steps
 +
## Target "Debug" compile files
 +
## Target "Debug" link files and generate binary output
 +
## Target "Debug" post-build steps (see notes below)
 +
## Target "Release" pre-build steps
 +
## Target "Release" compile files
 +
## Target "Release" link files and generate binary output
 +
## Target "Release" post-build steps (see notes below)
 +
# Project post-build steps
 +
 
 +
I hope this is self-explaining :)
 +
 
 +
''NOTE: Pre-build steps are always ran. Post-build steps will run only if the project/target they 're attached to is not up-to-date (i.e. is going to be built). You can change this by selecting "Always execute, even if target is up to date" in the build options.''
 +
 
 +
=== Script Samples ===
 +
Post-build script that copies the output file into the folder "C:\Program\bin" in Windows:
 +
cmd /c copy "$(PROJECT_DIR)$(TARGET_OUTPUT_FILE)" "C:\Program\bin"
 +
 
 +
Execute the bash script "copyresources.sh" in Linux:
 +
/bin/sh copyresources.sh
 +
 
 +
Create a new directory in the output directory:
 +
mkdir $(TARGET_OUTPUT_DIR)/data
 +
 
 +
 
 +
Original article by MortenMacFly
 +
 
 +
[[User:Mandrav|Mandrav]] 04:42, 14 July 2006 (EDT)
 +
 
 +
[[User:Elzorro|Elzorro]] 23:19, 4 August 2008 (CEST)

Latest revision as of 21:19, 4 August 2008


In this page, the build process is explained in detail. What goes on behind the scenes and "when" is covered. I hope it makes an interesting read :).


Build order

As you have probably guessed, Code::Blocks does not launch build commands at random but rather as a well thought out and prepared sequence. But first let's see what components are the subject of the build:

  • Workspace: contains one or more projects
  • Project: contains one or more build targets. It also contains the project's files.
  • Build target: project files are assigned to it, which are built as a group and generate one binary output. This output can either be an executable, a dynamic library or a static library. NOTE: there is one kind of build target that does not produce a binary output directly but rather just runs its pre/post build steps (which may generate a binary output externally).

Let's break these subjects in sections and explain them in more detail.


Workspace

The workspace is the top-level container item for organizing your projects. Since there can be only one workspace open at a time, there really is no build order issue for them. It's only one, so it's just built ;).

Use the menu "Build->Build workspace" to build a workspace (i.e. all the projects contained in it).


Projects

Here, things start getting interesting :).

Projects build order is different depending if the user has set project dependencies or not. Please read on.


Without project dependencies

In this case, projects are built in the order of appearence, from top to bottom. Most projects though (at least not the "hello world" ones), would want to setup project dependencies.


Using project dependencies

Project dependencies are a simple way to tell Code::Blocks that a given project "depends" on another (in the same workspace, always).

Thus imagine in your workspace you have a library project and an executable project which depends on the library. Then you could (and should) tell Code::Blocks about this dependency. To do this, you select "Project->Properties" and click the "Project's dependencies.." button.

Please notice that the dependency information is saved within the workspace file, not the project file as it is a dependency between two projects within a workspace.


Setting up project dependencies

It is very easy to use this dialog. Select the project you want to add a dependency and then put a checkmark on all projects that this project depends on. This will ensure that all the projects you checked will be built before the project that depends on them, ensuring a synchronized build.


Tip: You don't have to close this dialog and launch the other project's properties again to set their dependencies. You can set all projects dependencies from this same dialog. Just select a different project in the drop-down box :).


Some things to note:

  • Dependencies are set directly or indirectly. If project A depends directly on project B and project B depends on project C, then project A indirectly depends on project C too.
  • Code::Blocks is smart enough to watch out for circular dependencies and prohibit them. A circular dependency is caused when project A depends directly or indirectly on project B and project B depends directly or indirectly on project A.
  • Dependencies take effect either if building the whole workspace or a single project. In this case, only the dependencies needed for the project you 're building will be built too.


Build targets

Build targets build order depend on a couple of things.

  1. If the user has selected a specific build target in the compiler toolbar's drop-down box, then only this build target is built. If project dependencies are setup for the project containing this target, all projects it depends on will also build their target with the same name. If no such target exists, that project is skipped.
  2. If the virtual "All" target is selected, then all targets in the project (and all the projects it depends on) are built in order, top to bottom. There are a couple of exceptions to this:
    • A target is not built with "All" if the target option (in project properties "Targets" page) "Build this target with All" is not selected.
    • If no targets in the project have the above option selected, then no virtual "All" target appears in the list.


Preprocessing phase

Before the actual build process starts (i.e. the compiler/linker commands start executing), a preprocessing step runs which generates all required command-lines for the entire build process. This step caches much of the information it generates, making subsequent builds faster in effect.

This step also runs any attached build scripts.


Actual commands execution

This is the stage that the build process actually starts, from the user's point of view. The files start getting compiled and finally linked to generate the various binary outputs the build targets define.

In this step, the pre-build and post-build steps are also executed.


Pre-build and post-build steps

These are commands that can be setup on project and/or target level. They are shell commands that e.g. copy files around or any other operation you can do with a usual OS system shell.

The variables specified in the article Variable expansion can be used in the scripts to get things like target output directory, project directory, target type and others.

Here's a breakdown of the pre/post build steps execution order for an imaginary project with two targets (Debug/Release):

  1. Project pre-build steps
    1. Target "Debug" pre-build steps
    2. Target "Debug" compile files
    3. Target "Debug" link files and generate binary output
    4. Target "Debug" post-build steps (see notes below)
    5. Target "Release" pre-build steps
    6. Target "Release" compile files
    7. Target "Release" link files and generate binary output
    8. Target "Release" post-build steps (see notes below)
  2. Project post-build steps

I hope this is self-explaining :)

NOTE: Pre-build steps are always ran. Post-build steps will run only if the project/target they 're attached to is not up-to-date (i.e. is going to be built). You can change this by selecting "Always execute, even if target is up to date" in the build options.

Script Samples

Post-build script that copies the output file into the folder "C:\Program\bin" in Windows:

cmd /c copy "$(PROJECT_DIR)$(TARGET_OUTPUT_FILE)" "C:\Program\bin"

Execute the bash script "copyresources.sh" in Linux:

/bin/sh copyresources.sh

Create a new directory in the output directory:

mkdir $(TARGET_OUTPUT_DIR)/data


Original article by MortenMacFly

Mandrav 04:42, 14 July 2006 (EDT)

Elzorro 23:19, 4 August 2008 (CEST)