代码之家  ›  专栏  ›  技术社区  ›  MounirReg

gcc不解析外部全局变量,有或没有-c选项

  •  1
  • MounirReg  · 技术社区  · 15 年前

    所以我有一个问题:我在C程序中声明一些外部全局变量。 如果我不使用gcc的-c选项,我会得到未定义的引用错误。但是使用这个-c选项,链接没有完成,这意味着我没有生成可执行文件。

    那么我该如何解决这个问题呢?

    这是我的档案(感谢亚历克斯写的)

    CC = gcc                      # compiler/linker frontend
    INCL = -I$(INCL_DIR)          # includes
    DEFS = -D_DEBUG_              # defines
    CFLAGS = -g $(INCL) $(DEFS)   # compiler flags
    LFLAGS = -lpthread -lm -g     # linker flags
    
    OBJ = approx.o producteur.o sequentialApproximation.o main.o
    BIN = calculPi.exe
    LINKOBJ  = approx.o producteur.o sequentialApproximation.o main.o
    RM = rm -fv
    
    all: $(BIN)
    
    clean:
     ${RM} *\~ \#*\# $(OBJ)
    
    clean_all: clean
     ${RM} $(BIN)
    
    cleanall: clean
     ${RM} $(BIN)
    
    $(BIN): $(OBJ)
     $(CC) $(LFLAGS) -o $@ $^
    
    main.o: main.c
    approx.o: approx.c approx.h
    producteur.o: producteur.c producteur.h
    sequentialApproximation.o : sequentialApproximation.c sequentialApproximation.h
    
    .c.o:
     $(CC) $(CFLAGS) -c $<
    

    下面是make的输出: http://pastebin.com/NzsFetrn

    我确实在大约h(extern和global)中声明了extern变量,并尝试用大约c来调用它们,但在那里它不起作用。

    1 回复  |  直到 15 年前
        1
  •  3
  •   Alex Budovski    15 年前

    解决方案1

    你不能通过 -c 在链接阶段,这将告诉编译器跳过链接。

    你的问题是

    $(BIN): $(OBJ)
        $(CXX) $(LINKOBJ) -o "calculPi.exe"
    

    具有

    CXX_FLAGS =-g -c -lpthread -lm
    

    哪里 $(CXX) 扩展到 gcc -g -c -lpthread -lm ...

    摆脱 -C 那里。

    只有在从源模块编译到对象模块时才传递-c。

    解决方案2

    第二个问题是,实际上您没有在任何地方定义变量。在你 .c 文件需要行:

    Coord* production;
    int indice_prod;
    int indice_cons;
    

    (假设您真的想要全局变量)。这将修复未解决的外部错误。 你不能给他们写信,除非他们被分配了!

    笔记

    还要注意,您可以在一个规则中指定如何从源代码生成对象文件:

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

    并指定没有规则的依赖项:

    main.o: main.c
    approx.o: approx.c approx.h
    producteur.o: producteur.c producteur.h
    sequentialApproximation.o : sequentialApproximation.c sequentialApproximation.h
    

    等。

    其他注释。

    而且,作为一般经验法则, CXX 只应包含编译器名称,不应包含标志。那些应该进去 CXX_FLAGS . 你为什么叫它 CXX CC ?使用 g++ 如果你想要一个C++编译器,或者使用 科科斯群岛 . 既然你有 C 文件,我假设是C。所以在您的情况下,您应该更改:

    CXX_FLAGS =-g -c -lpthread -lm
    CXX = gcc $(CXX_FLAGS) $(INCL) $(DEFS)
    

    CC = gcc
    CFLAGS = -g -lpthread -lm $(INCL) $(DEFS)  # also removed -c
    

    你不需要单独的 LINK_CXX .

    样本生成文件

    因此,最小生成文件应该如下所示:

    # Makefile
    CC = gcc                      # compiler/linker frontend
    INCL = -I$(INCL_DIR)          # includes
    DEFS = -D_DEBUG_              # defines
    CFLAGS = -g $(INCL) $(DEFS)   # compiler flags
    LFLAGS = -lpthread -lm -g     # linker flags
    
    OBJ = approx.o producteur.o sequentialApproximation.o main.o
    BIN = calculPi.exe
    
    all: $(BIN)
    
    $(BIN): $(OBJ)
        $(CC) $(LFLAGS) -o$@ $^
    
    main.o: main.c
    approx.o: approx.c approx.h
    producteur.o: producteur.c producteur.h
    sequentialApproximation.o : sequentialApproximation.c sequentialApproximation.h
    
    .c.o:
        $(CC) $(CFLAGS) -c $<
    
    # clean and other stuff.