Optimize library ordering by native rules.
[SVN r22281]
This commit is contained in:
parent
f641d2ca34
commit
2d883c64d5
@ -320,7 +320,7 @@ set BJAM_SOURCES=%BJAM_SOURCES% newstr.c option.c parse.c pathunix.c pathvms.c r
|
||||
set BJAM_SOURCES=%BJAM_SOURCES% rules.c scan.c search.c subst.c timestamp.c variable.c modules.c
|
||||
set BJAM_SOURCES=%BJAM_SOURCES% strings.c filesys.c builtins.c pwd.c class.c w32_getreg.c native.c
|
||||
set BJAM_SOURCES=%BJAM_SOURCES% modules/set.c modules/path.c modules/regex.c
|
||||
set BJAM_SOURCES=%BJAM_SOURCES% modules/property-set.c modules/sequence.c
|
||||
set BJAM_SOURCES=%BJAM_SOURCES% modules/property-set.c modules/sequence.c modules/order.c
|
||||
|
||||
@echo ON
|
||||
rd /S /Q bootstrap.%BOOST_JAM_TOOLSET%
|
||||
|
@ -277,7 +277,7 @@ jam.source =
|
||||
timestamp.c variable.c modules.c strings.c filesys.c
|
||||
builtins.c pwd.c class.c native.c modules/set.c
|
||||
modules/path.c modules/regex.c modules/property-set.c
|
||||
modules/sequence.c
|
||||
modules/sequence.c modules/order.c
|
||||
;
|
||||
if $(NT)
|
||||
{
|
||||
|
@ -193,7 +193,7 @@ BJAM_SOURCES="\
|
||||
rules.c scan.c search.c subst.c timestamp.c variable.c modules.c\
|
||||
strings.c filesys.c builtins.c pwd.c class.c native.c modules/set.c\
|
||||
modules/path.c modules/regex.c modules/property-set.c\
|
||||
modules/sequence.c"
|
||||
modules/sequence.c modules/order.c"
|
||||
|
||||
echo_run rm -rf bootstrap.$BOOST_JAM_TOOLSET
|
||||
echo_run mkdir bootstrap.$BOOST_JAM_TOOLSET
|
||||
|
@ -277,6 +277,7 @@ load_builtins()
|
||||
init_regex();
|
||||
init_property_set();
|
||||
init_sequence();
|
||||
init_order();
|
||||
}
|
||||
|
||||
/*
|
||||
|
139
src/engine/modules/order.c
Normal file
139
src/engine/modules/order.c
Normal file
@ -0,0 +1,139 @@
|
||||
|
||||
#include "../native.h"
|
||||
#include "../lists.h"
|
||||
#include "../strings.h"
|
||||
#include "../newstr.h"
|
||||
#include "../variable.h"
|
||||
|
||||
|
||||
/* Use quite klugy approach: when we add order dependency from 'a' to 'b',
|
||||
just append 'b' to of value of variable 'a'.
|
||||
*/
|
||||
LIST *add_pair( PARSE *parse, FRAME *frame )
|
||||
{
|
||||
LIST* arg = lol_get( frame->args, 0 );
|
||||
|
||||
var_set(arg->string, list_copy(0, arg->next), VAR_APPEND);
|
||||
|
||||
return L0;
|
||||
}
|
||||
|
||||
/** Given a list and a value, returns position of that value in
|
||||
the list, or -1 if not found.
|
||||
*/
|
||||
int list_index(LIST* list, const char* value)
|
||||
{
|
||||
int result = 0;
|
||||
for(; list; list = list->next, ++result) {
|
||||
if (strcmp(list->string, value) == 0)
|
||||
return result;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
enum colors { white, gray, black };
|
||||
|
||||
/* Main routite of topological sort. Calls itself recursively on all
|
||||
adjacent vertices which were not yet visited. After that, 'current_vertex'
|
||||
is added to '*result_ptr'.
|
||||
*/
|
||||
int do_ts(int** graph, int current_vertex, int* colors, int** result_ptr)
|
||||
{
|
||||
int i;
|
||||
|
||||
colors[current_vertex] = gray;
|
||||
for(i = 0; graph[current_vertex][i] != -1; ++i) {
|
||||
int adjacent_vertex = graph[current_vertex][i];
|
||||
|
||||
if (colors[adjacent_vertex] == white)
|
||||
do_ts(graph, adjacent_vertex, colors, result_ptr);
|
||||
else if (colors[adjacent_vertex] == gray)
|
||||
; /* This is loop. Not sure what to do... */
|
||||
}
|
||||
colors[current_vertex] = black;
|
||||
**result_ptr = current_vertex;
|
||||
(*result_ptr)++;
|
||||
}
|
||||
|
||||
void topological_sort(int** graph, int num_vertices, int* result)
|
||||
{
|
||||
int i;
|
||||
int* colors = (int*)calloc(num_vertices, sizeof(int));
|
||||
for (i = 0; i < num_vertices; ++i)
|
||||
colors[i] = white;
|
||||
|
||||
for(i = 0; i < num_vertices; ++i)
|
||||
if (colors[i] == white)
|
||||
do_ts(graph, i, colors, &result);
|
||||
|
||||
free(colors);
|
||||
}
|
||||
|
||||
LIST *order( PARSE *parse, FRAME *frame )
|
||||
{
|
||||
LIST* arg = lol_get( frame->args, 0 );
|
||||
LIST* tmp;
|
||||
LIST* result = 0;
|
||||
int src, dst;
|
||||
|
||||
/* We need to create a graph of order dependencies between
|
||||
the passed objects. We assume that there are no duplicates
|
||||
passed to 'add_pair'.
|
||||
*/
|
||||
int length = list_length(arg);
|
||||
int** graph = (int**)calloc(length, sizeof(int*));
|
||||
int* order = (int*)malloc((length+1)*sizeof(int));
|
||||
|
||||
for(tmp = arg, src = 0; tmp; tmp = tmp->next, ++src) {
|
||||
/* For all object this one depend upon, add elements
|
||||
to 'graph' */
|
||||
LIST* dependencies = var_get(tmp->string);
|
||||
int index = 0;
|
||||
|
||||
graph[src] = (int*)calloc(list_length(dependencies)+1, sizeof(int));
|
||||
for(; dependencies; dependencies = dependencies->next) {
|
||||
int dst = list_index(arg, dependencies->string);
|
||||
if (dst != -1)
|
||||
graph[src][index++] = dst;
|
||||
}
|
||||
graph[src][index] = -1;
|
||||
}
|
||||
|
||||
topological_sort(graph, length, order);
|
||||
|
||||
{
|
||||
int index = length-1;
|
||||
for(; index >= 0; --index) {
|
||||
int i;
|
||||
tmp = arg;
|
||||
for (i = 0; i < order[index]; ++i, tmp = tmp->next);
|
||||
result = list_new(result, tmp->string);
|
||||
}
|
||||
}
|
||||
|
||||
/* Clean up */
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < length; ++i)
|
||||
free(graph[i]);
|
||||
free(graph);
|
||||
free(order);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void init_order()
|
||||
{
|
||||
{
|
||||
char* args[] = { "first", "second", 0 };
|
||||
declare_native_rule("class@order", "add-pair", args, add_pair);
|
||||
}
|
||||
|
||||
{
|
||||
char* args[] = { "objects", "*", 0 };
|
||||
declare_native_rule("class@order", "order", args, order);
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -35,6 +35,7 @@ class order
|
||||
{
|
||||
.constraits += $(first)--$(second) ;
|
||||
}
|
||||
NATIVE_RULE class@order : add-pair ;
|
||||
|
||||
# Given a list of objects, reorder them so that the constains specified
|
||||
# by 'add-pair' are satisfied.
|
||||
@ -92,6 +93,7 @@ class order
|
||||
}
|
||||
return $(result) ;
|
||||
}
|
||||
NATIVE_RULE class@order : order ;
|
||||
|
||||
# Eliminate constains which mentions objects not in 'objects'.
|
||||
# In graph-theory terms, this is finding subgraph induced by
|
||||
|
@ -244,7 +244,7 @@ t.rm(".")
|
||||
t.write(
|
||||
"Jamfile",
|
||||
"""
|
||||
lib main : main.cpp : : : <library>libs//lib1 ;
|
||||
lib main : main.cpp : <use>libs//lib1 : : <library>libs//lib1 ;
|
||||
exe hello : hello.cpp main : ;
|
||||
""")
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user