Просмотр исходного кода

Add support for Boost.Build V2.

* process_jam_log.cpp:

 (test_path_to_library_name): Handle a situation where a directory
 has some tests and subdirectories for a different library. Example
 is libs/functional/function_test and libs/functional/hash/test/*.

 (parse_skipped_msg): Extract duplicated code...
 (parse_skipped_msg_aux): ... here. Also add support for V2 target naming.

 (main): Handle --v2 option

* compiler_status.cpp
  (find_bin_path): New function for logic that was repeated in two places.
     Add support for V2.


[SVN r28205]
Vladimir Prus 21 лет назад
Родитель
Сommit
481793e0de
2 измененных файлов с 148 добавлено и 71 удалено
  1. 53 22
      tools/regression/compiler_status.cpp
  2. 95 49
      tools/regression/process_jam_log.cpp

+ 53 - 22
tools/regression/compiler_status.cpp

@@ -55,6 +55,7 @@ namespace
   bool ignore_pass;
   bool no_warn;
   bool no_links;
+  bool boost_build_v2;
 
   fs::path jamfile_path;
 
@@ -338,6 +339,47 @@ const string & attribute_value( const xml::element & element,
   return atr == element.attributes.end() ? empty_string : atr->value;
 }
 
+  // Takes a relative path from boost root to a Jamfile.
+  // Returns the directory where the build targets from
+  // that Jamfile are located. If not found, emits a warning 
+  // and returns empty path.
+  const fs::path find_bin_path(const string& relative)
+  {
+    fs::path bin_path;
+    if (boost_build_v2)
+    {
+      bin_path = locate_root / "bin.v2" / relative;
+      if (!fs::exists(bin_path))
+      {
+        std::cerr << "warning: could not found build results for '" 
+                  << relative << "'.\n";
+        std::cerr << "warning: tried directory " 
+                  << bin_path.native_directory_string() << "\n";
+        bin_path = "";
+      }
+    }
+    else
+    {
+      bin_path = locate_root / "bin/boost" / relative;
+      if (!fs::exists(bin_path))
+      {
+        bin_path = locate_root / "bin" / relative / "bin";
+        if (!fs::exists(bin_path))
+        {
+          bin_path = fs::path( locate_root / relative / "bin" );
+        }
+      }
+      if (!fs::exists(bin_path))
+      {
+        std::cerr << "warning: could not found build results for '" 
+                  << relative << "'.\n";
+        bin_path = "";
+      }
+    }
+    return bin_path;
+  }
+
+
 //  generate_report  ---------------------------------------------------------//
 
   // return 0 if nothing generated, 1 otherwise, except 2 if compiler msgs
@@ -655,17 +697,10 @@ const string & attribute_value( const xml::element & element,
         if ( pos == string::npos ) continue;
         string subinclude_bin_dir(
           line.substr( pos, line.find_first_of( " \t", pos )-pos ) );
-//      std::cout << "subinclude: " << subinclude_bin_dir << '\n';
-        fs::path subinclude_path( locate_root / "bin/boost" / subinclude_bin_dir );
-        if ( fs::exists( subinclude_path ) )
-          { do_rows_for_sub_tree( subinclude_path, results ); continue; }
-        subinclude_path = fs::path( locate_root / "bin" 
-                                    / subinclude_bin_dir / "bin" );
-        if ( fs::exists( subinclude_path ) )
-          { do_rows_for_sub_tree( subinclude_path, results ); continue; }
-        subinclude_path = fs::path( locate_root / subinclude_bin_dir / "/bin" );
-        if ( fs::exists( subinclude_path ) )
-          { do_rows_for_sub_tree( subinclude_path, results ); }
+
+        fs::path bin_path = find_bin_path(subinclude_bin_dir);
+        if (!bin_path.empty())
+          do_rows_for_sub_tree( bin_path, results );
       }
     }
 
@@ -686,16 +721,8 @@ const string & attribute_value( const xml::element & element,
     // - Boost.Build V2 location with top-lelve "build-dir" 
     // - Boost.Build V1 location without ALL_LOCATE_TARGET
     string relative( fs::initial_path().string() );
-    relative.erase( 0, boost_root.string().size()+1 );
-    fs::path bin_path( locate_root / "bin/boost" / relative );
-    if (!fs::exists(bin_path))
-    {
-      bin_path = locate_root / "bin/status/bin";
-      if (!fs::exists(bin_path))
-      {
-        bin_path = fs::path( locate_root / relative / "bin" );
-      }
-    }
+    relative.erase( 0, boost_root.string().size()+1 );    
+    fs::path bin_path = find_bin_path(relative);
 
     report << "<table border=\"1\" cellspacing=\"0\" cellpadding=\"5\">\n";
 
@@ -765,6 +792,7 @@ int cpp_main( int argc, char * argv[] ) // note name!
       { notes_map_path = fs::path( argv[2], fs::native ); --argc; ++argv; }
     else if ( std::strcmp( argv[1], "--ignore-pass" ) == 0 ) ignore_pass = true;
     else if ( std::strcmp( argv[1], "--no-warn" ) == 0 ) no_warn = true;
+    else if ( std::strcmp( argv[1], "--v2" ) == 0 ) boost_build_v2 = true;
     else if ( argc > 2 && std::strcmp( argv[1], "--jamfile" ) == 0)
       { jamfile_path = fs::path( argv[2], fs::native ); --argc; ++argv; }
     else { std::cerr << "Unknown option: " << argv[1] << "\n"; argc = 1; }
@@ -803,7 +831,10 @@ int cpp_main( int argc, char * argv[] ) // note name!
   if ( locate_root.empty() ) locate_root = boost_root;
   
   if (jamfile_path.empty())
-    jamfile_path = "Jamfile";
+    if (boost_build_v2)
+      jamfile_path = "Jamfile.v2";
+    else
+      jamfile_path = "Jamfile";
   jamfile_path = fs::complete( jamfile_path, fs::initial_path() );
   jamfile.open( jamfile_path );
   if ( !jamfile )

+ 95 - 49
tools/regression/process_jam_log.cpp

@@ -31,6 +31,7 @@ namespace fs = boost::filesystem;
 
 static bool echo = false;
 static bool create_dirs = false;
+static bool boost_build_v2 = false;
 
 namespace
 {
@@ -138,26 +139,101 @@ namespace
         ? pos : s.find( "/", pos )) - pos_start );
   }
 
+  // Take a path to a target directory of test, and
+  // returns library name corresponding to that path.
   string test_path_to_library_name( string const& path )
   {
     std::string result;
     string::size_type start_pos( path.find( "libs/" ) );
     if ( start_pos != string::npos )
     {
+      // The path format is ...libs/functional/hash/test/something.test/....      
+      // So, the part between "libs" and "test/something.test" can be considered
+      // as library name. But, for some libraries tests are located too deep,
+      // say numeric/ublas/test/test1 directory, and some libraries have tests
+      // in several subdirectories (regex/example and regex/test). So, nested
+      // directory may belong to several libraries.
+
+      // To disambituate, it's possible to place a 'sublibs' file in
+      // a directory. It means that child directories are separate libraries.
+      // It's still possible to have tests in the directory that has 'sublibs'
+      // file.
+
+      std::string interesting;
       start_pos += 5;
-      string::size_type end_pos( path.find( '/', start_pos ) );
-      result = path.substr( start_pos, end_pos - start_pos );
+      string::size_type end_pos( path.find( ".test/", start_pos ) );
+      end_pos = path.rfind('/', end_pos);
+      if (path.substr(end_pos - 5, 5) == "/test")
+        interesting = path.substr( start_pos, end_pos - 5 - start_pos );
+      else
+        interesting = path.substr( start_pos, end_pos - start_pos );
 
-      // if a "sublibs" file exists, the library name includes the
-      // next level down directory name.
-      if ( fs::exists( ( boost_root / "libs" ) / result / "sublibs" ) )
+      // Take slash separate elements until we have corresponding 'sublibs'.
+      end_pos = 0;
+      for(;;)
       {
-        result += path.substr( end_pos, path.find( '/', end_pos+1 ) - end_pos );
+        end_pos = interesting.find('/', end_pos);
+        if (end_pos == string::npos) {
+          result = interesting;
+          break;
+        }
+        result = interesting.substr(0, end_pos);
+
+        if ( fs::exists( ( boost_root / "libs" ) / result / "sublibs" ) )
+        {
+          end_pos = end_pos + 1;
+        }
+        else
+          break;
       }
     }
 
     return result;
   }
+
+  // Tries to find target name in the string 'msg', starting from 
+  // position start.
+  // If found, extract the directory name from the target name and
+  // stores it in 'dir', and return the position after the target name.
+  // Otherwise, returns string::npos.
+  string::size_type parse_skipped_msg_aux(const string& msg,
+                                          string::size_type start,
+                                          string& dir)
+  {
+    dir.clear();
+    string::size_type start_pos = msg.find( '<', start );
+    if ( start_pos == string::npos ) return string::npos;
+    ++start_pos;
+    string::size_type end_pos = msg.find( '>', start_pos );
+    dir += msg.substr( start_pos, end_pos - start_pos );
+    if ( boost_build_v2 )
+    {
+        // The first letter is a magic value indicating
+        // the type of grist.
+        convert_path_separators( dir );
+        dir.erase( 0, 1 );
+        // We need path from root, not from 'status' dir.
+        if (dir.find("../") == 0)
+          dir.erase(0,3);
+    }
+    else
+    {
+      if ( dir[0] == '@' )
+      {
+        // new style build path, rooted build tree
+        convert_path_separators( dir );
+        dir.replace( 0, 1, "bin/" );
+      }
+      else
+      {
+        // old style build path, integrated build tree
+        start_pos = dir.rfind( '!' );
+        convert_path_separators( dir );
+        dir.insert( dir.find( '/', start_pos + 1), "/bin" );
+      }
+    }
+    return end_pos;
+  }
   
   // the format of paths is really kinky, so convert to normal form
   //   first path is missing the leading "..\".
@@ -168,47 +244,10 @@ namespace
   void parse_skipped_msg( const string & msg,
     string & first_dir, string & second_dir )
   {
-    first_dir.clear();
-    second_dir.clear();
-    string::size_type start_pos( msg.find( '<' ) );
-    if ( start_pos == string::npos ) return;
-    ++start_pos;
-    string::size_type end_pos( msg.find( '>', start_pos ) );
-    first_dir += msg.substr( start_pos, end_pos - start_pos );
-    if ( first_dir[0] == '@' )
-    {
-      // new style build path, rooted build tree
-      convert_path_separators( first_dir );
-      first_dir.replace( 0, 1, "bin/" );
-    }
-    else
-    {
-      // old style build path, integrated build tree
-      start_pos = first_dir.rfind( '!' );
-      convert_path_separators( first_dir );
-      first_dir.insert( first_dir.find( '/', start_pos + 1), "/bin" );
-    }
-//std::cout << first_dir << std::endl;
-
-    start_pos = msg.find( '<', end_pos );
-    if ( start_pos == string::npos ) return;
-    ++start_pos;
-    end_pos = msg.find( '>', start_pos );
-    second_dir += msg.substr( start_pos, end_pos - start_pos );
-    if ( second_dir[0] == '@' )
-    {
-      // new style build path, rooted build tree
-      convert_path_separators( second_dir );
-      second_dir.replace( 0, 1, "bin/" );
-    }
-    else
-    {
-      // old style build path, integrated build tree
-      start_pos = second_dir.rfind( '!' );
-      convert_path_separators( second_dir );
-      second_dir.insert( second_dir.find( '/', start_pos + 1), "/bin" );
-    }
-//std::cout << second_dir << std::endl;
+    string::size_type pos = parse_skipped_msg_aux(msg, 0, first_dir);
+    if (pos == string::npos)
+      return;
+    parse_skipped_msg_aux(msg, pos, second_dir);
   }
 
 //  test_log hides database details  -----------------------------------------//
@@ -440,7 +479,7 @@ namespace
 int cpp_main( int argc, char ** argv )
 {
   if ( argc <= 1 )
-    std::cout << "Usage: bjam [bjam-args] | process_jam_log [--echo] [--create-directories] [locate-root]\n"
+    std::cout << "Usage: bjam [bjam-args] | process_jam_log [--echo] [--create-directories] [--v2] [locate-root]\n"
                  "locate-root         - the same as the bjam ALL_LOCATE_TARGET\n"
                  "                      parameter, if any. Default is boost-root.\n"
                  "create-directories  - if the directory for xml file doesn't exists - creates it.\n"
@@ -474,6 +513,13 @@ int cpp_main( int argc, char ** argv )
       --argc; ++argv;
   } 
 
+  if ( argc > 1 && std::strcmp( argv[1], "--v2" ) == 0 )
+  {
+    boost_build_v2 = true;
+    --argc; ++argv;
+  }
+
+
   if (argc > 1)
   {
       locate_root = fs::path( argv[1], fs::native );
@@ -591,7 +637,7 @@ int cpp_main( int argc, char ** argv )
     }
 
     else if ( line.find( "execute-test" ) != string::npos 
-             || line.find( "testing.capture-output" ) != string::npos )
+             || line.find( "capture-output" ) != string::npos )
     {
       if ( line.find( "...failed " ) != string::npos )
       {

粤ICP备19079148号