void CompilationEnvironment::parse_cpp( BasicVec<Ptr<CompilationTree> > &obj, const String &cpp_, bool dyn ) {
    String cpp = absolute_filename( cpp_ );

    // already parsed ?
    if ( parsed.contains( cpp ) )
        return;
    parsed << cpp;
    
    // parse
    CompilationCppParser cpp_parser( *this, cpp, dep_for( cpp ) );
    
    if ( cpp_parser.var_templ.size() ) {
        GetRemp gr;
        BasicVec<BasicVec<String,2> > rep;
        gr.aaadd( cpp_parser.var_templ, rep );
        
        File f( cpp );
        String dat = "#line 1 \"" + cpp + "\"\n" + f.c_str();
        dat = dat.replace( "#pragma template ", "// template " );
        for( int i = 0; i < gr.res.size(); ++i ) {
            String cp = dat;
            for( int j = 0; j < gr.res[ i ].size(); ++j )
                cp = cp.replace( gr.res[ i ][ j ][ 0 ], gr.res[ i ][ j ][ 1 ] );
            
            int p = cpp.rfind( '.' );
            String nc = cpp.beg_upto( p ) + '_' + String( i ) + cpp.end_from( p );
            if ( file_exists( nc ) ) {
                File o( nc );
                if ( cp == o.c_str() ) {
                    parse_cpp( obj, nc, dyn );
                    continue;
                }
            }
            
            File o( nc, "w" );
            o << cp;
            parse_cpp( obj, nc, dyn );
        }
        return;
    }

    // global flags
    for( int i = 0; i < cpp_parser.lnk_flags.size(); ++i )
        add_LDFLAG( cpp_parser.lnk_flags[ i ] );
    for( int i = 0; i < cpp_parser.lib_names.size(); ++i )
        add_lib_name( cpp_parser.lib_names[ i ] );
    for( int i = 0; i < cpp_parser.fra_names.size(); ++i )
        add_fra_name( cpp_parser.fra_names[ i ] );
    for( int i = 0; i < cpp_parser.lib_paths.size(); ++i )
        add_lib_path( cpp_parser.lib_paths[ i ] );
    if ( cpp_parser.cxx_name != "" )
        add_cxx_name( cpp_parser.cxx_name );

    // local flags
    CompilationEnvironment loc_ce( this );
    for( int i = 0; i < cpp_parser.inc_paths.size(); ++i )
        loc_ce.add_inc_path( cpp_parser.inc_paths[ i ] );
    for( int i = 0; i < cpp_parser.gpu_flags.size(); ++i )
        loc_ce.add_GPUFLAG( cpp_parser.gpu_flags[ i ] );
    for( int i = 0; i < cpp_parser.cpp_flags.size(); ++i )
        loc_ce.add_CPPFLAG( cpp_parser.cpp_flags[ i ] );

    // command
    Ptr<CompilationTree> res = loc_ce.make_obj_compilation_tree( loc_ce.obj_for( cpp, dyn ), make_cpp_compilation_tree( cpp ), dyn );
    for( int i = 0; i < cpp_parser.inc_files.size(); ++i ) {
        String hea = cpp_parser.inc_files[ i ];
        Ptr<CompilationTree> r_h = loc_ce.make_cpp_compilation_tree( hea );
        res->add_child( r_h );
        // moc file ?
        if ( cpp_parser.moc_files.contains( hea ) ) {
            String moc = loc_ce.moc_for( hea );
            if ( last_modification_time_or_zero_of_file_named( moc ) < last_modification_time_or_zero_of_file_named( hea ) )
                exec_cmd( "moc " + hea + " -o " + moc );
            cpp_parser.src_files.push_back_unique( moc );
        }
    }

    // moc file with a .cpp ?
    if ( cpp_parser.moc_files.contains( cpp ) ) {
        String moc = loc_ce.moc_for( cpp );
        if ( last_modification_time_or_zero_of_file_named( moc ) < last_modification_time_or_zero_of_file_named( cpp ) )
            exec_cmd( "moc " + cpp + " -o " + moc );
        cpp_parser.src_files.push_back_unique( moc );
    }

    // if ( not parsed.contains( cpp ) )
    obj.push_back_unique( res );

    // .h -> .cpp or .cu ?
    for( int i = 0; i < cpp_parser.inc_files.size(); ++i ) {
        String h = cpp_parser.inc_files[ i ];
        if ( h.ends_with( ".h" ) ) {
            String base = h.beg_upto( h.size() - 2 );
            if ( file_exists( base + ".cpp" ) )
                parse_cpp( obj, base + ".cpp", dyn );
            if ( file_exists( base + ".cu" ) )
                parse_cpp( obj, base + ".cu", dyn );
        }
    }

    // ext_cpp from src_file
    for( int i = 0; i < cpp_parser.src_files.size(); ++i ) {
        String ext_cpp = cpp_parser.src_files[ i ];
        parse_cpp( obj, ext_cpp, dyn );
    }
}
void CompilationEnvironment::get_def_procs( BasicVec<String> &res ) const {
    if ( child )
        child->get_def_procs( res );
    for( int i = 0; i < def_procs.size(); ++i )
        res.push_back_unique( def_procs[ i ] );
}