https://kotlinlang.org logo
#compose-desktop
Title
# compose-desktop
s

Sebastian Kürten

10/25/2023, 9:05 PM
It's been a while since I last posted an update about the Pinpit Gradle Plugin. A few days ago, I published version 0.7.0 to the Gradle plugin portal. Pinpit now supports packaging distributable zip archives for macOS 🎉. That completes the ability to build packages/installers cross-platform for all operating systems from a plain Ubuntu box. 🚀 That means you can build packages for all three major operating systems from your Linux development machine or CI server. If you're working on a different OS, building using a docker image should also work easily (we're testing building on CI machines, including the Github CI, but also tried vagrant and virtualbox based machines). I noticed that it takes quite a lot of work to set up all the assets required for a new project, such as the Gradle build script with everything configured and especially also the various launcher images and image assets for the Windows installer. To help with that, I created a command line tool that can do two things at the moment: 1. Create a new Compose for Desktop or Swing project from a template that builds using Gradle and the Pinpit plugin. After creating the app, it can directly be run using
./gradlew pinpitRun
or packaged using
./gradlew pinpitPackageDefault
. It also creates various assets from a Material symbol SVG file as input. That includes launcher files for Linux in PNG format, Windows in ICO format and macOS in ICNS format. 2. Update all the image assets in an existing project. If you decide to change your app icon, you can update all the relevant assets in a single step. At the moment any Material symbol can be used as input (just select the desired symbol, download as SVG and specify on the CLI). It should also be possible to support a custom logo SVG at a later step as the toolchain is already processing SVG, but at the moment it has some logic hardwired to work with Material symbols. For example, if you use the rocket launch icon and colors '0x127f73' for background and 'white' as foreground, you will get an launcher image as attached. Specify yet another color for the left side of the Windows installer background image (yellow in this case). The images are all generated as SVG too, so that you can start customizing your assets and use those images just as a starting point.
👍 2
🎉 4
❤️ 1
that second tool is inspired by the Android Studio "new project" wizzard where you can design your launcher icon and AS creates all the various image assets for you. It also let's you pick from a set of template apps (empty activity, fragment activity etc), in a similar fashion this tool lets you select among the existing templates to create a project with an example screen already (small Swing app or small Compose for Desktop app). Future work should include adding more templates (select among build.gradle vs build.gradle.kts and also select whether to also include an Android module)
b

benkuly

10/26/2023, 10:06 AM
Are there plans to upstream features to compose-multiplatform plugin?
s

Sebastian Kürten

10/26/2023, 11:40 AM
I'd love the compose-multiplatform plugin to develop in this direction, but it's not for me to say if that's a desired direction the upstream project is willing to take.
👍 1
p

PHondogo

10/26/2023, 4:55 PM
Hello, Sebastian! Trying to adopt Pinpit to my project. Could you help me with advice? Can I create several tasks for generating distributions in one project? If yes then how to configure each task without applying Pinpit plugin?
s

Sebastian Kürten

10/26/2023, 5:56 PM
I'm not sure I understand. It is possible to configure for a project which targets to build, i.e. deb, msi, macos zip etc. by adding the relevant blocks in the Gradle build file. In contrast to the Compose plugin, it is not necessary or possible to specify a list of target formats. That's implicit by the blocks you add such as this for macOS:
Copy code
macOS {
                packageName = "PinpitComposeHelloWorld"
                bundleID = "de.mobanisto.hello.world"
                appCategory = "public.app-category.utilities"
                distributableArchive {
                    format = "zip"
                    arch = "arm64"
                }
            }
It's probably best to try one of the example applications or create a sample project using https://github.com/mobanisto/pinpit CLI. From it's README, this should create a nice template for you
Copy code
./scripts/pinpit create-project --template compose-for-desktop \
    --output project --project-name "Foo Tool" --package "com.foo.tool" \
    --description "a tool for doing fancy stuff" \
    --vendor-full "Bar Inc" --vendor-short "Bar" \
    --input src/test/resources/rocket.svg
afterwards cd into the "project" directory and do a
./gradlew pinpitPackageDefault
to build all target packages
p

PHondogo

10/26/2023, 7:52 PM
For example, i want to create two .deb distributions for one projects. As i understand if using plugin it is possible to create only one per platform.
s

Sebastian Kürten

10/26/2023, 7:55 PM
ah, good point. Indeed you can have multiple
deb()
blocks and build multiple debian packages for different distros. See briar for an example: https://github.com/briar/briar-desktop/blob/main/briar-desktop/build.gradle.kts#L223
p

PHondogo

10/26/2023, 8:32 PM
Thanks, Sebastian!
From your last example I can see that configurations needed for distributions but I can't see where they are assigned to each variant.
Is it possible to specify just single jar file? (I have fat jar already). Without specifying from(SourceSet, FileCollection)
In other words it will be good to have such process: single.jar + <os/arch spec> +<os specific config> = distr
s

Sebastian Kürten

10/26/2023, 9:43 PM
From your last example I can see that configurations needed for distributions but I can't see where they are assigned to each variant.
you have a configuration such as
Copy code
val macosArm64: Configuration by configurations.creating {
    extendsFrom(configurations.implementation.get())
}
and the plugin determines itself that this is the configuration to use for this target:
Copy code
macOS {
                ...
                distributableArchive {
                    format = "zip"
                    arch = "arm64"
                }
            }
is that what you mean?
that logic how to match this is just part of the plugin
Is it possible to specify just single jar file? (I have fat jar already). Without specifying from(SourceSet, FileCollection) (edi
I'm not sure this can be achieved at this point yet. What the plugin does is package all the jars from the runtime classpath into the distributable app. We do have a ticket for release builds (minified etc): https://github.com/mobanisto/pinpit-gradle-plugin/issues/16 but this is not implemented yet
In other words it will be good to have such process: single.jar + <os/arch spec> +<os specific config> = distr
is your project open source by any chance? or could you create a minimal example project that shows what you're doing? thanks
p

PHondogo

10/26/2023, 9:57 PM
I understand that configuration is choosing for variant by some name convention depending of os and arch. But it will be good if there will be possibility to explicitly specify configuration for each variant. For example if I have two Deb variants for the same arch and for each i need different Gradle configuration.
s

Sebastian Kürten

10/27/2023, 8:55 AM
OK, interesting. I created an issue to track this feature request: https://github.com/mobanisto/pinpit-gradle-plugin/issues/32 What's your use-case with this? What kind of dependencies do you need declared for different Debian-based distros?
p

PHondogo

10/27/2023, 9:00 AM
I have custom gradle plugin that generates for one project several output for each platform. Ui thin client, service. I want for each output to make installer.
s

Sebastian Kürten

10/27/2023, 9:03 AM
and that plugin creates some dependency configurations itself, i.e. if you could specify those on the pinpit tasks, things should probably work for your case?
p

PHondogo

10/27/2023, 9:08 AM
Yes. I can make configuration for each plugin output by including output file to it. And if i could for each Pinpit distribution specify appropriate configuration it will solve my case.
For example, plugin output generated ui.jar and service.jar. I'll make configurations ui and service. And then in Pinpit distributions in for example linux.deb("ui") specify needed configuration, for example call smth like fromConfiguration(ui)
And it can override from(SourceSet, FileCollection) from application dsl scope
s

Sebastian Kürten

10/27/2023, 9:22 AM
another solution probably would be to have separate gradle modules for
ui
and
service
and let both apply the pinpit plugin. But maybe that doesn't fit the rest of your setup
p

PHondogo

10/27/2023, 9:24 AM
I'm trying to avoid this. Want to make it in one project. So that i can apply plugin to it and get all needed distributions in its output
s

Sebastian Kürten

10/27/2023, 9:27 AM
just out of curiosity: is this currently possible with the Compose plugin, did you find a way to make your thing work with that?
p

PHondogo

10/27/2023, 9:35 AM
For Compose plugin for now in common target I write
Copy code
compileOnly(project.ComposeDeps.runtime)
And in needed ui targtets i specify all needed Compose dependencies. There is request to make it truly separated but it hasn't done yet: https://github.com/JetBrains/compose-multiplatform/issues/537
Non ui targets building fine is such case. Just need to be carefull not to use compose runtime classes in it to avoid not found class in runtime.
3 Views