简体   繁体   English

我可以为C项目重新生成一个makefile,具有正确的链接顺序和依赖关系吗?

[英]Can I regenerate a makefile for a C project, with correct link order and dependencies?

I have source code I last worked on in the late 90's-2000 and have it all backed up, apart from the makefile (yes berate away, bad backups are almost as good as no backups): so... I am wondering if there is any automated way to generate the makefile or a good way to analyse the dependencies quickly? 我有源代码我最后一次工作在90年代后期 - 2000并且全部备份,除了makefile(是的,谴责,坏备份几乎和没有备份一样好):所以......我想知道是否有是生成makefile的自动方式还是快速分析依赖关系的好方法?

Specifically I am looking for: 具体我正在寻找:

  • a tool which could analyse the dependencies and correct the link order for me. 一个可以分析依赖关系并为我纠正链接顺序的工具。
  • if such does not exist, then advice is greatly appreciated as to how to best approach this problem from someone who has had similar problem(s) in the past 如果不存在,那么建议非常感谢如何从过去遇到类似问题的人那里最好地解决这个问题
  • failing either of the above two options, I think the best approach is to create an analysis/make-file creation tool which can automatically generate the dependencies order for linking (I have held off on this approach as time is always in short supply to squeeze in another project). 如果上述两个选项中的任何一个失败,我认为最好的方法是创建一个分析/生成文件创建工具,它可以自动生成链接的依赖关系顺序(由于时间总是供不应求,我已经暂停了这种方法在另一个项目中)。

The reason for this quest for help/advice is that the code-base is 300,000 lines of code (excluding comments) and spans hundreds of C/O files, and as often as I have tried creating a make-file by hand, it frustrates and confounds, hence my last attempt to seek help and ask in here. 这个寻求帮助/建议的原因是代码库是300,000行代码(不包括注释)并且跨越数百个C / O文件,并且我经常尝试手工创建一个make文件,这令人沮丧并且混淆,因此我最后一次尝试寻求帮助并在这里提出要求。

For reference: I have tried Cmake , AutoMake, GenMake and similar tools in the past to generate the makefile, all to no avail, as the dependencies are horrendous. 供参考: 我过去曾尝试过Cmake ,AutoMake, GenMake和类似的工具来生成makefile,但都无济于事,因为依赖是可怕的。


Generic makefile script 通用makefile脚本

As it may be of use to others, here is the makefile I usually use for less convoluted C and C++ projects, as it saves me having to worry about creating a new one every time: 因为它可能对其他人有用,这里是我通常用于较少复杂的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&clang可以生成依赖关系,请参阅高级自动依赖关系生成 ,这不会解决整个问题但会对您有所帮助。

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

On a linux/unix system: 在linux / unix系统上:

find . -name "*.c" -print > sources find . -name "*.c" -print > sources will give you a list of all the sources. find . -name "*.c" -print > sources将为您提供所有源的列表。

find . -name "*.c" -print|sed s/\\.c/\\.o > objects find . -name "*.c" -print|sed s/\\.c/\\.o > objects should give you a list that you can stick "OBJECTS=" in front of [maybe manually add some linebreaks]. find . -name "*.c" -print|sed s/\\.c/\\.o > objects应该为您提供一个列表,您可以在[可能手动添加一些换行符]前面贴上“OBJECTS =”。

cat sources|xargs gcc -M > myprog.deps should give you a list of header dependencies that you can include myprog.deps in your makefile. cat sources|xargs gcc -M > myprog.deps应该为您提供一个头依赖项列表,您可以在makefile中include myprog.deps [1] [1]

Now all you need is TARGET = myprog # Whatever you call your program! 现在你所需要的只是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 $@ $<

That should have MOST of the hard work done, unless you have to build internal tools or your many source files don't actually produce one final binary of course - in the latter case, you'll probably have to search for "main" and go through the above steps for each executable - you can still use a top-level Makefile and use include of the intermediate ones. 除非你必须构建内部工具或者你的许多源文件实际上并没有产生最终的二进制文件,否则应该完成大部分的努力工作 - 在后一种情况下,你可能需要搜索“main”和经过对每个可执行上述步骤-你仍然可以使用一个顶级Makefile和使用include中间的人的。

[1] You could add to the makefile - particularly if your project produces many different executables. [1]您可以添加到makefile中 - 特别是如果您的项目生成许多不同的可执行文件。

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

include myprog.deps

Thanks for the great response: concise and very informational. 感谢您的回应:简洁而且非常有信息。 Based on the answers I am now using a mixture of manual effort and GNU AutoMake (the modern successor to makedepend) to try recompiling, and so far seems to be quite effective. 基于答案,我现在使用手动工作和GNU AutoMake (makedepend的现代继承者)的混合来尝试重新编译,到目前为止似乎非常有效。

Then shall come the fun and games of porting to OO code in C++...that's a task I would gladly avoid but needs must. 然后将来到C ++中移植到OO代码的乐趣和游戏......这是我很乐意避免但需要的任务。

Thanks again! 再次感谢!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM