I have a flutter package flutter_opencc_ffi_web, which contains some JS files. This package is transitively included in another project of mine. When I build a non-web bundle, I'd like to exclude the JS assets(about 1Mb). How can I achieve that?
I've tried the build_config, but don't know how to exclude package assets. The following config doesn't work.
build.yaml
targets:
$default:
sources:
exclude:
- assets/opencc/**
- assets/packages/flutter_opencc_ffi_web/assets/opencc/**
dependencies:
flutter_opencc_ffi_web:
exclude:
- assets/opencc/**
Related
I'm working on one project for some time now on flutter. Part of the source code has been designed so that it can be used again as is in other projects.
I'm working with Visual Studio Code.
Now I'm creating a second project. I'd like to organize folders this way:
Parent folder
Project1 folder
Project2 folder
my_library
Is it possible to add the library folder to the projects, as it is not inside their respective folders?
In pubspec.yaml of project 1, refer to the library as:
dependencies:
my_library:
path: ../my_library
The way to solve this isn't straightforward for beginners. So I summed up the proposed solutions here (I provide the names out of fairness, and follow related potential discussions below each one).
From Richard Heap:
In pubspec.yaml of project 1, refer to the library as:
dependencies:
my_library:
path: ../my_library
From me:
In ../my_library, add a specific pubspec.yaml. Something like:
name: my_libraries
description: my own common libraries
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
version: 1.0.0+1
environment:
sdk: ">=2.17.1 <3.0.0"
dependencies:
flutter:
sdk: flutter
From me:
Drag and drop (maybe there's a menu) your my_libraries folder from a file explorer to the VSCODE Explorer panel, and choose "add folder to workspace". Of course, all dependencies to external libraries used in my_libraries must be specified in its own pub_spec.yaml file.
Remarks:
I added source files in my_libraries/lib/. Don't know if the lib sub-directory is mandatory. Didn't take time to test without, and I like better to keep the same structure in my_libraries than in projects.
in project (and my_library) source files, to import my_library source files, just do as:
import 'package/my_library/xxx.dart'
where xxx.dart is the file to import.
I create a blank template package:
> swift package init --name Temp
> open Package.swift
Xcode Version 13.2.1 (13C100) opens the package.
I add a dependency to the package.
dependencies: [
.package(url: "https://github.com/johnsundell/publish.git", from: "0.7.0")
],
Xcode > Product > Build succeeds at this point.
I edit Temp/Sources/Temp/Temp.swift to insert the first line the package that is defined in dependencies.
import Publish
A build now generates the following error:…/Temp/Sources/Temp/Temp.swift:1:8: error: no such module 'Publish'.
I feel certain this is an Apple bug. Or I could be missing something.
There are several posts about this problem when there is an xcodeproj and the additional structure that provides. Some of them hint at workarounds that help some people.
Has anyone seen this and/or know of how to resolve it?
Apple's Creating a Standalone Swift Package with Xcode document doesn't provide any insight.
thanks for the chatter in the comments, #Larme & #koen, it helped
The issue was user error (and/or a documentation lapse). Living on the (bleeding) edge.
Sometimes updates from changes are slow or require a clean or a relaunch.
Xcode auto-generates Schemes from the targets defined in your package. My build was targeting MyTarget.
Two things were missing:
name: "Publish" was not included in the package dependency - it's needed so you can reference it below (or maybe this can be derived, it's hard to tell because of Xcode refresh issues), and
a reference is needed in the dependencies for each target using the package-dependency, i needed to add dependencies: ["Publish"] in the related target
dependencies: [
.package(name: "Publish", url: "https://github.com/johnsundell/publish.git", from: "0.7.0")
],
…
targets: [
.target(
name: "MyTarget",
dependencies: ["Publish"]),
]
I am creating a Swift Package that is essentially a wrapper for multiple XCFrameworks generated from Objective-C frameworks so they can be installed via SPM.
Everything works fine as far as creating the SP and ability to add it as a dependency to an app. But I have a bunch non-essential files included in the SP's repository that I don't want to include in the actual SP - i.e. They shouldn't show up in Xcode's navigator when the SP is added as a dependency.
(These consist of the source Obj-C Frameworks, README, Changelog, Xcode Workspace for demo app, Script files for generating the XCFrameworks, etc).
Is this even possible?
Or will SPM always checkout the entire repo and make all files visible to the user?
I have tried using various permutations of the Target specifiers: source, path, exclude but to no avail.
Here is the closest I can get with a valid manifest, but when I check out the SP in a dummy Xcode app, I can still see all the files from the repo included:
// 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: "WrapperSwiftPackage",
platforms: [.iOS(.v13)],
products: [
.library(name: "WrapperSwiftPackage", targets: ["WrapperSwiftPackage"])
],
dependencies: [],
targets: [
.target(
name: "WrapperSwiftPackage",
dependencies: [
"ObjCFramework1",
"ObjCFramework2"
],
path: "", // Set to root directory so we can exclude files below
exclude: [
"CHANGELOG.md",
"Dangerfile.swift",
"README.md",
"Workspace.xcworkspace",
"Scripts/generate-xcframework.sh",
"Scripts/link_git_hooks.sh",
"Objective-C Frameworks/"
],
sources: [
"Sources/WrapperSwiftPackage/main.swift",
"XCFrameworks/ObjCFramework1.xcframework",
"XCFrameworks/ObjCFramework2.xcframework"
]
),
.binaryTarget(name: "ObjCFramework1", path: "XCFrameworks/ObjCFramework1.xcframework"),
.binaryTarget(name: "ObjCFramework2", path: "XCFrameworks/ObjCFramework2.xcframework")
]
)
Not sure if that isn't a bug though, but I've accidentaly came up to one solution for this.
If you put an empty Package.swift (I mean, one like this):
// swift-tools-version:5.5
import PackageDescription
let package = Package()
into one of project subfolders, then even though SPM is checking the subfolder out, it's excluded from Xcode navigator, and thus, from the project visibility.
I would like to know if that's a bug or is it documented somewhere, every hint is appreciated.
Works with local and remote dependencies.
Summary
While I understand why it could be dangerous to auto import transitive public dependencies, is there a way to enable auto-import when depending a local package via path?
Setup
The Flutter/Dart project consists of three packages
app
repository
api_client (auto-generated open api & models)
I do need api_client models in app & repository, but only want to import it in the repository package.
app/pubspec.yaml
dependencies:
# want to remove api_client here without loosing auto-import ability
api_client:
path: ../api_client
repository:
path: ../repository
repository/pubspec.yaml
dependencies:
api_client:
path: ../api_client
I want to configure Package.swift so that one target would be an extension to another, both of them should share the same code from the one folder, but for the "extended" version there is an additional subfolder. But configuration I try with path fails with "overlapping sources" error. So, how can I make two target with the same source folder?
.target(name: "App", dependencies: [ "Vapor" ... ], exclude: [ "Subfolder" ])
.target(name: "Extended", dependencies: [ "Vapor", ... ], path: "./Sources/App")
swift build ... error: target 'Extended' has sources overlapping sources...
SwiftPM is strict about one target gets to own the files. So you will need to set up a proper dependency chain for your files.
It sounds like Extended adds more functionality to App in this case. If so you want to have App all the things it currently is. Then have Extended depend on App and build all of the things exclusive to it.
This allows 1 target to own the source files and allows Extended to use the one implementation of those files.
In my case I had one of my executableTargets path set to the root "."
.executableTarget(
name: "ServiceA",
dependencies: [Vapor..],
path: "."),
.executableTarget(
name: "ServiceB",
dependencies: [Vapor..]),
After I removed the path from the constructor in ServiceA. I was able to set the proper folders and Xcode was able to infer the path of my executable targets
Sources
|_ServiceA
|_ServiceB
.executableTarget(
name: "ServiceA",
dependencies: [Vapor..])
.executableTarget(
name: "ServiceB",
dependencies: [Vapor..]),