Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • driver/cfa.cc

    rbbb1b35 r92a9768  
    1010// Created On       : Tue Aug 20 13:44:49 2002
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Aug 23 16:27:07 2019
    13 // Update Count     : 411
     12// Last Modified On : Fri Jan 31 16:48:03 2020
     13// Update Count     : 421
    1414//
    1515
    1616#include <iostream>
    17 #include <cstdio>                                                                               // perror
    18 #include <cstdlib>                                                                              // putenv, exit
    19 #include <unistd.h>                                                                             // execvp
    20 #include <string>                                                                               // STL version
    21 #include <string.h>                                                                             // strcmp
    22 #include <algorithm>                                                                    // find
     17#include <cstdio>      // perror
     18#include <cstdlib>     // putenv, exit
     19#include <climits>     // PATH_MAX
     20#include <unistd.h>    // execvp
     21#include <string>      // STL version
     22#include <string.h>    // strcmp
     23#include <algorithm>   // find
    2324
    2425#include <sys/types.h>
     
    3334using std::to_string;
    3435
    35 //#define __DEBUG_H__
    36 
     36// #define __DEBUG_H__
     37
     38// "N__=" suffix
     39static string __CFA_FLAGPREFIX__( "__CFA_FLAG" );
    3740
    3841void Putenv( char * argv[], string arg ) {
    39         static int flags = 0;                                                           // environment variables must have unique names
    40 
    41         if ( putenv( (char *)( *new string( string( "__CFA_FLAG" + to_string( flags++ ) + "__=" ) + arg ) ).c_str() ) ) {
     42        // environment variables must have unique names
     43        static int flags = 0;
     44
     45        if ( putenv( (char *)( *new string( string( __CFA_FLAGPREFIX__ + to_string( flags++ ) + "__=" ) + arg ) ).c_str() ) ) {
    4246                cerr << argv[0] << " error, cannot set environment variable." << endl;
    4347                exit( EXIT_FAILURE );
     
    4549} // Putenv
    4650
    47 
    48 bool prefix( const string & arg, const string & pre ) { // check if string has prefix
     51// check if string has prefix
     52bool prefix( const string & arg, const string & pre ) {
    4953        return arg.substr( 0, pre.size() ) == pre;
    5054} // prefix
    5155
    52 bool suffix( const string & arg ) {                                             // check if string has suffix
     56inline bool ends_with(const string & str, const string & sfix) {
     57        if (sfix.size() > str.size()) return false;
     58        return std::equal(str.rbegin(), str.rbegin() + sfix.size(), sfix.rbegin(), sfix.rend());
     59}
     60
     61// check if string has suffix
     62bool suffix( const string & arg ) {
    5363        enum { NumSuffixes = 3 };
    5464        static const string suffixes[NumSuffixes] = { "cfa", "hfa", "ifa" };
     
    6474    struct stat info;
    6575    if ( stat( path.c_str(), &info ) != 0 ) return false;
    66     if ( info.st_mode & S_IFDIR ) return true;
    67         return false;
     76        return (info.st_mode & S_IFDIR) != 0;
    6877} // dirExists
     78
     79static inline string dir(const string & path) {
     80        return path.substr(0, path.find_last_of('/'));
     81}
     82
     83// Different path modes
     84enum PathMode {
     85        Installed,     // cfa is installed, use prefix
     86        BuildTree,     // cfa is in the tree, use source and build tree
     87        Distributed    // cfa is distributed, use build tree for includes and executable directory for .cfs
     88};
     89
     90// Get path mode from /proc
     91PathMode FromProc() {
     92        std::string abspath;
     93        abspath.resize(PATH_MAX);
     94
     95        // get executable path from /proc/self/exe
     96        ssize_t size = readlink("/proc/self/exe", const_cast<char*>(abspath.c_str()), abspath.size());
     97        if(size <= 0) {
     98                std::cerr << "Error could not evaluate absolute path from /proc/self/exe" << std::endl;
     99                std::cerr << "Failed with " << std::strerror(errno) << std::endl;
     100                std::exit(1);
     101        }
     102
     103        // Trim extra characters
     104        abspath.resize(size);
     105
     106        // Are we installed
     107        if(abspath.rfind(CFA_BINDIR  , 0) == 0) { return Installed; }
     108
     109        // Is this the build tree
     110        if(abspath.rfind(TOP_BUILDDIR, 0) == 0) { return BuildTree; }
     111
     112        // Does this look like distcc
     113        if(abspath.find("/.cfadistcc/") != std::string::npos) { return Distributed; }
     114
     115        // None of the above? Give up since we don't know where the prelude or include directories are
     116        std::cerr << "Cannot find required files from excutable path " << abspath << std::endl;
     117        std::exit(1);
     118}
    69119
    70120
     
    82132        string heading;                                                                         // banner printed at start of cfa compilation
    83133        string arg;                                                                                     // current command-line argument during command-line parsing
    84         string Bprefix;                                                                         // path where gcc looks for compiler command steps
     134        string bprefix;                                                                         // path where gcc looks for compiler steps
    85135        string langstd;                                                                         // language standard
    86136
     
    103153        bool m32 = false;                                                                       // -m32 flag
    104154        bool m64 = false;                                                                       // -m64 flag
    105         bool intree = false;                                                            // build in tree
     155        bool compiling_libs = false;
    106156        int o_file = 0;                                                                         // -o filename position
     157
     158        PathMode path = FromProc();
    107159
    108160        const char *args[argc + 100];                                           // cfa command line values, plus some space for additional flags
     
    135187                        } else if ( arg == "-XCFA" ) {                          // CFA pass through
    136188                                i += 1;
     189                                if ( i == argc ) continue;                              // next argument available ?
    137190                                Putenv( argv, argv[i] );
    138191
     
    159212                        } else if ( arg == "-no-include-stdhdr" ) {
    160213                                noincstd_flag = true;                                   // strip the no-include-stdhdr flag
    161                         } else if ( arg == "-in-tree" ) {
    162                                 intree = true;
     214                        } else if ( arg == "-cfalib") {
     215                                compiling_libs = true;
    163216                        } else if ( arg == "-compiler" ) {
    164217                                // use the user specified compiler
     
    211264                                } // if
    212265                        } else if ( prefix( arg, "-B" ) ) {
    213                                 Bprefix = arg.substr(2);                                // strip the -B flag
    214                                 args[nargs++] = ( *new string( string("-D__GCC_BPREFIX__=") + Bprefix ) ).c_str();
     266                                bprefix = arg.substr(2);                                // strip the -B flag
    215267                        } else if ( arg == "-c" || arg == "-S" || arg == "-E" || arg == "-M" || arg == "-MM" ) {
    216268                                args[nargs++] = argv[i];                                // pass argument along
     
    263315        // -E flag stops at cc1 stage 1, so cfa-cpp in cc1 stage 2 is never executed.
    264316        if ( cpp_flag && CFA_flag ) {
    265                 cerr << argv[0] << " error, cannot use -E and -CFA flags together." << endl;
    266                 exit( EXIT_FAILURE );
     317                CFA_flag = false;
     318                cerr << argv[0] << " warning, both -E and -CFA flags specified, using -E and ignoring -CFA." << endl;
    267319        } // if
    268320
    269321        // add the CFA include-library paths, which allow direct access to header files without directory qualification
    270         if ( ! intree ) {
     322        string libbase;
     323        switch(path) {
     324        case Installed:
    271325                args[nargs++] = "-I" CFA_INCDIR;
    272                 if ( ! noincstd_flag ) {                                                // do not use during build
     326                // do not use during build
     327                if ( ! noincstd_flag ) {
    273328                        args[nargs++] = "-I" CFA_INCDIR "stdhdr";
    274329                } // if
    275330                args[nargs++] = "-I" CFA_INCDIR "concurrency";
    276331                args[nargs++] = "-I" CFA_INCDIR "containers";
    277         } else {
     332                libbase = CFA_LIBDIR;
     333                break;
     334        case BuildTree:
     335        case Distributed:
    278336                args[nargs++] = "-I" TOP_SRCDIR "libcfa/src";
    279                 if ( ! noincstd_flag ) {                                                // do not use during build
     337                // do not use during build
     338                if ( ! noincstd_flag ) {
    280339                        args[nargs++] = "-I" TOP_SRCDIR "libcfa/src" "/stdhdr";
    281340                } // if
    282341                args[nargs++] = "-I" TOP_SRCDIR "libcfa/src" "/concurrency";
    283342                args[nargs++] = "-I" TOP_SRCDIR "libcfa/src" "/containers";
     343
     344                libbase = TOP_BUILDDIR "libcfa/";
     345
     346                break;
    284347        } // if
    285348
     
    288351        args[nargs++] = "stdbool.h";
    289352
    290         string libbase;
    291         if ( ! intree ) {
    292                 libbase = CFA_LIBDIR;
    293         } else {
    294                 libbase = TOP_BUILDDIR "libcfa/";
     353        if( compiling_libs ) {
    295354                Putenv( argv, "-t" );
    296355        } // if
     
    305364        } // if
    306365
    307         string libdir( libbase + arch + "-" + (nolib ? "nolib" : (debug ? "debug": "nodebug")) );
    308         if ( ! dirExists( libdir ) ) {
    309                 cerr << argv[0] << " internal error, cannot find prelude directory " << libdir << endl;
    310                 exit( EXIT_FAILURE );
    311         } // if
     366        const char * config = nolib ? "nolib" : (debug ? "debug": "nodebug");
     367        string libdir = libbase + arch + "-" + config;
     368
     369        if (path != Distributed) {
     370                if ( ! nolib && ! dirExists( libdir ) ) {
     371                        cerr << argv[0] << " internal error, configuration " << config << " not installed." << endl;
     372                        cerr << "Was looking for " << libdir << endl;
     373                        for(int i = 1; i < argc; i++) {
     374                                cerr << argv[i] << " ";
     375                        }
     376                        cerr << endl;
     377                        libdir = libbase + arch + "-" + "nolib";
     378                } // if
     379
     380                if ( ! dirExists( libdir ) ) {
     381                        cerr << argv[0] << " internal error, cannot find prelude directory." << endl;
     382                        cerr << "Was looking for " << libdir << endl;
     383                        exit( EXIT_FAILURE );
     384                } // if
     385        } // if
     386
     387        switch(path) {
     388        case Installed   : Putenv( argv, "--prelude-dir=" + libdir ); break;
     389        case BuildTree   : Putenv( argv, "--prelude-dir=" + libdir + "/prelude" ); break;
     390        case Distributed : Putenv( argv, "--prelude-dir=" + dir(argv[0]) ); break;
     391        }
    312392
    313393        for ( int i = 0; i < nlibs; i += 1 ) {                          // copy non-user libraries after all user libraries
     
    322402                args[nargs++] = "-Xlinker";
    323403                args[nargs++] = "--undefined=__cfaabi_appready_startup";
    324 
    325                 // include the cfa library in case it's needed
    326                 args[nargs++] = ( *new string( string("-L" ) + libdir + (intree ? "/src/.libs" : "")) ).c_str();
    327                 args[nargs++] = ( *new string( string("-Wl,-rpath," ) + libdir + (intree ? "/src/.libs" : "")) ).c_str();
     404                args[nargs++] = "-z";
     405                args[nargs++] = "execstack";
     406
     407                // include the cfa library in case it is needed
     408                args[nargs++] = ( *new string( string("-L" ) + libdir + (path != Installed ? "/src/.libs" : "")) ).c_str();
     409                args[nargs++] = ( *new string( string("-Wl,-rpath," ) + libdir + (path != Installed ? "/src/.libs" : "")) ).c_str();
    328410                args[nargs++] = "-Wl,--push-state,--as-needed";
    329411                args[nargs++] = "-lcfathread";
    330412                args[nargs++] = "-Wl,--pop-state";
     413                args[nargs++] = "-Wl,--push-state,--no-as-needed";
    331414                args[nargs++] = "-lcfa";
    332                 args[nargs++] = "-lpthread";
     415                args[nargs++] = "-Wl,--pop-state";
     416                args[nargs++] = "-pthread";
    333417                args[nargs++] = "-ldl";
    334418                args[nargs++] = "-lrt";
     
    361445        } // if
    362446
    363         Putenv( argv, "--prelude-dir=" + libdir + (intree ? "/prelude" : "") );
    364 
    365447        if ( debug ) {
    366448                heading += " (debug)";
     
    370452        } // if
    371453
    372         if ( Bprefix.length() == 0 ) {
    373                 Bprefix = ! intree ? installlibdir : srcdriverdir;
    374                 if ( Bprefix[Bprefix.length() - 1] != '/' ) Bprefix += '/';
    375                 args[nargs++] = ( *new string( string("-D__GCC_BPREFIX__=") + Bprefix ) ).c_str();
     454        if ( bprefix.length() == 0 ) {
     455                switch(path) {
     456                case Installed   : bprefix = installlibdir; break;
     457                case BuildTree   : bprefix = srcdriverdir ; break;
     458                case Distributed : bprefix = dir(argv[0]) ; break;
     459                }
     460                if ( bprefix[bprefix.length() - 1] != '/' ) bprefix += '/';
     461                Putenv( argv, string("-B=") + bprefix );
    376462        } // if
    377463
     
    401487                args[nargs++] = "-fgnu89-inline";
    402488                args[nargs++] = "-D__int8_t_defined";                   // prevent gcc type-size attributes
    403                 args[nargs++] = ( *new string( string("-B") + Bprefix ) ).c_str();
     489                args[nargs++] = ( *new string( string("-B") + bprefix ) ).c_str();
    404490        } else {
    405491                cerr << argv[0] << " error, compiler \"" << compiler_name << "\" unsupported." << endl;
     
    415501                cerr << " \"" << args[i] << "\"" << endl;
    416502        } // for
     503        cerr << endl;
    417504        #endif // __DEBUG_H__
    418505
    419506        if ( ! quiet ) {
    420507                cerr << "CFA " << "Version " << Version << heading << endl;
    421 
    422508                if ( help ) {
    423509                        cerr <<
Note: See TracChangeset for help on using the changeset viewer.