Uploaded image for project: 'Qbs ("Cubes")'
  1. Qbs ("Cubes")
  2. QBS-643

Add a better way of dealing with Darwin bundles

    XMLWordPrintable

Details

    • Task
    • Resolution: Done
    • P2: Important
    • None
    • None
    • General
    • None
    • bfdc2953ecc4a9800c2974d2d63e528c2bdc9b96

    Description

      Needs discussion!

      Essentially we need:

      • Executable files:
        • Executable (MH_EXECUTE)
        • Static library (archive)
        • Dynamic library (MH_DYLIB)
        • Loadable module (MH_BUNDLE)
      • Executable files in a bundle structure:
        • Application bundle (bundled MH_EXECUTE)
        • Static framework (bundled archive)
        • (Dynamic) framework (bundled MH_DYLIB)
        • Loadable bundle (bundled MH_BUNDLE)

      Because there's a one-to-one mapping between bundled and unbundled versions, I wonder if we could simplify this somehow.

      For base product types we have: ["application", "staticlibrary", "dynamiclibrary", "loadablemodule"]

      For bundled product types we have: ["applicationbundle", "frameworkbundle"] (and would probably need staticframeworkbundle and loadablemodulebundle

      Perhaps bundled products could simply append the product type "bundle" to the existing four product types we have (and get rid of applicationbundle and frameworkbundle).

      • Application bundle: ["application", "bundle"]
      • Framework: ["dynamiclibrary", "bundle"]
      • Static framework: ["staticlibrary", "bundle"]
      • Bundle: ["loadablemodule", "bundle"]

      This could be done mainly through QML Items which set the product type conditionally based upon two such properties (like Application, DynamicLibrary, StaticLibrary, Bundle):

      property bool isBundled: {
          if (product.type.contains("dynamiclibrary") && qbs.targetOS.contains("ios") && parseInt(cpp.minimumIosVersion) < 8 /* && code-signing for Apple App Store */) {
              // yes, for technical reasons, not policy alone, there's no getting around it
              // developers who use alternative distribution methods won't see this warning since not codesigning for App Store (also dynamic frameworks DO work for development signed binaries on iOS 7 devices (only when run from debugger?) - I've tried - maybe for Ad Hoc too)
              console.warn("WARNING: Dynamic libraries cannot be deployed to the App Store with a deployment target below iOS 8.0.");
          }
          return qbs.targetOS.contains("darwin");
      }
      
      property string bundleExtension: {
          if (product.type.contains("application"))
              return "app"; // also appex for iOS 8 application extensions
          else if (product.type.contains("staticlibrary") || product.type.contains("dynamiclibrary"))
              return "framework";
          else if (product.type.contains("loadablebundle")
              return "bundle"; // custom extensions allowed too
      }
      

      However, this wouldn't solve the monstrous verbosity necessary for current iOS:

      product.type: {
          if (qbs.targetOS.contains("darwin")) {
              if (qbs.targetOS.contains("ios") && parseInt(cpp.minimumIosVersion) < 8) {
                  return "staticlibrary";
              }
              return "frameworkbundle";
          }
          return "dynamiclibrary";
      }
      

      It would be nice to specify the general kind of library (static or dynamic), and have the bundling be a little more automatic. Such as:

      product.type: (qbs.targetOS.contains("ios") && parseInt(cpp.minimumIosVersion) < 8) ? "staticlibrary" : "dynamiclibrary"
      isBundle: // defaults to qbs.targetOS.contains("darwin") === true
      

      A "Library" template could even do this. It uses a dynamic library if available, otherwise a static library, and uses bundles if available, otherwise normal libraries.

      For example, by default:

      • .dll on Windows
      • .so on Unix
      • .framework on macOS, iOS >= 8.0
      • .a on iOS < 8.0

      Other random thoughts:

      • Also, what about resource-only bundles (bundle as in "directory structure", not MH_BUNDLE)?
      • What about relocatable object files? (MH_OBJECT)
      • What about copying dependent products into the bundle? New property on Depends?
      • Look over Xcode's xcspec files for inspiration on structuring Qbs bundle support

      Some of this may be the mere 4 AM ramblings of a tired man but I'm dumping my memory for now and will revisit this with deeper thought in the morning.

      Attachments

        Issue Links

          For Gerrit Dashboard: QBS-643
          # Subject Branch Project Status CR V

          Activity

            People

              jakepetroules Jake Petroules (DO NOT ASSIGN ISSUES)
              jakepetroules Jake Petroules (DO NOT ASSIGN ISSUES)
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Gerrit Reviews

                  There are no open Gerrit changes