C项目:使用共享源编译多个应用程序

时间:2012-06-19 20:34:28

标签: c makefile

我正在启动一个有多个应用程序的项目。这些应用程序在源文件方面共享一些常用功能。每个应用程序都应该有自己的make文件,但能够从公共位置链接这些共享源文件。

为了说明这一点,这是我的目录布局:

project/
    lib/
        shared1/
            shared1.c
            shared1.h
        shared2/
            shared2.c
            shared2.h
    app1/
        app1.c
        app1.h
        makefile
    app2/
        app2.c
        app2.h
        makefile

目前其中一个makefile看起来有点像这样:

CC=gcc
XXXCFLAGS=-Wall -Wextra -pedantic -I../../lib/shared1
CFLAGS=-I. $(XXXCFLAGS)
DEPS = app2.h ../../lib/shared1/shared1.h
OBJ = ${DEPS:.h=.o}
LIBS=-lpthread

%.o: %.c $(DEPS)
    $(CC) -c -o $@ $< $(CFLAGS)

app2: $(OBJ)
    $(CC) -o $@ $^ $(CFLAGS) $(LIBS)
  1. 这大致是管理共享源的正确方法,还是有更好的方法。它们应该是单独编译的库吗?如果是这样,怎么样?

  2. 这样的相对路径好吗?

  3. 我应该使用autotools这样的东西吗?查看示例后,我看不到如何链接共享代码或库。

  4. 非常感谢任何指导。

2 个答案:

答案 0 :(得分:2)

这是布置源树的合理方法,但您可以考虑分离源文件和头文件。如果要构建库(如果许多应用程序使用,例如shared1),则可以为其编写规则,并将规则放在shared1/中的makefile中。有几种方法可以使用这样的规则,但在您确定需要库之前不要担心。

道路是必要的邪恶。它们将makefile锁定到特定的目录布局,但你不能完全没有它们。你可以做的是让他们保持联系:

SHARED1LIB = ../../lib/shared1
XXXCFLAGS=-Wall -Wextra -pedantic -I$(SHARED1DIR)
DEPS = app2.h $(SHARED1DIR)/shared1.h

您对依赖项的使用有点奇怪。首先,最好从源列表中派生对象列表,因为您可能有没有标题的源或没有源的标题:

SRCS = app2.c $(SHARED1DIR)/shared1.c
OBJ = ${SRCS:.c=.o}

其次,你使每个对象文件都依赖于所有标题,这可能是过度的。假设我们可以假设foo.o取决于foo.happ2.o取决于shared1.h;那么我们可以写一个更好的规则:

%.o: %.c %.h
    $(CC) -c -o $@ $< $(CFLAGS)

app2.o: $(SHARED1DIR)/shared1.h

如果你有很多对象并且这种方法过于繁琐,那么有一种非常复杂的方法可以自动处理这些列表,但它是一种先进的技术,你可能最好不要尝试

最后,如果您发现所有应用程序makefile看起来都很相似,那么您可以将所有常见内容放入project/

中的makefile中。
SHARED1LIB = ../../lib/shared1
SHARED2LIB = ../../lib/shared2

CC=gcc
XXXCFLAGS=-Wall -Wextra -pedantic
CFLAGS=-I. $(XXXCFLAGS)
OBJ = ${SRCS:.c=.o}
LIBS=-lpthread

%.o: %.c %.h
    $(CC) -c -o $@ $< $(CFLAGS)

app%: $(OBJ)
    $(CC) -o $@ $^ $(CFLAGS) $(LIBS)

然后app makefile就像这样:

SRCS = app2.c $(SHARED1DIR)/shared1.c

app2:
include ../Makefile

XXXCFLAGS += -I$(SHARED1DIR)

app2.o: $(SHARED1DIR)/shared1.h

答案 1 :(得分:1)

相对路径在项目中完全没问题...共享代码的一种更简单的方法就是将标题和库导出到一个公共位置,然后将驱动程序与它们链接起来。

这种方法在我的很多个人项目中使用,有时我使用CMake,然后将所有应用程序目标链接到我自己的库。