How to override the "unsafeFlags" behavior of Swift Package Manager? - swift

Swift Pacakage Manager allows a package manifest (Package.swift) file to specify build settings for targets.
As a security measure, some build settings can only be specified using "unsafeFlags" parameter. For example, specifying a framework search path outside the current directory using the -F build flag is considered "unsafe" because it could lead to code execution outside the package's own directory.
For packages downloaded from the internet, this could be considered an undesirable behavior. However, for locally-declared packages, this could be what we want to do.
However the design of SPM is such that any package that uses "unsafeFlags" cannot be depended on by another package.
Is there any override for this, for example, if we want to use unsafeFlags somewhere in a dependency structure of various locally-declared Swift packages?
Like, is there a setting we can supply for a package, framework, or app, so that it's allowed to depend on packages that use "unsafeFlags"?

Swift Package Manager allows unsafeOptions for dependencies specified by a commit hash. They're not allowed for versioned dependencies.
Example here.

Related

Integrating a remote Swift Package that has local Swift Packages: how to avoid invalidManifestFormat errors?

The situation:
I have a Swift Package, call it lib. lib lives in its own repository. In lib's repository, there are a bunch of local Packages; that is, these are packages that are defined, in lib, using the local-path dependency format, .package(path: "CursorPackage"), and whatnot.
All of this is fine as long as I'm locally importing lib into my actual application repository. The moment I try to import lib into my repo using SPM's remote options, which is obviously the way to go for doing things with CI, it throws the following error:
invalidManifestFormat("'CursorPackage' is not a valid path for path-based dependencies; use relative or absolute path instead.")
This error persists whether I use CursorPackage or ./CursorPackage. Obviously I don't want to try to use an absolute path, because I'm on CI, so that would involve either hard-coding things or ingesting an environment variable somehow that contains PWD.
What am I missing? This seems like it should just work. Is this just a bug in SPM that I should be reporting to Apple?
This isn't intended to be possible. If you look at the 5th bullet in the Proposed Solution section of the local packages proposal (https://github.com/apple/swift-evolution/blob/main/proposals/0201-package-manager-local-dependencies.md) it says that it's not intended for a remote package to be allowed to depend on a local package.
I expect its because there's the possibility that you could have both a versioned package with a given name and a local package with the same name; if so how would SPM resolve the conflict?
It is unfortunate though since allowing this would allow for more options in how people organize their packages, I agree.

Can I block or skip add_executable from third party repos? CMake FetchContent_Declare

enable_testing()
include(FetchContent)
FetchContent_Declare(
ut
GIT_REPOSITORY https://github.com/boost-ext/ut.git
GIT_TAG v1.1.8
)
#FetchContent_MakeAvailable(ut)
FetchContent_GetProperties(ut)
if(NOT ut_POPULATED)
FetchContent_Populate(ut)
add_subdirectory(${ut_SOURCE_DIR} ${ut_BINARY_DIR} EXCLUDE_FROM_ALL)
endif()
When including 3rd party repos using cmake, the list in clion shows all the executables and tests. Though discord suggested using EXCLUDE_FROM_ALL which helps. As it prevents these extra things from building when I build all.
What I want is just the libraries. Skip over add_executable lines in the third party cmake files.
If I have an executable named the same as them it'll show an error, example:
add_executable cannot create target "ut_1" because another target with
the same name already exists. The existing target is an executable
created in source directory
Blockquote
No, sadly, this is a fundamental limitation with the FetchContent approach. CMake offers no ways to remove targets once they've been added, and FetchContent is ultimately a call to add_subdirectory, which has no way of distinguishing between first-party and third-party targets.
Your only recourse is to patch the third-party build. You can do this by forking the project, trying to use the glitchy PATCH_COMMAND option, or by working with upstream to namespace their targets.
When designing libraries to be consumed by FetchContent, one should always use a <ProjName>_ prefix (or just <ProjName>).

Nuget xdt transform does not work for config files

