Команда вроде этого будет работать:
(LD) $(LDFLAGS) -o reip.app newlib/crt0.o reip.o renetif.o fs.o httpd.o liblwip.a newlib/libc.a
Но если я помещаю *.a перед *.o файлами - он не сможет найти функции из libs.
Я просмотрел некоторые старые проекты и нашел в make файлах такие строки:
$(CC) $(LIBS) -o $(TARGET) JukeboxMain.o JukeboxPlayer.o ...
который не работает, пока я не переместим $ (LIBS) в конец строки. Но я помню, что это работало для меня давным-давно. Может кто-то может ответить на то, что изменилось и почему он больше не работает) PS Я не большой поклонник игры с компиляторами, линкерами и другими инструментами - я предпочитаю больше всего создавать что-то;)
Я не могу ответить вам, почему вы думаете, что это могло бы сработать раньше. Но я могу сказать вам, почему это не работает вообще. Большинство компоновщиков в стиле POSIX, которые включают GNU binutils ld
использующие GNU/Linux и другие, являются однопроходными линкерами.
Это означает, что они ходят элементы, перечисленные в командной строке, от начала до конца один раз, и они не возвращаются. Когда компоновщик запускает его, в основном ищет один символ, main
. Когда он идет по командной строке, любой файл объекта (foo.o
), найденный компоновщиком, всегда добавляется к исполняемому файлу. Объект предоставляет список символов, которые определены, и список, который не определен (требуется от других объектов).
Когда компоновщик попадает в статическую библиотеку (libfoo.a
), он просматривает объектные файлы в этой библиотеке, и если объект содержит любой символ, который требуется компоновщику, он добавляет этот объект к исполняемому файлу. Если он не содержит никакого символа, который нужен компоновщику, он пропускает этот объект.
В конце командной строки, если какой-либо символ нужен, но не найден, ссылка не работает.
Таким образом, вы можете видеть, что для того, чтобы убедиться, что все найдено за один проход, вещи, которые НЕОБХОДИМЫЕ символы из библиотек должны поступать перед библиотеками, которые предоставляют эти символы, или когда компоновщик попадает в библиотеку за один проход, он выиграл Не знаю, нужны ли библиотеки и пропустит их.
-lpthread
- который необходим для большинства многопоточных приложений в системах Unix - следует этому же правилу. Однако -pthread
неоспоримым функционально эквивалентными , могут быть размещены в любом месте.
-lpthread
- это просто "найти библиотеку с именем pthread
", как и -lfoo
. Это не имеет особого значения. Но -pthread
- это магический флаг (не для компоновщика, а для драйвера компилятора), который говорит ему, что он должен делать все, что необходимо для обеспечения многопоточности. Это включает в себя добавление -lpthread
(в конце, как и должно быть), а также все, что необходимо во время компиляции (добавление -D_REENTRANT
или что-то еще). Поскольку разные системы используют разные опции, -pthread
был разработан, чтобы «заставить его работать» везде.