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

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

fpc foo.pas

вне:

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


person Jack    schedule 25.11.2013    source источник


Ответы (3)


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

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

person Marco van de Voort    schedule 25.11.2013
comment
У меня есть ld 2.24 и fpc 2.6.4, но я вижу это сообщение. Как мне указать fpc, чтобы заставить ld не печатать предупреждения? - person William; 27.11.2014
comment
Вы не можете. Однако вы можете передавать параметры непосредственно в LD. Просто найдите соответствующий переключатель LD для вашей версии и передайте его с -k. Поэтому, если опция --shutup, передайте -k--shutup в FPC. - person Marco van de Voort; 27.11.2014
comment
@Marco van de Voort При передаче параметров в ld есть несколько параметров, отключающих предупреждения (например, -no-warn-mismatch), но я не вижу никаких параметров ld для отключения рассматриваемого предупреждения. - person Alexander; 25.07.2017
comment
это не ошибка в некоторых версиях ld, так было с 2011 года. - person nurettin; 04.09.2017
comment
Хорошо, в некоторых версиях ld с 2011 года. - person Marco van de Voort; 04.09.2017
comment
Я получаю ту же проблему. Мой FreePascal 3.0.4 и /usr/bin/ld 2.30. - person Zamrony P. Juhara; 03.10.2018
comment
Это не ошибка. Смотрите мой ответ ниже. - person hermannk; 26.09.2020

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

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

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

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

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

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

person hermannk    schedule 15.01.2019
comment
ИМХО, отвечать на старые сообщения, в которых УКАЗЫВАЕТСЯ, что проблема изменилась в 2.19, с цитатами -T со страницы руководства 2.28, неконструктивно и игнорирует весь исторический контекст. В то время, когда все это было актуально, не было -T и, например, В стабильной ветке Debian все еще были линкеры без -T. - person Marco van de Voort; 28.09.2020
comment
@Marco van de Voort: см. заголовок этого поста. Очевидно, ревизия поддерживала ключ командной строки «-T». - person hermannk; 29.09.2020
comment
Но когда вышел рассматриваемый компилятор FPC, обе версии LD были в игре. - person Marco van de Voort; 29.09.2020

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

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

Эту программу можно сохранить как main.go и выполнить с помощью sudo go run main.go для исправления ld. Не забудьте сначала сделать резервную копию 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")
}
person Alexander    schedule 28.01.2021