I have .NetStandard library. I'm going to use it in .NetFramework and .NetCoreApp applications.
It uses System.Configuration.ConfigurationManager package for work with config files. I need to transform these config files during my library installation.
I found 2 ways:
tools folder in nuget package with install.ps1 file in it
content folder with app.config.install.xdt file in it
Non of them is does not work - nuget doesn't run install.ps1, nuget doesn't transform App.config.
There is a code from csproj:
<ItemGroup>
<Content Include="Content\app.config.install.xdt">
<PackagePath>content</PackagePath>
</Content>
</ItemGroup>
Nuget package contains this file... So I have no idea why it doesn't work.
Is this problem related to .NetStandard? What I'm doing wrong?
Executing ps1 scripts, and XDT transforms are both features that only work with packages.config, but not PackageReference. .NET Core (and I think .NET Standard) projects only work with SDK-style projects, and SDK style projects only support PackageReference. Packages.config only works with "old-style" projects, which may also PackageReference.
The way that Microsoft's ASP.NET Core libraries deal with this difference is that they no longer read settings directly from web.config. Instead the program has to register callback functions that will modify an existing in-memory options object. For example
services.AddMyService(options =>
{
options.setting = newValue;
});
This has some advantages to your users.
They are no longer limited to storing the configuration value in the location the library author demanded. They can choose to load configuration from a database, a configuration service, an xml file, a json file, or just hard-code it in the app. But it lets each developer choose what's best for their own system.
If the user overrides a setting that the package puts in the config file, and each update of the package overrides the user's preference, the user gets annoyed that the package doesn't respect their choice to change the default.
If the user doesn't want to override a setting that the package put in the config file, and the package author doesn't want to overwrite the config file each update, then it's very difficult for the package author to change a default value.
ASP.NET Core's new model is better for everyone because the package author creates the options object and pre-populates it with default values and then call the user's delegate method allowing them to change the settings they care about. If the package author wants to change a default value, they do so in their own code, publish a new package, and users that don't change the value get the new default, and users who explicitly set the value in their code keep using the value they want to, from whatever configuration store they want.
So, the TL:DR answer is that you can't do what you asked for with PackageReference projects, but I hope my longer answer has given you ideas how you can redesign your library which gives better both the package author and package user a better experience.

How to add packages to populate SDK as a host tool?

I have created my own recipe for building my SW, which requires native perl during building (e.g. invoking perl script for generating code). There is no problem if I add my recipe to an image and use bitbake to build my recipe with the image.
Now I also want to build SW with a populate SDK, but I found that when I generate the populate SDK, the native perl only contains a few modules without what is necessary to build my SW. I have found two ways to generate the populate SDK with additional perl modules:
Add TOOLCHAIN_HOST_TASK += "nativesdk-perl-modules" to my image .bb file before I generate the populate SDK
Add a bbappend file for nativesdk-packagegroup-sdk-host which includes "nativesdk-perl-modules" in RDEPENDS
For 1, it is an image-specific solution.
For 2, it is a global solution.
Now I am looking for a recipe-specific solution. Is there a solution where I could add some configuration in my recipe .bb file, and then I build populate SDK for any image which include my recipe will contains these additional native perl modules?
I'm afraid there isn't really a way for a specific recipe to hint at adding specific dependencies to an SDK. The closest thing I can think of would be to code something into anonymous python in something like an extra global class, where it checks the included target packages and then adds dependencies to TOOLCHAIN_HOST_TASK if the right target packages are being installed. Even this wouldn't detect non direct dependencies of your specific recipe.

How to use Matlab xunit without setting Matlab application path

As far as we can see, to use a library in Matlab it is necessary to add its path to the global Matlab application path e.g. to use the xunit unit testing library, its path must be added to the global path through the user interface. The problems with this are:
Each developer must set the dependency paths correctly on their machine, test machines and build machines etc. to be able to run the code correctly
We cannot set the paths for each developer centrally so when dependencies change, we must issue instructions for individuals to manually change their configuration
If different projects use incompatible dependencies then the path must be reconfigured between changing projects
For C++\C#\Java etc. projects, it is possible to refer to libraries with relative paths from within the project and not require changes to global environment variables.
How can we achieve this with Matlab?
You can use the addpath and rmpath commands to manually edit MATLAB's Path. Paths added via these two commands can be relative paths.