Changeset 20787

Show
Ignore:
Timestamp:
09/07/07 15:52:01 (1 year ago)
Author:
patrick
Message:

MFT: Set the environment variable JCCL_BASE_DIR automatically on all

platforms if it is not already set. Set the new environment variable
JCCL_DATA_DIR automatically (relative to JCCL_BASE_DIR) on all platforms
if it is not already set.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • juggler/branches/2.2/modules/jackal/ChangeLog

    r20709 r20787  
    11DATE        AUTHOR      CHANGE 
    22----------- ----------- ------------------------------------------------------- 
     3Sep-07-2007 patrick     Set JCCL_BASE_DIR automatically on all platforms. Use 
     4                        the new environment variable JCCL_DATA_DIR as a way to 
     5                        look up files in JCCL_BASE_DIR/share/jccl. 
     6 
    37[1.2.0 released - 8.14.2007]=================================================== 
    48Jul-08-2007 patrick     Debug-enabled code linked against the release runtime 
  • juggler/branches/2.2/modules/jackal/common/jccl/Makefile.in

    r19729 r20787  
    4848                Util 
    4949 
    50 SRCS=            
     50SRCS=           jcclmain.cpp 
    5151 
    5252EXTRA_INCLUDES= \ 
  • juggler/branches/2.2/modules/jackal/common/jccl/jcclmain.cpp

    r20500 r20787  
    2525 *************** <auto-copyright.pl END do not edit this line> ***************/ 
    2626 
    27 #if defined(WIN32) || defined(WIN64) 
    28 #include <windows.h> 
     27#include <jccl/jcclConfig.h> 
     28 
    2929#include <iostream> 
    3030#include <sstream> 
    3131#include <cstdlib> 
    3232#include <string> 
     33 
     34#if ! defined(WIN32) && ! defined(WIN64) 
     35#  include <dlfcn.h> 
     36#endif 
     37 
    3338#include <boost/filesystem/path.hpp> 
     39#include <boost/filesystem/operations.hpp> 
    3440#include <boost/filesystem/exception.hpp> 
    3541 
     42#include <vpr/vpr.h> 
     43 
    3644 
    3745namespace fs = boost::filesystem; 
    3846 
     47#if defined(WIN32) || defined(WIN64) 
    3948/** 
    4049 * Windows DLL entry point function. This ensures that the environment 
     
    5261      case DLL_PROCESS_ATTACH: 
    5362         { 
    54 #if defined(_MSC_VER) && _MSC_VER >= 1400 
    5563            char* env_dir(NULL); 
     64#if defined(_MSC_VER) && _MSC_VER >= 1400 
    5665            size_t len; 
    5766            _dupenv_s(&env_dir, &len, "JCCL_BASE_DIR"); 
    5867#else 
    59             const char* env_dir = std::getenv("JCCL_BASE_DIR"); 
    60 #endif 
    61  
    62             if ( NULL == env_dir ) 
    63             { 
    64                char tmppath[1024]; 
    65                std::memset(tmppath, 0, sizeof(tmppath)); 
    66                GetModuleFileName(module, tmppath, sizeof(tmppath)); 
    67  
    68                try 
    69                { 
    70                   fs::path dll_path(tmppath, fs::native); 
    71                   fs::path base_dir = dll_path.branch_path().branch_path(); 
     68            env_dir = std::getenv("JCCL_BASE_DIR"); 
     69#endif 
     70 
     71            try 
     72            { 
     73               fs::path base_dir; 
     74 
     75               // If JCCL_BASE_DIR is not set, look up the path to this DLL 
     76               // and use it to provide a default setting for that environment 
     77               // variable. 
     78               if ( NULL == env_dir ) 
     79               { 
     80                  char tmppath[1024]; 
     81                  std::memset(tmppath, 0, sizeof(tmppath)); 
     82                  GetModuleFileName(module, tmppath, sizeof(tmppath)); 
     83 
     84                  const fs::path dll_path(tmppath, fs::native); 
     85                  base_dir = dll_path.branch_path().branch_path(); 
    7286#if (defined(JUGGLER_DEBUG) || defined(JCCL_DEBUG)) && ! defined(_DEBUG) 
    7387                  // The debug DLL linked against the release runtime is in 
     
    7589                  base_dir = base_dir.branch_path(); 
    7690#endif 
     91 
    7792                  const std::string base_dir_str = 
    7893                     base_dir.native_directory_string(); 
     94 
    7995#if defined(_MSC_VER) && _MSC_VER >= 1400 
    8096                  _putenv_s("JCCL_BASE_DIR", base_dir_str.c_str()); 
     
    85101#endif 
    86102               } 
    87                catch (fs::filesystem_error& ex) 
    88                { 
    89                   std::cerr << "Automatic assignment of JCCL_BASE_DIR failed:\n" 
    90                             << ex.what() << std::endl; 
    91                } 
    92             } 
    93 #if defined(_MSC_VER) && _MSC_VER >= 1400 
    94             else 
    95             { 
    96                std::free(env_dir); 
    97             } 
    98 #endif 
     103               else 
     104               { 
     105                  base_dir = fs::path(env_dir, fs::native); 
     106#if defined(_MSC_VER) && _MSC_VER >= 1400 
     107                  std::free(env_dir); 
     108                  env_dir = NULL; 
     109#endif 
     110               } 
     111 
     112#if defined(_MSC_VER) && _MSC_VER >= 1400 
     113               _dupenv_s(&env_dir, &len, "JCCL_DATA_DIR"); 
     114#else 
     115               env_dir = std::getenv("JCCL_DATA_DIR"); 
     116#endif 
     117 
     118               // If JCCL_BASE_DIR is not set, set a default relative to 
     119               // base_dir. 
     120               if ( NULL == env_dir ) 
     121               { 
     122                  fs::path data_dir(base_dir / "share" / "jccl"); 
     123                  const std::string data_dir_str = 
     124                     data_dir.native_directory_string(); 
     125 
     126#if defined(_MSC_VER) && _MSC_VER >= 1400 
     127                  _putenv_s("JCCL_DATA_DIR", data_dir_str.c_str()); 
     128#else 
     129                  std::ostringstream env_stream; 
     130                  env_stream << "JCCL_DATA_DIR=" << data_dir_str; 
     131                  putenv(env_stream.str().c_str()); 
     132#endif 
     133               } 
     134#if defined(_MSC_VER) && _MSC_VER >= 1400 
     135               else 
     136               { 
     137                  std::free(env_dir); 
     138                  env_dir = NULL; 
     139               } 
     140#endif 
     141            } 
     142            catch (fs::filesystem_error& ex) 
     143            { 
     144               std::cerr << "Automatic assignment of JCCL environment " 
     145                         << "variables failed:\n" << ex.what() << std::endl; 
     146 
     147#if defined(_MSC_VER) && _MSC_VER >= 1400 
     148               if ( NULL != env_dir ) 
     149               { 
     150                  std::free(env_dir); 
     151               } 
     152#endif 
     153            } 
    99154         } 
    100155         break; 
     
    105160   return TRUE; 
    106161} 
    107  
    108  
     162#else 
     163/** 
     164 * Non-Windows shared library constructor. This ensures that the environment 
     165 * variable \c JCCL_BASE_DIR is set as soon as this shared library is loaded. 
     166 * If it is not set, then it sets it based on an assumption about the 
     167 * structure of a JCCL installation. More specifically, an assumption is made 
     168 * that this shared library lives in the \c lib subdirectory of the JCCL 
     169 * installation. Therefore, the root of the JCCL installation is the parent of 
     170 * the directory containing this shared library. 
     171 */ 
     172extern "C" void __attribute ((constructor)) jcclLibraryInit() 
     173
     174   fs::path base_dir; 
     175   const char* env_dir = std::getenv("JCCL_BASE_DIR"); 
     176 
     177   // If JCCL_BASE_DIR is not set, look up the path to this shared library and 
     178   // use it to provide a default setting for that environment variable. 
     179   if ( NULL == env_dir ) 
     180   { 
     181      Dl_info info; 
     182      info.dli_fname = 0; 
     183      const int result = 
     184#if defined(__GNUC__) && __GNUC_MAJOR__ < 4 
     185         dladdr((void*) &jcclLibraryInit, &info); 
     186#else 
     187         dladdr(reinterpret_cast<void*>(&jcclLibraryInit), &info); 
     188#endif 
     189 
     190      // NOTE: dladdr(3) really does return a non-zero value on success. 
     191      if ( 0 != result ) 
     192      { 
     193         try 
     194         { 
     195            fs::path lib_file(info.dli_fname, fs::native); 
     196            lib_file = fs::system_complete(lib_file); 
     197 
     198#if defined(VPR_OS_IRIX) && defined(_ABIN32) 
     199            const std::string bit_suffix("32"); 
     200#elif defined(VPR_OS_IRIX) && defined(_ABI64) || \ 
     201      defined(VPR_OS_Linux) && defined(__x86_64__) 
     202            const std::string bit_suffix("64"); 
     203#else 
     204            const std::string bit_suffix(""); 
     205#endif 
     206 
     207            // Get the directory containing this shared library. 
     208            const fs::path lib_path = lib_file.branch_path(); 
     209 
     210            // Start the search for the root of the JCCL installation in the 
     211            // parent of the directory containing this shared library. 
     212            base_dir = lib_path.branch_path(); 
     213 
     214            // Use the lib subdirectory to figure out when we have found the 
     215            // root of the JCCL installation tree. 
     216            const fs::path lib_subdir(std::string("lib") + bit_suffix); 
     217 
     218            bool found(false); 
     219            while ( ! found && ! base_dir.empty() ) 
     220            { 
     221               try 
     222               { 
     223                  if ( ! fs::exists(base_dir / lib_subdir) ) 
     224                  { 
     225                     base_dir = base_dir.branch_path(); 
     226                  } 
     227                  else 
     228                  { 
     229                     found = true; 
     230                  } 
     231               } 
     232               catch (fs::filesystem_error&) 
     233               { 
     234                  base_dir = base_dir.branch_path(); 
     235               } 
     236            } 
     237 
     238            if ( found ) 
     239            { 
     240               setenv("JCCL_BASE_DIR", 
     241                      base_dir.native_directory_string().c_str(), 1); 
     242            } 
     243         } 
     244         catch (fs::filesystem_error& ex) 
     245         { 
     246            std::cerr << "Automatic assignment of JCCL_BASE_DIR failed:\n" 
     247                      << ex.what() << std::endl; 
     248         } 
     249      } 
     250   } 
     251   else 
     252   { 
     253      base_dir = fs::path(env_dir, fs::native); 
     254   } 
     255 
     256   if ( ! base_dir.empty() ) 
     257   { 
     258      // If base_dir were empty, this would result in data_dir being relative 
     259      // to the current working directory. 
     260      const fs::path data_dir = base_dir / JCCL_SHARE_DIR; 
     261 
     262      // We use the overwrite value of 0 as a way around testing whether the 
     263      // environment variable is already set. 
     264      setenv("JCCL_DATA_DIR", data_dir.native_directory_string().c_str(), 0); 
     265   } 
     266
    109267#endif  /* defined(WIN32) || defined(WIN64) */