Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Linking error when building with target-feature=+crt-static #103

Open
AngelicosPhosphoros opened this issue Feb 2, 2021 · 2 comments
Open

Comments

@AngelicosPhosphoros
Copy link

This feature makes Visual C++ runtime to be linked output binaries statically.
I found a workaround but maybe there is some better way?

I build on Windows with:
MS Visual Studio 2019
Vulkan SDK 1.2.162.1
rustc 1.48.0 (7eac88abb 2020-11-16)

Code (build.rs):

use anyhow::*;
use glob::glob;
use std::path::PathBuf;

struct ShaderData {
    src: String,
    src_path: PathBuf,
    spv_path: PathBuf,
    kind: shaderc::ShaderKind,
}

impl ShaderData {
    pub fn load(src_path: PathBuf) -> Result<Self> {
        let extension = src_path
            .extension()
            .context("File has no extension")?
            .to_str()
            .context("Extension cannot be converted to &str")?;
        let kind = match extension {
            "vert" => shaderc::ShaderKind::Vertex,
            "frag" => shaderc::ShaderKind::Fragment,
            "comp" => shaderc::ShaderKind::Compute,
            _ => bail!("Unsupported shader: {}", src_path.display()),
        };

        let src = std::fs::read_to_string(src_path.clone())?;
        let spv_path = src_path.with_extension(format!("{}.spv", extension));

        Ok(Self {
            src,
            src_path,
            spv_path,
            kind,
        })
    }
}

fn main() -> Result<()> {
    // Collect all shaders recursively within /src/
    let mut shader_paths = [
        glob("./src/**/*.vert")?,
        glob("./src/**/*.frag")?,
        glob("./src/**/*.comp")?,
    ];

    let shaders: Result<Vec<_>> = shader_paths
        .iter_mut()
        .flatten()
        .map(|glob_res| -> Result<ShaderData> { ShaderData::load(glob_res?) })
        .collect();
    let shaders = shaders?;
    let mut compiler = shaderc::Compiler::new().context("Unable to create shader compiler")?;

    for shader in shaders {
        println!(
            "cargo:rerun-if-changed={}",
            shader
                .src_path
                .as_os_str()
                .to_str()
                .expect("Failed to get string name for shader")
        );
        let compiled = compiler.compile_into_spirv(
            &shader.src,
            shader.kind,
            shader.src_path.to_str().unwrap(),
            "main",
            None,
        )?;
        std::fs::write(shader.spv_path, compiled.as_binary_u8())?;
    }
    Ok(())
}

Cargo.toml:

[build-dependencies]
anyhow = "1.0"
glob = "0.3"
shaderc = "0.7"

I run build in Powershell with commands:

$env:RUSTFLAGS="-C target-feature=+crt-static"
cargo build

I expect build to compile but got this (this is only a part, a lot of omitted):

