#include "build.h" char *GEN_DIR = getenv("GEN_DIR"); char *toolname = "build"; char *inst_suffix = ".sys"; char *default_inst = "build.sys"; char *comp_suffix = ".cmp"; char *version = "<< Demeter Tools/C++ 5.0 >>"; char *tmpdir; extern int _demeter_hash(const char* classname); int greeting = _demeter_hash("Greeting"); main( int argc, char *argv[] ,char*envp[]) //----------------------------------------------------------------- // To show you an example of Demeter's generic function library, // some of the generic functions are included below. To program // for your own needs you can delete all or parts of this code. //----------------------------------------------------------------- { char inst_file[MAXDIRLEN+1]; /* inst file name */ char default_path[MAXDIRLEN+1]; /* default pp files path for pps */ char tmp[MAXDIRLEN+1]; /* basename */ char aname[MAXDIRLEN+1]; /* absolute name */ char n_buf[10*MAXDIRLEN+1]; char inst_path[MAXDIRLEN+1]; int cmd_status; int clean_flag = 0; int compile_flag = 0; int selftest_flag = 0; int inter_flag = 0; int propagate_flag = 0; int trace_flag = 0; struct stat buf; int i; assert( GEN_DIR != NULL ); assert(default_path != NULL); assert(tmp != NULL); assert(aname != NULL); assert(n_buf != NULL); assert(inst_path != NULL); cwd = getcwd(NULL,MAXDIRLEN); if (cwd == NULL) { cerr << toolname << ": unable to open the current directory." << endl; exit(1); } inst_file[0] = '\0'; default_path[0] = '\0'; if (argc == 1) abort_with_help(); i = 1; while ( (i < argc) && (argv[i][0] == '-') ) { if (strcmp(argv[i],"-trace")==0) trace_flag = 1; else if (strcmp(argv[i],"-selftest")==0) selftest_flag = 1; else if (strcmp(argv[i],"-clean")==0) clean_flag = 1; else if (strcmp(argv[i],"-propagate")==0) propagate_flag = 1; else if (strcmp(argv[i],"-inter")==0) inter_flag = 1; else if (strcmp(argv[i],"-compile")==0) compile_flag = 1; else abort_with_help(); i++; } if (i != argc-1) abort_with_help(); if ((strlen(argv[i]) < 6) || (strcmp(argv[i]+strlen(argv[i])-strlen(inst_suffix),inst_suffix)!=0)) { /* it must be a directory */ if (lstat(argv[i], &buf)) { derror('i',strlen(toolname)+strlen(argv[i])+8 > MAXDIRLEN+1, "user_calls(): name buffer overflow."); sprintf(tmp,"%s: open %s",toolname,argv[i]); perror(tmp); abort_with_help(); } else if ((buf.st_mode&S_IFMT) == S_IFDIR) { derror('i',strlen(argv[i]) > MAXDIRLEN+1, "user_calls(): name buffer overflow."); strcpy(aname,argv[i]); absolutename(aname); derror('i',strlen(aname)+strlen(default_inst)+2 > MAXDIRLEN+1, "user_calls(): name buffer overflow."); sprintf(inst_file,"%s/%s",aname,default_inst); polishpath(inst_file); strcpy(default_path,aname); absolutename(default_path); polishpath(default_path); cout << toolname << ": reading " << inst_file << " ..." << endl; } else abort_with_help(); } else { derror('i',strlen(argv[i]) > MAXDIRLEN+1, "user_calls(): name buffer overflow."); strcpy(aname,argv[i]); absolutename(aname); strcpy(inst_file,aname); polishpath(inst_file); basename(aname); strcpy(default_path,aname); polishpath(default_path); cout << toolname << ": reading " << inst_file << " ..." << endl; } /* create Instantiation object */ Instantiation *iInstantiation = new Instantiation(); assert( iInstantiation!= NULL ); iInstantiation = ( Instantiation * ) iInstantiation -> g_parse( inst_file ); if ( iInstantiation == NULL ) { cout << toolname << ": failed to parse the instantiation file." << endl; exit(1); } else cout << toolname << ": successfully parsed in the instantiation file." << endl; /* create schema object if necessary */ Cd_graph *iCd_graph = NULL; iInstantiation->create_schema(iCd_graph); if (iCd_graph == NULL) { cout << toolname << ": failed to create the schema object." << endl; exit(1); } else cout << toolname << ": successfully created the schema object specified in the instantiation file." << endl; iInstantiation->set_parsed_schema(iCd_graph); derror('e',strlen(iInstantiation->get_inst_name()->get_name()->get_val()) > MAXDIRLEN,"user_calls(): name buffer overflow."); derror('e',strlen(iInstantiation->get_inst_name()->get_name()->get_val()) > MAXNAMLEN,"user_calls(): name buffer overflow."); strcpy(inst_path,iInstantiation->get_inst_name()->get_name()->get_val()); if (inst_path[0] != '/') absolutename(inst_path); polishpath(inst_path); int rm_status = 0; if (clean_flag) { cout << toolname << ": removing the directory " << inst_path << " ..." << endl; rm_status = rm(inst_path); if (rm_status) exit(1); else cout << toolname << ": removed the directory " << inst_path << "." << endl; } int mkdir_status = mkdir(inst_path,0755); if (mkdir_status == 0) cout << toolname << ": created the directory " << inst_path << "." << endl; else if (mkdir_status && ( errno != EEXIST)) { derror('e',strlen(toolname) + strlen(inst_path) + 9 > MAXDIRLEN+1,"user_calls(): name buffer overflow."); sprintf(n_buf,"%s: mkdir %s",toolname,inst_path); perror(n_buf); exit(1); } if (access(inst_path, R_OK|W_OK|X_OK) != 0) { derror('e',strlen(toolname) + strlen(inst_path) + 9 > MAXDIRLEN+1,"user_calls(): name buffer overflow."); sprintf(n_buf,"%s : %s",toolname,inst_path); perror(n_buf); exit(1); } tmpdir = new char[strlen(inst_path)+50]; sprintf(tmpdir,"%s/notmod",inst_path); if (mkdir(tmpdir,0755)) { if (errno != EEXIST) { cerr << toolname << ": unable to create " << tmpdir << " for holding temporary files." << endl; perror(tmpdir); exit(1); } } if (access(tmpdir, X_OK | R_OK | W_OK )) { cerr << toolname << ": unable to have access to " << cwd << "/" << tmpdir << " for holding temporary files." << endl; perror(tmpdir); exit(1); } strcat(tmpdir,"/tmp"); if (mkdir(tmpdir,0755)) { if (errno != EEXIST) { cerr << toolname << ": unable to create " << tmpdir << " for holding temporary files." << endl; perror(tmpdir); exit(1); } } if (access(tmpdir, X_OK | R_OK | W_OK )) { cerr << toolname << ": unable to have access to " << cwd << "/" << tmpdir << " for holding temporary files." << endl; perror(tmpdir); exit(1); } /* create file cd in that env. */ derror('e',strlen(inst_path) + 30 > MAXDIRLEN+1,"user_calls(): name buffer overflow."); sprintf(n_buf,"%s/cd.cd",inst_path); strcpy(tmp,tempnam(tmpdir,"cd.cd")); ofstream cd_stream( tmp ); iCd_graph->g_print(cd_stream); cd_stream.close(); mv_if_change(mv_interactive,tmp,n_buf); sprintf(n_buf,"%s/main.C",inst_path); cout << toolname << ": generating " << n_buf << " ..." << endl; strcpy(tmp,tempnam(tmpdir,"main.C")); ofstream main_C( tmp ); if (!main_C) { cerr << toolname << ": unable to open " << tmp << " for output." << endl; exit(1); } main_C << "#include \"" << iInstantiation->get_inst_name()->get_name()->get_val() << ".h\"\n" << "\n" << "char *GEN_DIR = getenv(\"GEN_DIR\");\n" << "\n" << "main( int argc, char *argv[] ,char *envp[] )\n" << "{\n"; main_C << "\n" << iInstantiation->get_start()->get_code()->get_val() << "\n}\n"; main_C.close(); mv_if_change(mv_interactive,tmp,n_buf); // global.h sprintf(n_buf,"%s/global.h",inst_path); cout << toolname << ": generating " << n_buf << " ... " << endl; strcpy(tmp,tempnam(tmpdir,"global.h")); ofstream global_h( tmp ); if (!global_h) { cerr << toolname << ": unable to open " << tmp << " for output." << endl; exit(1); } global_h << "#include \n"; global_h << "\n"; global_h << "#ifndef NOTRACE\n"; global_h << "#define DEM_TRACE(c,m) DemTrace demTrace(__FILE__,__LINE__,c,m)\n"; global_h << "#else\n"; global_h << "#define DEM_TRACE(c,m)\n"; global_h << "#endif\n\n"; if ( iInstantiation->get_declared() ) global_h << iInstantiation->get_declared()->get_code()->get_val() << endl; global_h.close(); mv_if_change(mv_interactive,tmp,n_buf); if ( iInstantiation->get_defined() ) { sprintf(n_buf,"%s/%s_global.C",inst_path,iInstantiation->get_inst_name()->get_name()->get_val()); cout << toolname << ": generating " << n_buf << " ... " << endl; strcpy(tmp,tempnam(tmpdir,"global.C")); ofstream global_C( tmp ); if (!global_C) { cerr << toolname << ": unable to open " << tmp << " for output." << endl; exit(1); } global_C << "#include \"" << iInstantiation->get_inst_name()->get_name()->get_val() << ".h\"\n"; global_C << iInstantiation->get_defined()->get_code()->get_val() << "\n\n"; global_C.close(); mv_if_change(mv_interactive,tmp,n_buf); } /* put local propagation patterns in */ cout << "\n\n"; iInstantiation->inject_local_pps(inst_path,default_path); /* put components in */ Search_path_Nlist *comp_names = new Search_path_Nlist(); iInstantiation->inject_components(inst_path,default_path,comp_names); /* make */ sprintf(n_buf,"%s/Imakefile",inst_path); cout << toolname << ": generating " << n_buf << " ... " << endl; strcpy(tmp,tempnam(tmpdir,"Imakefile")); ofstream imakefile( tmp ); if (!imakefile) { cerr << toolname << ": unable to open " << tmp << " for output." << endl; exit(1); } imakefile << "#define IHaveSubdirs\n"; imakefile << "#define PassCDebugFlags 'CDEBUGFLAGS=$(CDEBUGFLAGS)'\n"; imakefile << "\n"; imakefile << "/**************************************************************\n"; imakefile << "* (1). The class dictionary file name. For example, if your *\n"; imakefile << "* file is called myclasses.cd, say *\n"; imakefile << "* *\n"; imakefile << "* USERCD = myclasses.cd *\n"; imakefile << "***************************************************************/\n"; imakefile << "\n"; imakefile << "USERCD = cd.cd\n"; imakefile << "\n"; imakefile << "\n"; imakefile << "/**************************************************************\n"; imakefile << "* (2). Give the name of this environment. *\n"; imakefile << "* It is mandatory if you want to build a library from *\n"; imakefile << "* this environment. *\n"; imakefile << "* *\n"; imakefile << "* o The include file for the library is $(TOPENVNAME).h *\n"; imakefile << "* o The name of the library if lib$(TOPENVNAME).a *\n"; imakefile << "* o The name is also used to add suffix to each class defined *\n"; imakefile << "* in this environment. *\n"; imakefile << "***************************************************************/\n"; imakefile << "\n"; imakefile << "TOPENVNAME = " << iInstantiation->get_inst_name()->get_name()->get_val() << "\n"; imakefile << "\n"; imakefile << "\n"; imakefile << "/**************************************************************\n"; imakefile << "* (3). SI for generating a single inheritance environment *\n"; imakefile << "* MI for generating a multiple inheritance environment *\n"; imakefile << "* *\n"; imakefile << "* SIMI = MI *\n"; imakefile << "***************************************************************/\n"; imakefile << "\n"; imakefile << "SIMI = SI\n"; imakefile << "\n"; imakefile << "/**************************************************************\n"; imakefile << "* (4). IMPORTANT!!! *\n"; imakefile << "* List all the names of libraries generated from other *\n"; imakefile << "* Demeter environments and used to build an executable *\n"; imakefile << "* in this environment. *\n"; imakefile << "***************************************************************/\n"; imakefile << "\n"; imakefile << "DEMETERBUILDLIBS =\n"; imakefile << "\n"; imakefile << "/**************************************************************\n"; imakefile << "* (5). If you do not want to have the intermediate files *\n"; imakefile << "* generated by propagate use *\n"; imakefile << "* *\n"; imakefile << "* WANTPPINTER = *\n"; imakefile << "***************************************************************/\n"; imakefile << "\n"; imakefile << "WANTPPINTER = -i\n"; imakefile << "\n"; imakefile << "/**************************************************************\n"; imakefile << "* (6). Subdirectory names in the current directory. *\n"; imakefile << "* In these subdirectories, you can write additional *\n"; imakefile << "* modules to create an executable program or create *\n"; imakefile << "* a libray. You have to provide your own Imakefile *\n"; imakefile << "* in these subdirectories. *\n"; imakefile << "* *\n"; imakefile << "* List all the names of the .o files created from these *\n"; imakefile << "* subdirectories and used to create an executable program *\n"; imakefile << "* or create a library. (IMPORTANT!!!) *\n"; imakefile << "* *\n"; imakefile << "* The names of subdirectories should be placed before *\n"; imakefile << "* notmod. *\n"; imakefile << "***************************************************************/\n"; imakefile << "\n"; imakefile << "SUBDIRS = notmod\n"; imakefile << "\n"; imakefile << "EXTRASRCS =\n"; imakefile << "\n"; imakefile << "EXTRAOBJS =\n"; imakefile << "\n"; imakefile << "\n"; imakefile << "/*************************************************************\n"; imakefile << "* (7) Give where Demeter lives. *\n"; imakefile << "* dmkmf will give default setup. You might use a *\n"; imakefile << "* different integration strategy. *\n"; imakefile << "**************************************************************/\n"; imakefile << "\n"; imakefile << "DEMETER = $(TOP)\n"; imakefile << "\n"; imakefile << "/*************************************************************\n"; imakefile << "* (8). Use INCLUDES to pass -I flags. *\n"; imakefile << "* Use DEFINES to pass -D or -U flags. *\n"; imakefile << "* *\n"; imakefile << "* Use -DNOTRACE to turn off trace. *\n"; imakefile << "**************************************************************/\n"; imakefile << "\n"; imakefile << "INCLUDES = -I$(DEMETER)/include\n"; imakefile << "\n"; imakefile << "DEFINES = -D$(SIMI) \n"; imakefile << "\n"; imakefile << "CDEBUGFLAGS = -g \n"; imakefile << "\n"; imakefile << "OCFLAGS= \n"; imakefile << "\n"; imakefile << "/***************************************************************\n"; imakefile << "* (9). Add the libraries(in full path) here, including all the *\n"; imakefile << "* names of libraries generated from Demeter environments *\n"; imakefile << "* and used to build an executable. *\n"; imakefile << "* *\n"; imakefile << "* IMPORTANT!!! *\n"; imakefile << "* Add those libraries BEFORE libdemeter.a *\n"; imakefile << "****************************************************************/\n"; imakefile << "LOCAL_LIBRARIES = $(DEMETER)/lib-$(SIMI)/`get-cpu`/libdemeter`basename $(CCC)`.a -ll\n"; imakefile << "\n"; imakefile << "/***************************************************************\n"; imakefile << "* (10). Set to nosuffix if you don't want to add suffixes to *\n"; imakefile << "* classes. *\n"; imakefile << "* Adding suffixes is to avoid name clashing when you *\n"; imakefile << "* build libraries. *\n"; imakefile << "* *\n"; imakefile << "* NOSUFFIX = *\n"; imakefile << "****************************************************************/\n"; imakefile << "\n"; imakefile << "NOSUFFIX = nosuffix\n"; imakefile << "\n"; imakefile << "\n"; imakefile << "/***************************************************************\n"; imakefile << "* (11). Choose your favorite C++ and C compilers *\n"; imakefile << "* *\n"; imakefile << "* CCC = g++ *\n"; imakefile << "****************************************************************/\n"; imakefile << "\n"; imakefile << "CCC = /local/apps/objectcenter/bin/CC\n"; imakefile << "\n"; imakefile << "CC = cc\n"; imakefile << "ccC = cc\n"; imakefile << "\n"; imakefile << "/****************************************************************\n"; imakefile << "* (12). Overwrite cd-print while regenerating this environment. *\n"; imakefile << "* *\n"; imakefile << "* OVERWRITECDPRINT=no *\n"; imakefile << "*****************************************************************/\n"; imakefile << "\n"; imakefile << "OVERWRITECDPRINT=yes\n"; imakefile << "\n"; imakefile << "/****************************************************************\n"; imakefile << "* (13). Overwrite cd-parse while regenerating this environment. *\n"; imakefile << "* *\n"; imakefile << "* OVERWRITECDPARSE=no *\n"; imakefile << "*****************************************************************/\n"; imakefile << "\n"; imakefile << "OVERWRITECDPARSE=yes\n"; imakefile << "\n"; imakefile << "/*****************************************************************\n"; imakefile << "* (14). Choose buildrun or leave it blank to build an executable *\n"; imakefile << "* program ONLY. *\n"; imakefile << "* *\n"; imakefile << "* Choose buildlib to build a library ONLY. *\n"; imakefile << "* *\n"; imakefile << "* Choose buildrunlib to build an executable program AND a *\n"; imakefile << "* library. *\n"; imakefile << "* *\n"; imakefile << "* EXECLIBFLAG = buildrun *\n"; imakefile << "* EXECLIBFLAG = buildlib *\n"; imakefile << "* EXECLIBFLAG = buildrunlib *\n"; imakefile << "******************************************************************/\n"; imakefile << "\n"; imakefile << "EXECLIBFLAG =\n"; imakefile << "\n"; imakefile << "\n"; imakefile << "/*****************************************************************\n"; imakefile << "* (15). The path where the target library is. *\n"; imakefile << "* The default name of the library is lib$(TOPENVNAME).a *\n"; imakefile << "******************************************************************/\n"; imakefile << "\n"; imakefile << "TARGETLIBDIR = ../lib\n"; imakefile << "TARGETLIBNAME = $(TOPENVNAME)\n"; imakefile << "\n"; imakefile << "\n"; imakefile << "/*****************************************************************\n"; imakefile << "* (16). The path of the header file, a concatenation of all the *\n"; imakefile << "* header files in this environment. *\n"; imakefile << "* The default name of the library is $(TOPENVNAME).h *\n"; imakefile << "******************************************************************/\n"; imakefile << "\n"; imakefile << "TARGETINCLUDEDIR = ../include\n"; imakefile << "TARGETINCLUDENAME = $(TOPENVNAME)\n"; imakefile << "\n"; imakefile << "\n"; imakefile << "/*****************************************************************\n"; imakefile << "* (17). The list of classes for which constructor will be not *\n"; imakefile << "* aumantically generated. *\n"; imakefile << "******************************************************************/\n"; imakefile << "\n"; imakefile << "NOCONSTRUCTOR=\n"; imakefile << "\n"; imakefile << "/*****************************************************************\n"; imakefile << "* (18). The list of the components used in this environment. *\n"; imakefile << "* COMPONENTS is generated. DONT EDIT!!! *\n"; imakefile << "******************************************************************/\n"; imakefile << "\n"; imakefile << "COMPONENTS = "; if (comp_names->list_length() > 0) { Search_path_list_iterator next_name(*comp_names); Search_path *each_name; while (each_name = next_name()) imakefile << each_name->get_search_path()->get_val() << " "; } imakefile << "\n"; imakefile << "\n"; imakefile << "/*****************************************************************\n"; imakefile << "* (19). The rule to build this environment. DONT EDIT!! *\n"; imakefile << "******************************************************************/\n"; imakefile << "\n"; imakefile << "\n"; imakefile << "DemeterProgram()\n"; imakefile << "\n"; imakefile << "\n"; imakefile.close(); mv_if_change(mv_interactive,tmp,n_buf); sprintf(n_buf,"cd %s; dmkmf; make ",inst_path); cmd_status = system(n_buf); if (cmd_status) { cout << toolname << ": got interrupt signal from propagate. Stopped." << endl; exit(1); } return (0); }