I can work around it if need be. I just felt that it was against the stated behaviour of find_path since that function is meant to give the folder where you can find "IOKit/pci/IOPCIDevice.h" rather than the folder where you can find "IOPCIDevice.h".
Harry Harry Mallon CODEX | Software Engineer 60 Poland Street | London | England | W1F 7NT E ha...@codexdigital.com | T +44 203 7000 989 > On 25 May 2016, at 20:44, Eric Wing <ewmail...@gmail.com> wrote: > > On 5/25/16, Harry Mallon <ha...@codexdigital.com> wrote: >> I have quite a specific problem with find_path where >> "find_path(IOKIT_INCLUDE_DIR "IOKit/pci/IOPCIDevice.h")" returns >> "/System/Library/Frameworks/Kernel.framework/Headers/IOKit/pci" rather than >> "/System/Library/Frameworks/Kernel.framework/Headers/". >> >> It is reproducible on OSX with the following CMakeLists.txt: >> >> cmake_minimum_required(VERSION 3.0) >> find_path(IOKIT_INCLUDE_DIR "IOKit/pci/IOPCIDevice.h") >> message("Path returned: ${IOKIT_INCLUDE_DIR}") >> >> Here is a patch which seems to fix it for me: >> > > This is a pretty atypical situation. I’m actually not sure what the > behavior should be. But we need to be careful to not break the > existing cases. I’m a little worried that there may be things out > there relying on the existing behavior. I’m also not convinced this > actually needs a patch. > > > The framework header path system was hammered out over a long period > of time. There are two common use cases that it was designed to > handle: > > case 1: #import <Cocoa/Cocoa.h> > find_path(COCOA_INCLUDE_DIR “Cocoa/Cocoa.h”) > # Returns something like /System/Library/Frameworks/Cocoa.framework > > > case 2: #include “al.h” > find_path(OPENAL_INCLUDE_DIR “al.h”) > # Returns something like /System/Library/Frameworks/OpenAL.framework/Headers > > > The reason for this behavior is that unlike other platforms, > frameworks are not a direct mapping to file system mapping. When > dealing with official Apple frameworks, you are expected to use case > 1. But the second form is an important concession for cross-platform > libraries. The problem is that many libraries, especially 3rd party > libraries, do not end up in subdirectories with the same names on all > platforms. > > For OpenGL, most Unix’s do <GL/gl.h>, but Apple does <OpenGL/gl.h>. > For OpenAL, it is crazier because it depends on which implementation > you use. Apple does <OpenAL/al.h>, OpenAL Soft does <AL/al.h>, but > others have presumes no subdirectory at all. > And a lot of third party libraries don’t have any official > conventions, so distributions do everything differently. So for > cross-platform, you are encouraged to do “Foo.h” omitting a path and > letting the build system deal with it (since CMake can do a better job > here than a massive, hand-coded mess of #ifdefs in your files. > > > So your case seems very atypical because you are using something > inside Kernel.framework and the header you want is not in > IOKit.framework. If it was a more typical scenario like > IOKit.framework, > > I would kind of expect you to find a file in IOKit at the top level > instead to represent all your IOKit dealings, e.g. > > find_path(IOKIT_INCLUDE_DIR “IOKit/IOKitLib.h”) > > Then in your code you would do: > #import <IOKit/pci/IOPCIDevice.h>, and what you get back from CMake > (/System/Library/Frameworks/IOKit.framework) would be correct. > > But since pci doesn’t actually seem to be directly in IOKit, but > instead the Kernel.framework subdirectory mess, I’m not sure what the > appropriate thing is. The normal native Xcode header path search > mechanism doesn’t seem to support this case and I found an old mailing > list thread suggesting that this is Apple’s way of telling you to > keep-out. > > > I would actually be inclined to suggest a much more generic find for > Kernel.framework and build your paths manually from there. > > > So either something simple like: > find_path(KERNEL_INCLUDE_DIR IOKit) > # return /System/Library/Frameworks/Kernel.framework/Headers > > > Or something a little more defensive to avoid possible name > collisions, but requires manual construction: > find_path(KERNEL_INCLUDE_DIR Kernel/IOKit) > # return /System/Library/Frameworks/Kernel.framework > set(KERNEL_IOKIT_INCLUDE_DIR “${KERNEL_INCLUDE_DIR}/Headers”) > > > -Eric > -- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: http://public.kitware.com/mailman/listinfo/cmake-developers