00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #if defined(IRIX_CC)
00037
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
00052
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
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
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
00230
00231
00232
00233
00234
00235
00236
00237
00238
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
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
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
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
00419
00420
00421
00422
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 }