Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members  

driver2.cc

Go to the documentation of this file.
00001 /*
00002   Copyright (C) 1997-2001 Shigeru Chiba, Tokyo Institute of Technology.
00003 
00004   Permission to use, copy, distribute and modify this software and   
00005   its documentation for any purpose is hereby granted without fee,        
00006   provided that the above copyright notice appear in all copies and that 
00007   both that copyright notice and this permission notice appear in 
00008   supporting documentation.
00009 
00010   Shigeru Chiba makes no representations about the suitability of this 
00011   software for any purpose.  It is provided "as is" without express or
00012   implied warranty.
00013 */
00014 
00015 /*
00016   Copyright (c) 1995, 1996 Xerox Corporation.
00017   All Rights Reserved.
00018 
00019   Use and copying of this software and preparation of derivative works
00020   based upon this software are permitted. Any copy of this software or
00021   of any derivative work must include the above copyright notice of
00022   Xerox Corporation, this paragraph and the one after it.  Any
00023   distribution of this software or derivative works must comply with all
00024   applicable United States export control laws.
00025 
00026   This software is made available AS IS, and XEROX CORPORATION DISCLAIMS
00027   ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE
00028   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00029   PURPOSE, AND NOTWITHSTANDING ANY OTHER PROVISION CONTAINED HEREIN, ANY
00030   LIABILITY FOR DAMAGES RESULTING FROM THE SOFTWARE OR ITS USE IS
00031   EXPRESSLY DISCLAIMED, WHETHER ARISING IN CONTRACT, TORT (INCLUDING
00032   NEGLIGENCE) OR STRICT LIABILITY, EVEN IF XEROX CORPORATION IS ADVISED
00033   OF THE POSSIBILITY OF SUCH DAMAGES.
00034 */
00035 
00036 #if defined(IRIX_CC)
00037 // for open()
00038 #include <sys/types.h>
00039 #include <sys/stat.h>
00040 #include <fcntl.h>
00041 #endif
00042 
00043 #include <stdio.h>
00044 #include <stdlib.h>
00045 #include <unistd.h>
00046 #include <string.h>
00047 #include <fstream.h>
00048 #include <iostream>
00049 #include "types.h"
00050 
00051 // g++ recognizes a .ii file as preprocessed C++ source code.
00052 // CC recognizes a .i file as preprocessed C++ source code.
00053 
00054 #if defined(IRIX_CC)
00055 #define OUTPUT_EXT      ".i"
00056 #else
00057 #define OUTPUT_EXT      ".ii"
00058 #endif
00059 
00060 #define CPP_EXT         ".occ"
00061 #define SLIB_EXT        ".so"
00062 #define OBJ_EXT         ".o"
00063 
00064 extern "C" {
00065 #if !defined(IRIX_CC) && !defined(__GLIBC__) && !defined(__STRICT_ANSI__)
00066     int execvp(...);
00067 #endif
00068     int wait(int*);
00069 }
00070 
00071 #if defined(IRIX_CC)
00072 const char* compilerName = "CC";
00073 #else
00074 const char* compilerName = "g++";
00075 #endif
00076 const char* linkerName = "ld";
00077 const char* opencxxErrorMessage = " Error(s).  OpenC++ stops.\n";
00078 
00079 // defined in driver.cc
00080 
00081 extern bool showProgram;
00082 extern bool doCompile;
00083 extern bool makeExecutable;
00084 extern bool doPreprocess;
00085 extern bool doTranslate;
00086 extern bool verboseMode;
00087 extern bool regularCpp;
00088 extern bool makeSharedLibrary;
00089 extern char* sharedLibraryName;
00090 extern bool preprocessTwice;
00091 
00092 extern const char* cppArgv[];
00093 extern const char* ccArgv[];
00094 
00095 extern void ParseCmdOptions(int from, int argc, char** argv, char*& source);
00096 extern void AddCppOption(const char* arg);
00097 extern void AddCcOption(const char* arg);
00098 extern void CloseCcOptions();
00099 extern void ShowCommandLine(const char* cmd, const char** args);
00100 
00101 bool ParseTargetSpecificOptions(char* arg, char*& source_file);
00102 void RunLinker();
00103 char* RunPreprocessor(const char* src);
00104 char* OpenCxxOutputFileName(const char* src);
00105 void RunCompiler(const char* src, const char* occsrc);
00106 void RunSoCompiler(const char* src_file);
00107 void* LoadSoLib(char* file_name);
00108 void* LookupSymbol(void* handle, char* symbol);
00109 
00110 #if !SHARED_OPTION
00111 static void RunSoLinker(const char* org_src, char* target);
00112 #endif
00113 static char* MakeTempFilename(const char* src, const char* suffix);
00114 
00115 
00116 bool ParseTargetSpecificOptions(char*, char*&)
00117 {
00118     return FALSE;
00119 }
00120 
00121 void RunLinker()
00122 {
00123     if(!doCompile || !makeExecutable){
00124         cerr << "OpenC++: no source file.\n";
00125         return;
00126     }
00127 
00128     const char* linker = compilerName;
00129     char* slib = nil;
00130     if(makeSharedLibrary){
00131 #if SHARED_OPTION
00132 #if defined(IRIX_CC)
00133         AddCcOption("-n32");
00134 #else
00135         AddCcOption("-fPIC");
00136 #endif
00137         AddCcOption("-shared");
00138 #else /* SHARED_OPTION */
00139         AddCcOption("-Bshareable");
00140         linker = linkerName;
00141 #endif
00142         if(sharedLibraryName != nil && *sharedLibraryName != '\0'){
00143             slib = MakeTempFilename(sharedLibraryName, SLIB_EXT);
00144             AddCcOption("-o");
00145             AddCcOption(slib);
00146         }
00147     }
00148 
00149     ccArgv[0] = linker;
00150     CloseCcOptions();
00151 
00152     if(verboseMode){
00153         cerr << "[Link... ";
00154         ShowCommandLine(linker, ccArgv);
00155         cerr << "]\n";
00156     }
00157 
00158     if(fork() == 0){
00159         execvp(linker, (char**)ccArgv);
00160         perror("cannot invoke a compiler");
00161     }
00162     else{
00163         int status;
00164 
00165         wait(&status);
00166         if(status != 0)
00167             exit(1);
00168     }
00169 
00170     delete [] slib;
00171 }
00172 
00173 char* RunPreprocessor(const char* src)
00174 {
00175     char* dest = MakeTempFilename(src, CPP_EXT);
00176     if(!regularCpp)
00177         AddCppOption("-D__opencxx");
00178 
00179     AddCppOption("-E");
00180 #if defined(IRIX_CC)
00181     AddCppOption("-n32");
00182 #else
00183     AddCppOption("-o");
00184     AddCppOption(dest);
00185     AddCppOption("-x");
00186     AddCppOption("c++");
00187 #endif
00188     AddCppOption(src);
00189     AddCppOption((char*)0);
00190 
00191     if(verboseMode){
00192         cerr << "[Preprocess... ";
00193         ShowCommandLine(compilerName, cppArgv);
00194 #if defined(IRIX_CC)
00195         cerr << " > " << dest;
00196 #endif
00197         cerr << "]\n";
00198     }
00199 
00200     if(fork() == 0){
00201 #if defined(IRIX_CC)
00202         int fd = open(dest, O_WRONLY | O_CREAT, 0666);
00203         if (fd < 0) {
00204             perror(dest);
00205             exit(1);
00206         }
00207         dup2(fd, 1);
00208 #endif
00209         execvp(compilerName, (char**)cppArgv);
00210         perror("cannot invoke a compiler");
00211     }
00212     else{
00213         int status;
00214 
00215         wait(&status);
00216         if(status != 0)
00217             exit(1);
00218     }
00219 
00220     return dest;
00221 }
00222 
00223 char* OpenCxxOutputFileName(const char* src)
00224 {
00225     return MakeTempFilename(src, OUTPUT_EXT);
00226 }
00227 
00228 /*
00229    To create a shared library foo.so from foo.cc,
00230 
00231    SunOS, Solaris, Linux (v2.0, gcc 2.7.2.2):
00232                 g++ -fPIC -shared -o foo.so foo.cc
00233 
00234    Irix with naitive CC:
00235                 CC -shared -n32 -o foo.so foo.cc
00236 
00237    FreeBSD:     g++ -fPIC -c foo.cc
00238                 ld -Bshareable -o foo.so foo.o
00239 
00240 */
00241 void RunCompiler(const char* org_src, const char* occ_src)
00242 {
00243     char* slib = nil;
00244     if(makeSharedLibrary){
00245         const char* name = org_src;
00246         if(sharedLibraryName != nil && *sharedLibraryName != '\0')
00247             name = sharedLibraryName;
00248 
00249         slib = MakeTempFilename(name, SLIB_EXT);
00250 #if SHARED_OPTION
00251 #if defined(IRIX_CC)
00252         AddCcOption("-n32");
00253 #else
00254         AddCcOption("-fPIC");
00255 #endif
00256         AddCcOption("-shared");
00257         if(makeExecutable){
00258             AddCcOption("-o");
00259             AddCcOption(slib);
00260         }
00261         else
00262             AddCcOption("-c");
00263 #else /* SHARED_OPTION */
00264         AddCcOption("-fPIC");
00265         AddCcOption("-c");
00266 #endif
00267     }
00268     else
00269         if(!makeExecutable)
00270             AddCcOption("-c");
00271 
00272 #if !defined(IRIX_CC)
00273     if(preprocessTwice){
00274         AddCcOption("-x");
00275         AddCcOption("c++");
00276     }
00277 #endif
00278 
00279     AddCcOption(occ_src);
00280     CloseCcOptions();
00281 
00282     if(verboseMode){
00283         cerr << "[Compile... ";
00284         ShowCommandLine(compilerName, ccArgv);
00285         cerr << "]\n";
00286     }
00287 
00288     if(fork() == 0){
00289         execvp(compilerName, (char**)ccArgv);
00290         perror("cannot invoke a compiler");
00291     }
00292     else{
00293         int status;
00294 
00295         wait(&status);
00296         if(status != 0)
00297             exit(1);
00298     }
00299 
00300 #if !SHARED_OPTION
00301     if(makeSharedLibrary && makeExecutable)
00302         RunSoLinker(org_src, slib);
00303 #endif
00304 
00305     delete [] slib;
00306 }
00307 
00308 void RunSoCompiler(const char* src_file)
00309 {
00310     const char* cc_argv[8];
00311     int i = 0;
00312 
00313     char* slib = MakeTempFilename(src_file, SLIB_EXT);
00314     cc_argv[i++] = compilerName;
00315 #if SHARED_OPTION
00316 #if defined(IRIX_CC)
00317     cc_argv[i++] = "-n32";
00318 #else
00319     cc_argv[i++] = "-fPIC";
00320 #endif
00321     cc_argv[i++] = "-shared";
00322     cc_argv[i++] = "-o";
00323     cc_argv[i++] = slib;
00324 #else
00325     cc_argv[i++] = "-fPIC";
00326     cc_argv[i++] = "-c";
00327 #endif
00328     cc_argv[i++] = src_file;
00329     cc_argv[i++] = (char*)0;
00330 
00331     if(verboseMode){
00332         cerr << "[Compile... ";
00333         ShowCommandLine(compilerName, cc_argv);
00334         cerr << "]\n";
00335     }
00336 
00337     if(fork() == 0){
00338         execvp(compilerName, (char**)cc_argv);
00339         perror("cannot invoke a compiler");
00340     }
00341     else{
00342         int status;
00343 
00344         wait(&status);
00345         if(status != 0)
00346             exit(1);
00347     }
00348 
00349 #if !SHARED_OPTION
00350     RunSoLinker(src_file, slib);
00351 #endif
00352 
00353     delete [] slib;
00354 }
00355 
00356 void* LoadSoLib(char* file_name)
00357 {
00358     void* handle = nil;
00359 #if USE_DLOADER
00360     handle = dlopen(file_name, RTLD_GLOBAL | RTLD_LAZY);
00361     handle = dlopen(file_name, RTLD_GLOBAL | RTLD_LAZY);
00362     if(handle == NULL){
00363         cerr << "dlopen(" << file_name << ") failed: " << dlerror() << '\n';
00364         exit(1);
00365     }
00366 #endif /* USE_DLOADER */
00367 
00368     return handle;
00369 }
00370 
00371 void* LookupSymbol(void* handle, char* symbol)
00372 {
00373     void* func = nil;
00374 #if USE_DLOADER
00375     func = dlsym(handle, symbol);
00376     if(func == NULL){
00377         cerr << "dlsym() failed (non metaclass?): " << dlerror() << '\n';
00378         exit(1);
00379     }
00380 #endif
00381     return func;
00382 }
00383 
00384 // RunSoLinker() is used only if SHARED_OPTION is false (FreeBSD).
00385 #if !SHARED_OPTION
00386 
00387 static void RunSoLinker(const char* org_src, char* target)
00388 {
00389     const char* ld_argv[6];
00390     ld_argv[0] = linkerName;
00391     ld_argv[1] = "-Bshareable";
00392     ld_argv[2] = "-o";
00393     ld_argv[3] = target;
00394     ld_argv[4] = MakeTempFilename(org_src, OBJ_EXT);
00395     ld_argv[5] = (char*)0;
00396 
00397     if(verboseMode){
00398         cerr << "[Link... ";
00399         ShowCommandLine(linkerName, ld_argv);
00400         cerr << "]\n";
00401     }
00402 
00403     if(fork() == 0){
00404         execvp(linkerName, (char**)ld_argv);
00405         perror("cannot invoke a linker");
00406     }
00407     else{
00408         int status;
00409 
00410         wait(&status);
00411         if(status != 0)
00412             exit(1);
00413     }
00414 
00415     unlink(ld_argv[4]);
00416     delete [] ld_argv[4];
00417 }
00418 #endif /* SHARED_OPTION */
00419 
00420 /*
00421    For example, if src is "../foo.cc", MakeTempFilename() makes
00422    "foo.<suffix>".
00423 */
00424 static char* MakeTempFilename(const char* src, const char* suffix)
00425 {
00426     const char* start;
00427     const char* end;
00428 
00429     start = strrchr(src, '/');
00430     if(start == nil)
00431         start = src;
00432     else
00433         ++start;
00434 
00435     end = strrchr(start, '.');
00436     if(end == nil)
00437         end = src + strlen(src);
00438 
00439     char* result = new char[end - start + strlen(suffix) + 1];
00440     strncpy(result, start, end - start);
00441     result[end - start] = '\0';
00442     strcat(result, suffix);
00443     return result;
00444 }

Generated on Mon Feb 10 17:32:46 2003 for VFiasco Semantics Compiler by doxygen1.2.15