Framework Installation Directory / Framework copying

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Framework Installation Directory / Framework copying

Glenn Hughes
Hi all,

Does anyone have any experience with how to copy a built framework
into the application bundle?

In Xcode we set the Installation Directory of the Framework to
@executable_path/../Frameworks/, then as a post-link phase of building
the app we run a python script to copy the built framework into the
application bundle.
I can set up the dependency between my app target and my framework
target, and if I leave everything alone the app even runs.
However, if  I move the framework into the app bundle by hand, it
won't launch because it can't find the framework. This is because the
Installation Directory is being set to the BINARY_DIR location.

If I by hand fix the Xcode project's Installation Directory to
@executable_path/../Frameworks/ and rebuild, (and move it to the
correct location by hand) everything works. (So, I know my suspicions
about what needs to be done are correct).

So, does anyone know how to set a Framework's Installation Directory
parameter via CMake?

Part of my problem in researching this problem is that "Installation
Directory" is an overloaded term in the CMake lexicon. I'm talking
about the OS X Framework attribute here, not the CPack or Squish
variables.

Also, any idea about the best way to do the Framework copy? I could
probably just re-use our python script, but maybe there's a cleaner
CMake way of doing something like this...

Thanks in advance...
Glenn
_______________________________________________
Powered by www.kitware.com

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Follow this link to subscribe/unsubscribe:
http://www.cmake.org/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Framework Installation Directory / Framework copying

Michael Jackson
http://www.cmake.org/Wiki/BundleUtilitiesExample

Might Help

Mike Jackson

On Dec 8, 2009, at 5:11 PM, Glenn Hughes wrote:

> Hi all,
>
> Does anyone have any experience with how to copy a built framework
> into the application bundle?
>
> In Xcode we set the Installation Directory of the Framework to
> @executable_path/../Frameworks/, then as a post-link phase of building
> the app we run a python script to copy the built framework into the
> application bundle.
> I can set up the dependency between my app target and my framework
> target, and if I leave everything alone the app even runs.
> However, if  I move the framework into the app bundle by hand, it
> won't launch because it can't find the framework. This is because the
> Installation Directory is being set to the BINARY_DIR location.
>
> If I by hand fix the Xcode project's Installation Directory to
> @executable_path/../Frameworks/ and rebuild, (and move it to the
> correct location by hand) everything works. (So, I know my suspicions
> about what needs to be done are correct).
>
> So, does anyone know how to set a Framework's Installation Directory
> parameter via CMake?
>
> Part of my problem in researching this problem is that "Installation
> Directory" is an overloaded term in the CMake lexicon. I'm talking
> about the OS X Framework attribute here, not the CPack or Squish
> variables.
>
> Also, any idea about the best way to do the Framework copy? I could
> probably just re-use our python script, but maybe there's a cleaner
> CMake way of doing something like this...
>
> Thanks in advance...
> Glenn

_______________________________________________
Powered by www.kitware.com

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Follow this link to subscribe/unsubscribe:
http://www.cmake.org/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Framework Installation Directory / Framework copying

Glenn Hughes
Thanks Mike,

I pretty much got my build process on the Mac working. The thing that
took me awhile to understand were the different running contexts that
bits of the CMake script are processed within. What I want is a little
different than the standard way that things are done in the CMake way
of handling Frameworks and bundles. I basically always want the
Frameworks copied into the app, not just during the install phase.

Here's what I'm doing:

1) In my framework CMakeLists.txt file, I have the following:

IF (APPLE)
  SET_TARGET_PROPERTIES( MyFramework PROPERTIES FRAMEWORK true)
        SET_TARGET_PROPERTIES( MyFramework PROPERTIES
XCODE_ATTRIBUTE_INSTALL_PATH @executable_path/../Frameworks/  )
ENDIF (APPLE)

The second "set_target_properties" line configures the framework to
always be looked for in the application bundle in the Frameworks
sub-folder.

2) In my top-level CMakeLists.txt file, I add setup a unified binary
output directory (thanks Mike!):

SET (CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/Bin)
SET (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/Bin )
SET (CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/Bin )

3) Then, in my applications' CMakeLists.txt file, I have the following:

IF (APPLE)
  ADD_CUSTOM_COMMAND(
  TARGET MyApp
  POST_BUILD
  COMMAND ${PYTHON_EXECUTABLE}
      ARGS ${CMAKE_HOME_DIRECTORY}/CopyFramework.py
                --binary ${PROJECT_BINARY_DIR}/Bin
                --framework MyFramework.framework
        --app MyApp.app

     )
ENDIF (APPLE)

This calls out to my python script, which does the work of assembling
the src and dest paths, and actually copying the Framework.

The final trick is that since this is a Mac only thing, I can rely on
an Xcode environment variable within the Python script:
                config= os.environ["CONFIGURATION"]

This allows me to assemble the complete path to the actual binary
locations of the framework and the app.

The one thing I wish was that there was a CMake variable that would
expand to the current Config within the context of the
ADD_CUSTOM_COMMAND... It'd be nice to not have to resort to using the
Xcode environment variable.

Thanks again
Glenn
_______________________________________________
Powered by www.kitware.com

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Follow this link to subscribe/unsubscribe:
http://www.cmake.org/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Framework Installation Directory / Framework copying

Michael Jackson
On Wed, Dec 9, 2009 at 4:05 PM, Glenn Hughes <[hidden email]> wrote:

> Thanks Mike,
>
> I pretty much got my build process on the Mac working. The thing that
> took me awhile to understand were the different running contexts that
> bits of the CMake script are processed within. What I want is a little
> different than the standard way that things are done in the CMake way
> of handling Frameworks and bundles. I basically always want the
> Frameworks copied into the app, not just during the install phase.
>
> Here's what I'm doing:
>
> 1) In my framework CMakeLists.txt file, I have the following:
>
> IF (APPLE)
>        SET_TARGET_PROPERTIES( MyFramework PROPERTIES FRAMEWORK true)
>        SET_TARGET_PROPERTIES( MyFramework PROPERTIES
> XCODE_ATTRIBUTE_INSTALL_PATH @executable_path/../Frameworks/  )
> ENDIF (APPLE)
>
> The second "set_target_properties" line configures the framework to
> always be looked for in the application bundle in the Frameworks
> sub-folder.
>
> 2) In my top-level CMakeLists.txt file, I add setup a unified binary
> output directory (thanks Mike!):
>
> SET (CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/Bin)
> SET (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/Bin )
> SET (CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/Bin )
>
> 3) Then, in my applications' CMakeLists.txt file, I have the following:
>
> IF (APPLE)
>        ADD_CUSTOM_COMMAND(
>                TARGET MyApp
>                POST_BUILD
>                COMMAND ${PYTHON_EXECUTABLE}
>                ARGS ${CMAKE_HOME_DIRECTORY}/CopyFramework.py
>                --binary ${PROJECT_BINARY_DIR}/Bin
>                --framework MyFramework.framework
>                --app MyApp.app
>
>     )
> ENDIF (APPLE)
>
> This calls out to my python script, which does the work of assembling
> the src and dest paths, and actually copying the Framework.
>
> The final trick is that since this is a Mac only thing, I can rely on
> an Xcode environment variable within the Python script:
>                config= os.environ["CONFIGURATION"]
>
> This allows me to assemble the complete path to the actual binary
> locations of the framework and the app.
>
> The one thing I wish was that there was a CMake variable that would
> expand to the current Config within the context of the
> ADD_CUSTOM_COMMAND... It'd be nice to not have to resort to using the
> Xcode environment variable.
>
> Thanks again
> Glenn

Looks like you generally have a handle on things. The subtle thing
about the Xcode Environment variables is that your CMake Code is run
at "Cmake Time" which will have no idea about the Xcode variables that
are set during a "Build Time". Chicken-and-Egg sort of thing. In the
recent HDF5 Version 1.8 CMake Port/Fork I have the following code that
runs an executable as soon as it is compiled:

SET (CFG_INIT "/${CMAKE_CFG_INTDIR}")
IF (MAKE_SYSTEM)
  SET (CFG_INIT "")
ENDIF (MAKE_SYSTEM)

SET (CMD ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}${CFG_INIT}/H5detect${EXE_EXT})
IF(XCODE)
  SET (CMD "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/\${CONFIGURATION}/H5detect")
ENDIF(XCODE)
ADD_EXECUTABLE(H5detect ${HDF5_SRC_DIR}/H5detect.c)

ADD_CUSTOM_COMMAND(
  OUTPUT ${HDF5_BINARY_DIR}/H5Tinit.c
  COMMAND ${CMD}
  ARGS > ${HDF5_BINARY_DIR}/H5Tinit.c
  DEPENDS H5detect
  )

The part to take away from this is that if you look at the if(XCODE)
section I am picking up the proper Xcode variable that determines the
"Debug/Release" sub directory of "Bin". That is then used in the
"add_custom_command()".

 The other thing you might be able to do would be to "save" the
CMAKE_*_OUTPUT_DIRECTORY variables, set those variables to inside the
MyApp.app bundle for the Framework target, then set them back to the
originals at the bottom of the Frameworks CMakeLists.txt file. This
_should_ end up compiling/generating the framework at the correct spot
in the App bundle.

 You could also use the add_custom_target() command to copy the built
framework into the app bundle after it is compiled:

add_custom_command(TARGET target
                    PRE_BUILD | PRE_LINK | POST_BUILD
             COMMAND command1 [ARGS] [args1...]
            [COMMAND command2 [ARGS] [args2...] ...]
                [WORKING_DIRECTORY dir]
                  [COMMENT comment] [VERBATIM]  )

add_custom_target(${qtlib}-Debug-Copy ALL
                            COMMAND ${CMAKE_COMMAND} -E
copy_if_different ${QT_DLL_PATH_tmp}/${qtlib}${TYPE}4.dll
                            ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Debug/
                            COMMENT "Copying ${qtlib}${TYPE}4.dll to
${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Debug/")


The "COMMAND" would be actually using CMake itself to do the copying. Just FYI.
_________________________________________________________
Mike Jackson                  [hidden email]
BlueQuartz Software                    www.bluequartz.net
Principal Software Engineer                  Dayton, Ohio
_______________________________________________
Powered by www.kitware.com

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Follow this link to subscribe/unsubscribe:
http://www.cmake.org/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Framework Installation Directory / Framework copying

Clinton Stimpson
On Wednesday 09 December 2009 02:23:34 pm Mike Jackson wrote:

> On Wed, Dec 9, 2009 at 4:05 PM, Glenn Hughes <[hidden email]> wrote:
> > Thanks Mike,
> >
> > I pretty much got my build process on the Mac working. The thing that
> > took me awhile to understand were the different running contexts that
> > bits of the CMake script are processed within. What I want is a little
> > different than the standard way that things are done in the CMake way
> > of handling Frameworks and bundles. I basically always want the
> > Frameworks copied into the app, not just during the install phase.
> >
> > Here's what I'm doing:
> >
> > 1) In my framework CMakeLists.txt file, I have the following:
> >
> > IF (APPLE)
> >        SET_TARGET_PROPERTIES( MyFramework PROPERTIES FRAMEWORK true)
> >        SET_TARGET_PROPERTIES( MyFramework PROPERTIES
> > XCODE_ATTRIBUTE_INSTALL_PATH @executable_path/../Frameworks/  )
> > ENDIF (APPLE)
> >
> > The second "set_target_properties" line configures the framework to
> > always be looked for in the application bundle in the Frameworks
> > sub-folder.
> >
> > 2) In my top-level CMakeLists.txt file, I add setup a unified binary
> > output directory (thanks Mike!):
> >
> > SET (CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/Bin)
> > SET (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/Bin )
> > SET (CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/Bin )
> >
> > 3) Then, in my applications' CMakeLists.txt file, I have the following:
> >
> > IF (APPLE)
> >        ADD_CUSTOM_COMMAND(
> >                TARGET MyApp
> >                POST_BUILD
> >                COMMAND ${PYTHON_EXECUTABLE}
> >                ARGS ${CMAKE_HOME_DIRECTORY}/CopyFramework.py
> >                --binary ${PROJECT_BINARY_DIR}/Bin
> >                --framework MyFramework.framework
> >                --app MyApp.app
> >
> >     )
> > ENDIF (APPLE)
> >
> > This calls out to my python script, which does the work of assembling
> > the src and dest paths, and actually copying the Framework.
> >
> > The final trick is that since this is a Mac only thing, I can rely on
> > an Xcode environment variable within the Python script:
> >                config= os.environ["CONFIGURATION"]
> >
> > This allows me to assemble the complete path to the actual binary
> > locations of the framework and the app.
> >
> > The one thing I wish was that there was a CMake variable that would
> > expand to the current Config within the context of the
> > ADD_CUSTOM_COMMAND... It'd be nice to not have to resort to using the
> > Xcode environment variable.
> >
> > Thanks again
> > Glenn
>
> Looks like you generally have a handle on things. The subtle thing
> about the Xcode Environment variables is that your CMake Code is run
> at "Cmake Time" which will have no idea about the Xcode variables that
> are set during a "Build Time". Chicken-and-Egg sort of thing. In the
> recent HDF5 Version 1.8 CMake Port/Fork I have the following code that
> runs an executable as soon as it is compiled:
>
> SET (CFG_INIT "/${CMAKE_CFG_INTDIR}")

Don't you mean "/\${CMAKE_CFG_INTDIR}", so the proper variable substitution
happens later?
If so, is that why you have an IF(XCODE) section?

Clint

_______________________________________________
Powered by www.kitware.com

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Follow this link to subscribe/unsubscribe:
http://www.cmake.org/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Framework Installation Directory / Framework copying

Glenn Hughes
In reply to this post by Michael Jackson
>The subtle thing
> about the Xcode Environment variables is that your CMake Code is run
> at "Cmake Time" which will have no idea about the Xcode variables that
> are set during a "Build Time".

Right. But in my case this is OK, because I evaluate the Xcode env
variable in my python script which is run at "build time" by Xcode and
not at "CMake time"...

I guess your code is doing something similar, but in the CMake
universe... Just to make sure I understand what you're doing:
You're quoting ${CONFIGURATION}  when you assemble the CMD string, so
it wont be evaluated until the command is actually run by Xcode,
right? That's a neat way of doing it, because then I could
theoretically build using vanilla make under OSX if I wanted to.

I don't want to try to generate the framework into the app bundle
itself. We've found you wind up with chicken-and-egg problems with
this approach because the Framework needs to be built before the app
so the app can link to it, but the app doesn't exist yet, etc etc.

In your custom target approach, I would need a different target for
each configuration?
I'm actually happy using my python script to do the copy, because it
can copy the whole framework, not just the dylib, and its also smart
about not copying things that are not out of date. This is some code
we'd already written so it was nice to be able to reuse it.

Anyway I've got it all working now... Thanks for the help!

Best wishes
Glenn
_______________________________________________
Powered by www.kitware.com

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Follow this link to subscribe/unsubscribe:
http://www.cmake.org/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Framework Installation Directory / Framework copying

Michael Jackson
In reply to this post by Clinton Stimpson
Hmm. I'll have to give that a try. Thanks
_________________________________________________________
Mike Jackson                  [hidden email]

On Wed, Dec 9, 2009 at 4:48 PM, Clinton Stimpson <[hidden email]> wrote:

