Make build information accessible by programs by extracting data from the local git repository (or a standalone file if a git repository is not present).
Changes * Adds a new class named Version to the core module * Adds a template file to the core module named version-defines.h.in * Adds --PrintVersion and --version arguments to the CommandLine class. * Creates a new waf tool which queries the local git repository and extracts build information from itCreate a waf task to extract version information from git repository
This commit is contained in:
committed by
Peter Barnes
parent
e752b2e937
commit
32e95f8228
2
.gitignore
vendored
2
.gitignore
vendored
@@ -36,3 +36,5 @@ build-dir/
|
||||
build/
|
||||
/.cproject
|
||||
/.project
|
||||
|
||||
version.cache
|
||||
|
||||
@@ -1155,3 +1155,106 @@ except that the program and ns-3 libraries will not be rebuilt.
|
||||
.. sourcecode:: bash
|
||||
|
||||
$ ./waf --run-no-build '<ns3-program> --arg1=value1 --arg2=value2 ...'
|
||||
|
||||
Build version
|
||||
+++++++++++++
|
||||
|
||||
As of the ns-3.32 release, a new Waf option was introduced to print out the
|
||||
version of the ns-3 build
|
||||
|
||||
.. sourcecode:: bash
|
||||
|
||||
$ ./waf --check-version
|
||||
|
||||
Waf will collect information about the build and print out something similar
|
||||
to the output below.
|
||||
|
||||
.. sourcecode:: text
|
||||
|
||||
ns-3.31+26@g82e7f5d-debug
|
||||
|
||||
The output of ``--check-version`` depends on how ns-3 was installed. If ns-3
|
||||
was installed from a tarball, the build information is included in one
|
||||
of the files in the tarball. In this case, the output of ``--check-version``
|
||||
will always be the same, except for the profile value which is based
|
||||
on the ``--build-profile`` option passed to ``waf configure``.
|
||||
|
||||
If ns-3 was downloaded using git, the build information is generated by
|
||||
examining the current state of the git repository. The output of
|
||||
``--check-version`` will change whenever the state of the active branch
|
||||
changes.
|
||||
|
||||
The output of ``--check-version`` has the following format:
|
||||
|
||||
.. sourcecode:: text
|
||||
|
||||
<version_tag>[+closest_tag][+distance_from_tag]@<commit_hash>[-tree_state]-<profile>
|
||||
|
||||
version_tag
|
||||
version_tag contains the version of the ns-3 code. The version tag is
|
||||
defined as a git tag with the format ns-3*. If multiple git tags match the
|
||||
format, the tag on the active branch which is closest to the current commit
|
||||
is chosen.
|
||||
|
||||
closest_tag
|
||||
closest_tag is similar to version_tag except it is the first tag found,
|
||||
regardless of format. The closest tag is not included in the output when
|
||||
closest_tag and version_tag have the same value.
|
||||
|
||||
distance_from_tag
|
||||
distance_from_tag contains the number of commits between the current commit
|
||||
and closest_tag. distance_from_tag is not included in the output when the
|
||||
value is 0 (i.e. when closest_tag points to the current commit)
|
||||
|
||||
commit_hash
|
||||
commit_hash is the hash of the commit at the tip of the active branch. The
|
||||
value is 'g' followed by the first 7 characters of the commit hash. The 'g'
|
||||
prefix is used to indicate that this is a git hash.
|
||||
|
||||
tree_state
|
||||
tree_state indicates the state of the working tree. When the working tree
|
||||
has uncommitted changes this field has the value 'dirty'. The tree state is
|
||||
not included in the version output when the working tree is clean (e.g. when
|
||||
there are no uncommitted changes).
|
||||
|
||||
profile
|
||||
The build profile specified in the ``--build-profile`` option passed to
|
||||
``waf configure``
|
||||
|
||||
A new class, named Version, has been added to the core module. The Version class
|
||||
contains functions to retrieve individual fields of the build version as well
|
||||
as functions to print the full build version like ``--check-version``.
|
||||
The ``build-version-example`` application provides an example of how to use
|
||||
the Version class to retrieve the various build version fields. See the
|
||||
documentation for the Version class for specifics on the output of the Version
|
||||
class functions.
|
||||
|
||||
.. sourcecode:: text
|
||||
|
||||
build-version-example:
|
||||
Program Version (according to CommandLine): ns-3.31+28@gce1eb40-dirty-debug
|
||||
|
||||
Version fields:
|
||||
LongVersion: ns-3.32+28@gcefeb91-dirty-debug
|
||||
ShortVersion: ns-3.32+*
|
||||
BuildSummary: ns-3.32+*
|
||||
VersionTag: ns-3.32
|
||||
Major: 3
|
||||
Minor: 32
|
||||
Patch: 0
|
||||
ReleaseCandidate:
|
||||
ClosestAncestorTag: ns-3.32
|
||||
TagDistance: 28
|
||||
CommitHash: gce1eb40
|
||||
BuildProfile: debug
|
||||
WorkingTree: dirty
|
||||
|
||||
The CommandLine class has also been updated to support the ``--version``
|
||||
option which will print the full build version and exit.
|
||||
|
||||
.. sourcecode:: text
|
||||
|
||||
./waf --run-no-build "command-line-example --version"
|
||||
Waf: Entering directory `/g/g14/mdb/gitlab/mdb/ns-3-dev/build/debug'
|
||||
ns-3.31+28@gce1eb40-dirty-debug
|
||||
|
||||
|
||||
71
src/core/examples/build-version-example.cc
Normal file
71
src/core/examples/build-version-example.cc
Normal file
@@ -0,0 +1,71 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2018 Lawrence Livermore National Laboratory
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Peter D. Barnes, Jr. <pdbarnes@llnl.gov>
|
||||
*/
|
||||
|
||||
#include "ns3/command-line.h"
|
||||
#include "ns3/version.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <string>
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \ingroup core-examples
|
||||
* Example program illustrating use of ns3::Version.
|
||||
*/
|
||||
|
||||
using namespace ns3;
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
|
||||
CommandLine cmd (__FILE__);
|
||||
cmd.Usage ("Version class example program.\n"
|
||||
"\n"
|
||||
"This program demonstrates the various outputs from the Version class");
|
||||
cmd.Parse (argc, argv);
|
||||
|
||||
std::cout << std::endl;
|
||||
std::cout << cmd.GetName () << ":" << std::endl;
|
||||
|
||||
//Print the source version used to build this example
|
||||
std::cout << "Program Version (according to CommandLine): ";
|
||||
cmd.PrintVersion (std::cout);
|
||||
std::cout << std::endl;
|
||||
|
||||
Version version;
|
||||
std::cout << "Version fields:\n"
|
||||
<< "LongVersion: " << version.LongVersion () << "\n"
|
||||
<< "ShortVersion: " << version.ShortVersion () << "\n"
|
||||
<< "BuildSummary: " << version.BuildSummary () << "\n"
|
||||
<< "VersionTag: " << version.VersionTag () << "\n"
|
||||
<< "Major: " << version.Major () << "\n"
|
||||
<< "Minor: " << version.Minor () << "\n"
|
||||
<< "Patch: " << version.Patch () << "\n"
|
||||
<< "ReleaseCandidate: " << version.ReleaseCandidate () << "\n"
|
||||
<< "ClosestAncestorTag: " << version.ClosestAncestorTag () << "\n"
|
||||
<< "TagDistance: " << version.TagDistance () << "\n"
|
||||
<< "CommitHash: " << version.CommitHash () << "\n"
|
||||
<< "BuildProfile: " << version.BuildProfile () << "\n"
|
||||
<< "WorkingTree: " << (version.DirtyWorkingTree () ? "dirty" : "clean")
|
||||
<< std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -28,7 +28,7 @@
|
||||
* \file
|
||||
* \ingroup core-examples
|
||||
* \ingroup commandline
|
||||
* \brief Example program illustrating use of ns3::CommandLine.
|
||||
* Example program illustrating use of ns3::CommandLine.
|
||||
*/
|
||||
|
||||
using namespace ns3;
|
||||
@@ -104,7 +104,13 @@ int main (int argc, char *argv[])
|
||||
|
||||
// Show initial values:
|
||||
std::cout << std::endl;
|
||||
std::cout << cmd.GetName () << std::endl;
|
||||
std::cout << cmd.GetName () << ":" << std::endl;
|
||||
|
||||
//Print the source version used to build this example
|
||||
std::cout << "Program Version: ";
|
||||
cmd.PrintVersion (std::cout);
|
||||
std::cout << std::endl;
|
||||
|
||||
std::cout << "Initial values:" << std::endl;
|
||||
|
||||
std::cout << std::left << std::setw (10) << "intArg:"
|
||||
|
||||
@@ -51,6 +51,10 @@ def build(bld):
|
||||
['core'])
|
||||
obj.source = 'system-path-examples.cc'
|
||||
|
||||
obj = bld.create_ns3_program('build-version-example',
|
||||
['core'])
|
||||
obj.source = 'build-version-example.cc'
|
||||
|
||||
if bld.env['ENABLE_THREADING'] and bld.env["ENABLE_REAL_TIME"]:
|
||||
obj = bld.create_ns3_program('main-test-sync', ['network'])
|
||||
obj.source = 'main-test-sync.cc'
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "system-path.h"
|
||||
#include "type-id.h"
|
||||
#include "string.h"
|
||||
#include "version.h"
|
||||
|
||||
#include <algorithm> // transform
|
||||
#include <cctype> // tolower
|
||||
@@ -328,11 +329,23 @@ CommandLine::PrintHelp (std::ostream &os) const
|
||||
<< " --PrintGroup=[group]: Print all TypeIds of group.\n"
|
||||
<< " --PrintTypeIds: Print all TypeIds.\n"
|
||||
<< " --PrintAttributes=[typeid]: Print all attributes of typeid.\n"
|
||||
<< " --PrintVersion: Print the ns-3 version.\n"
|
||||
<< " --PrintHelp: Print this help message.\n"
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
#include <unistd.h> // getcwd
|
||||
std::string
|
||||
CommandLine::GetVersion () const
|
||||
{
|
||||
return Version::LongVersion ();
|
||||
}
|
||||
|
||||
void
|
||||
CommandLine::PrintVersion (std::ostream & os) const
|
||||
{
|
||||
os << GetVersion () << std::endl;
|
||||
}
|
||||
|
||||
void
|
||||
CommandLine::PrintDoxygenUsage (void) const
|
||||
@@ -577,6 +590,12 @@ CommandLine::HandleArgument (const std::string &name, const std::string &value)
|
||||
PrintHelp (std::cout);
|
||||
std::exit (0);
|
||||
}
|
||||
if (name == "PrintVersion" || name == "version")
|
||||
{
|
||||
//Print the version, then exit the program
|
||||
PrintVersion (std::cout);
|
||||
std::exit (0);
|
||||
}
|
||||
else if (name == "PrintGroups")
|
||||
{
|
||||
// method below never returns.
|
||||
|
||||
@@ -64,9 +64,12 @@ namespace ns3 {
|
||||
--PrintGroup=[group]: Print all TypeIds of group.
|
||||
--PrintTypeIds: Print all TypeIds.
|
||||
--PrintAttributes=[typeid]: Print all attributes of typeid.
|
||||
--PrintVersion: Print the ns-3 version.
|
||||
--PrintHelp: Print this help message. \endverbatim
|
||||
*
|
||||
* The more common \c --help is a synonym for \c --PrintHelp; an example
|
||||
* The more common \c \--version is a synonym for \c \--PrintVersion.
|
||||
*
|
||||
* The more common \c \--help is a synonym for \c \--PrintHelp; an example
|
||||
* is given below.
|
||||
*
|
||||
* CommandLine can also handle non-option arguments
|
||||
@@ -82,7 +85,7 @@ namespace ns3 {
|
||||
* In use, arguments are given in the form
|
||||
* \verbatim
|
||||
--arg=value --toggle first-non-option\endverbatim
|
||||
* Most arguments expect a value, as in the first form, \c --arg=value.
|
||||
* Most arguments expect a value, as in the first form, \c \--arg=value.
|
||||
* Toggles, corresponding to boolean arguments, can be given in any of
|
||||
* the forms
|
||||
* \verbatim
|
||||
@@ -98,28 +101,29 @@ namespace ns3 {
|
||||
* will be the final value used. For example,
|
||||
* \verbatim
|
||||
--arg=one --toggle=f --arg=another --toggle \endverbatim
|
||||
* The variable set by \c --arg will end up with the value \c "another";
|
||||
* the boolean set by \c --toggle will end up as \c true.
|
||||
* The variable set by \c \--arg will end up with the value \c "another";
|
||||
* the boolean set by \c \--toggle will end up as \c true.
|
||||
*
|
||||
* Because arguments can be repeated it can be hard to decipher what
|
||||
* value each variable ended up with, especially when using boolean toggles.
|
||||
* Suggested best practice is for scripts to report the values of all items
|
||||
* settable through CommandLine, as done by the example below.
|
||||
*
|
||||
*
|
||||
* CommandLine can set the initial value of every attribute in the system
|
||||
* with the \c --TypeIdName::AttributeName=value syntax, for example
|
||||
* with the \c \--TypeIdName::AttributeName=value syntax, for example
|
||||
* \verbatim
|
||||
--Application::StartTime=3s \endverbatim
|
||||
* In some cases you may want to highlight the use of a particular
|
||||
* attribute for a simulation script. For example, you might want
|
||||
* to make it easy to set the \c Application::StartTime using
|
||||
* the argument \c --start, and have its help string show as part
|
||||
* the argument \c \--start, and have its help string show as part
|
||||
* of the help message. This can be done using the
|
||||
* \link AddValue(const std::string&, const std::string&) AddValue (name, attributePath) \endlink
|
||||
* method.
|
||||
*
|
||||
* CommandLine can also set the value of every GlobalValue
|
||||
* in the system with the \c --GlobalValueName=value syntax, for example
|
||||
* in the system with the \c \--GlobalValueName=value syntax, for example
|
||||
* \verbatim
|
||||
--SchedulerType=HeapScheduler \endverbatim
|
||||
*
|
||||
@@ -182,6 +186,7 @@ namespace ns3 {
|
||||
--PrintGroup=[group]: Print all TypeIds of group.
|
||||
--PrintTypeIds: Print all TypeIds.
|
||||
--PrintAttributes=[typeid]: Print all attributes of typeid.
|
||||
--PrintVersion: Print the ns-3 version.
|
||||
--PrintHelp: Print this help message. \endverbatim
|
||||
*
|
||||
* Having parsed the arguments, some programs will need to perform
|
||||
@@ -253,7 +258,7 @@ public:
|
||||
/**
|
||||
* Supply the program usage and documentation.
|
||||
*
|
||||
* \param [in] usage Program usage message to write with \c --help.
|
||||
* \param [in] usage Program usage message to write with \c \--help.
|
||||
*/
|
||||
void Usage (const std::string usage);
|
||||
|
||||
@@ -261,7 +266,7 @@ public:
|
||||
* Add a program argument, assigning to POD
|
||||
*
|
||||
* \param [in] name The name of the program-supplied argument
|
||||
* \param [in] help The help text used by \c \-\-PrintHelp
|
||||
* \param [in] help The help text used by \c \--PrintHelp
|
||||
* \param [out] value A reference to the variable where the
|
||||
* value parsed will be stored (if no value
|
||||
* is parsed, this variable is not modified).
|
||||
@@ -283,7 +288,7 @@ public:
|
||||
* Add a program argument, using a Callback to parse the value
|
||||
*
|
||||
* \param [in] name The name of the program-supplied argument
|
||||
* \param [in] help The help text used by \c --help
|
||||
* \param [in] help The help text used by \c \--help
|
||||
* \param [in] callback A Callback function that will be invoked to parse and
|
||||
* store the value.
|
||||
* \param [in] defaultValue Optional default value for argument.
|
||||
@@ -310,7 +315,7 @@ public:
|
||||
* Add a non-option argument, assigning to POD
|
||||
*
|
||||
* \param [in] name The name of the program-supplied argument
|
||||
* \param [in] help The help text used by \c \-\-PrintHelp
|
||||
* \param [in] help The help text used by \c \--PrintHelp
|
||||
* \param [out] value A reference to the variable where the
|
||||
* value parsed will be stored (if no value
|
||||
* is parsed, this variable is not modified).
|
||||
@@ -378,7 +383,7 @@ public:
|
||||
/**
|
||||
* \brief Print program usage to the desired output stream
|
||||
*
|
||||
* Handler for \c \-\-PrintHelp and \c \-\-help: print Usage(), argument names, and help strings
|
||||
* Handler for \c \--PrintHelp and \c \--help: print Usage(), argument names, and help strings
|
||||
*
|
||||
* Alternatively, an overloaded operator << can be used:
|
||||
* \code
|
||||
@@ -393,6 +398,22 @@ public:
|
||||
*/
|
||||
void PrintHelp (std::ostream &os) const;
|
||||
|
||||
/**
|
||||
* Get the program version.
|
||||
*
|
||||
* \return The program version
|
||||
*/
|
||||
std::string GetVersion () const;
|
||||
|
||||
/**
|
||||
* Print ns-3 version to the desired output stream
|
||||
*
|
||||
* Handler for \c \--PrintVersion and \c \--version.
|
||||
*
|
||||
* \param [in,out] os The output stream to print on.
|
||||
*/
|
||||
void PrintVersion (std::ostream &os) const;
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
@@ -402,7 +423,7 @@ private:
|
||||
class Item
|
||||
{
|
||||
public:
|
||||
std::string m_name; /**< Argument label: \c \-\--m_name=... */
|
||||
std::string m_name; /**< Argument label: \c \--m_name=... */
|
||||
std::string m_help; /**< Argument help string */
|
||||
virtual ~Item (); /**< Destructor */
|
||||
/**
|
||||
@@ -511,32 +532,32 @@ private:
|
||||
static bool HandleAttribute (const std::string name, const std::string value);
|
||||
|
||||
/**
|
||||
* Handler for \c \-\-PrintGlobals: print all global variables and values
|
||||
* Handler for \c \--PrintGlobals: print all global variables and values
|
||||
* \param [in,out] os The output stream to print on.
|
||||
*/
|
||||
void PrintGlobals (std::ostream &os) const;
|
||||
/**
|
||||
* Handler for \c \-\-PrintAttributes: print the attributes for a given type.
|
||||
* Handler for \c \--PrintAttributes: print the attributes for a given type.
|
||||
*
|
||||
* \param [in,out] os the output stream.
|
||||
* \param [in] type The TypeId whose Attributes should be displayed
|
||||
*/
|
||||
void PrintAttributes (std::ostream &os, const std::string &type) const;
|
||||
/**
|
||||
* Handler for \c \-\-PrintGroup: print all types belonging to a given group.
|
||||
* Handler for \c \--PrintGroup: print all types belonging to a given group.
|
||||
*
|
||||
* \param [in,out] os The output stream.
|
||||
* \param [in] group The name of the TypeId group to display
|
||||
*/
|
||||
void PrintGroup (std::ostream &os, const std::string &group) const;
|
||||
/**
|
||||
* Handler for \c \-\-PrintTypeIds: print all TypeId names.
|
||||
* Handler for \c \--PrintTypeIds: print all TypeId names.
|
||||
*
|
||||
* \param [in,out] os The output stream.
|
||||
*/
|
||||
void PrintTypeIds (std::ostream &os) const;
|
||||
/**
|
||||
* Handler for \c \-\-PrintGroups: print all TypeId group names
|
||||
* Handler for \c \--PrintGroups: print all TypeId group names
|
||||
*
|
||||
* \param [in,out] os The output stream.
|
||||
*/
|
||||
|
||||
145
src/core/model/version-defines.h.in
Normal file
145
src/core/model/version-defines.h.in
Normal file
@@ -0,0 +1,145 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2018 Lawrence Livermore National Laboratory
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors: Mathew Bielejeski <bielejeski1@llnl.gov>
|
||||
*/
|
||||
|
||||
#ifndef NS3_VERSION_DEFINES_H_
|
||||
#define NS3_VERSION_DEFINES_H_
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \ingroup buildversion
|
||||
* Defines the macro values for printing the build version.
|
||||
* These will be populated by the build system.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \ingroup buildversion
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* The first tag found which matches the pattern ns-3*.
|
||||
*
|
||||
* The expected format of the ns-3 version tag is: ns-3.<minor>[.patch][-release_candidate]
|
||||
*
|
||||
* The tag is found by starting at the tip of the current branch and walking
|
||||
* back towards the root.
|
||||
*
|
||||
* Type: string literal
|
||||
*/
|
||||
#define NS3_VERSION_TAG @VERSION_TAG@
|
||||
|
||||
/**
|
||||
* The tag closest to the tip of the current branch
|
||||
*
|
||||
* The tag is found by starting at the tip of the current branch and
|
||||
* walking back towards the root.
|
||||
*
|
||||
* This value will be the same as #NS3_VERSION_TAG when #NS3_VERSION_TAG is
|
||||
* the closest tag.
|
||||
*
|
||||
* Type: string literal
|
||||
*/
|
||||
#define NS3_VERSION_CLOSEST_TAG @CLOSEST_TAG@
|
||||
|
||||
/**
|
||||
* The major version extracted from #NS3_VERSION_TAG
|
||||
*
|
||||
* For a tag with the format ns-<digit>.<digit>[.digit], the major
|
||||
* version is the number after ns- and before the first period.
|
||||
*
|
||||
* Type: integer
|
||||
*/
|
||||
#define NS3_VERSION_MAJOR @VERSION_MAJOR@
|
||||
|
||||
/**
|
||||
* The minor version extracted from #NS3_VERSION_TAG
|
||||
*
|
||||
* For a tag with the format ns-<digit>.<digit>[.digit], the minor
|
||||
* version is the number after the first period.
|
||||
*
|
||||
* Type: integer
|
||||
*/
|
||||
#define NS3_VERSION_MINOR @VERSION_MINOR@
|
||||
|
||||
/**
|
||||
* The patch number extracted from #NS3_VERSION_TAG
|
||||
*
|
||||
* For a tag with the format ns-<digit>.<digit>[.digit], the patch
|
||||
* is the number after the last period.
|
||||
*
|
||||
* The patch value is optional and may not be present in the tag.
|
||||
* In cases where the patch value is not present, the field will be set to 0
|
||||
*
|
||||
* Type: integer
|
||||
*/
|
||||
#define NS3_VERSION_PATCH @VERSION_PATCH@
|
||||
|
||||
/**
|
||||
* The portion of the #NS3_VERSION_TAG indicating the version
|
||||
* of the release candidate (if applicable).
|
||||
*
|
||||
* In order for this field to contain a value, the #NS3_VERSION_TAG
|
||||
* must have the format ns-<digit>.<digit>[.digit][-RC<digit>].
|
||||
* The contents of the release candidate will be the RC<digit>
|
||||
* portion of the tag.
|
||||
*
|
||||
* Type: string literal
|
||||
*/
|
||||
#define NS3_VERSION_RELEASE_CANDIDATE @VERSION_RELEASE_CANDIDATE@
|
||||
|
||||
/**
|
||||
* The number of repository commits between #NS3_VERSION_CLOSEST_TAG
|
||||
* and the branch HEAD.
|
||||
*
|
||||
* Type: integer
|
||||
*/
|
||||
#define NS3_VERSION_TAG_DISTANCE @VERSION_TAG_DISTANCE@
|
||||
|
||||
/**
|
||||
* Hash value which uniquely identifies the commit of the
|
||||
* branch HEAD.
|
||||
* The first character of the commit hash is 'g' to indicate this hash is
|
||||
* a git hash
|
||||
*
|
||||
* Type: string literal
|
||||
*/
|
||||
#define NS3_VERSION_COMMIT_HASH @VERSION_COMMIT_HASH@
|
||||
|
||||
/**
|
||||
* Flag indicating whether the repository working tree had uncommitted
|
||||
* changes when the library was built.
|
||||
*
|
||||
* The flag will be 1 if there were uncommitted changes, 0 otherwise.
|
||||
*
|
||||
* Type: integer
|
||||
*/
|
||||
#define NS3_VERSION_DIRTY_FLAG @VERSION_DIRTY_FLAG@
|
||||
|
||||
/**
|
||||
* Indicates the build profile that was specified by the --build-profile option
|
||||
* of "waf configure"
|
||||
*
|
||||
* Type: string literal
|
||||
*/
|
||||
#define NS3_VERSION_BUILD_PROFILE "@BUILD_PROFILE@"
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif
|
||||
191
src/core/model/version.cc
Normal file
191
src/core/model/version.cc
Normal file
@@ -0,0 +1,191 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2018 Lawrence Livermore National Laboratory
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors: Mathew Bielejeski <bielejeski1@llnl.gov>
|
||||
*/
|
||||
|
||||
#include "version.h"
|
||||
#include "version-defines.h"
|
||||
#include <sstream>
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \ingroup buildversion
|
||||
* ns3::Version implementation
|
||||
*/
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
std::string
|
||||
Version::VersionTag (void)
|
||||
{
|
||||
return NS3_VERSION_TAG;
|
||||
}
|
||||
|
||||
std::string
|
||||
Version::ClosestAncestorTag (void)
|
||||
{
|
||||
return NS3_VERSION_CLOSEST_TAG;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
Version::Major (void)
|
||||
{
|
||||
return NS3_VERSION_MAJOR;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
Version::Minor (void)
|
||||
{
|
||||
return NS3_VERSION_MINOR;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
Version::Patch (void)
|
||||
{
|
||||
return NS3_VERSION_PATCH;
|
||||
}
|
||||
|
||||
std::string
|
||||
Version::ReleaseCandidate (void)
|
||||
{
|
||||
return std::string{NS3_VERSION_RELEASE_CANDIDATE};
|
||||
}
|
||||
|
||||
uint32_t
|
||||
Version::TagDistance (void)
|
||||
{
|
||||
return NS3_VERSION_TAG_DISTANCE;
|
||||
}
|
||||
|
||||
bool
|
||||
Version::DirtyWorkingTree (void)
|
||||
{
|
||||
return static_cast<bool> (NS3_VERSION_DIRTY_FLAG);
|
||||
}
|
||||
|
||||
std::string
|
||||
Version::CommitHash (void)
|
||||
{
|
||||
return std::string{NS3_VERSION_COMMIT_HASH};
|
||||
}
|
||||
|
||||
std::string
|
||||
Version::BuildProfile (void)
|
||||
{
|
||||
return std::string{NS3_VERSION_BUILD_PROFILE};
|
||||
}
|
||||
|
||||
std::string
|
||||
Version::ShortVersion (void)
|
||||
{
|
||||
std::ostringstream ostream;
|
||||
ostream << "ns-" << Major ()
|
||||
<< "." << Minor ();
|
||||
|
||||
//only include patch if it is not 0
|
||||
auto patch = Patch ();
|
||||
if (patch > 0)
|
||||
{
|
||||
ostream << '.' << patch;
|
||||
}
|
||||
|
||||
auto rc = ReleaseCandidate ();
|
||||
if (!rc.empty ())
|
||||
{
|
||||
ostream << '-' << rc;
|
||||
}
|
||||
|
||||
auto ancestorTag = ClosestAncestorTag ();
|
||||
if ( ( !ancestorTag.empty () && (ancestorTag != VersionTag ()) )
|
||||
|| TagDistance () > 0)
|
||||
{
|
||||
ostream << "+";
|
||||
}
|
||||
if (DirtyWorkingTree ())
|
||||
{
|
||||
ostream << "*";
|
||||
}
|
||||
|
||||
return ostream.str ();
|
||||
}
|
||||
|
||||
std::string
|
||||
Version::BuildSummary (void)
|
||||
{
|
||||
std::ostringstream ostream;
|
||||
ostream << ClosestAncestorTag ();
|
||||
|
||||
if (TagDistance () > 0)
|
||||
{
|
||||
ostream << "+";
|
||||
}
|
||||
if (DirtyWorkingTree ())
|
||||
{
|
||||
ostream << "*";
|
||||
}
|
||||
|
||||
return ostream.str ();
|
||||
}
|
||||
|
||||
std::string
|
||||
Version::LongVersion (void)
|
||||
{
|
||||
std::ostringstream ostream;
|
||||
ostream << "ns-" << Major ()
|
||||
<< "." << Minor ();
|
||||
|
||||
//only include patch if it is not 0
|
||||
auto patch = Patch ();
|
||||
if (patch > 0)
|
||||
{
|
||||
ostream << '.' << patch;
|
||||
}
|
||||
|
||||
auto rc = ReleaseCandidate ();
|
||||
if (!rc.empty ())
|
||||
{
|
||||
ostream << '-' << rc;
|
||||
}
|
||||
|
||||
auto ancestorTag = ClosestAncestorTag ();
|
||||
if ( !ancestorTag.empty () && (ancestorTag != VersionTag ()) )
|
||||
{
|
||||
ostream << '+' << ancestorTag;
|
||||
}
|
||||
|
||||
auto tagDistance = TagDistance ();
|
||||
|
||||
if ( tagDistance > 0 )
|
||||
{
|
||||
ostream << '+' << tagDistance;
|
||||
}
|
||||
|
||||
ostream << '@' << CommitHash ();
|
||||
|
||||
if ( DirtyWorkingTree () )
|
||||
{
|
||||
ostream << "-dirty";
|
||||
}
|
||||
|
||||
ostream << '-' << BuildProfile ();
|
||||
|
||||
return ostream.str ();
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
275
src/core/model/version.h
Normal file
275
src/core/model/version.h
Normal file
@@ -0,0 +1,275 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2018 Lawrence Livermore National Laboratory
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors: Mathew Bielejeski <bielejeski1@llnl.gov>
|
||||
*/
|
||||
|
||||
#ifndef BUILD_VERSION_H_
|
||||
#define BUILD_VERSION_H_
|
||||
|
||||
#include "ns3/int64x64.h"
|
||||
#include <string>
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \ingroup buildversion
|
||||
* class ns3::Version definition
|
||||
*/
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
/**
|
||||
* \ingroup core
|
||||
* \defgroup buildversion Build version reporting
|
||||
*
|
||||
* Version information is pulled from the local git repository during the build
|
||||
* process. If a git repository is not found, the build system will search for
|
||||
* a file named version.cache under the src/core directory. The version.cache
|
||||
* file must contain key/value pairs in the format key=value with one entry per
|
||||
* line. The build system will use the data pulled from the git repository, or
|
||||
* loaded from the version.cache file, to generate the file version-defines.h
|
||||
*
|
||||
* The build will fail if a local git repository is not present and
|
||||
* a version.cache file can not be found.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \ingroup buildversion
|
||||
*
|
||||
* Helper class providing functions to access various parts of the version
|
||||
* string, as well as functions for composing short and long variants of the
|
||||
* version string.
|
||||
*
|
||||
* See CommandLine::PrintVersion() for an example on how to
|
||||
* use Version to output a version string. command-line-example has been updated
|
||||
* to include CommandLine::PrintVersion() in its output
|
||||
*
|
||||
* build-version-example.cc illustrates using each of these functions.
|
||||
*
|
||||
* Below is a partial view of a git branch:
|
||||
*
|
||||
* \note Square nodes represent tags
|
||||
* \note Circle nodes represent commits
|
||||
*
|
||||
* \dot
|
||||
* digraph {
|
||||
* vt [label="ns-3.32", shape="box"]
|
||||
* t [label="mytag", shape="box"]
|
||||
* h [label="HEAD", shape="box"]
|
||||
* c1 [label="6ad7f05"]
|
||||
* c2 [label="05fc891"]
|
||||
* c3 [label="bd9ffac"]
|
||||
* c4 [label="70fa23b"]
|
||||
*
|
||||
* h -> c1 -> c2 -> c3 -> c4
|
||||
* t -> c2
|
||||
* vt -> c4
|
||||
* }
|
||||
* \enddot
|
||||
*
|
||||
* Here are the values that will be assigned based on this example branch:
|
||||
*
|
||||
* | Component | Value | Notes |
|
||||
* |--------------------|----------|-------|
|
||||
* | VersionTag | ns-3.32 | |
|
||||
* | ClosestAncestorTag | mytag | |
|
||||
* | Major | 3 | |
|
||||
* | Minor | 32 | |
|
||||
* | Patch | 0 | This version tag does not have a patch field |
|
||||
* | ReleaseCandidate | "" | This version tag does not have a release candidate field |
|
||||
* | TagDistance | 1 | |
|
||||
* | CommitHash | g6ad7f05 | g at front of hash indicates a git hash |
|
||||
* | DirtyWorkingTree | Variable | Depends on status of git working and stage areas |
|
||||
* | BuildProfile | Variable | Depends on the value of --build-profile option of waf configure |
|
||||
*/
|
||||
class Version
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Returns the ns-3 version tag of the closest ancestor commit.
|
||||
*
|
||||
* The format of the tag is
|
||||
* \verbatim ns3-<major>.<minor>[.patch] \endverbatim
|
||||
*
|
||||
* The patch field is optional and may not be present. The value of
|
||||
* patch defaults to 0 if the tag does not have a patch field.
|
||||
*
|
||||
* \return ns-3 version tag
|
||||
*/
|
||||
static std::string VersionTag (void);
|
||||
|
||||
/**
|
||||
* Returns the closest tag that is attached to a commit that is an ancestor
|
||||
* of the current branch head.
|
||||
*
|
||||
* The value returned by this function may be the same as VersionTag()
|
||||
* if the ns-3 version tag is the closest ancestor tag.
|
||||
*
|
||||
* \return Closest tag attached to an ancestor of the current commit
|
||||
*/
|
||||
static std::string ClosestAncestorTag (void);
|
||||
|
||||
/**
|
||||
* Major component of the build version
|
||||
*
|
||||
* The format of the build version string is
|
||||
* \verbatim ns-<major>.<minor>[.patch][-RC<digit>] \endverbatim
|
||||
*
|
||||
* The major component is the number before the first period
|
||||
*
|
||||
* \return The major component of the build version
|
||||
*/
|
||||
static uint32_t Major (void);
|
||||
|
||||
/**
|
||||
* Minor component of the build version
|
||||
*
|
||||
* The format of the build version string is
|
||||
* \verbatim ns-<major>.<minor>[.patch][-RC<digit>] \endverbatim
|
||||
*
|
||||
* The minor component is the number after the first period
|
||||
*
|
||||
* \return The minor component of the build version
|
||||
*/
|
||||
static uint32_t Minor (void);
|
||||
|
||||
/**
|
||||
* Patch component of the build version
|
||||
*
|
||||
* A build version with a patch component will have the format
|
||||
* \verbatim ns-<major>.<minor>.<patch> \endverbatim
|
||||
*
|
||||
* The patch component is the number after the second period
|
||||
*
|
||||
* \return The patch component of the build version or 0 if the build version
|
||||
* does not have a patch component
|
||||
*/
|
||||
static uint32_t Patch (void);
|
||||
|
||||
/**
|
||||
* Release candidate component of the build version
|
||||
*
|
||||
* A build version with a release candidate will have the format
|
||||
* \verbatim ns-<major>.<minor>[.patch]-RC<digit> \endverbatim
|
||||
*
|
||||
* The string returned by this function will have the format RC<digit>
|
||||
*
|
||||
* \return The release candidate component of the build version or an empty
|
||||
* string if the build version does not have a release candidate component
|
||||
*/
|
||||
static std::string ReleaseCandidate (void);
|
||||
|
||||
/**
|
||||
* The number of commits between the current
|
||||
* commit and the tag returned by ClosestAncestorTag().
|
||||
*
|
||||
* \return The number of commits made since the last tagged commit
|
||||
*/
|
||||
static uint32_t TagDistance (void);
|
||||
|
||||
/**
|
||||
* Indicates whether there were uncommitted changes during the build
|
||||
*
|
||||
* \return \c true if the working tree had uncommitted changes.
|
||||
*/
|
||||
static bool DirtyWorkingTree (void);
|
||||
|
||||
/**
|
||||
* Hash of the most recent commit
|
||||
*
|
||||
* The hash component is the id of the most recent commit.
|
||||
* The returned value is a hexadecimal string with enough data to
|
||||
* uniquely identify the commit.
|
||||
*
|
||||
* The first character of the string is a letter indicating the type
|
||||
* of repository that was in use: g=git
|
||||
*
|
||||
* Example of hash output: g6bfb0c9
|
||||
*
|
||||
* \return hexadecimal representation of the most recent commit id
|
||||
*/
|
||||
static std::string CommitHash (void);
|
||||
|
||||
/**
|
||||
* Indicates the type of build that was performed (debug/release/optimized).
|
||||
*
|
||||
* This information is set by the --build-profile option of waf configure
|
||||
*
|
||||
* \return String containing the type of build
|
||||
*/
|
||||
static std::string BuildProfile (void);
|
||||
|
||||
/**
|
||||
* Constructs a string containing the ns-3 major and minor version components,
|
||||
* and indication of additional commits or dirty status.
|
||||
*
|
||||
* The format of the constructed string is
|
||||
* \verbatim ns-<major>.<minor>[.patch][-rc]<flags> \endverbatim
|
||||
*
|
||||
* * [patch] is included when Patch() > 0.
|
||||
* * [-rc] is included when ReleaseCandidate() contains a non-empty string
|
||||
* * \c flags will contain `+` when TagDistance() > 0
|
||||
* * \c flags will contain `*` when DirtyWorkingTree() == true.
|
||||
*
|
||||
* [flags] will contain none, one, or both characters depending on the state
|
||||
* of the branch
|
||||
*
|
||||
* \return String containing the ns-3 major and minor components and flags.
|
||||
*/
|
||||
static std::string ShortVersion (void);
|
||||
|
||||
/**
|
||||
* Constructs a string containing the most recent tag and status flags.
|
||||
*
|
||||
* In the case where closest-ancestor-tag == version-tag, the output of this
|
||||
* function will be the same as ShortVersion()
|
||||
*
|
||||
* The format of the constructed string is `<closest-ancestor-tag>[flags]`.
|
||||
*
|
||||
* * \c flags will contain `+` when TagDistance() > 0
|
||||
* * \c flags will contain `*` when DirtyWorkingTree() == true.
|
||||
*
|
||||
* [flags] will contain none, one, or both characters depending on the state
|
||||
* of the branch
|
||||
*
|
||||
* \return String containing the closest ancestor tag and flags.
|
||||
*/
|
||||
static std::string BuildSummary (void);
|
||||
|
||||
/**
|
||||
* Constructs a string containing all of the build details
|
||||
*
|
||||
* The format of the constructed string is
|
||||
* \verbatim
|
||||
* ns-<major>.<minor>[.patch][-rc][-closest-tag]-<tag-distance>@<hash>[-dirty]-<build-profile>
|
||||
* \endverbatim
|
||||
*
|
||||
* [patch], [rc], [closest-tag], and [dirty] will only be present under certain circumstances:
|
||||
* * [patch] is included when Patch() > 0
|
||||
* * [rc] is included when ReleaseCandidate() is not an empty string
|
||||
* * [closest-tag] is included when ClosestTag() != VersionTag()
|
||||
* * [dirty] is included when DirtyWorkingTree() is \c true
|
||||
*
|
||||
* \return String containing full version
|
||||
*/
|
||||
static std::string LongVersion (void);
|
||||
|
||||
}; // class Version
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
#endif
|
||||
@@ -1,7 +1,8 @@
|
||||
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
|
||||
import sys
|
||||
import re
|
||||
|
||||
from waflib import Options, Utils
|
||||
from waflib import Context, Configure, Options, Utils
|
||||
import wutils
|
||||
|
||||
int64x64 = {
|
||||
@@ -41,9 +42,15 @@ def options(opt):
|
||||
action="store_true", default=False,
|
||||
dest='disable_pthread')
|
||||
|
||||
|
||||
opt.add_option('--check-version',
|
||||
help=("Print the current build version"),
|
||||
action="store_true", default=False,
|
||||
dest='check_version')
|
||||
|
||||
def configure(conf):
|
||||
|
||||
conf.load('versioning', ['waf-tools'])
|
||||
|
||||
int64x64_impl = Options.options.int64x64_impl
|
||||
if int64x64_impl == 'default' or int64x64_impl == 'int128':
|
||||
|
||||
@@ -150,8 +157,26 @@ int main ()
|
||||
conf.write_config_header('ns3/core-config.h', top=True)
|
||||
|
||||
def build(bld):
|
||||
|
||||
|
||||
bld.install_files('${INCLUDEDIR}/%s%s/ns3' % (wutils.APPNAME, wutils.VERSION), '../../ns3/core-config.h')
|
||||
|
||||
version_template = bld.path.find_node('model/version-defines.h.in')
|
||||
version_header = bld.bldnode.make_node('version-defines.h')
|
||||
|
||||
vers_tg = bld(features='version-defines',
|
||||
source=version_template,
|
||||
target=version_header)
|
||||
|
||||
#silence errors about no mapping for version-defines.h.in
|
||||
vers_tg.mappings['.h'] = lambda *a, **k: None
|
||||
vers_tg.mappings['.h.in'] = lambda *a, **k: None
|
||||
|
||||
if Options.options.check_version:
|
||||
print_version(bld, vers_tg)
|
||||
raise SystemExit(0)
|
||||
return
|
||||
|
||||
core = bld.create_ns3_module('core')
|
||||
core.source = [
|
||||
'model/time.cc',
|
||||
@@ -214,6 +239,7 @@ def build(bld):
|
||||
'model/time-printer.cc',
|
||||
'model/show-progress.cc',
|
||||
'model/system-wall-clock-timestamp.cc',
|
||||
'model/version.cc',
|
||||
]
|
||||
|
||||
if (bld.env['ENABLE_EXAMPLES']):
|
||||
@@ -342,6 +368,7 @@ def build(bld):
|
||||
'model/node-printer.h',
|
||||
'model/time-printer.h',
|
||||
'model/show-progress.h',
|
||||
'model/version.h',
|
||||
]
|
||||
|
||||
if (bld.env['ENABLE_EXAMPLES']):
|
||||
@@ -415,3 +442,45 @@ def build(bld):
|
||||
pymod = bld.ns3_python_bindings()
|
||||
if pymod is not None:
|
||||
pymod.source += ['bindings/module_helpers.cc']
|
||||
|
||||
def print_version(bld, tg):
|
||||
tg.post()
|
||||
|
||||
found = False
|
||||
for task in tg.tasks:
|
||||
if task.__class__.__name__ == 'git_ns3_version_info':
|
||||
found = True
|
||||
#manually run task
|
||||
task.run()
|
||||
break
|
||||
|
||||
if not found:
|
||||
print("Task to generate version information could not be found")
|
||||
return
|
||||
|
||||
handlers = {
|
||||
'VERSION_TAG': lambda s: s.strip('"'),
|
||||
'CLOSEST_TAG': lambda s: s.strip('"'),
|
||||
'VERSION_TAG_DISTANCE': lambda s: '' if s == '0' else "+" + s,
|
||||
'VERSION_COMMIT_HASH': lambda s: "@" + s.strip('"'),
|
||||
'VERSION_DIRTY_FLAG': lambda s: '' if s == '0' else '-dirty',
|
||||
'BUILD_PROFILE': lambda s: "-" + s
|
||||
}
|
||||
|
||||
fields=('VERSION_TAG', 'CLOSEST_TAG', 'VERSION_TAG_DISTANCE',
|
||||
'VERSION_COMMIT_HASH', 'VERSION_DIRTY_FLAG', 'BUILD_PROFILE')
|
||||
|
||||
parts = dict()
|
||||
|
||||
for field in fields:
|
||||
if field in bld.env:
|
||||
parts[field] = handlers[field](bld.env[field])
|
||||
else:
|
||||
parts[field] = ''
|
||||
|
||||
if parts['CLOSEST_TAG'] != parts['VERSION_TAG']:
|
||||
parts['CLOSEST_TAG'] = "+" + parts['CLOSEST_TAG']
|
||||
else:
|
||||
parts['CLOSEST_TAG'] = ""
|
||||
|
||||
print(''.join([parts[f] for f in fields]))
|
||||
|
||||
254
waf-tools/versioning.py
Normal file
254
waf-tools/versioning.py
Normal file
@@ -0,0 +1,254 @@
|
||||
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
|
||||
|
||||
import re
|
||||
|
||||
from waflib import ConfigSet, Configure, Context, Task, TaskGen
|
||||
|
||||
CACHE_FILE = 'version.cache'
|
||||
|
||||
class ns3_version_info(Task.Task):
|
||||
'''Base task which implements functionality common to all inherited tasks
|
||||
|
||||
This class handles parsing the ns-3 version tag into component parts
|
||||
as well as saving the version fields to a cache file
|
||||
|
||||
All version fields should be stored in the fields property
|
||||
|
||||
Derived classes should override _find_closest_tag() and
|
||||
_find_closest_ns3_tag()
|
||||
'''
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self._fields = ConfigSet.ConfigSet()
|
||||
|
||||
super(ns3_version_info, self).__init__(*args, **kwargs)
|
||||
|
||||
@property
|
||||
def fields(self):
|
||||
return self._fields
|
||||
|
||||
def _find_closest_tag(self, ctx):
|
||||
"""Override in derived classes"""
|
||||
pass
|
||||
|
||||
def _find_closest_ns3_tag(self, ctx):
|
||||
"""Override in derived classes"""
|
||||
pass
|
||||
|
||||
def _parse_version_tag(self, ctx, tag):
|
||||
safe_tag = tag.strip()
|
||||
matches = re.match("ns-(\d+)\.(\d+)(?:.(\d+))?(?:-(RC.+))?.*", safe_tag)
|
||||
|
||||
if not matches:
|
||||
return False
|
||||
|
||||
self.fields['VERSION_TAG'] = '"{}"'.format(safe_tag)
|
||||
self.fields['VERSION_MAJOR'] = matches.group(1)
|
||||
self.fields['VERSION_MINOR'] = matches.group(2)
|
||||
|
||||
patch = matches.group(3)
|
||||
|
||||
if not patch:
|
||||
patch = '0'
|
||||
|
||||
self.fields['VERSION_PATCH'] = patch
|
||||
|
||||
release_candidate = matches.group(4)
|
||||
|
||||
if not release_candidate:
|
||||
release_candidate = ''
|
||||
|
||||
self.fields['VERSION_RELEASE_CANDIDATE'] = '"{}"'.format(release_candidate)
|
||||
|
||||
return True
|
||||
|
||||
def run(self):
|
||||
ctx = self.generator.bld
|
||||
|
||||
try:
|
||||
self._find_closest_tag(ctx)
|
||||
|
||||
if 'VERSION_TAG' not in self.fields:
|
||||
self._find_closest_ns3_tag(ctx)
|
||||
|
||||
#Generate the path where the cache file will be stored
|
||||
base_path = self.generator.path.make_node('model')
|
||||
cache_path = base_path.make_node(CACHE_FILE)
|
||||
|
||||
#Write the version information out to the cache file
|
||||
#The cache file is used to populate the version fields when a git
|
||||
#repository can not be found
|
||||
self.fields.store(cache_path.abspath())
|
||||
|
||||
#merge version info into main configset
|
||||
ctx.env.update(self.fields)
|
||||
|
||||
except Exception as e:
|
||||
ctx.to_log("Extracting version information from tags failed: {}\n".format(e))
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
class git_ns3_version_info(ns3_version_info):
|
||||
'''Task to generate version fields from an ns-3 git repository'''
|
||||
always_run = True
|
||||
|
||||
def _find_closest_tag(self, ctx):
|
||||
cmd = [
|
||||
'git',
|
||||
'describe',
|
||||
'--tags',
|
||||
'--dirty',
|
||||
'--long'
|
||||
]
|
||||
|
||||
try:
|
||||
out = ctx.cmd_and_log(cmd,
|
||||
output=Context.STDOUT,
|
||||
quiet=Context.BOTH)
|
||||
except Exception as e:
|
||||
raise Exception(e.stderr.strip())
|
||||
|
||||
matches = re.match('(.+)-(\d+)-(g[a-fA-F0-9]+)(?:-(dirty))?', out)
|
||||
|
||||
if not matches:
|
||||
raise ValueError("Closest tag found in git log"
|
||||
"does not match the expected format (tag='{}')"
|
||||
.format(out))
|
||||
|
||||
tag = matches.group(1)
|
||||
|
||||
self.fields['CLOSEST_TAG'] = '"{}"'.format(tag)
|
||||
self.fields['VERSION_TAG_DISTANCE'] = matches.group(2)
|
||||
self.fields['VERSION_COMMIT_HASH'] = '"{}"'.format(matches.group(3))
|
||||
self.fields['VERSION_DIRTY_FLAG'] = '1' if matches.group(4) else '0'
|
||||
|
||||
self._parse_version_tag(ctx, tag)
|
||||
|
||||
def _find_closest_ns3_tag(self, ctx):
|
||||
cmd = [
|
||||
'git',
|
||||
'describe',
|
||||
'--tags',
|
||||
'--abbrev=0',
|
||||
'--match',
|
||||
'ns-3*',
|
||||
'HEAD'
|
||||
]
|
||||
|
||||
try:
|
||||
out = ctx.cmd_and_log(cmd,
|
||||
output=Context.STDOUT,
|
||||
quiet=Context.BOTH)
|
||||
except Exception as e:
|
||||
raise Exception(e.stderr.strip())
|
||||
|
||||
tag = out.strip()
|
||||
|
||||
result = self._parse_version_tag(ctx, tag)
|
||||
|
||||
if not result:
|
||||
raise ValueError("Closest ns3 tag found in git log"
|
||||
"does not match the expected format (tag='{}')"
|
||||
.format(tag))
|
||||
|
||||
@TaskGen.feature('version-defines')
|
||||
def generate_version_defines(self):
|
||||
|
||||
#Create a substitution task to generate version-defines.h
|
||||
#from fields stored in env
|
||||
subst_task = self.create_task('subst', self.source, self.target)
|
||||
|
||||
if self.env['HAVE_GIT_REPO']:
|
||||
#if a git repo is present, run the version task first to
|
||||
#populate the appropriate fields with data from the git repo
|
||||
version_task = self.create_task('git_ns3_version_info')
|
||||
subst_task.set_run_after(version_task)
|
||||
|
||||
@Configure.conf
|
||||
def check_git_repo(self):
|
||||
'''Determine if a git repository is present'''
|
||||
|
||||
root = False
|
||||
cmd = [
|
||||
'git',
|
||||
'rev-parse',
|
||||
'--show-toplevel'
|
||||
]
|
||||
|
||||
try:
|
||||
#determine if the current directory is part of a git repository
|
||||
self.find_program('git')
|
||||
|
||||
out = self.cmd_and_log(cmd, output=Context.STDOUT, quiet=Context.BOTH)
|
||||
|
||||
root = out.strip()
|
||||
except Exception:
|
||||
root = False
|
||||
|
||||
self.msg('Checking for local git repository', root)
|
||||
|
||||
return bool(root)
|
||||
|
||||
@Configure.conf
|
||||
def check_git_repo_has_ns3_tags(self):
|
||||
'''Determine if the git repository is an ns-3 repository
|
||||
|
||||
A repository is considered an ns-3 repository if it has at least one
|
||||
tag that matches the regex ns-3*
|
||||
'''
|
||||
|
||||
tag = False
|
||||
|
||||
cmd = [
|
||||
'git',
|
||||
'describe',
|
||||
'--tags',
|
||||
'--abbrev=0',
|
||||
'--match',
|
||||
'ns-3*'
|
||||
]
|
||||
|
||||
try:
|
||||
out = self.cmd_and_log(cmd, output=Context.STDOUT, quiet=Context.BOTH)
|
||||
|
||||
tag = out.strip()
|
||||
|
||||
except Exception:
|
||||
tag = False
|
||||
|
||||
self.msg('Checking local git repository for ns3 tags', tag)
|
||||
|
||||
return bool(tag)
|
||||
|
||||
def configure(ctx):
|
||||
|
||||
has_ns3_tags = False
|
||||
|
||||
if ctx.check_git_repo():
|
||||
has_ns3_tags = ctx.check_git_repo_has_ns3_tags()
|
||||
|
||||
ctx.env['HAVE_GIT_REPO'] = has_ns3_tags
|
||||
|
||||
if not has_ns3_tags:
|
||||
#no ns-3 repository, look for a cache file containing the version info
|
||||
ctx.start_msg('Searching for file {}'.format(CACHE_FILE))
|
||||
|
||||
glob_pattern = '**/{}'.format(CACHE_FILE)
|
||||
cache_path = ctx.path.ant_glob(glob_pattern)
|
||||
|
||||
if len(cache_path) == 0:
|
||||
ctx.end_msg(False)
|
||||
ctx.fatal("Could not find {} under {}. This file must exist and contain "
|
||||
"version information when a git repository is not "
|
||||
"present.".format(CACHE_FILE, ctx.path))
|
||||
|
||||
#Found cache file
|
||||
#Load it and merge the information into the main context environment
|
||||
src_path = cache_path[0].srcpath()
|
||||
ctx.end_msg(src_path)
|
||||
|
||||
version_cache = ConfigSet.ConfigSet ()
|
||||
version_cache.load (src_path)
|
||||
ctx.env.update(version_cache)
|
||||
|
||||
Reference in New Issue
Block a user