Swift package manager conditional compile not respecting flags - swift-package-manager

I have a Package.swift file with the following structure
var package = Package(
name: "MyProject",
targets: [
Target(name: "MyProject")
],
dependencies: [],
exclude: ["Exclude"]
)
#if DEBUG
package.dependencies.append(Package.Dependency.Package(url: "Dependency-One.git", majorVersion: 0, minor: 0))
#else
package.dependencies.append(Package.Dependency.Package(url: "Dependency-Two.git", majorVersion: 0, minor: 0))
#endif
When I build this with any of the following:
swift build
swift build -c release
swift build -c debug
swift build -c RELEASE
swift build -c DEBUG
It still always downloads Dependency-Two.git. This remains true if I prepend all of the above with
rm -rf .build/ && rm -rf Packages/
So I don't think it's because it's reusing some cache. Is it possible to do what I'm intending here?

Still not available. My workaround has been to create multiple Package.swift files, named like Package-DEBUG.swift and have a script copy the appropriate one to Package.swift at build time.
This is a really mindless workaround and the SPM developers really need to implement command-line flags.

This is by design. The manifest is not intended to be used to declare conditional behaviors in this manner, but unfortunately for what you are trying to do, the mechanism by which this would be supported (e.g., including additional APIs from PackageDescription to declare what you want in each configuration) is not designed yet.
I suggest you file an enhancement request for this feature on https://bugs.swift.org.

Related

Where do I find JavaFX ant tasks in Java 11?

