在C中编译多个文件

时间:2013-09-15 17:36:24

标签: c gcc compilation makefile

我最近问过this question有关在C中编译多个文件的问题,以便文件main.c可以引用文件modules.c。答案最终是将模块文件放入头文件并主要导入它。

我现在被告知这是一种不正确的方法,因为C支持模块化编译。我的Makefile在下面,这应该是正确的,但我在main.c - warning: implicit declaration of function X中的每个函数调用都会收到错误。

使用两个.c文件而不是.c.h文件,我需要做什么才能正确编译? main.c文件具有main()函数,需要能够调用modules.c中的函数。

生成文件:

#################################################################
# Variables
# -- allows C-source and assembly-source files mix. Again, the
# -- indented lines start with a TAB(^I) and not spaces..
#################################################################

CFLAGS  = -g -Wall -Werror
LDFLAGS =
CC      = gcc
LD      = gcc

TARG    = driver
OBJS    = modules.o main.o

#################################################################
# Rules for make
#################################################################

$(TARG): $(OBJS)
        $(LD) $(LDFLAGS) $(OBJS) -o $(TARG)

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

clean:
        rm -f *.o *˜ $(TARG)

print:
        pr -l60 Makefile modules.c main.c | lpr

#################################################################
# Dependencies -- none in this program
#################################################################

3 个答案:

答案 0 :(得分:2)

您已经获得了有关使用GCC和Makefile的反馈,并且已经注意到完成任务的典型方法是两个.c文件和一个.h文件。但是如果使用函数声明(可以说更简单,更难维护和有用),则不需要.h文件,如下面的示例所示。

main.c中:

void moduleFunc1(int); // extern keyword required for vars, not for functions

int main()
{
    moduleFunc1(100);

    return 0;
}

的module.c:

#include <stdio.h>

void moduleFunc1(int value)
{
    printf("%d\n", value);
}

编译:

gcc main.c module.c

编辑:在查看了您链接的作业后,我最好的猜测实际上仍然是您正在寻找的功能声明。引用作业,在“其他”下,#7:

A function should be declared in the module/function where
it is called and not in global scope. Say A calls B and C does
not call it then B should be declared in A only.

在我的示例中,函数声明位于调用它的模块中,似乎符合A-B-C示例。 (令人困惑的部分是全局范围注释,但我不会说函数声明的范围是全局的。例如,如果你将声明移到main()下面,它就会让事情变得混乱。我还没有发现一些东西。尽管如此,对这一点具有严格的权威性。)

答案 1 :(得分:0)

您可以通过几种方式执行此操作,但无论您选择哪种方式,如果main.c从module.c调用函数,那么main.c必须#include一个标头,用于声明这些函数的原型。

第一种也是最简单的方法就是这样做:

gcc -Wall -g main.c module.c -o myprogram

第二种更华丽的方法是首先将module.c构建为目标文件。这种方法的主要目的是在开发/调试/编译具有多个部分的大型程序时节省时间 - 而不必重新编译整个程序,您只需重新编译已更改的部分即可。它还允许您轻松混合和匹配部件。这对makefile来说最简单:

myprogram: main.c module.o
    CC $(CFLAGS) main.c module.o -o myprogram

module.o:
    CC $(CFLAGS) -c module.c

请注意,makefile中的“myprogram”目标与(prereq)模块一起使用。 o ,而普通gcc方法适用于模块。 c


如果根据你的任务,你不能使用标题或全局声明,你可以在函数内声明原型:

void somefunc () {
    char *whatever (int x);  // prototype
    printf("%s\n", whatever(12));
}  

很好,假定whatever()在某处定义,在编译和运行它时会起作用。

答案 2 :(得分:0)

阅读完作业后,你的导师可能会有以下意思吗?

main.c中:

#include <stdio.h>

int main() {
  int plus(int a, int b); /* declaration */

  printf("%d ", plus(4, 5));

  exit(0);
}

的module.c:

int plus(int a, int b) {
  return a + b;
}

gcc -Wall -Wextra main.c module.c

但事实上,plus()在全局命名空间中可用。所以我有点失落。

暂且不说:

3. int next = 234;
   printf("%6d ", next);
   will print value of next, right justified in 6 columns

6. Use separate statements for declaration and initialization
   of a variable as:
   int xval;
   xval = 100;

按照我的说法,不要像我一样!