kaixuan1115 / notes

笔记收录
6 stars 0 forks source link

RUST编译MSVC 2013缺少`legacy_stdio_definitions.lib`解决办法 #39

Closed xiaokaixuan closed 1 year ago

xiaokaixuan commented 1 year ago

此为第一方案,嫌麻烦的直接看第二条comment的简单方案

  1. 使用代理链接器link_wrapper.exe,链接时忽略legacy_stdio_definitions.lib
    
    // link_wrapper project main.go
    package main

import ( "bytes" "fmt" "io/ioutil" "log" "os" "os/exec" "strings" "unicode/utf16" "unicode/utf8" )

const LINK_PATH = "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\amd64\link.exe"

var IGNORE_LIBS = map[string]bool{ "legacy_stdio_definitions.lib": true, }

type ArgsParser struct { Args []string }

func (ap *ArgsParser) ProcessArg(str string) error { str = strings.Trim(str, "\"") if str == "" { return nil } else if str[0] == '@' { content, err := ap.ReadFileUtf16(str[1:]) if err != nil { return err } strs := strings.Split(content, "\n") for _, str1 := range strs { err := ap.ProcessArg(str1) if err != nil { return err } } } else if !IGNORE_LIBS[str] { ap.Args = append(ap.Args, str) } return nil }

func (*ArgsParser) ReadFileUtf16(filename string) (string, error) { b, err := ioutil.ReadFile(filename) if err != nil { return "", err } lb := len(b) if len(b)%2 != 0 { return "", fmt.Errorf("ReadFileUtf16 length mod 2 != 0") }

u16s := make([]uint16, 1)
ret := &bytes.Buffer{}
b8buf := make([]byte, 4)

for i := 2; i < lb; i += 2 {
    u16s[0] = uint16(b[i]) + (uint16(b[i+1]) << 8)
    r := utf16.Decode(u16s)
    n := utf8.EncodeRune(b8buf, r[0])
    ret.Write(b8buf[:n])
}

return ret.String(), nil

}

func main() { ap := ArgsParser{} for _, str := range os.Args[1:] { err := ap.ProcessArg(str) if err != nil { log.Fatalf("ProcessArg Error: %v\n", err) } } //ioutil.WriteFile("linkargs.log", []byte(strings.Join(ap.Args, "\n")), 0666) //stdout, := os.OpenFile("stdout.log", os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0666) //defer stdout.Close()

cmd := exec.Command(LINK_PATH, ap.Args...)
cmd.Stderr = os.Stderr
cmd.Stdout = os.Stdout
if err := cmd.Run(); err != nil {
    if err1, ok := err.(*exec.ExitError); ok {
        os.Exit(err1.ExitCode())
    } else {
        log.Fatalf("Command Error: %v\n", err)
    }
}

}

2. 项目下`Cargo.toml`同级创建`.cargo/config.toml`,同时将`link_wrapper.exe`放入`.cargo`目录。内容如下:
```toml
[target.x86_64-pc-windows-msvc]
linker = ".cargo\\link_wrapper.exe"
rustflags = ["-C", "target-feature=+crt-static"]

[build]
target = "x86_64-pc-windows-msvc"
  1. 如需全局使用link_wrapper.exe,只需创建C:\User\XXX\.cargo\config.toml,同时将link_wrapper.exe放入.cargo目录。内容如下:
    [target.x86_64-pc-windows-msvc]
    linker = "C:\\Users\\XXX\\.cargo\\link_wrapper.exe"
    rustflags = ["-C", "target-feature=+crt-static"]
  2. Demo如下: hello_demo.zip
xiaokaixuan commented 1 year ago

以下为第二种方案

将以下文件解压后改名为缺失的lib文件名legacy_stdio_definitions.lib,放到其他已有的lib文件同目录即可。 其他类似的代码未调用的缺失lib文件,亦可依此方法处理。 以下压缩包中包含一个空的lib文件: fake_lib.zip

xiaokaixuan commented 1 year ago

Win 7无法使用JetBrains.Rider缺少USERENV.DLL的解决办法,使用代理rider64.exe

// rider64 project main.go
package main

import (
    "log"
    "os"
    "os/exec"
    "syscall"
)

// go build -ldflags -H=windowsgui
func main() {
    cmd := exec.Command("rider.bat", os.Args[1:]...)
    cmd.Stderr = os.Stderr
    cmd.Stdout = os.Stdout
    cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
    if err := cmd.Run(); err != nil {
        if err1, ok := err.(*exec.ExitError); ok {
            os.Exit(err1.ExitCode())
        } else {
            log.Fatalf("Command Error: %v\n", err)
        }
    }
}