[cmake-developers] Problem with find_path and Frameworks

Harry Mallon Harry at codexdigital.com
Thu May 26 07:24:11 EDT 2016


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 harry at codexdigital.com | T +44 203 7000 989
> On 25 May 2016, at 20:44, Eric Wing <ewmailing at gmail.com> wrote:
>
> On 5/25/16, Harry Mallon <Harry at 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
>



More information about the cmake-developers mailing list