VSCode, Java 11 JavaFX 18.0.2
I am trying to package my code up for distribution as a desktop app. In my case I want a fully self-contained app because of my target user's profile.
I have been through Jenkov add the Oracle docs here and here which suggest I need ant-javafx.jar. That jar file seems to have been dropped from the standard Java SDK some time around Java 7 and put into the regular JavaFX install lib folder.
It's not there in the build I have.
JavaFX seems to have gone to openjfx.io and nowhere in there can I see support for the ant packaging jar. In fact I see openjfx as a retrograde step as they are increasingly forcing everyone into paid plans (try going round and round the loop of downloading anything that doesn't require an LTS payment).
I have a suspicion that there is some silent assumption that everyone will use something from maven or gradle, and maybe the packaging tools are buried away in one of those build tools. For historical reasons I don't use either and it should be possible to do this packaging without one of them.
So where do I get the JavaFX Ant build tasks from without having to pay someone?
I have found that the following works as an alternative with Java 19 and OpenJFX 19. I use the maven-dependency-plugin to copy all the dependency jars (excluding JavaFX, which I use as modules from a "full" JDK [one that includes JavaFX)] into the target/lib directory.
#!/bin/bash
set -o errexit
set -o noclobber
set -o xtrace
# find dependency modules of required modules
DEP_MODS=$(jdeps -quiet --class-path "target/lib/*" --add-modules java.base,java.logging,java.sql,javafx.controls,javafx.fxml --multi-release base --ignore-missing-deps --print-module-deps target/myapp-4.0-beta.jar)
# create a modular runtime image
jlink --compress=1 --no-header-files --no-man-pages --add-modules "java.logging,java.sql,javafx.controls,javafx.fxml,$DEP_MODS" --output target/myapp-4.0-beta
# Example of running it out of the runtime image
# TEST target/myapp-4.0-beta/bin/java -cp "../../myapp-4.0-beta.jar:../../lib/*" org.myapp.App
# symlink to the artifact jar from the lib directory
$(cd target/lib && ln -s ../myapp-4.0-beta.jar)
# use the lib directory and modular runtime image as input to jpackage
jpackage --input target/lib --runtime-image target/myapp-4.0-beta --main-jar myapp-4.0-beta.jar --main-class org.myapp.App --type app-image --app-version 4.0 --name app --dest target/dist/bundle --mac-entitlements src/dist/mac/entitlements.plist

Compile Rescript with CLI -- no bsconfig.json

Is there a way to compile ReScript with just the CLI?
In other words, without the bsconfig.json?
Ideally, I would like to be able to just call the CLI and be able to compile into ES6, declare external dependencies, etc.
The rescript compiler executable is called bsc, and I believe mroe or less takes the same options as ocamlc.
Assuming you have rescript installed locally, and two source files main.res and foo.res where Main depends on Foo, and with no other dependencies, you can compile them to commonjs modules by invoking the following commands:
npx bsc foo.res > foo.js
npx bsc -I . main.res > main.js
Unfortunately I don't think you can compile directly to es6 without bsconfig.json. The compiler option to do so is -bs-package-output es6, but that requires passing both -bs-package-name and a bsconfig.json file.

Appveyor - Compiling static qt5.10 application (with openssl and qml webview)

I'm trying to set up autobuild appveyor on my Qt project.
My app is using qt5.10.1, with qml and openSSL features.
I'm lost... I didn't know from where to start :/
# 1:
I found some examples of .apveyor.yml config files, but they are all using mingw32 compilator which do not allow me to use qml webview module (why)... I didn't find what I have to write in my appveyor config file to compile my app with msv2017 where is the compilator ?
Actually, my appveyor.yml looks like that (I try to do as QtCreator is doing on my local computer but it's not working)
image: Visual Studio 2017
branches:
only:
- master
install:
- set QTDIR=C:\Qt\5.10.1\msvc2017_64
- set PATH=%QTDIR%\bin;C:\Qt\Tools\mingw530_32\bin;%PATH%;
build_script:
- qmake app/QRegovar.pro -spec win32-msvc
- qmake_all
- C:\Qt\Tools\QtCreator\bin\jom.exe -f Makefile.Release
deploy:
- provider: GitHub
artifact: C:/projects/qregovar
draft: true
prerelease: false
on:
branch: master
appveyor_repo_tag: true
And it's failling with the following error:
Build started
git clone -q --branch=master https://github.com/REGOVAR/QRegovar.git C:\projects\qregovar
git checkout -qf 7357eb2adab349c4de9e0b346dc99027964ea5a5
Running Install scripts
set QTDIR=C:\Qt\5.10.1\msvc2017_64
set PATH=%QTDIR%\bin;C:\Qt\Tools\mingw530_32\bin;%PATH%;
qmake app/QRegovar.pro -spec win32-msvc
Project ERROR: Cannot run compiler 'cl'. Output:
===================
===================
Maybe you forgot to setup the environment?
Command exited with code 3
# 2:
I'm also wondering if appveyor is using qt static build ? As I would like to create "ready to use" package for the user ?
I'm using CMake, but I guess the trick is to setup 'cl' compiler into PATH, so qmake is able to find it.
In sample appveyor scripts the main build script is '.\qtmodules-travis\ci\win\build.bat'. This script will check/use AppVeyor matrix-defined variable for platform (line 7+) and then the script define VC_DIR etc.
And on the end is invoking script referred by you 'build-msvc.bat' where is invoked:
call %VC_DIR% %VC_VARSALL% || exit /B 1
QtCreator will do the setup for you (you are using Kits...)
When you are building in clean command line, you should do 'vcvarsXXX.bat call yourself before 'qmake' call.
In my opinion AppVeyor doesn't trigger this call for you, because developer may wish different build env. setup (e.g. x86, x64, arm etc.). It's your choice. Actually this is the hint as well when you start 'Qt command line' on your PC from start menu (it call 'C:\Qt\5.11.0\msvc2017_64\bit\qtenv2.bat' shell setup script)

Force project to be recompiled using dotnet build

Using dotnet build the project will not by recomplied if there are no changes:
Project {project name} was previously compiled. Skipping compilation.
Is it possible to force project to be recompiled? I have looked into command options, but haven't found any related parameters.
You should either switch the incremental compilation off by specifying the --no-incremental option (by default the incremental compilation is on which means that compiler will compile the code if it detects any changes in methods, etc) or clean up the output directory.

Ignore "Local NPM module not found" warning in Grunt

I'm using matchdep to read dependencies from my package.json file into grunt.
require('matchdep').filterAll('grunt-*').forEach(grunt.loadNpmTasks);
I have my dependencies split between dependencies (for everyone) and devDependencies (for front-end developers.)
Our back-end devs will run the following to get a build of the static assets without requiring jasmine, phantomJS, etc (things that will be run by front-end devs and the CI server)
$ npm install --production
$ grunt build
However, when using the --production build, grunt.loadNpmTasks() will emit a warning for any missing packages.
>> Local Npm module "grunt-contrib-watch" not found. Is it installed?
Is there a way to supress this warning?
You have to question why your "back-end devs" would have to actually build your package - put otherwise, why do they need grunt but NOT devDependencies. This is kind of backwards (requiring users to build your package is certainly an anti-pattern).
That being said, using matchdep, you can / should use:
require('matchdep').filter inside your "production" target
require('matchdep').filterAll inside your "development" target
Certainly, that would require you to specialize your grunt build (eg: have grunt builddev and grunt buildproduction - or maybe use environment variables) - but again, see above...
You can use CLI flags to pass options into grunt. For consistency, I am using a --production flag, just as I do with npm.
So, from the CLI:
$ grunt build --production
And then in the Gruntfile:
var dependencies;
// test for the production flag
if (grunt.option('production')) {
// scan dependencies but ignore dev
dependencies = require('matchdep').filter('grunt-*');
} else {
// scan all dependencies
dependencies = require('matchdep').filterAll('grunt-*');
}
// load only relevant dependencies
dependencies.forEach(grunt.loadNpmTasks);
This is done at the top of the module before any custom tasks are registered.

Resources