Clang linker не распознает опцию -e, но GCC linker делает - PullRequest
0 голосов
/ 06 октября 2019

Я хотел бы использовать Makefile для генерации двоичного файла, который выполняет модульные тесты для меня. Он берет все объектные файлы моей программы, а также скомпилированный объект тестера и упаковывает все это вместе. Проблема в том, что я хочу использовать пользовательскую точку входа внутри файла тестера вместо main.

Так что нет проблем, ld поставляется с флагом -e, где я могу указать указанную точку входа. Итак, внутри моего Makefile я написал:

$(CC) $(ALL_CFLAGS) -Wl,-e$(TEST_ENTRY) $(OBJDIR)/$(TEST_SUITE:.c=.o) $(OBJECTS) -o $(BINDIR)/$(TARGET)-test

С учётом того, что я делаю все мои связи с функцией gcc, поэтому я должен передать свою команду компоновщику с помощью -Wl. Вот где начинается проблема:

Использование gcc в Debian, эта команда работает отлично, и моя программа работает должным образом.

Использование clang в MacOS, мне представлено следующееошибка во время компиляции:

ld: неизвестный параметр: -etester
clang: ошибка: сбой команды компоновщика с кодом выхода 1 (используйте -v для просмотра вызова)
make: *** [test] Ошибка 1

Makefile помещает точку входа (с именем tester) в аргумент без пробела. Насколько я знаю, это должно быть вполне приемлемо? В конце концов, gcc принимает его.

Если я добавлю пробел, он будет считать $(TEST_ENTRY) аргументом для компилятора. Я могу избежать этого с помощью кавычек. Поэтому я также попробовал следующее:

-Wl,"-e $(TEST_ENTRY)"

Однако я получаю ту же ошибку

ld: неизвестный параметр: -e тестер

Могу ли яспросите, знает ли кто-нибудь решение, которое позволит clang функционировать правильно, не саботируя тот факт, что он уже работает в gcc? Возможно, я что-то здесь упускаю.

Ответы [ 2 ]

1 голос
/ 08 октября 2019

Mangling имени функции

Похоже, это связано с искажением имени функции clang. Во избежание дублирования имен пользовательских функций с внутренними именами функций в libc или Sysmte.A, компилятор обрабатывает имена пользовательских функций. для языка c обычно в качестве префикса добавляется '_'.

например,

int test(..)

искажено до

_test в процедуре компиляции clang.

Проект тестирования:

#include "stdio.h"

int main(int argc, char const *argv[]) {
  printf("hello world\n");
  return 0;
}

int test(int argc, char const* argv[]){
  printf("hello test entry\n");
  return 0;
}

При компиляции с clang helloworld.c -o helloworld,
Результат выполнения:

╰─$ ./helloworld     
hello world

при компиляции с clang helloworld.c -o helloworld -e_test,
результат выполнения:

╰─$ ./helloworld     
hello test entry

см. https://en.wikipedia.org/wiki/Name_mangling для получения более подробной информации или ответа на вопрос.

0 голосов
/ 06 октября 2019

Справочная страница для lld (компоновщик LLVM) говорит, что флаг для указания точки входа - --entry. Поэтому в MacOS вам придется использовать аргумент типа -Wl,--entry=$(TEST_ENTRY).

...