Build system with our own NAnt tools and tasks

From OpenPetra Wiki
Jump to navigation Jump to search

Introduction

We have come quite a long way:

  • First, we had all our SharpDevelop projects committed in the source code revision system.
  • But then we often had problems with the references, and other developers prefered to use additional IDEs.
  • Another issue was that we wanted to control how the software is built, comparable both on Linux and on Windows.
  • One approach was to work recursively through the directory structure, and build directly from the sourcecode. This decreased the speed of the build.
  • The current approach is much faster, but still provides the flexibility we need. Project and solution files are generated really quickly, and we use msbuild or csc to build the assemblies.

The main NAnt tasks available

nant generateNamespaceMap

  • This is mainly based on our own nant task defined in inc\nanttasks\GenerateNamespaceMap.cs
  • It parses all directories for .cs files, and retrieves the namespaces defined in each file, and calculates the names of the assembly, that each file will belong to. The names of assemblies are based on the location in the directory tree. The result of this is stored in the file delivery\projects\namespace.map.
  • At the same time, the using namespace is evaluated of each file, which helps to create a map of dependencies. Also the type of the deliverable is determined, eg. exe, winexe or library, and the name of the executable. The result of this is stored in the file delivery\projects\project.map.
    • the name of the exe file is determined from the namespace of the file that contains the Main() function. The names of dlls cannot be specified by the namespace, they are exclusively built according to their location in the directory tree.

nant generateProjectFiles

  • This uses the project.map and the namespace.map that have been generated with nant generateNamespaceMap
  • it also uses the templates for the project and solution files defined in eg. inc/template/sharpdevelop4. The supported IDEs are defined in inc/nant/OpenPetra.common.xml in property projectfiles.templates-list; if you are only using SharpDevelop, there is no need to create project files and solution file(s) for Visual Studio and for monodevelop, too. By default, project files are generated for all three IDEs, but by using this property one specific IDE can be selected, which slightly speeds up the project and solution files generation.
    • Valid values for property projectfiles.templates-list:
      • sharpdevelop4 (for SharpDevelop 4 IDE format)
      • vs2010 (for Visual Studio 2010 IDE format)
      • monodevelop2 (for monodevelop2 IDE format)
    • Note: the solution and project files for SharpDevelop 4 will always be generated as they are needed for compilation!
  • the project GUIDs are generated and stored for reuse in delivery\projects\projectuuid.map
  • the solution file is written in the correct order, so the projects with the most dependencies are listed last.

nant minimalGenerateSolution

  • this will run create all the code and project files
  • this means you can open the solution and work in your IDE.
    • ie generateNamespaceMap, generateProjectFiles, generateTools, generateWinforms and generateORM are run

nant generateSolution

  • this will run create all the code and project files, and also compile the full project
  • this means that you can run nant startPetraServer startPetraClient

nant generateProjectFiles

  • this only works, if minimalGenerateSolution or generateSolution have been run once before, because it does not generate any code.
  • this will just recreate the namespace map and the project files.
  • this is useful to add new files to a project, or add a new project or reference.

How to create a new project

  • create a new directory, create a file inside, and run nant generateProjectFiles

How to add a file to a project

  • create a file in the directory of the project, and run nant generateProjectFiles

How to add a reference to a project

  • add the using clause to one file in that directory of your project, and run nant generateProjectFiles

How to add a new Third Party DLL

  • see the file csharp\ThirdParty\namespace.map
  • in that file, you need to define which namespaces are defined in that dll. You can use a star at the end of the namespace, that will include all namespaces below. You also specify the path to the third party DLL.
  • eg. Npgsql*=${dir.3rdParty}/Npgsql/Npgsql.dll
  • Don't forget to add a using clause to one file in a project that references the Third Party DLL. This is necessary in order for the generateSolution... tasks to include it as a Project Reference in that C# Project.

How to add a new standard .net dll

  • this is similar to the third party dlls, so also edit the file csharp\ThirdParty\namespace.map
  • in that file, you need to define which namespaces are defined in that dll. You can use a star at the end of the namespace, that will include all namespaces below. You also specify the name of the standard .net DLL.
  • the order is important, so first add the more specific, and then the wildcard version.
  • eg.
System.Drawing.Design*=${csharpStdLibs}/System.Drawing.Design.dll
System.Drawing*=${csharpStdLibs}/System.Drawing.dll
  • Don't forget to add a using clause to one file in a project that references the standard .net dll. This is necessary in order for the generateSolution... tasks to include it as a Project Reference in that C# Project.