MantisBT - CMake
View Issue Details
0008563CMakeCMakepublic2009-02-19 14:482016-06-10 14:30
Sean McBride 
Bill Hoffman 
normalmajoralways
closedmoved 
Mac OS XMac OS X10.5
CMake-2-6 
 
0008563: CMake sometimes uses/detects wrong case in file paths
Using 2.6.3rc15, I created a fresh build of VTK. I noticed that CMake sometimes has the wrong case in several paths. See attachment.

For example, I see:
Tcl.framework
and
tcl.framework

By default, the Mac file system is case-preserving but case-insensitive. So for most people, this will not be a problem. However, one can optionally format as case-sensitive, and then I suspect this would be a big problem.
No tags attached.
duplicate of 0006215closed Bill Hoffman FIND_LIBARY not returning the proper capitalization on found frameworks/libraries (OS X) 
related to 0004572closed David Cole Tk and Tcl frameworks references with incorrect case 
png Cmake-case-mismatch.png (38,761) 2009-02-19 14:48
https://public.kitware.com/Bug/file/2069/Cmake-case-mismatch.png
png
Issue History
2009-02-19 14:48Sean McBrideNew Issue
2009-02-19 14:48Sean McBrideFile Added: Cmake-case-mismatch.png
2009-02-19 14:58Bill HoffmanNote Added: 0015226
2009-02-19 15:04Sean McBrideNote Added: 0015227
2009-02-19 15:09Bill HoffmanNote Added: 0015228
2009-02-19 15:12Bill HoffmanNote Added: 0015229
2009-02-19 15:12Bill HoffmanStatusnew => assigned
2009-02-19 15:12Bill HoffmanAssigned To => Bill Hoffman
2009-02-19 15:35Mike JacksonNote Added: 0015230
2009-02-19 15:51Bill HoffmanNote Added: 0015231
2009-02-19 16:06Mike JacksonNote Added: 0015234
2009-02-19 16:15Mike JacksonNote Added: 0015235
2009-02-19 16:16Mike JacksonNote Added: 0015236
2009-02-19 17:25Bill HoffmanRelationship addedduplicate of 0006215
2009-02-19 17:27Bill HoffmanRelationship addedrelated to 0004572
2009-02-19 17:28Sean McBrideNote Added: 0015239
2009-02-27 10:15Sean McBrideNote Added: 0015457
2010-07-05 15:35Sean McBrideNote Added: 0021246
2010-08-29 01:32Kovarththanan RajaratnamCategoryCCMake => CMake
2016-06-10 14:27Kitware RobotNote Added: 0041504
2016-06-10 14:27Kitware RobotStatusassigned => resolved
2016-06-10 14:27Kitware RobotResolutionopen => moved
2016-06-10 14:30Kitware RobotStatusresolved => closed

Notes
(0015226)
Bill Hoffman   
2009-02-19 14:58   
I think this is an old bug... If someone can show me the code that gets the actual case of a file, then I could fix it. Unlike windows, this function did not seem to be available last time I checked. The find stuff finds the lower case version, and it is valid...
(0015227)
Sean McBride   
2009-02-19 15:04   
I'm also pretty sure this bug has been around a long time.

To my knowledge, all file-system APIs on Mac OS return the actual case of the file. After all, the system is deliberately case-preserving.

I suspect CMake is inadvertently doing something "weird". Where is "the find stuff" in CMake? I could take a look...
(0015228)
Bill Hoffman   
2009-02-19 15:09   
No, it is not doing something weird....

It is looking for the lower case version of the framework because there is a find_library(tcl), and not find_library(Tcl). I could fix this if there was (like on windows), a function to call that would get the real case of a path. CMake just does a stat on tcl.framework, and of course it finds it. Then there is no way to convert that to the actual path.
(0015229)
Bill Hoffman   
2009-02-19 15:12   
See this function:
cmFindLibraryCommand.cxx:
std::string cmFindLibraryCommand::FindFrameworkLibrary()

The names are the names that are given to the find_library call.
(0015230)
Mike Jackson   
2009-02-19 15:35   
NSString* getActualPath(NSString* path) {
        FSRef ref;
        OSStatus sts;
        UInt8* actualPath;

        //first get an FSRef for the path
        sts = FSPathMakeRef((const UInt8 *)[path UTF8String], &ref, NULL);
        if (sts) return [NSString stringWithFormat:@"Error #%d making ref.", sts];

        //then get a path from the FSRef
        actualPath = malloc(sizeof(UInt8)*MAX_PATH_LENGTH);
        sts = FSRefMakePath(&ref, actualPath, MAX_PATH_LENGTH);
        if (sts) return [NSString stringWithFormat:@"Error #%d making path.", sts];

        return [NSString stringWithUTF8String:(const char*)actualPath];
}


There is some Objective-C thrown in there but it can be cleaned up and removed.
(0015231)
Bill Hoffman   
2009-02-19 15:51   
If something like that was called in here: cmFindLibraryCommand::FindFrameworkLibrary()

That should fix the problem. Is there just a C function that can do this?
(0015234)
Mike Jackson   
2009-02-19 16:06   
//----------------------------------------------------------------------------
std::string cmFindLibraryCommand::FindFrameworkLibrary()
{
  // Search for a framework of each name in the entire search path.
  for(std::vector<std::string>::const_iterator ni = this->Names.begin();
      ni != this->Names.end() ; ++ni)
    {
    // Search the paths for a framework with this name.
    std::string fwName = *ni;
    fwName += ".framework";
    std::string fwPath = cmSystemTools::FindDirectory(fwName.c_str(),
                                                      this->SearchPaths,
                                                      true);
#ifdef __APPLE__
    FSRef ref;
    OSStatus sts;
   #define MAX_PATH_LENGTH 16384
    sts = FSPathMakeRef((const UInt8*)(fwPath.c_str()), &ref, NULL);
    if (sts) { return ""; }
    std::string actualPath( sizeof(UInt8)*MAX_PATH_LENGTH, 0);
    sts = FSRefMakePath(&ref, (UInt8*)(actualPath.data()), MAX_PATH_LENGTH);
    if (sts) { return ""; }
    fwPath = actualPath;
#endif

    if(!fwPath.empty())
      {
      return fwPath;
      }
    }

  // No framework found.
  return "";
}

you will also have to link the CMakeLib.a against -framework Carbon also.

You would think there was an easier way but that seems to be about it. Note I have NOT tested the code besides trying to compile it against the 10.5 SDK.

Now, if you want to ONLY use 10.5 then you could probably use CoreFoundation only and NOT have to use Carbon but I don't see having to use Carbon, at this point in time, as a problem. I may eat my words on that.

You could probably write it a lot simpler using Objective-C++ if needed, that would remove the reliance on Carbon. It might be a fun tangent for someone to try..

Mike
(0015235)
Mike Jackson   
2009-02-19 16:15   
Check that:
 you need the following include at the top of the file cmFindLibraryCommand.cxx

#ifdef __APPLE__
#include <CoreServices/CoreServices.h>
#endif


Then in the Source/CMakeLists.txt file edit the lines to look like below

# On Apple we need CoreFoundation & CoreServices
IF(APPLE)
  TARGET_LINK_LIBRARIES(CMakeLib "-framework CoreFoundation -framework CoreServices")
ENDIF(APPLE)

Anyone want to test this?
Mike
(0015236)
Mike Jackson   
2009-02-19 16:16   
http://developer.apple.com/documentation/Carbon/Reference/File_Manager/Reference/reference.html [^]

might help

Mike
(0015239)
Sean McBride   
2009-02-19 17:28   
I knew this was familiar! :)
(0015457)
Sean McBride   
2009-02-27 10:15   
I think Mike's proposal (path->FSRef->path) is good. I asked on an Apple dev list for better ideas, but no one had any.
(0021246)
Sean McBride   
2010-07-05 15:35   
A more portable solution might be to use realpath(), see 'man 3 realpath'. But it resolves symlinks, which may or may not be good...
(0041504)
Kitware Robot   
2016-06-10 14:27   
Resolving issue as `moved`.

This issue tracker is no longer used. Further discussion of this issue may take place in the current CMake Issues page linked in the banner at the top of this page.