> On Wednesday 09 December 2009 02:42:13 pm you wrote:
>> _________________________________________________________
>> Mike Jackson                  [hidden email]
>> BlueQuartz Software                    www.bluequartz.net
>> Principal Software Engineer                  Dayton, Ohio
>>
>> On Wed, Dec 9, 2009 at 4:33 PM, Clinton Stimpson <[hidden email]>
> wrote:
>> > On Wednesday 09 December 2009 02:23:34 pm Mike Jackson wrote:
>> >> On Wed, Dec 9, 2009 at 4:05 PM, Glenn Hughes <[hidden email]>
> wrote:
>> >> > Thanks Mike,
>> >> >
>> >> > I pretty much got my build process on the Mac working. The thing that
>> >> > took me awhile to understand were the different running contexts that
>> >> > bits of the CMake script are processed within. What I want is a little
>> >> > different than the standard way that things are done in the CMake way
>> >> > of handling Frameworks and bundles. I basically always want the
>> >> > Frameworks copied into the app, not just during the install phase.
>> >> >
>> >> > Here's what I'm doing:
>> >> >
>> >> > 1) In my framework CMakeLists.txt file, I have the following:
>> >> >
>> >> > IF (APPLE)
>> >> >        SET_TARGET_PROPERTIES( MyFramework PROPERTIES FRAMEWORK true)
>> >> >        SET_TARGET_PROPERTIES( MyFramework PROPERTIES
>> >> > XCODE_ATTRIBUTE_INSTALL_PATH @executable_path/../Frameworks/  )
>> >> > ENDIF (APPLE)
>> >> >
>> >> > The second "set_target_properties" line configures the framework to
>> >> > always be looked for in the application bundle in the Frameworks
>> >> > sub-folder.
>> >> >
>> >> > 2) In my top-level CMakeLists.txt file, I add setup a unified binary
>> >> > output directory (thanks Mike!):
>> >> >
>> >> > SET (CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/Bin)
>> >> > SET (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/Bin )
>> >> > SET (CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/Bin )
>> >> >
>> >> > 3) Then, in my applications' CMakeLists.txt file, I have the
>> >> > following:
>> >> >
>> >> > IF (APPLE)
>> >> >        ADD_CUSTOM_COMMAND(
>> >> >                TARGET MyApp
>> >> >                POST_BUILD
>> >> >                COMMAND ${PYTHON_EXECUTABLE}
>> >> >                ARGS ${CMAKE_HOME_DIRECTORY}/CopyFramework.py
>> >> >                --binary ${PROJECT_BINARY_DIR}/Bin
>> >> >                --framework MyFramework.framework
>> >> >                --app MyApp.app
>> >> >
>> >> >     )
>> >> > ENDIF (APPLE)
>> >> >
>> >> > This calls out to my python script, which does the work of assembling
>> >> > the src and dest paths, and actually copying the Framework.
>> >> >
>> >> > The final trick is that since this is a Mac only thing, I can rely on
>> >> > an Xcode environment variable within the Python script:
>> >> >                config= os.environ["CONFIGURATION"]
>> >> >
>> >> > This allows me to assemble the complete path to the actual binary
>> >> > locations of the framework and the app.
>> >> >
>> >> > The one thing I wish was that there was a CMake variable that would
>> >> > expand to the current Config within the context of the
>> >> > ADD_CUSTOM_COMMAND... It'd be nice to not have to resort to using the
>> >> > Xcode environment variable.
>> >> >
>> >> > Thanks again
>> >> > Glenn
>> >>
>> >> Looks like you generally have a handle on things. The subtle thing
>> >> about the Xcode Environment variables is that your CMake Code is run
>> >> at "Cmake Time" which will have no idea about the Xcode variables that
>> >> are set during a "Build Time". Chicken-and-Egg sort of thing. In the
>> >> recent HDF5 Version 1.8 CMake Port/Fork I have the following code that
>> >> runs an executable as soon as it is compiled:
>> >>
>> >> SET (CFG_INIT "/${CMAKE_CFG_INTDIR}")
>> >
>> > Don't you mean "/\${CMAKE_CFG_INTDIR}", so the proper variable
>> > substitution happens later?
>> > If so, is that why you have an IF(XCODE) section?
>> >
>> > Clint
>>
>> Well I tried that and either CMake or Xcode just didn't really know
>> what to do with it.
>>
>> CMake turns the add_custom_command into a shell script. The
>> "CONFIGURATION" is an environment variable that is set by Xcode during
>> the execution of the shell script so during the actual execution the
>> proper value gets substituted and everything works. If there is a
>> better way, I am all ears..
>
> This works for me in XCode/Visual Studio/Makefiles/etc...:
>
> ADD_CUSTOM_COMMAND(
>  OUTPUT ${foo_BINARY_DIR}/allwords.h
>  COMMAND ${foo_BINARY_DIR}/CMake/${CMAKE_CFG_INTDIR}/wordlist
>  ARGS allwords.h ${COMMAND_TABLES}
>  DEPENDS ${COMMAND_TABLES}
>        ${foo_BINARY_DIR}/CMake/${CMAKE_CFG_INTDIR}/wordlist
>       )
>
> Clint
>
>
_______________________________________________
Powered by www.kitware.com

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Follow this link to subscribe/unsubscribe:
http://www.cmake.org/mailman/listinfo/cmake