Makefile: como alterar uma regra específica

0

esta é a minha primeira pergunta aqui, espero fazer tudo da maneira certa.

Sou um usuário Ubuntu bastante novo e, se possível, preciso de ajuda com um Makefile específico. Eu baixei o QEMU 2.1.0 e atualmente estou alterando alguns arquivos de código-fonte para uma versão personalizada. Em particular, eu tenho um arquivo sd.c como o seguinte:

[...]
#include "hw/mydistribution.h"
[...]
Nac = poisson_distribution(Nac_mean);

e um arquivo mydistribution.h onde por exemplo eu defino o poisson_distribution () usando funções da biblioteca 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;
}

Agora, sei que se eu tivesse todas as partes mencionadas no mesmo arquivo [por exemplo, myfile.c] Eu poderia compilar a partir do terminal usando:

gcc myfile.c -o myfile -lgsl -lgslcblas -lm

e funciona porque eu tentei. Mas como perguntar ao QEMU Makefile para fazer isso? honestamente este Makefile parece muito complexo para o meu nível de entrada. Eu googled informações sobre makefiles e depois de ler eu pensei em encontrar no Makefile QEMU algo como:

LDLIBS := -lgsl -lgslcblas -lm
[...]
$(CC) -o $@ $^ $(LDLIBS)

mas procurando a implementação real do Makefile do QEMU eu encontrei o arquivo rules.mak onde:

%.o: %.c
    $(call quiet-command,$(CC) $(QEMU_INCLUDES) $(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) $($@-cflags) -c -o $@ $<,"  CC    $(TARGET_DIR)$@")

Talvez esta seja a linha a ser ajustada. A questão é: como ajustar? Eu tentei editar esta linha como:

%.o: %.c
    $(call quiet-command,$(CC) $(QEMU_INCLUDES) $(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) $($@-cflags) -c -o $@ $< -lgsl -lgslcblas -lm,"  CC    $(TARGET_DIR)$@")

mas não funcionou e recebi os seguintes erros

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

E, afinal, acho que não seria uma solução perfeita, já que os outros arquivos não precisam da biblioteca GSL e não há necessidade de aplicar -lgsl -lgslcblas -lm em todos os arquivos .c. Eu gostaria de criar um novo Makefile onde todos os outros arquivos continuam a ser compilados como o Makefile original, mas quando se trata de sd.c eu gostaria que ele fosse compilado como dito antes, a fim de evitar referências indefinidas

Agradecemos antecipadamente às pessoas que me fornecerão sugestões precisas para me ajudar a corrigir esse problema

    
por Antonino 29.09.2014 / 23:49

2 respostas

0

Acho que depois de dias de dúvidas, pesquisas, manuais e assim por diante eu finalmente resolvi meu problema e quero compartilhar meus esforços com você

Após o comentário da Steeldriver, comecei a observar mais de perto a fase de vinculação. A solução que encontrei foi adicionar as seguintes linhas para configurar o arquivo antes da seção analógica do 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

o propósito de gsl_ran_weibull_pdf (11, 10, 5) é verificar a presença de libgsl0-dev. Se tivermos do que quando encontrarmos -lgsl-lgslcblas, podemos interpretá-los corretamente, senão o usuário será informado sobre a ausência dessa biblioteca

Agora, quando digito:     ubuntu @ ubuntu: ~ / Desktop / qemu-2.1.0 $ make

não há mais referências indefinidas:

  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

Tenho certeza de que essa solução pode ser mais aprimorada e estou aberto a novas sugestões, se houver. Mas eu admito já estar extremamente feliz em encontrar esse resultado

Agradecimentos especiais a @muru e @steeldriver pelo apoio

    
por Antonino 02.10.2014 / 03:25
0

Acima desta linha curinga:

%.o: %.c

adicione uma regra específica para o arquivo específico:

myfile.o: myfile.c
    gcc -c -o $@ $< -lgsl -lgslcblas -lm
    
por muru 29.09.2014 / 23:58