2014-10-02 14 views
5

Per farla breve: abbiamo un grande SDK contenente ~ 1 Gb di codice peloso hackerato insieme dagli slave di codice Elbonian, annodato insieme da un reticolo tremolante di RPC, memoria condivisa , mutex/semafori e sputi. È compilato su una macchina Linux per un target SoC incorporato.Comprende correttamente le librerie POSIX in sorgenti/makefile profondamente annidati

Come parte di un tentativo di migliorare parte del codice, voglio aggiungere POSIX semafori a una delle fonti, che viene inclusa da alcune routine RPC.

Tuttavia, solo la scrittura di un codice valido & attaccare

#include <semaphore.h> 

al top è ovviamente insufficiente per permettere la compilazione.

Ciò che è necessario sono le bandiere speciali nel makefile, a seconda di ciò che si legge che potrebbe essere uno/tutti:

-pthread 
-lpthread 
-lpthreads 
-lrt 
-rt 

Non ho una grande esperienza di scrittura makefile, e purtroppo a causa di la dimensione del codebase contiene più livelli nidificati di essi (più di 2000 makefile nell'SDK) con tutti i tipi di dipendenze, tutti generati dallo One True Makefile nella cartella principale.

C'è molta macroification (TM) in corso nei makefile che non aiuta i miei sforzi per svelare il corretto incantesimo.

Come un assaggio della struttura del progetto e il file che sto cercando di modificare la struttura delle cartelle è qualcosa di simile:

/home/project/kernel/... Contains the Linux kernel & PSP/BSP 
/home/project/the_system/... Contains the software suite we're building 

e il file che stiamo cercando è in:

/home/project/the_system/core_app/interface/src/messaging.c 

che si è incluso con forse 5 altre fonti, come:

/home/project/the_system/core_app/interface/src/sys-control.c 
/home/project/the_system/core_app/interface/src/file-control.c 
/home/project/the_system/core_app/interface/src/audio-control.c 

... si ottiene il idea. Ognuno di questi può quindi essere incluso/chiamato da altri processi che desiderano comunicare tra loro. Ho detto che è tutto orribile?

ci sono makefile in quasi ogni cartella in quella catena, il makefile nella cartella locale

/home/project/the_system/core_app/interface/src/Makefile 

è qualcosa di simile (ho tolto un paio di bit per chiarezza, ignorare gli oggetti non referenziati):

INCLUDES += -I./ -I$(PUBLIC_INCLUDE_DIR) -I$(LINUXKERNEL_INSTALL_DIR)/include -I$(CMEM_INSTALL_DIR)/packages/ti/sdo/linuxutils/cmem/include -lpthreads 

    C_FLAGS += -Wall -g -O3 
    AR_FLAGS += -r 

    CC = $(MVTOOL_PREFIX)gcc $(INCLUDES) $(C_FLAGS) -c 
    AR = $(MVTOOL_PREFIX)ar 

    REL_EXE1 = reboot_me 

    REL_LIB1 = file-control.a 

    REL_LIB3 = share_mem.a 

    REL_LIB4 = sys-control.a 

    REL_LIB5 = msg_util.a 

    REL_LIB9 = messaging.a 

    REL_LIB10 = sysctrl.a 

    REL_LIB11 = audio-control.a 

    REL_OBJ1 = file-control.o share_mem.o msg_util.o 

    REL_OBJ3 = share_mem.o 

    REL_OBJ4 = sys-control.o share_mem.o msg_util.o 

    REL_OBJ5 = msg_util.o 

    REL_OBJ9 = messaging.o 

    REL_OBJ10 = sysctrl.o sys-control.o share_mem.o msg_util.o messaging.o audio-control.o 

    REL_OBJ11 = audio-control.o messaging.o share_mem.o msg_util.o 


    all: $(REL_EXE1) $(REL_LIB9) $(REL_LIB12) $(REL_LIB3) $(REL_LIB1) $(REL_LIB2) $(REL_LIB4) $(REL_LIB5) $(REL_LIB6) $(REL_LIB7) $(REL_LIB8) $(REL_LIB10) $(REL_LIB11) install 

    $(REL_LIB1): $(REL_OBJ1) 
     $(AR) $(AR_FLAGS) $(REL_LIB1) $(REL_OBJ1) 

    $(REL_LIB2): $(REL_OBJ2) 
     $(AR) $(AR_FLAGS) $(REL_LIB2) $(REL_OBJ2) 

    $(REL_LIB3): $(REL_OBJ3) 
     $(AR) $(AR_FLAGS) $(REL_LIB3) $(REL_OBJ3) 

    $(REL_LIB4): $(REL_OBJ4) 
     $(AR) $(AR_FLAGS) $(REL_LIB4) $(REL_OBJ4) 

    $(REL_LIB5): $(REL_OBJ5) 
     $(AR) $(AR_FLAGS) $(REL_LIB5) $(REL_OBJ5) 

    $(REL_LIB7): $(REL_OBJ7) 
     $(AR) $(AR_FLAGS) $(REL_LIB7) $(REL_OBJ7) 

    $(REL_LIB8): $(REL_OBJ8) 
     $(AR) $(AR_FLAGS) $(REL_LIB8) $(REL_OBJ8) 

    $(REL_LIB9): $(REL_OBJ9) 
     $(AR) $(AR_FLAGS) $(REL_LIB9) $(REL_OBJ9) 

    $(REL_LIB10): $(REL_OBJ10) 
     $(AR) $(AR_FLAGS) $(REL_LIB10) $(REL_OBJ10) 

    $(REL_LIB11): $(REL_OBJ11) 
     $(AR) $(AR_FLAGS) $(REL_LIB11) $(REL_OBJ11) 

    $(REL_LIB12): $(REL_OBJ12) 
     $(AR) $(AR_FLAGS) $(REL_LIB12) $(REL_OBJ12) 


    file-control.o : file-control.c $(PUBLIC_INCLUDE_DIR)/file-control.h $(PUBLIC_INCLUDE_DIR)/Msg_Def.h\ 
      $(PUBLIC_INCLUDE_DIR)/sys_env_type.h 
     $(CC) $(C_FLAGS) -o [email protected] $< 

    audio-control.o : audio-control.c $(PUBLIC_INCLUDE_DIR)/audio-control.h \ 
      $(PUBLIC_INCLUDE_DIR)/Msg_Def.h $(PUBLIC_INCLUDE_DIR)/sys_env_type.h 
     $(CC) $(C_FLAGS) -o [email protected] $< 

    share_mem.o: share_mem.c $(PUBLIC_INCLUDE_DIR)/share_mem.h 
     $(CC) $(C_FLAGS) -o [email protected] $< 

    sys-control.o : sys-control.c $(PUBLIC_INCLUDE_DIR)/sys-control.h $(PUBLIC_INCLUDE_DIR)/Msg_Def.h\ 
      $(PUBLIC_INCLUDE_DIR)/sys_env_type.h $(PUBLIC_INCLUDE_DIR)/share_mem.h 
     $(CC) $(C_FLAGS) -o [email protected] $< 

    msg_util.o: msg_util.c $(PUBLIC_INCLUDE_DIR)/Msg_Def.h 
     $(CC) $(C_FLAGS) -o [email protected] $< 

    messaging.o: messaging.c $(PUBLIC_INCLUDE_DIR)/messaging.h 
     $(CC) $(C_FLAGS) -o [email protected] $< 

    sysctrl.o: sysctrl.c $(PUBLIC_INCLUDE_DIR)/sysctrl.h $(PUBLIC_INCLUDE_DIR)/sys_env_type.h 
     $(CC) $(C_FLAGS) -o [email protected] $< 

    reboot_me: 
     $(MVTOOL_PREFIX)gcc -g -Wall -static -c -o reboot_me.o reboot_me.c 
     $(MVTOOL_PREFIX)gcc -o reboot_me reboot_me.o  

    clean: 
     -$(RM) -f *.o 
     -$(RM) -f *.a 
     -$(RM) -f $(REL_EXE1) 
     -$(RM) -Rf $(APP_LIB_DIR) 

    install: $(REL_EXE1) $(REL_LIB3) $(REL_LIB1) $(REL_LIB2) $(REL_LIB4) $(REL_LIB5) $(REL_LIB7) 
     install -d $(APP_LIB_DIR) 
     install $(REL_LIB1) $(APP_LIB_DIR) 
     install $(REL_LIB2) $(APP_LIB_DIR) 
     install $(REL_LIB3) $(APP_LIB_DIR) 
     install $(REL_LIB4) $(APP_LIB_DIR) 
     install $(REL_LIB5) $(APP_LIB_DIR) 
     install $(REL_LIB7) $(APP_LIB_DIR) 
     install $(REL_LIB8) $(APP_LIB_DIR) 
     install $(REL_LIB9) $(APP_LIB_DIR) 
     install $(REL_LIB10) $(APP_LIB_DIR) 
     install $(REL_LIB11) $(APP_LIB_DIR) 
     install $(REL_LIB12) $(APP_LIB_DIR) 
     install $(REL_EXE1) $(EXEC_DIR) 

Comunque, avendo aggiunto

#include <semaphore.h> 

in cima

/home/project/the_system/core_app/interface/src/messaging.c 

quello che devo fare per permettere a questa di compilare correttamente?


Come una domanda bonus, c'è un modo per determinare quale di:

-pthread 
-lpthread 
-lpthreads 
-lrt 
-rt 

è quello corretto per il nostro particolare ambiente di sviluppo?


Modifica per aggiungere (anche TL; DR):

mi sembra di essere incontrare un duplicato esatto dello scenario di cui al this question.

Tuttavia, non importa dove mi attengo le -lpthread e -lrt argomenti che ricevo errori.

Per esempio, ho provato ad aggiungere una chiamata a pthread_mutex_trylock, e non riesce a compilare:

undefined reference to 'pthread_mutex_trylock' 

... anche se esistenti le funzioni di chiamata pthread_mutex_lock compilare OK.

+0

"Che è incluso ..." Aspetta, cosa? Un file .c è stato incluso? –

+0

Il flag '-pthread' di solito implica il collegamento con la libreria' pthread'. Per quanto ne so, non esiste alcun flag '-rt', ma esiste una libreria' rt' che può essere collegata con. Se è necessario il collegamento con la libreria 'rt' (o la libreria' pthread' per quella materia) dovrebbe essere nelle pagine di manuale per le funzioni che si usano. Se non sei sicuro di una funzione e di quali librerie devi collegare (o dei file di intestazione da includere) *** consulta sempre la pagina di manuale delle funzioni. –

+0

@ IgnacioVazquez-Abrams - No, ../inc/messaging.h è stato incluso, senza dubbio messaging.o /.a ottiene anche una menzione nei makefile rilevanti. Stavo solo cercando di usare i tratti generici piuttosto che i dettagli totali. –

risposta

0

Beh, finalmente ho la cosa odiosa per costruire, purtroppo più attraverso la forza bruta & ignoranza di alcuni eleganti maestro del genio della codifica.

Tuttavia, dovrebbe aiutare alcuni generazione futura, il percorso che ho seguito è stato questo:

  • Aggiungi -lrt -lpthread-C_FLAGS nel mio esempio makefile, e poi ha cercato di make
  • Quando make fallito, guardare la posizione in cui non è riuscita, caricare il makefile da quel luogo e aggiungere -lrt -lpthread in modo simile in quel makefile.
  • Lather, risciacquo, ripetere fino a quando make ha esito positivo.

Ora sembra funzionare bene, naturalmente ci sono ora 100 altri bug da sistemare, ma almeno ho preso per compilare alla fine.

Infermiera, gli schermi!

0

Non sono sicuro di cosa intendi con la prima domanda. Cercherò di coprire tutte le possibilità.

La risposta alla seconda domanda è stata praticamente trattata da Joachim.

Il sistema sarà tentativo di costruire messaging.o se si cambia messaging.c, per esempio, se si aggiunge un file di intestazione verso l'alto.

Se si desidera sapere come eseguire il tentativo, è necessario fornire la posizione corretta del file semaphore.h nella variabile INCLUDES. È un file "di sistema", in una delle directory di "sistema" incluse.

Se si vuole garantire, che si ricostruisce messaging.o quando semaphore.h cambiato, si avrebbe bisogno di leggere la sezione sulla generazione avanzata di auto-dipendenza nel GNU Make manuale o sul sito di Scienziato pazzo http://mad-scientist.net/make/autodep.html

In alternativa, utilizzare l'ElectricAccelerator , EricMelski parla di tutto il tempo. Questo fantastico software ha una generazione di dipendenze automatica integrata gratuitamente. Non devi fare nulla.

Inoltre, come già sapete, il Makefile che state mostrando è scritto molto male, molto "naiivo". E sembra che tu abbia un sistema ricorsivo di diverse migliaia di Makefile ugualmente poveri. Sì, è terribile.

E sembra che tu personalmente non desideri correggere questo sistema di generazione in quanto tale, sei solo interessato ad aggiungere alcune funzionalità al software stesso.

Quindi, penso che sia necessario assumere un consulente esperto per scrivere alla vostra azienda un sistema all'avanguardia, magari usando ElectricAccelerator o semplicemente GNU Make. Hai il suggerimento?Ehm, se Eric può mettere tappi qui tutto il tempo e lui si allontana con esso, allora lo posso :)

+0

Personalmente mi piacerebbe ** l'amore ** per sistemare l'intero sistema, ma una riscrittura "one-man" di un SDK contenente milioni di righe di codice non è qualcosa che il cliente mi pagherà per passare i prossimi 10 anni a fare . –

+0

No Stavo solo parlando di riscrivere il sistema di compilazione, i Makefile. No, non sarebbero 10 anni. Tutti i progetti di costruzione richiedono 1/2 anno o meno, indipendentemente dalle dimensioni. Questa è la "legge di Mark" :) Sembra che tu sia un consulente tu stesso, che lavori per quella società cliente, ma non sei interessato a sistemare il sistema di build, vuoi semplicemente aggiungere funzionalità all'SDK stesso. –

+0

Mi accontenterò di ottenere una migliore comprensione del WTF e di come lo costruisco in modo affidabile. Se il nostro cliente potesse permettersi consulenti esperti superstar, non ci pagherebbe per fare il lavoro di 10 persone nella metà del tempo per 1/50 del denaro ... ovviamente questo significa che non possiamo permetterci consulenti esperti superstar - non fino a quando non facciamo funzionare questa roba e vendiamo almeno qualche migliaio di unità! –