Skip to content
This repository was archived by the owner on Dec 3, 2025. It is now read-only.

Conversation

@jonahwilliams
Copy link

Requires framework changes in flutter/flutter#31631.

FLUTTER_APP_DIR=$(CURDIR)/..
FLUTTER_APP_BUILD_DIR=$(FLUTTER_APP_DIR)/build
FLUTTER_ROOT:=$(shell cat $(CURDIR)/.generated_flutter_root)
FLUTTER_ARTIFACT_CACHE_DIR=$(FLUTTER_ROOT)/bin/cache/artifacts/engine/linux-x64
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just leave this as a fallback for if it's not set, rather than making it a required parameter?

# When the Flutter engine version changes, the local copy of engine artifacts
# needs to be updated.
$(FLUTTER_COPY_STAMP_FILE): $(FLUTTER_ENGINE_VERSION_FILE)
$(FLUTTER_BIN) precache --linux --no-android --no-ios
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing this may break non-flutter run cases; we should probably leave it until the copy is being done from the Flutter side.

FLUTTER_COPY_STAMP_FILE=$(FLUTTER_LIBRARY_COPY_DIR)/.last_copied_flutter_version
# The Flutter engine version file.
FLUTTER_ENGINE_VERSION_FILE=$(FLUTTER_ROOT)/bin/internal/engine.version
FLUTTER_ENGINE_VERSION_FILE=$(CURDIR)/.generated_engine_stamp
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The makefile doesn't read FLUTTER_ENGINE_VERSION_FILE, it's just part of the timestamp analysis process. Your other patch writes this file unconditionally, so regardless of what's being written into it, the rules depending on this file are always going to re-run.

@jonahwilliams
Copy link
Author

Updated to read from cache directory populated by flutter tool

rm -rf $(OUT_DIR); \
cd $(FLUTTER_APP_DIR); \
$(FLUTTER_BIN) clean
$(FLUTTER_BIN) clean
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add missing newline please (to avoid churn next time I edit it, since my editors are generally configured to add them)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

^^^

FLUTTER_COPY_STAMP_FILE=$(FLUTTER_LIBRARY_COPY_DIR)/.last_copied_flutter_version
# The Flutter engine version file.
FLUTTER_ENGINE_VERSION_FILE=$(FLUTTER_ROOT)/bin/internal/engine.version
FLUTTER_COPY_STAMP_FILE=$(FLUTTER_APP_CACHE_DIR)/generated_flutter_root
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should just be removed, along with the dependency below using it; it no longer makes sense to have the Makefile have a concept of when the copies need to be updated since it doesn't have a way to copy them.

Although now that I'm thinking about it that way, there's a structural problem with this pair of patches: as written, make will no longer work reliably, because the copies of the files won't be updated. We need to follow the macOS model where there's a script that we can call to do copying and such but that doesn't invoke make, so that make can call it. Sorry I missed this when reviewing the other patch.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tool re-entrance requirements add a lot of complexity to this process - It only kind of works at best too.

It is a requirement for iOS due to Xcode and for Android due to Gradle, but I don't see a compelling case yet for Windows or Linux.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is a requirement for iOS due to Xcode and for Android due to Gradle, but I don't see a compelling case yet for Windows or Linux.

I'm not sure I follow. How is Xcode fundamentally different from Visual Studio, or Make (or whatever other "native" build system we settle on for Linux)? In all these cases, the use case seems to be the same: "I want to build with a native workflow I'm used to for my platform"

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These workflows do not work if you don't run flutter first - making the tooling call to copy the assets over re-entrant does not change this

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only because we don't have a flutter create pre-populating some of the generated files, right?

There's a difference between needing to have run the flutter tool once in the past in order to do a build with the underlying build system, and not being able to do a build with the underlying build system in the future either.

And I'm still not clear on how Xcode is different here.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the workflow we are designing for here? Is this for changing local engine sources, or for working with the native application code?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I mean is, lets go back about 6 steps:

  1. The makefile copies the required sources into its own cache directory.
  2. The tool can write a config flag which overwrites the default for local engine builds.
  3. ???
    4 Profit

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't want to design a build system for one workflow though; we should have a build system that supports multiple workflows. Primary cases:

  • Just being able to flutter run
  • Using local engine builds
  • Working on the native application code (for which being able to use the underlying native build directly is likely to be easiest)

The iOS/macOS structure seems to strike a good balance of supporting all of that. I'd like the Windows and Linux builds to do balance them as well, so using that structure (where the flutter tool sets configuration and invokes the native build, and the native build has access to a script that copies necessary resources) seems like a good option.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case though the native build either needs to know the directory location to copy, or it needs to know the location of a script to invoke that can do so for it. This is where I'll plead ignorance a bit in that I don't see too much of a difference between the two (that said, i'll defer to your judgement here).

So I will create an asset sync script for Linux (and Windows) which can be invoked for either a bin/cache or local engine configuration. This will copy the sources into linux/flutter and windows/flutter. flutter build will be responsible for setting a generated_flutter_root file or a build mode override.

I think that should satisfy the requirement that the native build is still directly usable, while still delegating the heavy lifting to code controlled by the flutter tool

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see too much of a difference between the two

