c-在深度嵌套的源代码/makefile中正确地包含(POSIX)库



长话短说:我们有一个大型SDK,其中包含大约1Gb的毛茸茸的代码,这些代码被Elbonian代码奴隶们砍在一起,被RPC的颤动晶格绑在一起,共享内存,互斥/信号量,以及spit。它是在Linux机器上为嵌入式SoC目标编译的。

作为改进部分代码的尝试的一部分,我想将POSIXSemaphores添加到其中一个源代码中,其中包括一些RPC例程。

然而,只要写一些有效的代码&粘贴

#include <semaphore.h>

顶部当然不足以进行编译。

需要的是makefile中的特殊标志,这取决于你读到的内容,它可能是的任何一个/全部

-pthread
-lpthread
-lpthreads
-lrt
-rt

我没有太多编写Makefile的经验,不幸的是,由于代码库的大小,它们有多个嵌套级别(SDK中有2000多个Makefile),具有各种依赖关系,所有这些都是从根文件夹中的One True Makefile中生成的。

makefile中有很多宏化(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):

我似乎遇到了这个问题中提到的完全重复的场景。

然而,无论我把-lpthread-rrt参数放在哪里,我都会出错。

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

undefined reference to 'pthread_mutex_trylock'

即使调用pthread_mutex_lock的现有函数compile OK。

我不确定第一个问题的确切含义。我将尝试涵盖所有的可能性。

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

如果更改messaging.c,例如在顶部添加头文件,则系统尝试构建messaging.o

如果您想知道如何成功尝试,那么,您需要在INCLUDES变量中提供文件semaphore.h的正确位置。它是一个"系统"文件,位于"系统"中的一个包含目录中。

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

或者,使用EricMelski一直在谈论的电动加速器。这个神奇的软件,内置了免费的自动依赖生成功能。你什么都不用做。

此外,正如你已经知道的,你展示的Makefile写得非常糟糕,非常"天真"。听起来你有一个由几千个同样糟糕的Makefile组成的递归系统。是的,太可怕了。

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

所以,我认为你需要聘请一位专家顾问,为你的公司编写一个最先进的系统,也许可以使用ElectricAccelerator,或者简单的旧GNUMake。你明白提示了吗?嗯,如果Eric可以一直在这里插插头,并且他可以逃脱惩罚,那么我也可以:)

好吧,我终于构建了这个可恶的东西,不幸的是,更多的是通过暴力&无知胜过某种优雅的编程天才。

然而,如果它能帮助下一代,我遵循的路线是:

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

现在它似乎还可以运行,当然现在还有100个其他错误需要修复,但至少我最终还是编译了它。

护士,屏幕

最新更新