Makefile: как изменить конкретное правило
Это мой первый вопрос здесь, я надеюсь сделать все правильно.
Я совершенно новый пользователь Ubuntu и, если возможно, мне нужна помощь с конкретным Makefile. Я скачал QEMU 2.1.0 и в настоящее время я изменяю некоторые файлы исходного кода для пользовательской версии. В частности, у меня есть файл sd.c, подобный следующему:
[...]
#include "hw/mydistribution.h"
[...]
Nac = poisson_distribution(Nac_mean);
и файл mydistribution.h, где, например, я определяю poisson_distribution() с использованием функций из библиотеки GSL:
#include <math.h>
#include <gsl/gsl_rng.h>
#include <gsl/gsl_randist.h>
[...]
unsigned int poisson_distribution(double expected_value) {
const gsl_rng_type * T;
gsl_rng * r;
unsigned int k;
gsl_rng_env_setup();
T = gsl_rng_default;
r = gsl_rng_alloc (T);
k = gsl_ran_poisson (r, expected_value);
gsl_rng_free (r);
return k;
}
Теперь я знаю, что если бы у меня были все вышеупомянутые части в одном файле [например, myfile.c], я мог бы скомпилировать из терминала, используя:
gcc myfile.c -o myfile -lgsl -lgslcblas -lm
и это работает, потому что я пытался. Но как попросить QEMU Makefile сделать это? честно говоря, этот Makefile кажется слишком сложным для моего начального уровня. Я погуглил информацию о make-файлах и после прочтения подумал найти в QEMU Makefile что-то вроде:
LDLIBS := -lgsl -lgslcblas -lm
[...]
$(CC) -o $@ $^ $(LDLIBS)
но в поисках реальной реализации Makefile QEMU я нашел файл rules.mak, где:
%.o: %.c
$(call quiet-command,$(CC) $(QEMU_INCLUDES) $(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) $($@-cflags) -c -o $@ $<," CC $(TARGET_DIR)$@")
Может быть, это линия для настройки. Вопрос: как настроить? Я пытался редактировать эту строку как:
%.o: %.c
$(call quiet-command,$(CC) $(QEMU_INCLUDES) $(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) $($@-cflags) -c -o $@ $< -lgsl -lgslcblas -lm," CC $(TARGET_DIR)$@")
но это не сработало, и я получил следующие ошибки
ubuntu@ubuntu:~/Desktop/qemu-2.1.0$ make
GEN config-host.h
GEN trace/generated-tracers.h
GEN trace/generated-tracers.c
GEN arm-softmmu/config-target.h
LINK arm-softmmu/qemu-system-arm
../hw/sd/sd.o: In function `poisson_distribution':
/home/ubuntu/Desktop/qemu-2.1.0/include/hw/mycard.h:1630: undefined reference to `gsl_rng_env_setup'
/home/ubuntu/Desktop/qemu-2.1.0/include/hw/mycard.h:1632: undefined reference to `gsl_rng_default'
/home/ubuntu/Desktop/qemu-2.1.0/include/hw/mycard.h:1633: undefined reference to `gsl_rng_alloc'
/home/ubuntu/Desktop/qemu-2.1.0/include/hw/mycard.h:1641: undefined reference to `gsl_ran_poisson'
/home/ubuntu/Desktop/qemu-2.1.0/include/hw/mycard.h:1646: undefined reference to `gsl_rng_free'
../hw/sd/sd.o: In function `weibull_distribution':
/home/ubuntu/Desktop/qemu-2.1.0/include/hw/mycard.h:1676: undefined reference to `gsl_rng_env_setup'
/home/ubuntu/Desktop/qemu-2.1.0/include/hw/mycard.h:1678: undefined reference to `gsl_rng_default'
/home/ubuntu/Desktop/qemu-2.1.0/include/hw/mycard.h:1679: undefined reference to `gsl_rng_alloc'
/home/ubuntu/Desktop/qemu-2.1.0/include/hw/mycard.h:1687: undefined reference to `gsl_ran_weibull'
/home/ubuntu/Desktop/qemu-2.1.0/include/hw/mycard.h:1692: undefined reference to `gsl_rng_free'
collect2: error: ld returned 1 exit status
make[1]: *** [qemu-system-arm] Error 1
make: *** [subdir-arm-softmmu] Error 2
В конце концов, я думаю, что это не было бы идеальным решением, поскольку другим файлам не нужна библиотека GSL, и нет необходимости применять -lgsl -lgslcblas -lm к каждому.c-файлу. Я хотел бы создать новый Makefile, в котором все остальные файлы продолжают компилироваться, как и оригинальный Makefile, но когда дело доходит до sd.c, я хотел бы, чтобы он был скомпилирован, как сказано ранее, чтобы избежать неопределенных ссылок
Заранее благодарим тех, кто даст мне точные предложения, чтобы помочь мне решить эту проблему
2 ответа
Я думаю, что после нескольких дней сомнений, исследований, руководств и так далее, я наконец решил свою проблему, и я хочу поделиться своими усилиями с вами
После комментария стали, я стал более внимательно следить за фазой связывания. Решением, которое я нашел, было добавление следующих строк для настройки файла непосредственно перед разделом аналогового librt:
##########################################
# Do we need libgsl0-dev
cat > $TMPC << EOF
#include <gsl/gsl_rng.h>
#include <gsl/gsl_randist.h>
int main(void) { return (int) gsl_ran_weibull_pdf (11, 10, 5); }
EOF
if compile_prog "" "" ; then
:
elif compile_prog "" "-lgsl -lgslcblas" ; then
LIBS="-lgsl -lgslcblas $LIBS"
libs_qga="-lgsl -lgslcblas $libs_qga"
else
error_exit "libgsl0-dev check failed"
fi
Целью gsl_ran_weibull_pdf (11, 10, 5) является проверка наличия libgsl0-dev. Если он у нас есть, то когда мы найдем -lgsl -lgslcblas, мы сможем правильно их интерпретировать, иначе пользователь будет проинформирован об отсутствии этой библиотеки.
Теперь, когда я печатаю: ubuntu@ubuntu:~/Desktop/qemu-2.1.0$ make
больше нет неопределенных ссылок:
GEN config-host.h
GEN trace/generated-tracers.h
GEN trace/generated-tracers.c
CC hw/sd/sd.o
GEN arm-softmmu/config-target.h
LINK arm-softmmu/qemu-system-arm
GEN arm-linux-user/config-target.h
Я уверен, что это решение может быть доработано, и я открыт для новых предложений, если таковые имеются. Но я признаю, что уже очень счастлив найти этот результат
Отдельное спасибо @muru и @steeldriver за поддержку
Над этой подстановочной строкой:
%.o: %.c
добавьте конкретное правило для конкретного файла:
myfile.o: myfile.c
gcc -c -o $@ $< -lgsl -lgslcblas -lm