对头文件中已定义的函数的未定义引用

Undefined reference to function that is already defined in my header file

提问人:ThatPrimitive_Remastered 提问时间:9/13/2022 最后编辑:ThatPrimitive_Remastered 更新时间:9/13/2022 访问量:118

问:

我有三个文件,和 。我计划做的是添加在整个项目中使用的函数,然后我调用它来测试函数,然后在 中使函数。我遇到的问题是,即使我在posl.hstate.cmain.cposl.hmain.cstate.cundefined reference to init_poslState()posl.h

main.c

#include <posl.h>

int main(int argc, char * argv[]) {
    pState poslState = init_poslState();
    return 0;
}

posl.h

#ifndef POSL_LANGUAGE_H
#define POSL_LANGUAGE_H

#define POSL_MAJOR_VERSION 1
#define POSL_MINOR_VERSION 0
#define POSL_RELEASE_VERSION 0

// State
typedef struct POSL_STATE {
    // ...
} pState;
pState init_poslState();
void free_poslState(pState poslState);

#endif

状态.c

#include "state.h"
#include <posl.h>

pState init_poslState() {
    pState newState;
    return newState;
}

生成文件

CFLAGS=-g -Wall -Wextra -I./include
CC=gcc $(CFLAGS)
CORE_O_FILES=./src/Core/lexer.o ./src/Core/parser.o ./src/Core/state.o
CLI_O_FILES=
O_FILES=$(CORE_O_FILES)

# Making CLI Tool
posl: $(CLI_O_FILES) libposl.a ./src/CLI/main.c
    $(CC) -o posl -L./ -lposl ./src/CLI/main.c $(CLI_O_FILES)

# Making Library
libposl.a: $(O_FILES) ./include/posl.h
    ar rcs libposl.a $^


# Core Files
./src/Core/lexer.o: ./src/Core/lexer.c ./src/Core/lexer.h
    $(CC) -o $@ -c ./src/Core/lexer.c
./src/Core/parser.o: ./src/Core/parser.c ./src/Core/parser.h
    $(CC) -o $@ -c ./src/Core/parser.c
./src/Core/state.o: ./src/Core/state.c ./src/Core/state.h
    $(CC) -o $@ -c ./src/Core/state.c

# PHONY List

.PHONY: all
all:
    make update-libs
    make libposl.a
    make posl
    make pcc

# Post-Compile Clean
.PHONY: pcc
pcc:
    rm -rf ./src/Core/*.o
    rm -rf ./src/CLI/*.o

.PHONY: clean
clean:
    make pcc
    rm -rf ./libposl.a ./posl*
c makefile 未定义引用

评论

4赞 user17732522 9/13/2022
这是一个声明,但不是定义。您没有显示任何定义(即带有函数体的声明)。它在哪里?
0赞 ThatPrimitive_Remastered 9/13/2022
@user17732522不好,我把它加进了问题中
1赞 user17732522 9/13/2022
标志的顺序很重要。它们位于链接器调用中的源文件之后。-l

答:

0赞 ThatPrimitive_Remastered 9/13/2022 #1

好吧,@user17732522回答了我的问题。我把标志搞砸了,它不是在我的源文件之后。~谢谢大家!~-l

1赞 John Bollinger 9/13/2022 #2

编译器和(尤其是)链接器选项的顺序非常重要。有了这个命令......

    $(CC) -o posl -L./ -lposl ./src/CLI/main.c $(CLI_O_FILES)

...链接器不会尝试解析 libposl.a 中针对函数的任何函数引用。它只会查看在命令行上出现之后的对象和库。main.cmain.c

因此,将该配方重写为

     $(CC) -o posl -L. ./src/CLI/main.c $(CLI_O_FILES) -lposl