CMake:Bundles And Frameworks: Difference between revisions

From KitwarePublic
Jump to navigationJump to search
No edit summary
Line 67: Line 67:
   )
   )
</pre>
</pre>


Comment: (submitted by david.cole)
Comment: (submitted by david.cole)
I like the suggested api. One thing to keep in mind, however, is that some of the file system entities Mac programmers perceive as files are actually bundles themselves... For example, the resource files produced by Interface Builder (the *.nib "files") are actually bundles/directories themselves. As a Mac programmer, I think of the *.nib "file" as just another source file... In reality it's a directory with contents, which is supposed to be recursively copied into the correct location of the target bundle at build time. I would expect to be able to add either ''a file or a directory'' as a MACOSX_BUNDLE_CONTENT element in the ADD_EXECUTABLE/ADD_LIBRARY commands. If it's a file it gets copied into the target bundle at the specified location. If it's a directory, same thing, but recursively. This is '''mandatory''' in my opinion because Apple could decide to add, remove or completely reorganize elements within the *.nib file format with their next version of Xcode. I definitely don't want to mirror the hierarchical structure of a *.nib file in my CMakeLists.txt files. I also definitely don't want to be forced into using FILE(GLOB_RECURSE ...) in order to do things on a file by file basis. As a Mac programmer, I don't necessarily know whether one of these things is a file or directory - I can't tell CMake what I don't know, so CMake should definitely be able to handle either. CMake needs to support copying directories verbatim as bundle elements to make this feature worthwhile.
I like the suggested api. One thing to keep in mind, however, is that some of the file system entities Mac programmers perceive as files are actually bundles themselves... For example, the resource files produced by Interface Builder (the *.nib "files") are actually bundles/directories themselves. As a Mac programmer, I think of the *.nib "file" as just another source file... In reality it's a directory with contents, which is supposed to be recursively copied into the correct location of the target bundle at build time. I would expect to be able to add either ''a file or a directory'' as a MACOSX_BUNDLE_CONTENT element in the ADD_EXECUTABLE/ADD_LIBRARY commands. If it's a file it gets copied into the target bundle at the specified location. If it's a directory, same thing, but recursively. This is '''mandatory''' in my opinion because Apple could decide to add, remove or completely reorganize elements within the *.nib file format with their next version of Xcode. I definitely don't want to mirror the hierarchical structure of a *.nib file in my CMakeLists.txt files. I also definitely don't want to be forced into using FILE(GLOB_RECURSE ...) in order to do things on a file by file basis. As a Mac programmer, I don't necessarily know whether one of these things is a file or directory - I can't tell CMake what I don't know, so CMake should definitely be able to handle either. CMake needs to support copying directories verbatim as bundle elements to make this feature worthwhile.


Line 81: Line 79:
/Library/
/Library/
         Frameworks/
         Frameworks/
                   libr1.framework/
                   FRlibr1.framework/
                                libr1    -> Versions/Current/libr1
                                  FRlibr1  -> Versions/Current/FRlibr1
                                Resources -> Versions/Current/Resources
                                  Resources -> Versions/Current/Resources
                                Libraries -> Versions/Current/Libraries
                                  Libraries -> Versions/Current/Libraries
                                Headers  -> Versions/Current/Headers
                                  Headers  -> Versions/Current/Headers
                                Versions/
                                  Versions/
                                        Current -> ver2
                                          Current -> ver2
                                        ver2/
                                          ver2/
                                            libr1
                                              FRlibr1
                                            Resources/
                                              Resources/
                                                      Info.plist
                                                        Info.plist
                                                      version.plist
                                                        version.plist
                                            Libraries/
                                              Libraries/
                                                      libr2.dylib
                                                        libr2.dylib
                                                      libr3.dylib
                                                        libr3.dylib
                                            Headers/
                                              Headers/
                                                    libr1_header1.h
                                                      FRlibr1_header1.h
                                                    libr1_header2.h
                                                      FRlibr1_header2.h
                                                    libr1_header3.h
                                                      FRlibr1_header3.h
</pre>
</pre>


Line 107: Line 105:
<pre>
<pre>
ADD_LIBRARY(
ADD_LIBRARY(
   libr1
   FRlibr1
   SHARED MACOSX_FRAMEWORK
   SHARED MACOSX_FRAMEWORK
   appl1_src1.cxx
   appl1_src1.cxx
   appl1_src2.cxx
   appl1_src2.cxx
   libr1_header4.h
   FRlibr1_header4.h
   libr1_header5.h
   FRlibr1_header5.h
   libr1_header6.h
   FRlibr1_header6.h
   ...
   ...
   MACOSX_FRAMEWORK_HEADERS
   MACOSX_FRAMEWORK_HEADERS
   libr1_header1.h
   FRlibr1_header1.h
   libr1_header2.h
   FRlibr1_header2.h
   libr1_header3.h
   FRlibr1_header3.h
   )
   )


TARGET_LINL_LIBRARIES(
TARGET_LINL_LIBRARIES(
   libr1
   FRlibr1
   libr2 libr3)
   libr2 libr3)
</pre>
</pre>
Line 144: Line 142:
/Library/
/Library/
         Frameworks/
         Frameworks/
                   libr1.framework/
                   FRlibr1.framework/
                                libr1    -> Versions/Current/libr1
                                  FRlibr1  -> Versions/Current/FRlibr1
                                Resources -> Versions/Current/Resources
                                  Resources -> Versions/Current/Resources
                                Libraries -> Versions/Current/Libraries
                                  Libraries -> Versions/Current/Libraries
                                Headers  -> Versions/Current/Headers
                                  Headers  -> Versions/Current/Headers
                                Versions/
                                  Versions/
                                        Current -> ver2
                                          Current -> ver2
                                        ver2/
                                          ver2/
                                            libr1
                                              FRlibr1
                                            Resources/
                                              Resources/
                                                      Info.plist
                                                        Info.plist
                                                      version.plist
                                                        Version.plist
                                            Libraries/
                                              Libraries/
                                                      libr2.dylib
                                                        libr2.dylib
                                                      libr3.dylib
                                                        libr3.dylib
                                            Headers/
                                              Headers/
                                                    libr1_header1.h
                                                      FRlibr1_header1.h
                                                    libr1_header2.h
                                                      FRlibr1_header2.h
                                                    libr1_header3.h
                                                      FRlibr1_header3.h
</pre>
</pre>


Line 197: Line 195:
/Library/
/Library/
         Frameworks/
         Frameworks/
                   libr1.framework/
                   FRlibr1.framework/
                                libr1    -> Versions/Current/libr1
                                  FRlibr1  -> Versions/Current/FRlibr1
                                Resources -> Versions/Current/Resources
                                  Resources -> Versions/Current/Resources
                                Libraries -> Versions/Current/Libraries
                                  Libraries -> Versions/Current/Libraries
                                Headers  -> Versions/Current/Headers
                                  Headers  -> Versions/Current/Headers
                                Commands  -> Versions/Current/Commands
                                  Commands  -> Versions/Current/Commands
                                Versions/
                                  Versions/
                                        Current -> ver2
                                          Current -> ver2
                                        ver2/
                                          ver2/
                                            libr1
                                              FRlibr1
                                            Resources/
                                              Resources/
                                                      Info.plist
                                                        Info.plist
                                                      version.plist
                                                        version.plist
                                            Libraries/
                                              Libraries/
                                                      libr2.dylib
                                                        libr2.dylib
                                                      libr3.dylib
                                                        libr3.dylib
                                            Headers/
                                              Headers/
                                                    libr1_header1.h
                                                      FRlibr1_header1.h
                                                    libr1_header2.h
                                                      FRlibr1_header2.h
                                                    libr1_header3.h
                                                      FRlibr1_header3.h
                                            Commands/
                                              Commands/
                                                    appl2
                                                      appl2
                                            bin/
                                              bin/
                                                appl3
                                                  appl3
/usr/
/usr/
     bin/
     bin/
       appl1
       appl1
       appl2 -> /Library/Frameworks/libr1.framework/Commands/appl2
       appl2 -> /Library/Frameworks/FRlibr1.framework/Commands/appl2
       appl3 -> /Library/Frameworks/libr1.framework/Version/ver1/bin/appl3
       appl3 -> /Library/Frameworks/FRlibr1.framework/Version/ver1/bin/appl3
     share/
     share/
       appl1-version/
       appl1-version/
Line 250: Line 248:
/Library/
/Library/
         Frameworks/
         Frameworks/
                   libr1.framework/
                   FRlibr1.framework/
                                libr1     -> Versions/Current/libr1
                                  FRlibr1     -> Versions/Current/FRlibr1
                                Resources -> Versions/Current/Resources
                                  Resources -> Versions/Current/Resources
                                Libraries -> Versions/Current/Libraries
                                  Libraries -> Versions/Current/Libraries
                                Headers  -> Versions/Current/Headers
                                  Headers  -> Versions/Current/Headers
                                Commands  -> Versions/Current/Commands
                                  Commands  -> Versions/Current/Commands
                                Versions/
                                  Versions/
                                        Current -> ver2
                                          Current -> ver2
                                        ver2/
                                          ver2/
                                            libr1
                                              FRlibr1
                                            Resources/
                                              Resources/
                                                      Info.plist
                                                        Info.plist
                                                      version.plist
                                                        version.plist
                                            Libraries/
                                              Libraries/
                                                      libr2.dylib
                                                        libr2.dylib
                                                      libr3.dylib
                                                        libr3.dylib
                                            Headers/
                                              Headers/
                                                    libr1_header1.h
                                                      FRlibr1_header1.h
                                                    libr1_header2.h
                                                      FRlibr1_header2.h
                                                    libr1_header3.h
                                                      FRlibr1_header3.h
                                            Commands/
                                              Commands/
                                                    appl2
                                                      appl2
                                            bin/
                                              bin/
                                                appl3
                                                  appl3
/usr/
/usr/
     bin/
     bin/
       appl1
       appl1
       appl2 -> /Library/Frameworks/libr1.framework/Commands/appl2
       appl2 -> /Library/Frameworks/FRlibr1.framework/Commands/appl2
       appl3 -> /Library/Frameworks/libr1.framework/Version/ver1/bin/appl3
       appl3 -> /Library/Frameworks/FRlibr1.framework/Version/ver1/bin/appl3
     share/
     share/
         appl1-version/
         appl1-version/

Revision as of 14:04, 17 March 2006

Issue

On Mac there are several different cases of combinations of bundles, frameworks, and unix tools.

The problem is that CMAKE_INSTALL_PREFIX is not enough. Also, when creating bundles and frameworks, auxilary files should be in the proper subdirectory structure.

Notation

  • In all examples, the applications are named appl1, appl2, ...
  • libraries are named libr1, libr2, ...
  • header files are named appl1_header1, appl2_header2, libr1_header1, ...
  • there are auxilary files associated with application and library appl1_aux1, appl2_aux2, libr1_aux1, ...
  • and some resource files associated with application and library appl1_res1, appl2_res2, libr1_res1, ...
  • All versions are ver1, ver2, ...
  • All libraries have lib in their name, while frameworks do not. To differentiate, all frameworks will have names FRlibr1, FRlibr2, ...

Cases

Unix tools only

  • No issues (just like any other unix)

Bundle only

  • Everything in a same directory:
/Applications/
             appl1.app/
                      Contents/
                              Info.plist
                              MacOS/
                                   appl1 -> appl1-1
                                   appl1-1
                                   appl1_aux1
                                   appl1_aux2
                              Resources/
                                   appl1_res1
                                   appl1_res2
  • Suggested api:
ADD_EXECUTABLE(
  appl1
  MACOSX_BUNDLE
  appl1_src1.cxx
  appl1_src2.cxx
  ...
  MACOSX_BUNDLE_CONTENT
  apple1_aux1
  apple1_aux2
  apple1_res1
  apple1_res2
  )

SET_SOURCE_FILES_PROPERTIES(
  apple1_aux1
  apple1_aux2
  PROPERTIES
  MACOSX_BUNDLE_LOCATION MacOSX
  )
SET_SOURCE_FILES_PROPERTIES(
  apple1_res1
  apple1_res2
  PROPERTIES
  MACOSX_BUNDLE_LOCATION Resources
  )

Comment: (submitted by david.cole) I like the suggested api. One thing to keep in mind, however, is that some of the file system entities Mac programmers perceive as files are actually bundles themselves... For example, the resource files produced by Interface Builder (the *.nib "files") are actually bundles/directories themselves. As a Mac programmer, I think of the *.nib "file" as just another source file... In reality it's a directory with contents, which is supposed to be recursively copied into the correct location of the target bundle at build time. I would expect to be able to add either a file or a directory as a MACOSX_BUNDLE_CONTENT element in the ADD_EXECUTABLE/ADD_LIBRARY commands. If it's a file it gets copied into the target bundle at the specified location. If it's a directory, same thing, but recursively. This is mandatory in my opinion because Apple could decide to add, remove or completely reorganize elements within the *.nib file format with their next version of Xcode. I definitely don't want to mirror the hierarchical structure of a *.nib file in my CMakeLists.txt files. I also definitely don't want to be forced into using FILE(GLOB_RECURSE ...) in order to do things on a file by file basis. As a Mac programmer, I don't necessarily know whether one of these things is a file or directory - I can't tell CMake what I don't know, so CMake should definitely be able to handle either. CMake needs to support copying directories verbatim as bundle elements to make this feature worthwhile.

Maybe this concept could be generalized to "any file/directory that needs to be copied from source or binary tree into a location relative to the build exe/dll/lib" on any platform. Perhaps naming the features AUXILIARY_CONTENT_FILE and AUXILIARY_CONTENT_LOCATION would be more useful. I could see wanting to have different configuration files copied to where the exe is as part of the build step on Windows or Linux also. It's sort of an easier way of guaranteeing that a file is part of the build tree. Rather than explicit CONFIGURE_FILE or cmake -E copy/copy_directory commands, you could just add a source file as an AUXILIARY_CONTENT_FILE and cmake would make sure it gets copied/configured at build time.

Framework only

  • Everything in a same directory:
/Library/
        Frameworks/
                  FRlibr1.framework/
                                   FRlibr1   -> Versions/Current/FRlibr1
                                   Resources -> Versions/Current/Resources
                                   Libraries -> Versions/Current/Libraries
                                   Headers   -> Versions/Current/Headers
                                   Versions/
                                           Current -> ver2
                                           ver2/
                                               FRlibr1
                                               Resources/
                                                        Info.plist
                                                        version.plist
                                               Libraries/
                                                        libr2.dylib
                                                        libr3.dylib
                                               Headers/
                                                      FRlibr1_header1.h
                                                      FRlibr1_header2.h
                                                      FRlibr1_header3.h


  • Suggested api:
ADD_LIBRARY(
  FRlibr1
  SHARED MACOSX_FRAMEWORK
  appl1_src1.cxx
  appl1_src2.cxx
  FRlibr1_header4.h
  FRlibr1_header5.h
  FRlibr1_header6.h
  ...
  MACOSX_FRAMEWORK_HEADERS
  FRlibr1_header1.h
  FRlibr1_header2.h
  FRlibr1_header3.h
  )

TARGET_LINL_LIBRARIES(
  FRlibr1
  libr2 libr3)

Bundle + Framework

  • Bundle stuff in one directory, framework stuff in another one
/Applications/
             appl1.app/
                      Contents/
                              Info.plist
                              MacOS/
                                   appl1 -> appl1-ver1
                                   appl1-ver2
                                   appl1_aux1
                                   appl1_aux2
                              Resources/
                                   appl1_res1
                                   appl1_res2
/Library/
        Frameworks/
                  FRlibr1.framework/
                                   FRlibr1   -> Versions/Current/FRlibr1
                                   Resources -> Versions/Current/Resources
                                   Libraries -> Versions/Current/Libraries
                                   Headers   -> Versions/Current/Headers
                                   Versions/
                                           Current -> ver2
                                           ver2/
                                               FRlibr1
                                               Resources/
                                                        Info.plist
                                                        Version.plist
                                               Libraries/
                                                        libr2.dylib
                                                        libr3.dylib
                                               Headers/
                                                      FRlibr1_header1.h
                                                      FRlibr1_header2.h
                                                      FRlibr1_header3.h

Bundle + Unix tools

  • Bundle stuff in one directory, unix tools in typical unix location
/Applications/
             appl1.app/
                      Contents/
                              Info.plist
                              MacOS/
                                   appl1 -> appl1-ver1
                                   appl1-ver2
                                   appl1_aux1
                                   appl1_aux2
                              Resources/
                                   appl1_res1
                                   appl1_res2

/usr/
    bin/
       appl2
    share/
       appl2-version/
                    appl2_aux1
                    appl2_aux2

Framework + Unix tools

  • Framework stuff in one directory, unix tools in typical unix location
/Library/
        Frameworks/
                  FRlibr1.framework/
                                   FRlibr1   -> Versions/Current/FRlibr1
                                   Resources -> Versions/Current/Resources
                                   Libraries -> Versions/Current/Libraries
                                   Headers   -> Versions/Current/Headers
                                   Commands  -> Versions/Current/Commands
                                   Versions/
                                           Current -> ver2
                                           ver2/
                                               FRlibr1
                                               Resources/
                                                        Info.plist
                                                        version.plist
                                               Libraries/
                                                        libr2.dylib
                                                        libr3.dylib
                                               Headers/
                                                      FRlibr1_header1.h
                                                      FRlibr1_header2.h
                                                      FRlibr1_header3.h
                                               Commands/
                                                       appl2
                                               bin/
                                                  appl3
/usr/
    bin/
       appl1
       appl2 -> /Library/Frameworks/FRlibr1.framework/Commands/appl2
       appl3 -> /Library/Frameworks/FRlibr1.framework/Version/ver1/bin/appl3
    share/
       appl1-version/
                    appl1_aux1
                    appl1_aux2

Bundle + Framework + Unix tools

  • Framework stuff in one directory, unix tools in typical unix location
/Applications/
             appl1.app/
                      Contents/
                              Info.plist
                              MacOS/
                                   appl1 -> appl1-ver1
                                   appl1-ver2
                                   appl1_aux1
                                   appl1_aux2
                              Resources/
                                   appl1_res1
                                   appl1_res2
/Library/
        Frameworks/
                  FRlibr1.framework/
                                   FRlibr1     -> Versions/Current/FRlibr1
                                   Resources -> Versions/Current/Resources
                                   Libraries -> Versions/Current/Libraries
                                   Headers   -> Versions/Current/Headers
                                   Commands  -> Versions/Current/Commands
                                   Versions/
                                           Current -> ver2
                                           ver2/
                                               FRlibr1
                                               Resources/
                                                        Info.plist
                                                        version.plist
                                               Libraries/
                                                        libr2.dylib
                                                        libr3.dylib
                                               Headers/
                                                      FRlibr1_header1.h
                                                      FRlibr1_header2.h
                                                      FRlibr1_header3.h
                                               Commands/
                                                       appl2
                                               bin/
                                                  appl3
/usr/
    bin/
       appl1
       appl2 -> /Library/Frameworks/FRlibr1.framework/Commands/appl2
       appl3 -> /Library/Frameworks/FRlibr1.framework/Version/ver1/bin/appl3
    share/
         appl1-version/
                      appl1_aux1
                      appl1_aux2

Linking Issues

Assuming:

/Applications/
             appl1.app/
                      Contents/
                              Info.plist
                              MacOS/
                                   appl1 -> appl1-1
                                   appl1-1
                                   appl1_aux1
                                   appl1_aux2
                              Resources/
                                   appl1_res1
                                   appl1_res2
                              Framework/
                                   libr1-ver1.dylib

You have to run:

install_name_tool \
  -id @executable_path/../Frameworks/libr-ver1.dylib \
   appl1.app/Contents/Frameworks/libr1-ver1.dylib

and

install_name_tool \
  -change libr-ver1.dylib \
   @executable_path/../Frameworks/libr-ver1.dylib \
   appl1.app/Contents/MacOS/appl1

Related Work



CMake: [Welcome | Site Map]