在深度嵌套的源/ makefile中正确包含(POSIX)库

时间:2014-10-02 16:25:28

标签: c linux gcc makefile include

长话短说:我们有一个大型的SDK,其中包含由Elbonian Code Slaves共同攻击的~1Gb毛茸茸的代码,由一个颤抖的RPC格子,共享内存,互斥/信号量和吐痰捆绑在一起。它是在Linux机器上编译的,用于嵌入式SoC目标。

作为改进部分代码的一部分,我想将POSIX信号量添加到其中一个源中,这些源包含在一些RPC例程中。

但是,只需编写一些有效的代码&粘

#include <semaphore.h>
顶部的

当然不足以启用编译。

makefile中需要的是特殊标志,具体取决于您所读取的内容,可能是以下任何一个:

-pthread
-lpthread
-lpthreads
-lrt
-rt

我没有很多编写makefile的经验,不幸的是由于代码库的大小,它们有多个嵌套级别(SDK中超过2,000个makefile),并且具有各种依赖关系,所有这些都依赖于根文件夹中的 One True Makefile

makefile中有很多macroification(TM)正在进行,这无助于我解开正确的咒语。

作为项目结构和我试图修改的文件的一瞥,文件夹结构如下:

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

我们正在查看的文件位于:

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

其中包括5个其他来源,包括:

/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

...你明白了。其中每一个都可以被其他希望相互沟通的进程包含/调用我是否提到过这一切可怕?

该链中的每个文件夹中都有makefile,本地文件夹中的makefile

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

是这样的(为清楚起见,删除了一些位,忽略了未引用的对象):

    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 $@ $<

    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 $@ $<

    share_mem.o: share_mem.c $(PUBLIC_INCLUDE_DIR)/share_mem.h
        $(CC) $(C_FLAGS) -o $@ $<

    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 $@ $<

    msg_util.o: msg_util.c $(PUBLIC_INCLUDE_DIR)/Msg_Def.h
        $(CC) $(C_FLAGS) -o $@ $<

    messaging.o: messaging.c $(PUBLIC_INCLUDE_DIR)/messaging.h
        $(CC) $(C_FLAGS) -o $@ $<

    sysctrl.o: sysctrl.c $(PUBLIC_INCLUDE_DIR)/sysctrl.h $(PUBLIC_INCLUDE_DIR)/sys_env_type.h
        $(CC) $(C_FLAGS) -o $@ $<

    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)

无论如何,已添加

#include <semaphore.h>

的顶部
/home/project/the_system/core_app/interface/src/messaging.c

我需要做些什么才能正确编译?


作为奖励问题,有没有办法确定哪一个:

-pthread
-lpthread
-lpthreads
-lrt
-rt

我们特定的构建环境是正确的吗?


编辑添加(也是TL; DR):

我似乎遇到了this question中提到的情景的完全重复。

但是,无论我在哪里粘贴 -lpthread -lrt 参数,都会出错。

例如,我尝试添加对pthread_mutex_trylock的调用,但无法编译:

undefined reference to 'pthread_mutex_trylock'

...即使现有的函数调用pthread_mutex_lock编译好了。

2 个答案:

答案 0 :(得分:0)

我不确定第一个问题到底是什么意思。我将尝试涵盖所有可能性。

第二个问题的答案几乎被约阿希姆所覆盖。

如果您更改messaging.o,系统尝试构建messaging.c,例如,如果您将头文件添加到顶部。

如果您想知道如何成功完成该尝试,那么您需要在semaphore.h变量中提供文件INCLUDES的正确位置。这是一个&#34;系统&#34;文件,在&#34;系统&#34;之一包含目录。

如果您想确保在messaging.o更改时重建semaphore.h,则需要阅读GNU Make Manual或MadScientist上的高级自动依赖生成部分。网站http://mad-scientist.net/make/autodep.html

或者,使用EricMelski一直在谈论的ElectricAccelerator。这个梦幻般的软件,免费内置自动依赖生成。你不必做任何事情。

另外,正如您已经知道的那样,您正在显示的Makefile编写得很糟糕,非常&#34; naiive&#34;。听起来你有一个由几千个同样可怜的Makefile组成的递归系统。是的,太可怕了。

听起来你个人不想修复这个构建系统,你只想为软件本身添加一些功能。

所以,我认为您需要聘请一位专家顾问,为您的公司编写一个最先进的系统,可能使用ElectricAccelerator或普通的旧GNU Make。你有提示吗?嗯,如果埃里克可以随时把插头放在这里,他就可以使用它,那么我也可以:)

答案 1 :(得分:0)

好吧,我终于得到了可恨的东西来构建,不幸的是更多的是通过蛮力和&amp;无知而不是一些优雅的编码天才大师。

然而,如果它有助于下一代,我遵循的路线就是:

  • 在我的示例makefile中将-lrt -lpthread添加到C_FLAGS,然后尝试make
  • make失败时,查看失败的位置,从该位置加载makefile并在该makefile中以类似的方式添加-lrt -lpthread
  • 泡沫,冲洗,重复直到make成功。

它现在似乎工作正常,当然现在还有100个其他错误需要修复,但至少我最终还是要编译它。

护士,屏幕!