View Issue Details Jump to Notes ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0005139CMakeCMakepublic2007-06-07 09:052016-06-10 14:30
ReporterPhilippe BERNERY 
Assigned ToBill Hoffman 
PrioritynormalSeverityminorReproducibilityalways
StatusclosedResolutionmoved 
PlatformOSOS Version
Product Version 
Target VersionFixed in Version 
Summary0005139: find_path seems to not work correctly on Mac OS X
DescriptionI have the following in a find script:

find_path(COIPMANAGER_INCLUDE_DIRS
  NAMES
    coipmanager/CoIpManager.h
  PATHS
    /Library/Frameworks/CoIpManager.framework/Headers
    ${MORE_PATH}
)

and COIPMANAGER_INCLUDE_DIRS contains /Library/Frameworks/CoIpManager.framework/Headers/coipmanager whereas it should contain /Library/Frameworks/CoIpManager.framework/Headers
TagsNo tags attached.
Attached Files

 Relationships

  Notes
(0013796)
Bill Hoffman (manager)
2008-10-09 13:08

Is this still an issue?
(0013862)
Philippe BERNERY (reporter)
2008-10-13 14:36

I cannot test it since I'm not working on this project anymore.
(0016612)
Hugues De Keyzer (reporter)
2009-06-03 10:16
edited on: 2009-06-04 04:10

Yes, it is still an issue. I encountered the same problem with CMake 2.6.4 when using FindLibXml2. It uses the command:
FIND_PATH(LIBXML2_INCLUDE_DIR libxml/xpath.h HINTS ... PATH_SUFFIXES libxml2)

On GNU/Linux, this defines LIBXML2_INCLUDE_DIR as:
LIBXML2_INCLUDE_DIR:PATH=/usr/include/libxml2
This directory contains a subdirectory named libxml that contains xpath.h. As the headers are included as <libxml/xpath.h>, it is the correct value and it works fine.

On Mac OS X, this gives:
LIBXML2_INCLUDE_DIR:PATH=/Library/Frameworks/libxml2.framework/Headers/libxml
This directory contains xpath.h. With this value, the headers includes doesn't work. It should be /Library/Frameworks/libxml2.framework/Headers.

The way I use to solve this for now is by copying FindLibXml2.cmake into my source tree, and modifying it. I replace this part:

FIND_PATH(LIBXML2_INCLUDE_DIR libxml/xpath.h
   HINTS
   ${PC_LIBXML_INCLUDEDIR}
   ${PC_LIBXML_INCLUDE_DIRS}
   PATH_SUFFIXES libxml2
   )

by this:

IF (APPLE)
   SET(LIBXML2_FRAMEWORK_DIRECTORY libxml2/)
ENDIF (APPLE)

FIND_PATH(LIBXML2_INCLUDE_DIR ${LIBXML2_FRAMEWORK_DIRECTORY}libxml/xpath.h
   HINTS
   ${PC_LIBXML_INCLUDEDIR}
   ${PC_LIBXML_INCLUDE_DIRS}
   PATH_SUFFIXES libxml2
   )

This doesn't look really good, but at least it works…
[EDIT]
Correction: this doesn't work neither, as this gives
LIBXML2_INCLUDE_DIR:PATH=/Library/Frameworks/libxml2.framework
instead of:
LIBXML2_INCLUDE_DIR:PATH=/Library/Frameworks/libxml2.framework/Headers

[EDIT]
To make it work, we can use this even more crappy hack:

IF (APPLE)
   SET(LIBXML2_FRAMEWORK_DIRECTORY libxml2/)
   SET(LIBXML2_INCLUDE_DIR_PREVIOUS ${LIBXML2_INCLUDE_DIR})
ENDIF (APPLE)

FIND_PATH(LIBXML2_INCLUDE_DIR ${LIBXML2_FRAMEWORK_DIRECTORY}libxml/xpath.h
   HINTS
   ${PC_LIBXML_INCLUDEDIR}
   ${PC_LIBXML_INCLUDE_DIRS}
   PATH_SUFFIXES libxml2
   )

IF (APPLE AND NOT (LIBXML2_INCLUDE_DIR STREQUAL LIBXML2_INCLUDE_DIR_PREVIOUS))
   SET(LIBXML2_INCLUDE_DIR ${LIBXML2_INCLUDE_DIR}/Headers CACHE PATH "Path to a file." FORCE)
ENDIF (APPLE AND NOT (LIBXML2_INCLUDE_DIR STREQUAL LIBXML2_INCLUDE_DIR_PREVIOUS))

I’m rather new to CMake, so probably I’m not using it completely correctly.
[/EDIT]
[/EDIT]

I took a look at cmFindPathCommand::FindHeaderInFramework(). What seems to happen is that it tests whether /Library/Frameworks/libxml.framework/Headers/xpath.h exists, which is false, then it performs a glob search with "/Library/Frameworks/*.framework/Headers/libxml/xpath.h", finds /Library/Frameworks/libxml2.framework/Headers/libxml/xpath.h and returns that path without the filename. It should probably be better if the end of the string was compared with the searched filename and this part removed to form the path.

It should be even better if this function also used the PATH_SUFFIXES in its search.

One last thing, this function begins with:

std::string
cmFindPathCommand::FindHeaderInFramework(std::string const& file,
                                         std::string const& dir)
{
  cmStdString fileName = file;
  cmStdString frameWorkName;
  cmStdString::size_type pos = fileName.find("/");
  // if there is a / in the name try to find the header as a framework
  // For example bar/foo.h would look for:
  // bar.framework/Headers/foo.h
  if(pos != fileName.npos)
    {
    // remove the name from the slash;
    fileName = fileName.substr(pos+1);
    frameWorkName = file;
    frameWorkName =
      frameWorkName.substr(0, frameWorkName.size()-fileName.size()-1);
    // if the framework has a path in it then just use the filename
    if(frameWorkName.find("/") != frameWorkName.npos)
      {
      fileName = file;
      frameWorkName = "";
      }

This last if condition can never happen, as frameWorkName is formed by taking the start of the string, up to one character before the first '/'.

(0016632)
Hugues De Keyzer (reporter)
2009-06-04 05:32

Frameworks on Mac OS X are a little tricky to handle. When including the OpenGL header, for example, with this instruction:

#include <OpenGL/gl.h>

it looks for <FRAMEWORK_DIRECTORIES>/OpenGL.framework/Headers/gl.h. <FRAMEWORK_DIRECTORIES> are the directory containing frameworks (/System/Library/Frameworks, /Library/Frameworks), which can be specified with -F on the gcc command line. So, with this include above, no special arguments are needed on the command line as the OpenGL framework is in a standard framework directory (/System/Library/Frameworks).

When using the FindOpenGL module, which uses:

FIND_PATH(OPENGL_INCLUDE_DIR OpenGL/gl.h DOC "Include for OpenGL on OSX")

it defines:

//Include for OpenGL on OSX
OPENGL_INCLUDE_DIR:PATH=/System/Library/Frameworks/OpenGL.framework

This value will not be used as -I argument on the command line, instead it will be used for adding a -F argument like this:

-F/System/Library/Frameworks

(Actually, it doesn't add this one, because it is the system default framework directory, but it would if the framework was in another directory.)

So, on Mac OS X, there are different cases that appear the same:

#include <OpenGL/gl.h>
#include <libxml/xpath.h>

The first one means “include the gl.h file from the OpenGL framework”, while the second means “include the libxml/xpath.h file from the libxml2 framework”. So first, we need to look whether the first part of the path is an existing framework, if it is, add a -F argument with the dir in which /the framework/ resides, if it's not, search all frameworks for the whole path, and add a -I argument with <PATH_TO_THE_FRAMEWORK>/Headers.
(0041364)
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
2008-10-09 13:08 Bill Hoffman Note Added: 0013796
2008-10-13 14:36 Philippe BERNERY Note Added: 0013862
2009-06-03 10:16 Hugues De Keyzer Note Added: 0016612
2009-06-03 10:18 Hugues De Keyzer Note Edited: 0016612
2009-06-03 10:49 Hugues De Keyzer Note Edited: 0016612
2009-06-03 11:22 Hugues De Keyzer Note Edited: 0016612
2009-06-03 12:07 Hugues De Keyzer Note Edited: 0016612
2009-06-04 04:10 Hugues De Keyzer Note Edited: 0016612
2009-06-04 05:32 Hugues De Keyzer Note Added: 0016632
2016-06-10 14:27 Kitware Robot Note Added: 0041364
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