10

我正在使用 fpc 编译器,我想删除这个警告。我已经阅读了 fpc 的选项,但我找不到如何做到这一点。这可能吗?当我运行命令时出现:

fpc foo.pas

出去:

目标操作系统:Linux for i386 编译 foo.pas 链接 p2 /usr/bin/ld:警告:link.res 包含输出部分;你忘了-T吗?编译 79 行,0.1 秒

4

3 回答 3

3

这是某些 LD 版本中的错误。暂时忽略它,或者查看您的发行版是否有针对您的 LD 的更新。(包 binutils)

http://www.freepascal.org/faq.var#unix-ld219

于 2013-11-25T19:46:12.717 回答
1

这不是一个错误,因为它的ld行为类似于它的规范。ld2.28的手册页内容如下:

如果链接器无法识别目标文件的格式,它将假定它是链接描述文件。以这种方式指定的脚本扩充了用于链接的主链接描述文件(默认链接描述文件或使用 -T 指定的链接描述文件)。此功能允许链接器链接一个看似对象或存档的文件,但实际上只是定义了一些符号值,或使用“INPUT”或“GROUP”来加载其他对象。以这种方式指定脚本只会增加主链接器脚本,并在主脚本之后放置额外的命令;使用 -T 选项完全替换默认链接描述文件,但请注意“INSERT”命令的效果。

TL;博士☺。简而言之:在大多数情况下,用户不知道他们正在使用的链接器脚本,因为工具链提供了“主脚本”(=默认脚本)。主脚本大量引用了编译器生成部分的内在函数,您必须学习更改它的技巧。大多数用户没有。

提供您自己的脚本的常用方法是通过-T选项。这样,主链接器脚本将被忽略,您的脚本将接管对链接的控制。但是您必须从头开始编写所有内容。

如果您只想添加一个次要功能,您可以将您的规范写入一个文件并将文件名附加到ld(或 gcc / g++)的命令行而不带选项-T。这样,主链接器脚本仍然可以完成主要工作,但您的文件会增加它。如果您使用这种方法,您会收到该线程标题的消息,通知您您可能无意中提供了损坏的对象。

这种混淆的根源在于无法指定附加文件的角色。这可以通过添加另一个选项来轻松解决,ld就像“<strong>default scriptfile”的选项一样:为“<strong>supplemental scriptfile”-dT引入一个选项。-sT

于 2019-01-15T09:25:25.397 回答
0

这已在 binutils 的 2.35.1(或更高版本)版本中得到修复。

如果你有一个有问题的 binutils 版本,我已经创建了一个二进制补丁的快速程序来/usr/bin/ld消除这个非常烦人的警告消息。

这个程序可以保存为补丁main.go并执行。如果您的二进制文件放在其他地方,请记住首先备份并修改主函数中的路径。sudo go run main.goldld

main.go

package main

import (
    "bytes"
    "fmt"
    "io/ioutil"
    "os"
)

// patchAway takes a filename and a string
// If the string is found in the file, the first byte is
// set to 0, to make the string zero length in C.
func patchAway(filename, cstring string) error {
    data, err := ioutil.ReadFile(filename)
    if err != nil {
        return err
    }

    // Find the position of the warning
    pos := bytes.Index(data, []byte(cstring))

    // If it does not exist, the file has most likely already been patched
    if pos == -1 {
        return fmt.Errorf("%s has already been patched", filename)
    }

    // Silence the message with a 0 byte
    data[pos] = 0

    // Retrieve the permissions of the original file
    fi, err := os.Stat(filename)
    if err != nil {
        return err
    }
    perm := fi.Mode().Perm()

    // Write the patched data to the new file, but with the same permissions as the original file
    return ioutil.WriteFile(filename, data, perm)
}

func main() {
    filename := "/usr/bin/ld"
    warningMessage := "%P: warning: %s contains output sections"
    fmt.Printf("Patching %s... ", filename)
    if err := patchAway(filename, warningMessage); err != nil {
        fmt.Fprintln(os.Stderr, err)
        os.Exit(1)
    }
    fmt.Println("ok")
}
于 2021-01-28T09:53:14.570 回答