Show
Ignore:
Timestamp:
08/27/04 18:14:21 (10 years ago)
Author:
robert
Message:

Added a new osgDB::appendPlatformSpecificLibraryFilePaths() method to FileUtils?.cpp
Includes a new OSX code from Eric Wing

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • OpenSceneGraph/trunk/src/osgDB/FileUtils.cpp

    r2992 r3330  
    4040 
    4141 
     42void osgDB::convertStringPathIntoFilePathList(const std::string& paths,FilePathList& filepath) 
     43{ 
     44#if defined(WIN32) && !defined(__CYGWIN__) 
     45    char delimitor = ';'; 
     46#else 
     47    char delimitor = ':'; 
     48#endif 
     49 
     50    if (!paths.empty()) 
     51    { 
     52        std::string::size_type start = 0; 
     53        std::string::size_type end; 
     54        while ((end = paths.find_first_of(delimitor,start))!=std::string::npos) 
     55        { 
     56            filepath.push_back(std::string(paths,start,end-start)); 
     57            start = end+1; 
     58        } 
     59 
     60        filepath.push_back(std::string(paths,start,std::string::npos)); 
     61    } 
     62  
     63} 
     64 
    4265bool osgDB::fileExists(const std::string& filename) 
    4366{ 
     
    272295 
    273296#endif // ! target mac carbon 
     297 
     298 
     299 
     300///////////////////////////////////////////////////////////////////////////////////////////////// 
     301// 
     302// Implementation of appendPlatformSpecificLibraryFilePaths(..) 
     303// 
     304#ifdef __sgi 
     305 
     306    void osgDB::appendPlatformSpecificLibraryFilePaths(FilePathList& filepath) 
     307    { 
     308        convertStringPathIntoFilePathList("/usr/lib32/:/usr/local/lib32/",filepath); 
     309 
     310        // bloody mess see rld(1) man page 
     311        #if (_MIPS_SIM == _MIPS_SIM_ABI32) 
     312 
     313        char* ptr; 
     314        if( (ptr = getenv( "LD_LIBRARY_PATH" ))) 
     315        { 
     316            convertStringPathIntoFilePathList(ptr,filepath); 
     317        } 
     318 
     319        #elif (_MIPS_SIM == _MIPS_SIM_NABI32) 
     320 
     321        if( !(ptr = getenv( "LD_LIBRARYN32_PATH" ))) 
     322            ptr = getenv( "LD_LIBRARY_PATH" ); 
     323 
     324        if( ptr ) 
     325        { 
     326            convertStringPathIntoFilePathList(ptr,filepath); 
     327        } 
     328 
     329        #elif (_MIPS_SIM == _MIPS_SIM_ABI64) 
     330 
     331        if( !(ptr = getenv( "LD_LIBRARY64_PATH" ))) 
     332            ptr = getenv( "LD_LIBRARY_PATH" ); 
     333 
     334        if( ptr ) 
     335        { 
     336            convertStringPathIntoFilePathList(ptr,filepath); 
     337        } 
     338        #endif 
     339    } 
     340 
     341 
     342#elif defined(__CYGWIN__) 
     343 
     344    void osgDB::appendPlatformSpecificLibraryFilePaths(FilePathList& filepath) 
     345    { 
     346        char* ptr; 
     347        if ((ptr = getenv( "PATH" ))) 
     348        { 
     349            convertStringPathIntoFilePathList(ptr,filepath); 
     350        } 
     351 
     352        convertStringPathIntoFilePathList("/usr/bin/:/usr/local/bin/",filepath); 
     353 
     354    } 
     355     
     356#elif defined(WIN32) 
     357 
     358    void osgDB::appendPlatformSpecificLibraryFilePaths(FilePathList& filepath) 
     359    { 
     360        char* ptr; 
     361        if ((ptr = getenv( "PATH" ))) 
     362        { 
     363            convertStringPathIntoFilePathList(ptr,filepath); 
     364        } 
     365 
     366        convertStringPathIntoFilePathList("C:/Windows/System/",filepath); 
     367    } 
     368     
     369#elif defined(__APPLE__) 
     370 
     371    // The Cocoa version is about 10 lines of code. 
     372    // The Carbon version is noticably longer. 
     373    // Unfortunately, the Cocoa version requires -lobjc to be  
     374    // linked in when creating an executable.  
     375    // Rumor is that this will be done autmatically in gcc 3.5/Tiger, 
     376    // but for now, this will cause a lot of headaches for people 
     377    // who aren't familiar with this concept, so the Carbon version  
     378    // is preferable. 
     379    // But for the curious, both implementations are here. 
     380    // Note that if the Cocoa version is used, the file should be  
     381    // renamed to use the .mm extension to denote Objective-C++. 
     382    // And of course, you will need to link against Cocoa 
     383 
     384    // #define COMPILE_COCOA_VERSION_WITH_OBJECT-C++ 
     385    #ifdef COMPILE_COCOA_VERSION_WITH_OBJECT-C++ 
     386    #include <Foundation/Foundation.h> 
     387    // OS X has preferred locations for where PlugIns should be located. 
     388    // This function will set this as the order to search: 
     389    // YourProgram.app/Contents/PlugIns 
     390    // ~/Library/Application Support/OpenSceneGraph/PlugIns 
     391    // /Library/Application Support/OpenSceneGraph/PlugIns 
     392    // /Network/Library/Application Support/OpenSceneGraph/PlugIns 
     393    //  
     394    // As a side effect of this function, if the application is not a  
     395    // bundle, the first place searched becomes 
     396    // YourProgram/PlugIns 
     397    // 
     398    // In principle, these other directories should be searched: 
     399    // ~/Library/Application Support/YourProgram/PlugIns 
     400    // /Library/Application Support/YourProgram/PlugIns 
     401    // /Network/Library/Application Support/TheProgram/PlugIns  
     402    // But I'm not going to worry about it for now because the  
     403    // bundle's PlugIns directory is supposed to be the preferred  
     404    // place for this anyway. 
     405    // 
     406    // Another directory that might be worth considering is 
     407    // the directory the program resides in, 
     408    // but I'm worried about multiplatform distribution. 
     409    // Because .so is used by other platforms like Linux, we  
     410    // could end up loading the wrong binary. 
     411    // I'm not sure how robust the current code is for this case. 
     412    // Assuming the program doesn't crash, will OSG move on to the  
     413    // next search directory, or just give up? 
     414    void osgDB::appendPlatformSpecificLibraryFilePaths(FilePathList& filepath) 
     415    { 
     416        char* ptr; 
     417        if ((ptr = getenv( "DYLD_LIBRARY_PATH" )) ) 
     418        { 
     419            convertStringPathIntoFilePathList(ptr, filepath); 
     420        } 
     421 
     422        // Since this is currently the only Objective-C code in the 
     423        // library, we need an autoreleasepool for obj-c memory management. 
     424        // If more Obj-C is added, we might move this pool to another  
     425        // location so it can be shared. Pools seem to be stackable, 
     426        // so I don't think there will be a problem if multiple pools 
     427        // exist at a time. 
     428        NSAutoreleasePool* mypool = [[NSAutoreleasePool alloc] init]; 
     429 
     430        NSString* myBundlePlugInPath; 
     431        NSString* userSupportDir; 
     432 
     433        // This will grab the "official" bundle plug in path. 
     434        // It will be YourProgram.app/Contents/PlugIns (for App bundles) 
     435        // or YourProgram/PlugIns (for Unix executables) 
     436        myBundlePlugInPath = [[NSBundle mainBundle] builtInPlugInsPath]; 
     437 
     438        // Now setup the other search paths 
     439        // Cocoa has a nice method for tilde expansion. 
     440        // There's probably a better way of getting this directory, but I  
     441        // can't find the call. 
     442        userSupportDir = [@"~/Library/Application Support/OpenSceneGraph/PlugIns" stringByExpandingTildeInPath]; 
     443 
     444        // Can setup the remaining directories directly in C++ 
     445 
     446        // Since Obj-C and C++ objects don't understand each other, 
     447        // the Obj-C strings must be converted down to C strings so 
     448        // C++ can make them into C++ strings. 
     449        filepath.push_back( [myBundlePlugInPath UTF8String] ); 
     450        filepath.push_back( [userSupportDir UTF8String] ); 
     451 
     452        filepath.push_back( "/Library/Application Support/OpenSceneGraph/PlugIns" ); 
     453        filepath.push_back( "/Network/Library/Application Support/OpenSceneGraph/PlugIns" ); 
     454 
     455        // Clean up the autorelease pool 
     456        [mypool release]; 
     457    } 
     458 
     459    #else 
     460 
     461    #include <CoreServices/CoreServices.h> 
     462    // OS X has preferred locations for where PlugIns should be located. 
     463    // This function will set this as the order to search: 
     464    // YourProgram.app/Contents/PlugIns 
     465    // ~/Library/Application Support/OpenSceneGraph/PlugIns 
     466    // /Library/Application Support/OpenSceneGraph/PlugIns 
     467    // /Network/Library/Application Support/OpenSceneGraph/PlugIns 
     468    //  
     469    // As a side effect of this function, if the application is not a  
     470    // bundle, the first place searched becomes 
     471    // YourProgram/PlugIns 
     472    // 
     473    // In principle, these other directories should be searched: 
     474    // ~/Library/Application Support/YourProgram/PlugIns 
     475    // /Library/Application Support/YourProgram/PlugIns 
     476    // /Network/Library/Application Support/TheProgram/PlugIns  
     477    // But I'm not going to worry about it for now because the  
     478    // bundle's PlugIns directory is supposed to be the preferred  
     479    // place for this anyway. 
     480    // 
     481    // Another directory that might be worth considering is 
     482    // the directory the program resides in, 
     483    // but I'm worried about multiplatform distribution. 
     484    // Because .so is used by other platforms like Linux, we  
     485    // could end up loading the wrong binary. 
     486    // I'm not sure how robust the current code is for this case. 
     487    // Assuming the program doesn't crash, will OSG move on to the  
     488    // next search directory, or just give up? 
     489    void osgDB::appendPlatformSpecificLibraryFilePaths(FilePathList& filepath) 
     490    { 
     491        char* ptr; 
     492        if ((ptr = getenv( "DYLD_LIBRARY_PATH" )) ) 
     493        { 
     494            convertStringPathIntoFilePathList(ptr, filepath); 
     495        } 
     496 
     497        const int MAX_OSX_PATH_SIZE = 1024; 
     498        const std::string OSG_PLUGIN_PATH("/OpenSceneGraph/PlugIns"); 
     499        char buffer[MAX_OSX_PATH_SIZE]; 
     500        char bundlePathBuffer[MAX_OSX_PATH_SIZE]; 
     501        CFURLRef  url; 
     502        CFStringRef pathString; 
     503        CFBundleRef myBundle; 
     504        CFStringRef bundlePathString; 
     505        FSRef     f; 
     506        OSErr   errCode; 
     507 
     508        // Start with the the Bundle PlugIns directory. 
     509        // Unlike the Cocoa API, it seems that the PlugIn path is relative 
     510        // and not absolute. So I will need to fetch both the bundle path 
     511        // (which is absolute) and the PlugIn path (which is relative), 
     512        // and combine the two to form a full path. 
     513 
     514        // Get the bundle first 
     515        myBundle = CFBundleGetMainBundle(); 
     516        if(myBundle != NULL) 
     517        { 
     518            // Get the URL to the bundle 
     519            url = CFBundleCopyBundleURL( myBundle ); 
     520 
     521            // Convert the URL to a CFString that looks like a Unix file path 
     522            bundlePathString = CFURLCopyFileSystemPath( url, kCFURLPOSIXPathStyle ); 
     523            // Convert the CFString to a C string 
     524            CFStringGetCString( bundlePathString, bundlePathBuffer, MAX_OSX_PATH_SIZE, kCFStringEncodingUTF8 ); 
     525 
     526            CFRelease( url ); 
     527 
     528            // Now find the PlugIns directory 
     529            // Get the URL to the bundle 
     530            url = CFBundleCopyBuiltInPlugInsURL( myBundle ); 
     531            //pathString = CFURLCopyPath( url ); 
     532            // Convert the URL to a CFString that looks like a Unix file path 
     533            pathString = CFURLCopyFileSystemPath( url, kCFURLPOSIXPathStyle ); 
     534            // Convert the CFString to a C string 
     535            CFStringGetCString( pathString, buffer, MAX_OSX_PATH_SIZE, kCFStringEncodingUTF8 ); 
     536 
     537            // Combine the string and copy it into the FilePath list 
     538            filepath.push_back(  
     539                std::string(bundlePathBuffer)  
     540                + std::string("/") 
     541                + std::string(buffer) 
     542            ); 
     543 
     544            CFRelease( pathString ); 
     545            CFRelease( bundlePathString ); 
     546            CFRelease( url ); 
     547 
     548            // I was getting random crashes which I believe were caused by 
     549            // releasing the bundle. The documentation says I'm responsible 
     550            // for retaining and releasing which didn't immediately register 
     551            // in my head. I never retain the bundle, so I don't release it. 
     552            // CFRelease( myBundle ); 
     553 
     554            pathString = NULL; 
     555            bundlePathString = NULL; 
     556            url = NULL; 
     557            // myBundle = NULL; 
     558        } 
     559        else 
     560        { 
     561            notify( DEBUG_INFO ) << "Couldn't find the Application Bundle" << std::endl; 
     562        } 
     563 
     564        // Next, check the User's Application Support folder 
     565        errCode = FSFindFolder( kUserDomain, kApplicationSupportFolderType, kDontCreateFolder, &f ); 
     566        if(noErr == errCode) 
     567        { 
     568            // Get the URL 
     569            url = CFURLCreateFromFSRef( 0, &f ); 
     570            // Convert the URL to a CFString that looks like a Unix file path 
     571            pathString = CFURLCopyFileSystemPath( url, kCFURLPOSIXPathStyle ); 
     572            // Convert the CFString to a C string 
     573            CFStringGetCString( pathString, buffer, MAX_OSX_PATH_SIZE, kCFStringEncodingUTF8 ); 
     574 
     575            // Add the directory to the FilePathList 
     576            filepath.push_back(  
     577                std::string(buffer)  
     578                + OSG_PLUGIN_PATH 
     579            ); 
     580 
     581            CFRelease( url ); 
     582            CFRelease( pathString ); 
     583        } 
     584        else 
     585        { 
     586            notify( DEBUG_INFO ) << "Couldn't find the User's Application Support Path" << std::endl; 
     587        } 
     588 
     589        // Next, check the Local System's Application Support Folder 
     590        errCode = FSFindFolder( kLocalDomain, kApplicationSupportFolderType, kDontCreateFolder, &f ); 
     591        if(noErr == errCode) 
     592        { 
     593            // Get the URL 
     594            url = CFURLCreateFromFSRef( 0, &f ); 
     595            // Convert the URL to a CFString that looks like a Unix file path 
     596            pathString = CFURLCopyFileSystemPath( url, kCFURLPOSIXPathStyle ); 
     597            // Convert the CFString to a C string 
     598            CFStringGetCString( pathString, buffer, MAX_OSX_PATH_SIZE, kCFStringEncodingUTF8 ); 
     599 
     600            // Add the directory to the FilePathList 
     601            filepath.push_back(  
     602                std::string(buffer)  
     603                + OSG_PLUGIN_PATH 
     604            ); 
     605 
     606            CFRelease( url ); 
     607            CFRelease( pathString ); 
     608        } 
     609        else 
     610        { 
     611            notify( DEBUG_INFO ) << "Couldn't find the Local System's Application Support Path" << std::endl; 
     612        } 
     613 
     614        // Finally, check the Network Application Support Folder 
     615        // This one has a likely chance of not existing so an error 
     616        // may be returned. Don't panic. 
     617        errCode = FSFindFolder( kNetworkDomain, kApplicationSupportFolderType, kDontCreateFolder, &f ); 
     618        if(noErr == errCode) 
     619        { 
     620            // Get the URL 
     621            url = CFURLCreateFromFSRef( 0, &f ); 
     622            // Convert the URL to a CFString that looks like a Unix file path 
     623            pathString = CFURLCopyFileSystemPath( url, kCFURLPOSIXPathStyle ); 
     624            // Convert the CFString to a C string 
     625            CFStringGetCString( pathString, buffer, MAX_OSX_PATH_SIZE, kCFStringEncodingUTF8 ); 
     626 
     627            // Add the directory to the FilePathList 
     628            filepath.push_back(  
     629                std::string(buffer)  
     630                + OSG_PLUGIN_PATH 
     631            ); 
     632 
     633            CFRelease( url ); 
     634            CFRelease( pathString ); 
     635        } 
     636        else 
     637        { 
     638            notify( DEBUG_INFO ) << "Couldn't find the Network Application Support Path" << std::endl; 
     639        } 
     640    } 
     641 
     642    #endif 
     643     
     644#else    
     645 
     646    void osgDB::appendPlatformSpecificLibraryFilePaths(FilePathList& filepath) 
     647    { 
     648 
     649       char* ptr; 
     650       if( (ptr = getenv( "LD_LIBRARY_PATH" )) ) 
     651        { 
     652            convertStringPathIntoFilePathList(ptr,filepath); 
     653        } 
     654 
     655        convertStringPathIntoFilePathList("/usr/lib/:/usr/local/lib/",filepath); 
     656 
     657    } 
     658 
     659#endif 
     660 
     661 
     662 
     663 
     664 
     665 
     666 
     667 
     668 
     669