LINK : warning LNK4098: defaultlib 'MSVCRT' conflicts with use of other libs; use /NODEFAULTLIB:library
          LINK : warning LNK4286: symbol '_invalid_parameter_noinfo_noreturn' defined in 'libucrt.lib(invalid_parameter.obj)' is imported by 'libshaderc_sys-cae357ba032ea1ca.rlib(validate_scopes.obj)'
          LINK : warning LNK4217: symbol '_invalid_parameter_noinfo_noreturn' defined in 'libucrt.lib(invalid_parameter.obj)' is imported by 'libshaderc_sys-cae357ba032ea1ca.rlib(loop_dependence_helpers.obj)' in function '"protected: virtual class std::fpos<struct _Mbstatet> __cdecl std::basic_stringbuf<char,struct std::char_traits<char>,class std::allocator<char> >::seekoff(__int64,int,int)" (?seekoff@?$basic_stringbuf@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@MEAA?AV?$fpos@U_Mbstatet@@@2@_JHH@Z)'
          LINK : warning LNK4286: symbol '_invalid_parameter_noinfo_noreturn' defined in 'libucrt.lib(invalid_parameter.obj)' is imported by 'libshaderc_sys-cae357ba032ea1ca.rlib(PpTokens.obj)'
          LINK : warning LNK4286: symbol '_invalid_parameter_noinfo_noreturn' defined in 'libucrt.lib(invalid_parameter.obj)' is imported by 'libshaderc_sys-cae357ba032ea1ca.rlib(basic_block.obj)'
          LINK : warning LNK4286: symbol '_invalid_parameter_noinfo_noreturn' defined in 'libucrt.lib(invalid_parameter.obj)' is imported by 'libshaderc_sys-cae357ba032ea1ca.rlib(construct.obj)'
          LINK : warning LNK4286: symbol '_invalid_parameter_noinfo_noreturn' defined in 'libucrt.lib(invalid_parameter.obj)' is imported by 'libshaderc_sys-cae357ba032ea1ca.rlib(instruction.obj)'
          LINK : warning LNK4286: symbol '_invalid_parameter_noinfo_noreturn' defined in 'libucrt.lib(invalid_parameter.obj)' is imported by 'libshaderc_sys-cae357ba032ea1ca.rlib(loop_utils.obj)'
          LINK : warning LNK4286: symbol '_invalid_parameter_noinfo_noreturn' defined in 'libucrt.lib(invalid_parameter.obj)' is imported by 'libshaderc_sys-cae357ba032ea1ca.rlib(loop_fusion.obj)'
          LINK : warning LNK4286: symbol '_invalid_parameter_noinfo_noreturn' defined in 'libucrt.lib(invalid_parameter.obj)' is imported by 'libshaderc_sys-cae357ba032ea1ca.rlib(scalar_analysis_simplification.obj)'
          LINK : warning LNK4286: symbol '_invalid_parameter_noinfo_noreturn' defined in 'libucrt.lib(invalid_parameter.obj)' is imported by 'libshaderc_sys-cae357ba032ea1ca.rlib(bit_vector.obj)'
          LINK : warning LNK4286: symbol '_invalid_parameter_noinfo_noreturn' defined in 'libucrt.lib(invalid_parameter.obj)' is imported by 'libshaderc_sys-cae357ba032ea1ca.rlib(instrument_pass.obj)'
          LINK : warning LNK4286: symbol '_invalid_parameter_noinfo_noreturn' defined in 'libucrt.lib(invalid_parameter.obj)' is imported by 'libshaderc_sys-cae357ba032ea1ca.rlib(register_pressure.obj)'
          LINK : warning LNK4286: symbol '_invalid_parameter_noinfo_noreturn' defined in 'libucrt.lib(invalid_parameter.obj)' is imported by 'libshaderc_sys-cae357ba032ea1ca.rlib(scalar_analysis.obj)'
          LINK : warning LNK4286: symbol '_invalid_parameter_noinfo_noreturn' defined in 'libucrt.lib(invalid_parameter.obj)' is imported by 'libshaderc_sys-cae357ba032ea1ca.rlib(loop_dependence.obj)'
          LINK : warning LNK4286: symbol '_invalid_parameter_noinfo_noreturn' defined in 'libucrt.lib(invalid_parameter.obj)' is imported by 'libshaderc_sys-cae357ba032ea1ca.rlib(dominator_analysis.obj)'
          LINK : warning LNK4217: symbol '_invalid_parameter_noinfo_noreturn' defined in 'libucrt.lib(invalid_parameter.obj)' is imported by 'libshaderc_sys-cae357ba032ea1ca.rlib(struct_cfg_analysis.obj)' in function '"private: void __cdecl spvtools::opt::StructuredCFGAnalysis::AddBlocksInFunction(class spvtools::opt::Function *)" (?AddBlocksInFunction@StructuredCFGAnalysis@opt@spvtools@@AEAAXPEAVFunction@23@@Z)'
          LINK : warning LNK4286: symbol '_invalid_parameter_noinfo_noreturn' defined in 'libucrt.lib(invalid_parameter.obj)' is imported by 'libshaderc_sys-cae357ba032ea1ca.rlib(value_number_table.obj)'
          LINK : warning LNK4286: symbol '_invalid_parameter_noinfo_noreturn' defined in 'libucrt.lib(invalid_parameter.obj)' is imported by 'libshaderc_sys-cae357ba032ea1ca.rlib(inline_pass.obj)'
          LINK : warning LNK4286: symbol '_invalid_parameter_noinfo_noreturn' defined in 'libucrt.lib(invalid_parameter.obj)' is imported by 'libshaderc_sys-cae357ba032ea1ca.rlib(folding_rules.obj)'
          LINK : warning LNK4217: symbol '_invalid_parameter_noinfo_noreturn' defined in 'libucrt.lib(invalid_parameter.obj)' is imported by 'libshaderc_sys-cae357ba032ea1ca.rlib(fold.obj)' in function '"public: class std::_Tree_iterator<class std::_Tree_val<struct std::_Tree_simple_types<struct std::pair<class spvtools::opt::analysis::Constant const * const,unsigned int> > > > __cdecl std::_Tree<class std::_Tmap_traits<class spvtools::opt::analysis::Constant const *,unsigned int,struct std::less<class spvtools::opt::analysis::Constant const *>,class std::allocator<struct std::pair<class spvtools::opt::analysis::Constant const * const,unsigned int> >,1> >::erase(class std::_Tree_const_iterator<class std::_Tree_val<struct std::_Tree_simple_types<struct std::pair<class spvtools::opt::analysis::Constant const * const,unsigned int> > > >,class std::_Tree_const_iterator<class std::_Tree_val<struct std::_Tree_simple_types<struct std::pair<class spvtools::opt::analysis::Constant const * const,unsigned int> > > >)" (?erase@?$_Tree@V?$_Tmap_traits@PEBVConstant@analysis@opt@spvtools@@IU?$less@PEBVConstant@analysis@opt@spvtools@@@std@@V?$allocator@U?$pair@QEBVConstant@analysis@opt@spvtools@@I@std@@@6@$00@std@@@std@@QEAA?AV?$_Tree_iterator@V?$_Tree_val@U?$_Tree_simple_types@U?$pair@QEBVConstant@analysis@opt@spvtools@@I@std@@@std@@@std@@@2@V?$_Tree_const_iterator@V?$_Tree_val@U?$_Tree_simple_types@U?$pair@QEBVConstant@analysis@opt@spvtools@@I@std@@@std@@@std@@@2@0@Z)'
          LINK : warning LNK4217: symbol '_invalid_parameter_noinfo_noreturn' defined in 'libucrt.lib(invalid_parameter.obj)' is imported by 'libshaderc_sys-cae357ba032ea1ca.rlib(block_merge_util.obj)' in function '"bool __cdecl spvtools::opt::blockmergeutil::CanMergeWithSuccessor(class spvtools::opt::IRContext *,class spvtools::opt::BasicBlock *)" (?CanMergeWithSuccessor@blockmergeutil@opt@spvtools@@YA_NPEAVIRContext@23@PEAVBasicBlock@23@@Z)'
          LINK : warning LNK4286: symbol '_invalid_parameter_noinfo_noreturn' defined in 'libucrt.lib(invalid_parameter.obj)' is imported by 'libshaderc_sys-cae357ba032ea1ca.rlib(propagator.obj)'
          LINK : warning LNK4286: symbol '_invalid_parameter_noinfo_noreturn' defined in 'libucrt.lib(invalid_parameter.obj)' is imported by 'libshaderc_sys-cae357ba032ea1ca.rlib(decoration_manager.obj)'
          LINK : warning LNK4286: symbol '_invalid_parameter_noinfo_noreturn' defined in 'libucrt.lib(invalid_parameter.obj)' is imported by 'libshaderc_sys-cae357ba032ea1ca.rlib(debug_info_manager.obj)'
          LINK : warning LNK4286: symbol '_invalid_parameter_noinfo_noreturn' defined in 'libucrt.lib(invalid_parameter.obj)' is imported by 'libshaderc_sys-cae357ba032ea1ca.rlib(eliminate_dead_functions_util.obj)'
          LINK : warning LNK4286: symbol '_invalid_parameter_noinfo_noreturn' defined in 'libucrt.lib(invalid_parameter.obj)' is imported by 'libshaderc_sys-cae357ba032ea1ca.rlib(const_folding_rules.obj)'
          LINK : warning LNK4286: symbol '_invalid_parameter_noinfo_noreturn' defined in 'libucrt.lib(invalid_parameter.obj)' is imported by 'libshaderc_sys-cae357ba032ea1ca.rlib(ir_context.obj)'
          LINK : warning LNK4286: symbol '_invalid_parameter_noinfo_noreturn' defined in 'libucrt.lib(invalid_parameter.obj)' is imported by 'libshaderc_sys-cae357ba032ea1ca.rlib(type_manager.obj)'
          LINK : warning LNK4217: symbol '_invalid_parameter_noinfo_noreturn' defined in 'libucrt.lib(invalid_parameter.obj)' is imported by 'libshaderc_sys-cae357ba032ea1ca.rlib(ir_loader.obj)' in function '"protected: void __cdecl std::vector<class std::unique_ptr<class spvtools::opt::BasicBlock,struct std::default_delete<class spvtools::opt::BasicBlock> >,class std::allocator<class std::unique_ptr<class spvtools::opt::BasicBlock,struct std::default_delete<class spvtools::opt::BasicBlock> > > >::_Reallocate(unsigned __int64)" (?_Reallocate@?$vector@V?$unique_ptr@VBasicBlock@opt@spvtools@@U?$default_delete@VBasicBlock@opt@spvtools@@@std@@@std@@V?$allocator@V?$unique_ptr@VBasicBlock@opt@spvtools@@U?$default_delete@VBasicBlock@opt@spvtools@@@std@@@std@@@2@@std@@IEAAX_K@Z)'

I currently use a hack with specifying target explicitely. It makes cargo send custom compiler flags only to the final binary compilations and ignore build scripts:

cargo run --target x86_64-pc-windows-msvc
@guilhermewerner
Copy link

Instead of passing the --target to cargo you can put this in your .cargo/config.toml:

[target.x86_64-pc-windows-msvc]
rustflags = ["-C", "target-feature=+crt-static"]

@AngelicosPhosphoros
Copy link
Author

@guilhermewerner
rustflags in config.toml have same effect as setting RUSTFLAGS environment variable so it is unrelated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants