View Issue Details Jump to Notes ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0008563CMakeCMakepublic2009-02-19 14:482016-06-10 14:30
ReporterSean McBride 
Assigned ToBill Hoffman 
PrioritynormalSeveritymajorReproducibilityalways
StatusclosedResolutionmoved 
PlatformMac OS XOSMac OS XOS Version10.5
Product VersionCMake-2-6 
Target VersionFixed in Version 
Summary0008563: CMake sometimes uses/detects wrong case in file paths
DescriptionUsing 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.
TagsNo tags attached.
Attached Filespng file icon Cmake-case-mismatch.png [^] (38,761 bytes) 2009-02-19 14:48

 Relationships
duplicate of 0006215closedBill Hoffman FIND_LIBARY not returning the proper capitalization on found frameworks/libraries (OS X) 
related to 0004572closedDavid Cole Tk and Tcl frameworks references with incorrect case 

  Notes
(0015226)
Bill Hoffman (manager)
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 (reporter)
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 (manager)
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 (manager)
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 (reporter)
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 (manager)
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 (reporter)
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 (reporter)
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 (reporter)
2009-02-19 16:16

http://developer.apple.com/documentation/Carbon/Reference/File_Manager/Reference/reference.html [^]

might help

Mike
(0015239)
Sean McBride (reporter)
2009-02-19 17:28

I knew this was familiar! :)
(0015457)
Sean McBride (reporter)
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 (reporter)
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 (administrator)
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.

 Issue History
Date Modified Username Field Change
2009-02-19 14:48 Sean McBride New Issue
2009-02-19 14:48 Sean McBride File Added: Cmake-case-mismatch.png
2009-02-19 14:58 Bill Hoffman Note Added: 0015226
2009-02-19 15:04 Sean McBride Note Added: 0015227
2009-02-19 15:09 Bill Hoffman Note Added: 0015228
2009-02-19 15:12 Bill Hoffman Note Added: 0015229
2009-02-19 15:12 Bill Hoffman Status new => assigned
2009-02-19 15:12 Bill Hoffman Assigned To => Bill Hoffman
2009-02-19 15:35 Mike Jackson Note Added: 0015230
2009-02-19 15:51 Bill Hoffman Note Added: 0015231
2009-02-19 16:06 Mike Jackson Note Added: 0015234
2009-02-19 16:15 Mike Jackson Note Added: 0015235
2009-02-19 16:16 Mike Jackson Note Added: 0015236
2009-02-19 17:25 Bill Hoffman Relationship added duplicate of 0006215
2009-02-19 17:27 Bill Hoffman Relationship added related to 0004572
2009-02-19 17:28 Sean McBride Note Added: 0015239
2009-02-27 10:15 Sean McBride Note Added: 0015457
2010-07-05 15:35 Sean McBride Note Added: 0021246
2010-08-29 01:32 Kovarththanan Rajaratnam Category CCMake => CMake
2016-06-10 14:27 Kitware Robot Note Added: 0041504
2016-06-10 14:27 Kitware Robot Status assigned => resolved
2016-06-10 14:27 Kitware Robot Resolution open => moved
2016-06-10 14:30 Kitware Robot Status resolved => closed


Copyright © 2000 - 2018 MantisBT Team