Re: [cmake-developers] Linking Apple frameworks

2017-08-05 Thread Eric Wing
On 8/5/17, Craig Scott  wrote:
> I'm exploring the behaviour of target_link_libraries() where the library to
> be linked is an Apple framework. As part of this, I noticed that the
> following does not work:
>
> target_link_libraries(foo PRIVATE -framework AppKit)
>
>
> This fails because the link command ends up with -framework -lAppKit
> instead of -framework AppKit. Maybe that's expected, but then the following
> DOES work:
>
> target_link_libraries(foo PRIVATE "-framework AppKit")
>
>
> Strangely, with the library quoted as above, the embedded space is not
> escaped, leading to the (desirable but surprising) result -framework AppKit
> in
> the linker command line (i.e. the space isn't escaped and the two words are
> not quoted). *Which of these is the correct way (if either) and are both
> behaving as expected?*


I would argue both of the above are incorrect.

For some history, people passing explicit flags (e.g. -l and -L) was
the exact problem we fought in the first place many years ago. Most
people's scripts wouldn't work when porting to Mac because they
weren't using the CMake abstractions to inform CMake was going on, but
instead bypassing them by setting flags explicitly. So when brought to
Mac, things didn't necessarily work because there were a bunch of
explicit flags written in the scripts (including the Find*.cmake
scripts.) (There was actually a similar problem when porting to Visual
Studio too.)

Then when Apple brought (back) Universal binaries for Intel and then
64-bit, the flags needed to handle the build process got more
complicated. People passing their own flags at the wrong place could
cause problems. (A similar problem occurred as Apple pushed the SDK
model.)

Then (when not talking about system supplied frameworks), when iOS
came, they forbidded dynamic linking for the longest time, so
everything had to be as static libraries. So -framework flags would
not work. Obeying the normal CMake abstractions prevents problems here
too since it knows what to do for static libraries vs. frameworks.

And I would argue this is still wrong today because CMake will have a
harder time understanding there is a library involved here because you
didn't declare it with find_library. Particularly with the Xcode
generator, this information is very useful because the information
isn't always explicitly passed down to a command line invocation.
Sometimes it needs to be declarative so for the Xcode recognizes that
a framework is involved and allows Xcode to handle the correct
behavior.

Already there exists a problem in the Xcode generator that it doesn't
completely use all the framework and library built-in mechanisms, and
this is currently causing me problems for apps that need to be
codesigned. Xcode has a copy-frameworks-and-codessign phase which
CMake does not use. I hope this can be fixed, but I suspect it would
never work with the above two approaches you are asking about.

-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


[cmake-developers] Linking Apple frameworks

2017-08-05 Thread Craig Scott
I'm exploring the behaviour of target_link_libraries() where the library to
be linked is an Apple framework. As part of this, I noticed that the
following does not work:

target_link_libraries(foo PRIVATE -framework AppKit)


This fails because the link command ends up with -framework -lAppKit
instead of -framework AppKit. Maybe that's expected, but then the following
DOES work:

target_link_libraries(foo PRIVATE "-framework AppKit")


Strangely, with the library quoted as above, the embedded space is not
escaped, leading to the (desirable but surprising) result -framework AppKit in
the linker command line (i.e. the space isn't escaped and the two words are
not quoted). *Which of these is the correct way (if either) and are both
behaving as expected?*

As extra context, a correct final linker command line can also be achieved
like this:

find_library(APPKIT_LIB AppKit)
target_link_libraries(foo PRIVATE ${APPKIT_LIB})


In this case, while APPKIT_LIB contains a full absolute path to the
framework, CMake manages to recognise it as a framework and shortens the
linker flags to just -framework AppKit. This is mentioned in the
find_library() docs:

If the library found is a framework, then  will be set to the full
> path to the framework /A.framework. When a full path to a
> framework is used as a library, CMake will use a -framework A, and a
> -F to link the framework to the target.
>

So it is clear why the find_library() approach works, but the behaviour of
directly specifying the framework without find_library() seems somewhat
surprising.

-- 
Craig Scott
Melbourne, Australia
https://crascit.com
-- 

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