Как убрать предупреждение: link.res содержит выходные разделы; ты забыл -T?

Я использую компилятор fpc и хочу удалить это предупреждение. Я прочитал опции fpc, но не могу найти, как это сделать. Это возможно? это появляется, когда я запускаю команду:

fpc foo.pas

из:

Целевая ОС: Linux для i386 Компиляция foo.pas Linking p2 /usr/bin/ld: warning: link.res содержит выходные разделы; ты забыл -T? Составлено 79 строк, 0,1 сек

3 ответа

Решение

Это ошибка в некоторых версиях LD. Просто проигнорируйте его или посмотрите, есть ли в вашем дистрибутиве обновление для вашего LD. (пакет binutils)

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

Это не ошибка, потому что ld ведет себя как его спецификация. Справочная страница ld 2.28 гласит:

Если компоновщик не может распознать формат объектного файла, он будет считать, что это скрипт компоновщика. Указанный таким образом сценарий дополняет основной сценарий компоновщика, используемый для ссылки (либо сценарий компоновщика по умолчанию, либо сценарий, указанный с помощью -T). Эта функция позволяет компоновщику связываться с файлом, который выглядит как объект или архив, но на самом деле просто определяет некоторые значения символов или использует "INPUT" или "GROUP" для загрузки других объектов. Указание сценария таким способом просто дополняет сценарий основного компоновщика, добавляя дополнительные команды после основного сценария; используйте опцию -T, чтобы полностью заменить скрипт компоновщика по умолчанию, но обратите внимание на эффект команды "INSERT".

TL; DR ☺. В двух словах: в большинстве случаев пользователи не знают о сценарии компоновщика, который они используют, потому что "основной сценарий" (= сценарий по умолчанию) предоставляется цепочкой инструментов. Основной сценарий в значительной степени относится к внутренним элементам сгенерированных компилятором разделов, и вы должны изучить веревки, чтобы изменить его. Большинство пользователей этого не делают.

Общий подход к предоставлению собственного сценария заключается в -T вариант. Таким образом, основной скрипт компоновщика игнорируется, и ваш скрипт перехватывает контроль над связью. Но вы должны написать все с нуля.

Если вы просто хотите добавить второстепенную функцию, вы можете записать свои спецификации в файл и добавить имя файла в командную строку ld (или gcc / g++) без -T вариант. Таким образом, скрипт основного компоновщика все еще выполняет основную работу, но ваш файл дополняет его. Если вы используете этот подход, вы получите сообщение заголовка этой темы, сообщающее вам, что вы могли непреднамеренно предоставить сломанный объект.

Источник этой путаницы заключается в том, что нет способа указать роль дополнительного файла. Это можно легко решить, добавив еще один параметр в ld так же, как -dT опция для "файла сценария по умолчанию": введите -sT опция для "файла сценариев".

Это исправлено в версии 2.35.1 (или более поздней) binutils.

Если у вас проблемная версия binutils, я создал быструю программу для бинарного патча /usr/bin/ldчтобы заглушить это чрезвычайно раздражающее предупреждающее сообщение.

Эту программу можно сохранить как main.goи быть выполненным с sudo go run main.goзалатать . Не забудьте сделать резервную копию ldсначала и измените путь в основной функции, если ваш двоичный файл находится в другом месте.

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")
}
Другие вопросы по тегам