[Swift Package Manager] Use of Info-plist; use for apps

1. I recall there’s a way to make a command-line tool in macOS have an “Info.plist” file, which is compiled/linked in the executable’s data segment. I used Xcode back then. Is there a way to do this through “swift build”? (I think the Xcode directions are in Apple’s Code Signing Guide.) (I can’t use Xcode here since that project file is generated from swift-build!)

2. I don’t think the Package Manager can be used to create GUI apps, but can it be used to set up library code which is called from a Xcode project for a GUI app?

···


Daryle Walker
Mac, Internet, and Video Game Junkie
darylew AT mac DOT com

1 Like

I recall there’s a way to make a command-line tool in macOS have an “Info.plist” file, which is compiled/linked in the executable’s data segment.

Correct. Xcode has explicit support for this, namely the “Create Info.plist Section in Binary” build setting (`CREATE_INFOPLIST_SECTION_IN_BINARY`). This uses the file from the standard “Info.plist File” (`INFOPLIST_FILE`) build setting.

Is there a way to do this through “swift build”?

The above is implemented in terms of the `-sectcreate __TEXT __info_plist /path/to/file` linker option, which you can read about in <x-man-page://1/ld>. If you create a dummy Xcode command line tool project, you can look at the build transcript to see how it works.

I kinda presume that SPM has a way to pass in custom linker options but I don’t have direct experience with that.

Share and Enjoy

···

On 22 Aug 2017, at 06:13, Daryle Walker via swift-users <swift-users@swift.org> wrote:
--
Quinn "The Eskimo!" <http://www.apple.com/developer/>
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

2 Likes

I haven’t yet had the pleasure of investigating what’s available in
3.2/4.0’s swiftpm, but I did once hack this together in the 3.x
toolchain using a dummy module:

Hierarchy:
Sources/
-- InfoPlist
---- Dummy.c
---- include/
------ InfoPlist.h

InfoPlist.h:

__attribute__((used, section("__TEXT,__info_plist")))
static const char __darwin_info_plist[] = "<##escaped XML string##>";

__attribute__((used))
static inline void includeInfoPlist(void) {
    (void)(__darwin_info_plist);
}

partial main.swift:

import InfoPlist

includeInfoPlist()

I sure do hope there’s a better way to do this now, but just throwing it
out there for posterity.

Sincerely,
Zachary Waldowski
zach@waldowski.me[mailto:zach@waldowski.me]

···

On Tue, Aug 22, 2017, at 03:30 AM, Quinn The Eskimo! via swift-users wrote:

On 22 Aug 2017, at 06:13, Daryle Walker via swift-users > <swift-users@swift.org> wrote:

> I recall there’s a way to make a command-line tool in macOS have an “Info.plist” file, which is compiled/linked in the executable’s data segment.

Correct. Xcode has explicit support for this, namely the “Create
Info.plist Section in Binary” build setting
(`CREATE_INFOPLIST_SECTION_IN_BINARY`). This uses the file from the
standard “Info.plist File” (`INFOPLIST_FILE`) build setting.

> Is there a way to do this through “swift build”?

The above is implemented in terms of the `-sectcreate __TEXT __info_plist
/path/to/file` linker option, which you can read about in
<x-man-page://1/ld>. If you create a dummy Xcode command line tool
project, you can look at the build transcript to see how it works.

I kinda presume that SPM has a way to pass in custom linker options but I
don’t have direct experience with that.

Share and Enjoy
--
Quinn "The Eskimo!" <http://www.apple.com/developer/>
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

Any advances on this story?

1 Like

I am interested in that, too. I'd like to write a swift package that uses CLLocationManager and I want to be able to run tests via XCTest. Without the appropriate usage-descriptions the tests fail with a NSInconsistencyException. Is there a way to provide a .plist just for running the test?

Is there a way to provide a .plist just for running the test?

No. This affects more than just Info.plist properties; you’ll see similar problems if your test code requires an entitlement. We definitely have bugs on file to improve this (r. 14493584) but, for the moment, the best solution is to host your test bundle in your app [1]. At that point, your app’s Info.plist, entitlements, and so on will apply.

To set this up, choose your app in the Product > Scheme > Edit Scheme > Run > Info > Executable popup for the test target.

Share and Enjoy

Quinn “The Eskimo!” @ DTS @ Apple

[1] Create a dummy test app if you don’t have one already.

1 Like

I really hope we see some improvements in this area soon - so many things are protected by entitlements these days, and the lack of Info.plist/entitlement support in SPM packages (and even CLI apps in Xcode) is really frustrating.

It seems inevitable that we will need SwiftPM to generate the Info.plist. There is some information (like the version) which is not even explicitly stated in the Package.swift manifest, so that information is only available to SwiftPM. Come to think of it - is there any reason SPM shouldn't be generating Info.plists for executables and libraries on macOS today? Could we enable this by default?

2 Likes

Target can take a linkerSettings argument, I have just recently used it and can confirm the binary does get an __info_plist section, example:

// ...
.target(
   name: "my-awesome-cli",
   dependencies: [],
   linkerSettings: [ .unsafeFlags( ["-sectcreate",
                                    "__TEXT",
                                    "__info_plist",
                                    "Resources/Info.plist"] )
    ]),
// ...
2 Likes

I'm able to build in Xcode example from below correctly with Info.plist
targets: [
.target(
name: "git-srs",
dependencies: ...
linkerSettings: [ .unsafeFlags( ["-sectcreate",
"__TEXT",
"__info_plist",
"Resources/Info.plist"] )]),
...
]

but "swift build" executed from command line fail:

% swift build
:0: error: unknown argument: '-sectcreate'
[0/1] Linking git-srs

Do I need to pass some special command line arguments to build this using swift tool? I would like to be able to build and use this application cross-platform, for example on Linux.

any update on this?

swift build, builds fail
But the tip works fine through Xcode UI as well as xcodebuild

Hmm .. time passes!

It seems the above linkerSettings usage works when the project is executable but not if it is a library. Not being deeply versed in this stuff, I assumed that the linker doesn't care what the resulting product is. I'd love to have my confusion resolved!

1 Like

If this worked in November 2020, something has changed.

The flags are passed to the Swift compiler so, in order to pass them along to the linker, each string must be preceded by -Xlinker like this:

      linkerSettings: [
      	.unsafeFlags( ["-Xlinker", "-sectcreate",
                       "-Xlinker", "__TEXT",
                       "-Xlinker", "__info_plist",
                       "-Xlinker", "Resources/Info.plist"] )
      ]),

How the incorrect description of this usage has lasted so long in this forum, and others, is beyond me, unless I'm being really stupid .. I suspect people read the documentation but never actually tried it. The error reported elsewhere in this thread: error: unknown argument: '-sectcreate' is a direct result of the missing -Xlinker options.

I have verified that the above code works .. here's a piece of my swift build generated executable:

 . . . . 5F5F 696E 666F 5F70 6C69 7374 == "__info_plist"

and I verified that the contents of Resources/Info.plist is also embedded in the executable. SPM's linkerSettings.unsafeFlags should perhaps stuff in the -Xlinker options for us?

1 Like