The main difference I see is that it gives us the ability to put a lot of logic in the tool itself, and change that logic over time without breaking things:

  • Details of where the caches live and how they are updated
  • Details of how we decide whether re-copying is necessary (for eventually fixing the alway-relink regression we've introduced to FDE, for instance)
  • Understanding of how local build overrides work

So I will create an asset sync script for Linux (and Windows) which can be invoked for either a bin/cache or local engine configuration.

SGTM. We should be able to use environment variables to communicate local build overrides, as in the macOS script. For Windows, generated properties files can set values that will be in the build environment, and for Linux we can either do another file read in the Makefile like for the Flutter root (eventually I think we'll need a build system with an actual property management system that can replace using files like that), or just for now make the setting non-persistent on Linux and set in in the environment when invoking make from the tool.

@jonahwilliams
Copy link
Author

I might need some help cleaning up the makefile, though I do have both the flutter tool changes and makefile changes working locally

Copy link
Collaborator

@stuartmorgan-g stuartmorgan-g left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since I haven't tested a fixed version I'm not sure if the comments below found everything. Please be sure to test a completely clean build to be sure it works once fix, and also audit the Makefile for targets that are cruft or reference non-existent variables (since that's annoyingly not an error for make).

BUILD=debug

# Configuration provided via flutter tool.
include flutter/generated_config
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TIL! Nice find :)

rm -rf $(OUT_DIR); \
cd $(FLUTTER_APP_DIR); \
$(FLUTTER_BIN) clean
$(FLUTTER_BIN) clean
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

^^^

# Targets

.PHONY: all
all: $(FLUTTER_ROOT)/packages/flutter_tools/bin/linux_backend.sh
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having two entries for all seems confusing. But also this doesn't actually ever run the script (I'm guessing you didn't test this on a clean build?)

I think what we want is a:

.PHONY: flutterbuild
flutterbuild:
    $(FLUTTER_ROOT)/packages/flutter_tools/bin/linux_backend.sh

And rather than all depending on that, the steps that would fail without it should depend on it, otherwise parallel builds, or direct target builds, would fail. Changing the line below that currently depends on $(FLUTTER_COPY_STAMP_FILE) to depend on flutterbuild instead, since that's now the build step that creates those files, should do it.

That should be a order-only dependency ([...]: | flutterbuild) so that when we improve linux_backend.sh to not re-copy the files when it's not necessary, it won't still do unnecessary relinking.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, the $(FLUTTER_ASSETS_SOURCE) rule below that currently calls build build should be removed, and $(FLUTTER_ASSETS_SOURCE) should become part of the left hand side of the rule depending on flutterbuild

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to create a separate sync target and then remove the dependency on build bundle so we dont call it twice

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You still have necessary files that don't have generation rules (everything that's still depending on the now-non-existent $(FLUTTER_COPY_STAMP_FILE) variable in your current patch; many scenarios would still fail. For instance, try, in a completely clean setup, running make build/linux/debug/flutter_desktop_example. (That's an unlikely scenario, but the same thing happens very easily if someone passes -j.)

I thought an order-only PHONY dependency wouldn't run multiple times; could you post the version with the dependencies where you saw the backend script firing repeatedly?

(Specifically, I thought this would work:

$(WRAPPER_SOURCES) $(FLUTTER_LIB): | sync

...

bundleflutterassets: | sync

# Resources
ICU_DATA_NAME=icudtl.dat
ICU_DATA_SOURCE=$(FLUTTER_ARTIFACT_CACHE_DIR)/$(ICU_DATA_NAME)
ICU_DATA_SOURCE=$(FLUTTER_APP_CACHE_DIR)/$(ICU_DATA_NAME)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your other PR doesn't copy icudtl.dat to this location, so either it should do that, or this Makefile needs to know how to go get it from the Flutter cache internals. (My vote would be for the former.)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

@stuartmorgan-g
Copy link
Collaborator

stuartmorgan-g commented May 6, 2019

@michaelmartins09 Please don't randomly approve PRs in this project.

CACHE_DIR=$(OUT_DIR)/cache
FLUTTER_LIBRARY_COPY_DIR=$(CACHE_DIR)/flutter_library

export FLUTTER_APP_CACHE_DIR=flutter/cache
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why export?

# Targets

.PHONY: all
all: $(FLUTTER_ROOT)/packages/flutter_tools/bin/linux_backend.sh
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You still have necessary files that don't have generation rules (everything that's still depending on the now-non-existent $(FLUTTER_COPY_STAMP_FILE) variable in your current patch; many scenarios would still fail. For instance, try, in a completely clean setup, running make build/linux/debug/flutter_desktop_example. (That's an unlikely scenario, but the same thing happens very easily if someone passes -j.)

I thought an order-only PHONY dependency wouldn't run multiple times; could you post the version with the dependencies where you saw the backend script firing repeatedly?

(Specifically, I thought this would work:

$(WRAPPER_SOURCES) $(FLUTTER_LIB): | sync

...

bundleflutterassets: | sync


.PHONY: all
all: $(BIN_OUT) bundle
all: sync $(BIN_OUT) bundle
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should be able to remove |sync| here since it's a dependency of other things. It's not a top-level thing that we need independently, which is what |all| should depend on.

all: $(BIN_OUT) bundle
all: sync $(BIN_OUT) bundle

.PHONY: sync
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a comment here saying that it's phony because we don't know the inputs, so we trust the Flutter tooling to run only when necessary.

@jonahwilliams jonahwilliams merged commit cc62553 into google:master May 11, 2019
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 8, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants