【问题标题】:How to remove warning: link.res contains output sections; did you forget -T?如何删除警告:link.res 包含输出部分;你忘了-T吗?
【发布时间】:2013-12-09 17:14:35
【问题描述】:

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

fpc foo.pas

出来:

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

【问题讨论】:

    标签: linux pascal ld fpc


    【解决方案1】:

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

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

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

    ma​​in.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")
    }
    

    【讨论】:

      【解决方案2】:

      这不是错误,因为ld 的行为与其规范一样。 ld 2.28 的手册页内容如下:

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

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

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

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

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

      【讨论】:

      • 恕我直言,回复旧帖子指出问题在 2.19 中发生了变化,并在 2.28 的联机帮助页中引用了 -T 引用,这是不具建设性的,并且绕过了所有历史背景。在这一切都相关的时候,没有-T,例如debian stable 分支仍然有没有 -T 的链接器。
      • @Marco van de Voort:见这篇文章的标题。显然该版本支持“-T”命令行开关。
      • 但是当有问题的 FPC 编译器问世时,两个版本的 LD 都在发挥作用。
      【解决方案3】:

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

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

      【讨论】:

      • 我有 ld 2.24fpc 2.6.4 但我看到了这条消息。如何告诉 fpc 强制 ld 不打印警告?
      • 你不能。不过,您可以将选项直接传递给 LD。只需为您的版本查找相关的 LD 开关并使用 -k 传递它。因此,如果选项是 --shutup,则将 -k--shutup 传递给 FPC。
      • @Marco van de Voort 将选项传递给ld 时,有一些选项可以禁用警告(如-no-warn-mismatch),但我看不到任何ld 选项来禁用有问题的警告。
      • 这不是“某些ld版本中的错误”,自2011年以来一直如此。
      • 好,自 2011 年以来的一些 ld 版本。
      猜你喜欢
      • 2021-11-12
      • 2015-10-05
      • 2018-06-19
      • 2014-11-22
      • 2019-08-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多