Package resources on Windows

Hi,

I have been playing around with OpenGL and GLFW with Swift on Windows and the experience has been quite pleasant especially with the new SourceKit LSP support!
Right now the version of Swift (and SPM which comes with the installer) I'm using is

swift --version
compnerd.org Swift version 5.3-dev (LLVM f9c85c8b92cf757, Swift 4f49b6ab81b7dcb)
Target: x86_64-unknown-windows-msvc

Downloaded from VS2019#20201009.1

Today I tried adding resources for fun to my package and when I try to build the package it seems like SPM creates a resource_bundle_accessor.swift file that contains an extension for users to access the Bundle.module bundle. The buildPath variable has some issues though (probably the backslashes)

C:\Dev\SwiftProjects\resource_bug\.build\x86_64-unknown-windows-msvc\debug\resource_bug.build\DerivedSources\resource_bundle_accessor.swift:6:29: error: invalid escape sequence in literal
        let buildPath = "C:\Dev\SwiftProjects\resource_bug\.build\x86_64-unknown-windows-msvc\debug\resource_bug_resource_bug.resources"
                            ^
C:\Dev\SwiftProjects\resource_bug\.build\x86_64-unknown-windows-msvc\debug\resource_bug.build\DerivedSources\resource_bundle_accessor.swift:6:33: error: invalid escape sequence in literal
        let buildPath = "C:\Dev\SwiftProjects\resource_bug\.build\x86_64-unknown-windows-msvc\debug\resource_bug_resource_bug.resources"
                                ^
C:\Dev\SwiftProjects\resource_bug\.build\x86_64-unknown-windows-msvc\debug\resource_bug.build\DerivedSources\resource_bundle_accessor.swift:6:60: error: invalid escape sequence in literal
        let buildPath = "C:\Dev\SwiftProjects\resource_bug\.build\x86_64-unknown-windows-msvc\debug\resource_bug_resource_bug.resources"
                                                           ^
C:\Dev\SwiftProjects\resource_bug\.build\x86_64-unknown-windows-msvc\debug\resource_bug.build\DerivedSources\resource_bundle_accessor.swift:6:67: error: invalid escape sequence in literal
        let buildPath = "C:\Dev\SwiftProjects\resource_bug\.build\x86_64-unknown-windows-msvc\debug\resource_bug_resource_bug.resources"
                                                                  ^
C:\Dev\SwiftProjects\resource_bug\.build\x86_64-unknown-windows-msvc\debug\resource_bug.build\DerivedSources\resource_bundle_accessor.swift:6:95: error: invalid escape sequence in literal
        let buildPath = "C:\Dev\SwiftProjects\resource_bug\.build\x86_64-unknown-windows-msvc\debug\resource_bug_resource_bug.resources"
                                                                                              ^
error: fatalError

The package is an empty one with only a main.swift file and a "resource.txt" file inside the Sources directory.
Package.swift

// swift-tools-version:5.3
// The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription
let package = Package(
    name: "resource_bug",
    targets: [
        .target(
            name: "resource_bug",
            resources: [.process("resource.txt")])
    ]
)

The same thing happens also when using .copy("resource.txt") instead of .process("resource.txt") and with proper packages with multiple sourcefiles etc.
The resource_bundle_accessor.swift file looks like this

import class Foundation.Bundle

extension Foundation.Bundle {
    static var module: Bundle = {
        let mainPath = Bundle.main.bundlePath + "/" + "resource_bug_resource_bug.resources"
        let buildPath = "C:\Dev\SwiftProjects\resource_bug\.build\x86_64-unknown-windows-msvc\debug\resource_bug_resource_bug.resources"

        let preferredBundle = Bundle(path: mainPath)

        guard let bundle = preferredBundle != nil ? preferredBundle : Bundle(path: buildPath) else {
            fatalError("could not load resource bundle: from \(mainPath) or \(buildPath)")
        }
        return bundle
    }()
}

One other thing that I discovered is that swift build -Xswiftc -wmo and that the executable produced by swift build -c release doesn't work properly yet but normal optimizations do work just fine. Right now these aren't a big deal to me but I thought you guys might want to know about them :)

3 Likes

Hi!

That sounds really cool! It has been a while since I played with FLTK and GLFW, but I do remember it being a lot of fun.

Yes, I believe that is a recent regression in swift-package-manager (or at least I think its recent, I only hit it a few days ago with SourceKit-LSP). I forgot to upload a fix for that yesterday (apple/swift-package-manager#2972) that should resolve the path issues.

Hmm, could you be a bit more precise about what doesn't work properly? If you have a test case, that would be extremely helpful.

Definitely! The general usage information is helpful and belongs here. However, issues are best reported to bugs.swift.org so that they can be tracked. That said, bringing them up on the forums is still useful sometimes for finding workarounds, so really, a combination of the two is usually a good approach.

2 Likes

Wow that was a fast fix :)

I'll use the same package as an example as I did above but without the resources present.
Package.swift:

// swift-tools-version:5.3
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
    name: "resource_bug",
    targets: [
        .target(name: "resource_bug")
    ]
)

main.swift

import Foundation

print("Hello, world!")

var i: Double = 0
let startDate = Date()
var lastPrintValue: Double = 0.0
while i < 10_000_000.0 {
    i += Date().timeIntervalSince(startDate)
    if i > lastPrintValue {
        lastPrintValue += i
        print("Printing time!", i)
    }
}
print("Done")

_ = readLine()

With swift build and swift build -Xswiftc -O -Xcc -O2 it works just fine printing some time interval values:

Hello world!
Printing time! 0.0010013580322265625
Printing time! 0.002002716064453125
Printing time! 0.00400543212890625
Printing time! 0.008007049560546875
...
Printing time! 3266880.746433258
Printing time! 6533761.248313904
Done

With swift build -c release the output starts well and then... stops and eventually crashes

Hello, world!
Printing time!

It stalls there and if the program is run by just double clicking the exe file, the command prompt will disappear after a second or two.

Now regarding the swift build -Xswiftc -wmo if we add a new file to the package, for example
Util.swift

class Queue {
    var count: Int = 1024
}

I will get this as console output:

swift build -Xswiftc -wmo
C:\Dev\SwiftProjects\resource_bug: warning: Creating library C:\Users\SEBAST~1\AppData\Local\Temp\TemporaryDirectory.3bgiOm\resource_bug-manifest.lib and object C:\Users\SEBAST~1\AppData\Local\Temp\TemporaryDirectory.3bgiOm\resource_bug-manifest.exp
<unknown>:0: warning: ignoring '-enable-batch-mode' because '-whole-module-optimization' was also specified[1/3] Compiling resource_bug Util.swift
<unknown>:0: error: index output filenames do not match input source files

The eventual crash sounds like it shouldn't happen.

Interesting. This seems something generic and not specific to Windows. Perhaps @NeoNacho or @abertelrud have thoughts on what is the cause of this. Would you mind filing an issue on bugs.swift.org for this? I think that this might require a deeper investigation.

Sorry for the delay. I filed SR-13721 (hopefully correctly :))

Thanks! Yes, it seems fine - I did add the Windows tag to it to make it easier to track all the Windows items.

The fixes needed for the manifest were only merged today, so that should hopefully be fixed with the next snapshot.

1 Like
Terms of Service

Privacy Policy

Cookie Policy