【问题标题】:Can I regenerate a makefile for a C project, with correct link order and dependencies?我可以使用正确的链接顺序和依赖项为 C 项目重新生成生成文件吗?
【发布时间】:2013-01-31 10:27:22
【问题描述】:

我有我最后一次在 90 年代后期 - 2000 年工作的源代码,并且除了 makefile 之外,我已经将它全部备份了(是的,糟糕的备份几乎和没有备份一样好):所以......我是想知道是否有任何自动生成 makefile 的方法或快速分析依赖关系的好方法?

我正在寻找:

  • 一个可以为我分析依赖关系并更正链接顺序的工具。
  • 如果不存在这样的问题,那么非常感谢过去曾遇到过类似问题的人就如何最好地解决此问题提出建议
  • 如果上述两个选项都失败了,我认为最好的方法是创建一个分析/生成文件创建工具,它可以自动生成链接的依赖顺序(我推迟了这种方法,因为时间总是很短供应以挤入另一个项目)。

寻求帮助/建议的原因是代码库有 300,000 行代码(不包括 cmets)并且跨越数百个 C/O 文件,而且我经常尝试手动创建一个 make-file ,它令人沮丧和困惑,因此我最后一次尝试在这里寻求帮助和询问。

供参考: 我过去曾尝试过Cmake、AutoMake、GenMake 和类似的工具来生成makefile,但都无济于事,因为依赖是可怕的。


通用 makefile 脚本

因为它可能对其他人有用,这里是我通常用于不太复杂的 C 和 C++ 项目的 makefile,因为它让我不必担心每次都创建一个新的:

$(VERBOSE).SILENT:
PROGRAMNAME = prog
CC = gcc
CC += -c
CPP = g++
CPP += -c
ASM = nasm
ASM += -f elf -d ELF_TYPE
LD = g++
OBJFILES = $(patsubst %.c,%.o,$(wildcard *.c))
OBJFILES += $(patsubst %.s,%.o,$(wildcard *.s))
OBJFILES += $(patsubst %.cpp,%.o,$(wildcard *.cpp))

all: $(PROGRAMNAME)

clean:
    @echo "Cleaning object files"
    @echo "    rm -f     *.o"
    rm -f *.o
    @echo "Cleaning backups"
    @echo "    rm -f     *~"
    rm -f *~
    @echo "Removing program file"
    @echo "    rm -f     "$(PROGRAMNAME)
    rm -f $(PROGRAMNAME)

%.o: %.s
    @echo "Assembling ASMs "$@
    @echo "    ASM       "$<
    $(ASM) $<

%.o: %.c
    @echo "(C)ompiling "$@
    @echo "    CC        "$<
    $(CC) $<

%.o: %.cpp
    @echo "(C++)ompiling "$@
    @echo "    CPP       "$<
    $(CPP) $<

$(PROGRAMNAME): $(OBJFILES)
    @echo "Get ready...."
    @echo "Linking "$@
    @echo "    LD        -o "$(PROGRAMNAME)"        "$(OBJFILES)
    $(LD) -o $(PROGRAMNAME) $(OBJFILES)
    @echo "Cry if it worked! Scream swear and cry if it did not..."

strip: $(PROGRAMNAME)
    @echo "Stripping "$(PROGRAMNAME)
    echo -n "Size of "$(PROGRAMNAME)" before stripping is "
    ls -sh $(PROGRAMNAME) | cut -d' ' -f1
    @echo "    Stripping     "$(PROGRAMNAME)
    strip $(PROGRAMNAME)
    echo -n "Size of "$(PROGRAMNAME)" after stripping is "
    ls -sh $(PROGRAMNAME) | cut -d' ' -f1

nothing:
    @echo "Nothing to do; see you later - I'm going home!!!"
    @echo "Hey, try some of these:"
    @echo "make all   - this would be the one you want"
    @echo "make strip - does not work in the real world, only in computers"
    @echo "make clean - will help clean your mind up"

【问题讨论】:

  • 听起来你已经尝试了所有显而易见的工具;如果他们无法解决您的依赖关系,那么您可能需要做一些手动工作!
  • 伟大时代的四个伟大答案:大家欢呼。非常感谢!
  • 也许你应该从gcc-M 标志开始获取源依赖项,然后逐个目录查找应该在那里做什么(仅编译,从外部链接,创建一个库或可执行文件)。也许ldd 应用于可执行文件会告诉你一些事情。
  • Cheers Vonbrand: ldd 非常方便,我喜欢输出,非常适合在编译后跟踪我的代码 :) 使用仅 Windows 的编译器太久了,似乎忘记了我在遥控器上的 ssh 会话编码.

标签: c linux unix makefile


【解决方案1】:

您正在寻找来自 MIT 的经典 Unix 工具,makedepend

【讨论】:

  • 很棒的链接,我不敢相信我不知道这个工具,因为它几乎完全符合我的需要:)
【解决方案2】:

gcc & clang 可以生成依赖,见Advanced Auto-Dependency Generation,这不能解决整个问题,但会帮助你。

【讨论】:

    【解决方案3】:

    在 linux/unix 系统上:

    find . -name "*.c" -print &gt; sources 将为您提供所有来源的列表。

    find . -name "*.c" -print|sed s/\.c/\.o &gt; objects 应该给你一个列表,你可以在 [也许手动添加一些换行符] 前面加上 "OBJECTS="。

    cat sources|xargs gcc -M &gt; myprog.deps 应该给你一个头文件依赖列表,你可以在你的makefile 中include myprog.deps。 [1]

    现在你只需要 TARGET = myprog # 不管你怎么称呼你的程序!

    OBJECTS = ... # from "objects" file above. 
    SOURCES = ... # from "sources" file above
    
    INCLUDES = -I subdir1 -I subdir2 ...     # include directories used by this product
    
    CFLAGS = ... ${INCLUDES} # Some suitable settings
    CC = gcc
    LD = ${CC}
    LDFLAGS =  ...    # I don't know what this needs to be - usually nothing complicated.
    
    all: ${TARGET}
    
    clean:
        rm -f ${TARGET} ${OBJECTS}
    
    ${TARGET}: ${OBJECTS}
        ${LD} -o $@ ${OBJECTS}
    
    .c.o:
        ${CC} -o $@ $<
    

    这应该已经完成​​了大部分艰苦的工作,除非您必须构建内部工具,或者您的许多源文件当然不会实际生成最终的二进制文件 - 在后一种情况下,您可能必须搜索“ main" 并为每个可执行文件执行上述步骤 - 您仍然可以使用顶级 Makefile 并使用中间的 include

    [1] 您可以添加到 makefile - 特别是当您的项目生成许多不同的可执行文件时。

    myprog.deps: ${SOURCES}
        ${CC} -MM ${SOURCES} > myprog.deps
    
    include myprog.deps
    

    【讨论】:

    • 为解释清楚的 makefile 干杯:) 也给了我一些关于重组我自己的 makefile 的想法。
    【解决方案4】:

    感谢您的出色回复:简洁且信息丰富。根据答案,我现在正在使用手动和GNU AutoMake(makedepend 的现代继任者)的混合体来尝试重新编译,到目前为止似乎非常有效。

    接下来将是在 C++ 中移植到 OO 代码的乐趣和游戏......这是我很乐意避免但必须必须完成的任务。

    再次感谢!

    【讨论】:

      猜你喜欢
      • 2010-09-23
      • 1970-01-01
      • 2012-06-25
      • 2014-01-23
      • 1970-01-01
      • 2019-03-12
      • 2014-02-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多