Skip to content

Windows - MinGW gcc: Compiled object always gets put in the root project directory #819

@Spencer1O1

Description

@Spencer1O1

The issue:

I have a C file in the root of my Rust project: my_interop.c (the issue persists wherever I place it)
My build.rs script, about as simple as it can get, looks like this:

fn main() {
    cc::Build::new()
        .file("my_interop.c")
        .compile("my_interop");
    println!("cargo:rustc-link-lib=user32"); // my_interop.c includes <windows.h>
}

When building, the log says,

running: "C:\\MinGW\\bin\\gcc.exe" "-O0" "-ffunction-sections" "-fdata-sections" "-g" "-fno-omit-frame-pointer" "-m64" "-Wall" "-Wextra" "-FoC:\\Dev\\my-project\\target\\debug\\build\\my-project-4a742f3493d90fa9\\out\\my_interop.o" "-c" "my_interop.c"

which should put the object file in target/debug/build/my-project-.../out/get_wp_handle.o
However, I find the object file in the root directory, outside of target.

Then, in the linking step, the log says,

running: "C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Tools\\MSVC\\14.34.31933\\bin\\HostX64\\x64\\lib.exe" "-out:C:\\Dev\\my-project\\target\\debug\\build\\my-project-4a742f3493d90fa9\\out\\libmy_interop.a" "-nologo" "C:\\Dev\\my-project\\target\\debug\\build\\my-project-4a742f3493d90fa9\\out\\my_interop.o"
  LINK : fatal error LNK1181: cannot open input file 'C:\Dev\my-project\target\debug\build\my-project-4a742f3493d90fa9\out\my_interop.o'
  exit code: 1181

which is obviously because the object file got put in the root directory rather than the designated output directory.

In my build script I have tried adding .output_dir("some/specific/dir") but the object file still gets put at the root.

The temporary solution:

If I change my build script to be

fn main() {
    cc::Build::new()
        .file("my_interop.c")
        .out_dir(".")
        .compile("my_interop");
    println!("cargo:rustc-link-lib=user32"); // my_interop.c uses #include <windows.h>
}

the linking step will expect the object file to be in the root directory.
It compiles as needed, and the project runs fine.
However, now the issue is that all of the other output files get put there too.
We end up a bunch of junk like this,

<Dir>    .
<Dir>    ..
         .gitignore
         build.rs
         Cargo.lock
         Cargo.toml
         my_interop.c
         my_interop.lib
         my_interop.o
         libmy_interop.a
<Dir>    src
<Dir>    target

which isn't good for maintainability.

Full Log:

error: failed to run custom build command for `my-project v0.1.0 (C:\Dev\my-project)`

Caused by:
  process didn't exit successfully: `C:\Dev\my-project\target\debug\build\my-project-e6e1131d5fda03d6\build-script-build` (exit code: 1)
  --- stdout
  TARGET = Some("x86_64-pc-windows-msvc")
  OPT_LEVEL = Some("0")
  HOST = Some("x86_64-pc-windows-msvc")
  cargo:rerun-if-env-changed=CC_x86_64-pc-windows-msvc
  CC_x86_64-pc-windows-msvc = None
  cargo:rerun-if-env-changed=CC_x86_64_pc_windows_msvc
  CC_x86_64_pc_windows_msvc = None
  cargo:rerun-if-env-changed=HOST_CC
  HOST_CC = None
  cargo:rerun-if-env-changed=CC
  CC = Some("C:\\MinGW\\bin\\gcc.exe")
  cargo:rerun-if-env-changed=CFLAGS_x86_64-pc-windows-msvc
  CFLAGS_x86_64-pc-windows-msvc = None
  cargo:rerun-if-env-changed=CFLAGS_x86_64_pc_windows_msvc
  CFLAGS_x86_64_pc_windows_msvc = None
  cargo:rerun-if-env-changed=HOST_CFLAGS
  HOST_CFLAGS = None
  cargo:rerun-if-env-changed=CFLAGS
  CFLAGS = None
  cargo:rerun-if-env-changed=CRATE_CC_NO_DEFAULTS
  CRATE_CC_NO_DEFAULTS = None
  DEBUG = Some("true")
  CARGO_CFG_TARGET_FEATURE = Some("fxsr,sse,sse2")
  running: "C:\\MinGW\\bin\\gcc.exe" "-O0" "-ffunction-sections" "-fdata-sections" "-g" "-fno-omit-frame-pointer" "-m64" "-Wall" "-Wextra" "-FoC:\\Dev\\my-project\\target\\debug\\build\\my-project-4a742f3493d90fa9\\out\\my_interop.o" "-c" "my_interop.c"
  exit code: 0
  cargo:rerun-if-env-changed=AR_x86_64-pc-windows-msvc
  AR_x86_64-pc-windows-msvc = None
  cargo:rerun-if-env-changed=AR_x86_64_pc_windows_msvc
  AR_x86_64_pc_windows_msvc = None
  cargo:rerun-if-env-changed=HOST_AR
  HOST_AR = None
  cargo:rerun-if-env-changed=AR
  AR = None
  cargo:rerun-if-env-changed=ARFLAGS_x86_64-pc-windows-msvc
  ARFLAGS_x86_64-pc-windows-msvc = None
  cargo:rerun-if-env-changed=ARFLAGS_x86_64_pc_windows_msvc
  ARFLAGS_x86_64_pc_windows_msvc = None
  cargo:rerun-if-env-changed=HOST_ARFLAGS
  HOST_ARFLAGS = None
  cargo:rerun-if-env-changed=ARFLAGS
  ARFLAGS = None
  running: "C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Tools\\MSVC\\14.34.31933\\bin\\HostX64\\x64\\lib.exe" "-out:C:\\Dev\\my-project\\target\\debug\\build\\my-project-4a742f3493d90fa9\\out\\libmy_interop.a" "-nologo" "C:\\Dev\\my-project\\target\\debug\\build\\my-project-4a742f3493d90fa9\\out\\my_interop.o"
  LINK : fatal error LNK1181: cannot open input file 'C:\Dev\my-project\target\debug\build\my-project-4a742f3493d90fa9\out\my_interop.o'
  exit code: 1181

I'm new to C and all of the compiling and linking, so I'm having trouble coming up with a solution. I'm not sure if this is a problem with cc-rs or gcc.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions