diff --git a/src/cargo/util/toml/mod.rs b/src/cargo/util/toml/mod.rs
index 2c24d9ee3ee..edbfe996292 100644
--- a/src/cargo/util/toml/mod.rs
+++ b/src/cargo/util/toml/mod.rs
@@ -9,7 +9,7 @@ use crate::core::summary::MissingDependencyError;
 use crate::AlreadyPrintedError;
 use anyhow::{anyhow, bail, Context as _};
 use cargo_platform::Platform;
-use cargo_util::paths::{self, normalize_path};
+use cargo_util::paths;
 use cargo_util_schemas::manifest::{
     self, PackageName, PathBaseName, TomlDependency, TomlDetailedDependency, TomlManifest,
 };
@@ -2712,7 +2712,7 @@ fn prepare_toml_for_publish(
     let mut package = me.package().unwrap().clone();
     package.workspace = None;
     if let Some(StringOrBool::String(path)) = &package.build {
-        let path = paths::normalize_path(Path::new(path));
+        let path = Path::new(path).to_path_buf();
         let included = packaged_files.map(|i| i.contains(&path)).unwrap_or(true);
         let build = if included {
             let path = path
@@ -3017,7 +3017,7 @@ pub fn prepare_target_for_publish(
     gctx: &GlobalContext,
 ) -> CargoResult<Option<manifest::TomlTarget>> {
     let path = target.path.as_ref().expect("previously normalized");
-    let path = normalize_path(&path.0);
+    let path = &path.0;
     if let Some(packaged_files) = packaged_files {
         if !packaged_files.contains(&path) {
             let name = target.name.as_ref().expect("previously normalized");
@@ -3030,7 +3030,7 @@ pub fn prepare_target_for_publish(
     }
 
     let mut target = target.clone();
-    let path = normalize_path_sep(path, context)?;
+    let path = normalize_path_sep(path.to_path_buf(), context)?;
     target.path = Some(manifest::PathValue(path.into()));
 
     Ok(Some(target))
diff --git a/src/cargo/util/toml/targets.rs b/src/cargo/util/toml/targets.rs
index ebade72da19..3fe018433b6 100644
--- a/src/cargo/util/toml/targets.rs
+++ b/src/cargo/util/toml/targets.rs
@@ -15,6 +15,7 @@ use std::fs::{self, DirEntry};
 use std::path::{Path, PathBuf};
 
 use anyhow::Context as _;
+use cargo_util::paths;
 use cargo_util_schemas::manifest::{
     PathValue, StringOrBool, StringOrVec, TomlBenchTarget, TomlBinTarget, TomlExampleTarget,
     TomlLibTarget, TomlManifest, TomlTarget, TomlTestTarget,
@@ -133,7 +134,7 @@ pub fn normalize_lib(
     warnings: &mut Vec<String>,
 ) -> CargoResult<Option<TomlLibTarget>> {
     if is_normalized(original_lib, autodiscover) {
-        let Some(lib) = original_lib.cloned() else {
+        let Some(mut lib) = original_lib.cloned() else {
             return Ok(None);
         };
 
@@ -143,6 +144,10 @@ pub fn normalize_lib(
         validate_proc_macro(&lib, "library", edition, warnings)?;
         validate_crate_types(&lib, "library", edition, warnings)?;
 
+        if let Some(PathValue(path)) = &lib.path {
+            lib.path = Some(PathValue(paths::normalize_path(path).into()));
+        }
+
         Ok(Some(lib))
     } else {
         let inferred = inferred_lib(package_root);
@@ -184,6 +189,10 @@ pub fn normalize_lib(
             }
         }
 
+        if let Some(PathValue(path)) = lib.path.as_ref() {
+            lib.path = Some(PathValue(paths::normalize_path(&path).into()));
+        }
+
         Ok(Some(lib))
     }
 }
@@ -255,11 +264,15 @@ pub fn normalize_bins(
     has_lib: bool,
 ) -> CargoResult<Vec<TomlBinTarget>> {
     if are_normalized(toml_bins, autodiscover) {
-        let toml_bins = toml_bins.cloned().unwrap_or_default();
-        for bin in &toml_bins {
+        let mut toml_bins = toml_bins.cloned().unwrap_or_default();
+        for bin in toml_bins.iter_mut() {
             validate_bin_name(bin, warnings)?;
             validate_bin_crate_types(bin, edition, warnings, errors)?;
             validate_bin_proc_macro(bin, edition, warnings, errors)?;
+
+            if let Some(PathValue(path)) = &bin.path {
+                bin.path = Some(PathValue(paths::normalize_path(path).into()));
+            }
         }
         Ok(toml_bins)
     } else {
@@ -300,7 +313,7 @@ pub fn normalize_bins(
                 }
             });
             let path = match path {
-                Ok(path) => path,
+                Ok(path) => paths::normalize_path(&path).into(),
                 Err(e) => anyhow::bail!("{}", e),
             };
             bin.path = Some(PathValue(path));
@@ -603,13 +616,17 @@ fn normalize_targets_with_legacy_path(
     autodiscover_flag_name: &str,
 ) -> CargoResult<Vec<TomlTarget>> {
     if are_normalized(toml_targets, autodiscover) {
-        let toml_targets = toml_targets.cloned().unwrap_or_default();
-        for target in &toml_targets {
+        let mut toml_targets = toml_targets.cloned().unwrap_or_default();
+        for target in toml_targets.iter_mut() {
             // Check early to improve error messages
             validate_target_name(target, target_kind_human, target_kind, warnings)?;
 
             validate_proc_macro(target, target_kind_human, edition, warnings)?;
             validate_crate_types(target, target_kind_human, edition, warnings)?;
+
+            if let Some(PathValue(path)) = &target.path {
+                target.path = Some(PathValue(paths::normalize_path(path).into()));
+            }
         }
         Ok(toml_targets)
     } else {
@@ -651,7 +668,7 @@ fn normalize_targets_with_legacy_path(
                     continue;
                 }
             };
-            target.path = Some(PathValue(path));
+            target.path = Some(PathValue(paths::normalize_path(&path).into()));
             result.push(target);
         }
         Ok(result)
@@ -1037,7 +1054,14 @@ pub fn normalize_build(build: Option<&StringOrBool>, package_root: &Path) -> Opt
             }
         }
         // Explicitly no build script.
-        Some(StringOrBool::Bool(false)) | Some(StringOrBool::String(_)) => build.cloned(),
+        Some(StringOrBool::Bool(false)) => build.cloned(),
+        Some(StringOrBool::String(build_file)) => {
+            let build_file = paths::normalize_path(Path::new(build_file));
+            let build = build_file.into_os_string().into_string().expect(
+                "`build_file` started as a String and `normalize_path` shouldn't have changed that",
+            );
+            Some(StringOrBool::String(build))
+        }
         Some(StringOrBool::Bool(true)) => Some(StringOrBool::String(BUILD_RS.to_owned())),
     }
 }
diff --git a/tests/testsuite/binary_name.rs b/tests/testsuite/binary_name.rs
index 8cf321b1d14..61569168c22 100644
--- a/tests/testsuite/binary_name.rs
+++ b/tests/testsuite/binary_name.rs
@@ -2,6 +2,7 @@
 
 use cargo_test_support::install::assert_has_installed_exe;
 use cargo_test_support::install::assert_has_not_installed_exe;
+use cargo_test_support::is_nightly;
 use cargo_test_support::paths;
 use cargo_test_support::prelude::*;
 use cargo_test_support::project;
@@ -340,3 +341,187 @@ fn check_msg_format_json() {
         )
         .run();
 }
+
+#[cargo_test]
+fn targets_with_relative_path_in_workspace_members() {
+    let p = project()
+        .file(
+            "Cargo.toml",
+            r#"
+            [workspace]
+            members = ["relative-bar"]
+            resolver = "2"
+        "#,
+        )
+        .file(
+            "relative-bar/Cargo.toml",
+            r#"
+                [package]
+                name = "relative-bar"
+                version = "0.1.0"
+                edition = "2021"
+
+                build = "./build.rs"
+
+                [[bin]]
+                name = "bar"
+                path = "./src/main.rs"
+
+                [lib]
+                name = "lib"
+                path = "./src/lib.rs"
+
+                [[example]]
+                name = "example"
+                path = "./example.rs"
+
+                [[test]]
+                name = "test"
+                path = "./test.rs"
+
+                [[bench]]
+                name = "bench"
+                path = "./bench.rs"
+            "#,
+        )
+        .file("relative-bar/build.rs", "fn main() { let a = 1; }")
+        .file("relative-bar/src/main.rs", "fn main() { let a = 1; }")
+        .file("relative-bar/src/lib.rs", "fn a() {}")
+        .file("relative-bar/example.rs", "fn main() { let a = 1; }")
+        .file(
+            "relative-bar/test.rs",
+            r#"
+                fn main() {}
+
+                #[test]
+                fn test_a() { let a = 1; } 
+            "#,
+        )
+        .file(
+            "relative-bar/bench.rs",
+            r#"  
+                #![feature(test)]
+                #[cfg(test)]
+                extern crate test;
+
+                #[bench]
+                fn bench_a(_b: &mut test::Bencher) { let a = 1; }
+            "#,
+        )
+        .build();
+
+    p.cargo("check")
+        .with_stderr_data(str![[r#"
+...
+ --> relative-bar/build.rs:1:17
+...
+ --> relative-bar/src/lib.rs:1:4
+...
+ --> relative-bar/src/main.rs:1:17
+...
+"#]])
+        .run();
+
+    p.cargo("check --example example")
+        .with_stderr_data(str![[r#"
+...
+ --> relative-bar/example.rs:1:17
+...
+"#]])
+        .run();
+
+    p.cargo("check --test test")
+        .with_stderr_data(str![[r#"
+...
+ --> relative-bar/test.rs:5:35
+...
+"#]])
+        .run();
+
+    if is_nightly() {
+        p.cargo("check --bench bench")
+            .with_stderr_data(str![[r#"
+...
+ --> relative-bar/bench.rs:7:58
+...
+"#]])
+            .run();
+    }
+
+    // Disable Cargo target auto-discovery.
+    p.change_file(
+        "relative-bar/Cargo.toml",
+        r#"
+            [package]
+            name = "relative-bar"
+            version = "0.1.0"
+            edition = "2021"
+
+            autolib = false
+            autobins = false
+            autoexamples = false
+            autotests = false
+            autobenches = false
+
+            build = "./build.rs"
+
+            [[bin]]
+            name = "bar"
+            path = "./src/main.rs"
+
+            [lib]
+            name = "lib"
+            path = "./src/lib.rs"
+
+            [[example]]
+            name = "example"
+            path = "./example.rs"
+
+            [[test]]
+            name = "test"
+            path = "./test.rs"
+
+            [[bench]]
+            name = "bench"
+            path = "./bench.rs"
+        "#,
+    );
+
+    p.cargo("check")
+        .with_stderr_data(str![[r#"
+...
+ --> relative-bar/build.rs:1:17
+...
+ --> relative-bar/src/lib.rs:1:4
+...
+ --> relative-bar/src/main.rs:1:17
+...
+"#]])
+        .run();
+
+    p.cargo("check --example example")
+        .with_stderr_data(str![[r#"
+...
+ --> relative-bar/example.rs:1:17
+...
+"#]])
+        .run();
+
+    p.cargo("check --test test")
+        .with_stderr_data(str![[r#"
+...
+ --> relative-bar/test.rs:5:35
+...
+"#]])
+        .run();
+
+    if is_nightly() {
+        p.cargo("check --bench bench")
+            .with_stderr_data(str![[r#"
+...
+ --> relative-bar/bench.rs:7:58
+...
+"#]])
+            .run();
+    }
+}