SPM Init Library boilerplate not usable by default

Hello,

This is rather a minor complaint, but is it just me, or is the default boilerplate code generated for an SPM Library not very useful?

e.g. If one creates a new SPM package of type Library:

mkdir Library
cd Library
swift package init --type library

Then a package is created, named 'Library', with a product named 'Library', and a target named 'Library'
There is also a source file created: 'Sources/Library/Library.swift' which contains the following: (a struct named 'Library')

struct Library {
 var text = "Hello, World!"
}

A user new to Swift or SPM may be experimenting with their first library and attempt to extend the autocreated struct with a function or other property. e.g.

struct Library {
 var text = "Hello, World!"
 let answer = 42
 func whatsTheAnswer() -> Int {
 	return self.answer
 }
}

However, if one adds this package as a dependency to an executable the 'Library' struct is not accessable as its name clashes with the module itself....

e.g.

mkdir Executable
cd Executable
swift package init --type executable

then modify 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: "Executable",
    dependencies: [
        // Dependencies declare other packages that this package depends on.
        // .package(url: /* package url */, from: "1.0.0"),
        .package(path: "../Library"),

    ],
    targets: [
        // Targets are the basic building blocks of a package. A target can define a module or a test suite.
        // Targets can depend on other targets in this package, and on products in packages this package depends on.
        .target(
            name: "Executable",
            dependencies: ["Library"]),
        .testTarget(
            name: "ExecutableTests",
            dependencies: ["Executable"]),
    ]
)

Then modify the file Executable/Sources/Executable/main.switt file:

import Library
print("Hello, world!")

let lib = Library()
print(lib.whatsTheAnswer())

gives the error:

Cannot call value of non-function type 'module<Library>'

Perhaps it would be worth changing the name of the autogenerated struct by adding a suffix?

Does it work if you make everything public?

1 Like

Ah, yes it does! I see that that change has already been made in the Main branch (back in April), so this problem will eventually solve itself.

Thanks.

2 Likes