Skip to content

Commit a519fba

Browse files
authored
fix platform unification (#4536)
* fix platform unification * fix doc
1 parent a8230d8 commit a519fba

File tree

2 files changed

+68
-73
lines changed

2 files changed

+68
-73
lines changed

packages/cli/src/build/request.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,6 @@ pub(crate) struct BuildRequest {
372372
pub(crate) profile: String,
373373
pub(crate) release: bool,
374374
pub(crate) bundle: BundleFormat,
375-
pub(crate) enabled_renderers: Vec<Renderer>,
376375
pub(crate) triple: Triple,
377376
pub(crate) device: bool,
378377
pub(crate) package: String,
@@ -619,12 +618,6 @@ impl BuildRequest {
619618
},
620619
};
621620

622-
// Just grab the renderers from the enabled renderers and discard the feature names
623-
let enabled_renderers = enabled_renderers
624-
.into_iter()
625-
.map(|(renderer, _)| renderer)
626-
.collect::<Vec<_>>();
627-
628621
// We usually use the simulator unless --device is passed *or* a device is detected by probing.
629622
// For now, though, since we don't have probing, it just defaults to false
630623
// Tools like xcrun/adb can detect devices
@@ -808,7 +801,6 @@ impl BuildRequest {
808801
device,
809802
workspace,
810803
config,
811-
enabled_renderers,
812804
target_dir,
813805
custom_linker,
814806
link_args_file,

packages/cli/src/cli/build.rs

Lines changed: 68 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -40,41 +40,77 @@ pub struct BuildTargets {
4040
pub server: Option<BuildRequest>,
4141
}
4242

43-
impl BuildArgs {
44-
fn default_client(&self) -> &TargetArgs {
45-
&self.build_arguments
46-
}
43+
impl CommandWithPlatformOverrides<BuildArgs> {
44+
/// We need to decompose the combined `BuildArgs` into the individual targets that we need to build.
45+
///
46+
/// Only in a few cases do we spin out an additional server binary:
47+
/// - the fullstack feature is passed
48+
/// - the fullstack flag is enabled
49+
/// - the server flag is enabled
50+
///
51+
/// The buildtargets configuration comes in two flavors:
52+
/// - implied via the `fullstack` feature
53+
/// - explicit when using `@server and @client`
54+
///
55+
/// We use the client arguments to build the client target, and then make a few changes to make
56+
/// the server target.
57+
///
58+
/// The `--fullstack` feature is basically the same as passing `--features fullstack`
59+
///
60+
/// Some examples:
61+
/// ```shell, ignore
62+
/// dx serve --target wasm32-unknown-unknown --fullstack # serves both client and server
63+
/// dx serve --target wasm32-unknown-unknown --features fullstack # serves both client and server
64+
/// dx serve --target wasm32-unknown-unknown # only serves the client
65+
/// dx serve --target wasm32-unknown-unknown # servers both if `fullstack` is enabled on dioxus
66+
/// dx serve @client --target wasm32-unknown-unknown # only serves the client
67+
/// dx serve @client --target wasm32-unknown-unknown --fullstack # serves both client and server
68+
/// ```
69+
///
70+
/// Currently it is not possible to serve the server without the client, but this could be added in the future.
71+
pub async fn into_targets(self) -> Result<BuildTargets> {
72+
let workspace = Workspace::current().await?;
73+
74+
// do some logging to ensure dx matches the dioxus version since we're not always API compatible
75+
workspace.check_dioxus_version_against_cli();
76+
77+
// The client args are the `@client` arguments, or the shared build arguments if @client is not specified.
78+
let client_args = &self.client.as_ref().unwrap_or(&self.shared).build_arguments;
79+
80+
// Create the client build request
81+
let client = BuildRequest::new(client_args, None, workspace.clone()).await?;
82+
83+
// Create the server build request if needed
84+
// This happens when 1) fullstack is enabled, 2)
85+
let mut server = None;
86+
if matches!(self.shared.fullstack, Some(true))
87+
|| client.fullstack_feature_enabled()
88+
|| self.server.is_some()
89+
{
90+
match self.server.as_ref() {
91+
Some(server_args) => {
92+
server = Some(
93+
BuildRequest::new(
94+
&server_args.build_arguments,
95+
Some(client.main_target.clone()),
96+
workspace.clone(),
97+
)
98+
.await?,
99+
);
100+
}
101+
None => {
102+
let mut args = self.shared.build_arguments.clone();
103+
args.platform = Some(crate::Platform::Server);
104+
args.renderer.renderer = Some(crate::Renderer::Server);
105+
args.target = Some(target_lexicon::Triple::host());
106+
server = Some(BuildRequest::new(&args, None, workspace.clone()).await?);
107+
}
108+
}
109+
}
47110

48-
fn default_server(&self, client: &BuildRequest) -> Option<&TargetArgs> {
49-
// Now resolve the builds that we need to.
50-
// These come from the args, but we'd like them to come from the `TargetCmd` chained object
51-
//
52-
// The process here is as follows:
53-
//
54-
// - Create the BuildRequest for the primary target
55-
// - If that BuildRequest is "fullstack", then add the client features
56-
// - If that BuildRequest is "fullstack", then also create a BuildRequest for the server
57-
// with the server features
58-
//
59-
// This involves modifying the BuildRequest to add the client features and server features
60-
// only if we can properly detect that it's a fullstack build. Careful with this, since
61-
// we didn't build BuildRequest to be generally mutable.
62-
let default_server = client.enabled_renderers.contains(&crate::Renderer::Server);
63-
64-
// Make sure we set the fullstack platform so we actually build the fullstack variant
65-
// Users need to enable "fullstack" in their default feature set.
66-
// todo(jon): fullstack *could* be a feature of the app, but right now we're assuming it's always enabled
67-
//
68-
// Now we need to resolve the client features
69-
let fullstack = ((default_server || client.fullstack_feature_enabled())
70-
|| self.fullstack.unwrap_or(false))
71-
&& self.fullstack != Some(false);
72-
73-
fullstack.then_some(&self.build_arguments)
111+
Ok(BuildTargets { client, server })
74112
}
75-
}
76113

77-
impl CommandWithPlatformOverrides<BuildArgs> {
78114
pub async fn build(self) -> Result<StructuredOutput> {
79115
tracing::info!("Building project...");
80116

@@ -105,37 +141,4 @@ impl CommandWithPlatformOverrides<BuildArgs> {
105141
server: targets.server.map(|s| s.root_dir()),
106142
})
107143
}
108-
109-
pub async fn into_targets(self) -> Result<BuildTargets> {
110-
let workspace = Workspace::current().await?;
111-
112-
// do some logging to ensure dx matches the dioxus version since we're not always API compatible
113-
workspace.check_dioxus_version_against_cli();
114-
115-
let client_args = match &self.client {
116-
Some(client) => &client.build_arguments,
117-
None => self.shared.default_client(),
118-
};
119-
let client = BuildRequest::new(client_args, None, workspace.clone()).await?;
120-
121-
let server_args = match &self.server {
122-
Some(server) => Some(&server.build_arguments),
123-
None => self.shared.default_server(&client),
124-
};
125-
126-
let mut server = None;
127-
// If there is a server, make sure we output in the same directory as the client build so we use the server
128-
// to serve the web client
129-
if let Some(server_args) = server_args {
130-
// Copy the main target from the client to the server
131-
let main_target = client.main_target.clone();
132-
let mut server_args = server_args.clone();
133-
// The renderer in the server build is always set to Server
134-
server_args.renderer.renderer = Some(crate::Renderer::Server);
135-
server =
136-
Some(BuildRequest::new(&server_args, Some(main_target), workspace.clone()).await?);
137-
}
138-
139-
Ok(BuildTargets { client, server })
140-
}
141144
}

0 commit comments

Comments
 (0)