此问题在此处已有答案:
Why does the order in which libraries are linked sometimes cause errors in GCC?(10个答案)
13小时前关闭
我目前正在尝试Windows下的C编程。我有Windows 11,我在VS Code上编写代码,我已经安装了MinGW并将其正确添加到PATH中。问题是我无法将我的程序链接到libiphlapi
和ws2_32
库。
这是我的工作环境:
tree /F
D:.
│ Makefile
│
├───.vscode
│ settings.json
│
├───build
├───include
│ windows_backup_scheduler.h
│
├───obj
│ hwid.o
│ main.o
│
└───src
hwid.c
main.c
字符串
生成文件:
BUILD_DIR := build
INCLUDE_DIR := include
OBJ_DIR := obj
SRC_DIR := src
NAME := windows_backup_scheduler.exe
CC := gcc
CFLAGS := -m64 -fPIE -Wall -Wextra -Werror -pedantic -g3
LFLAGS := -I$(INCLUDE_DIR) -I"C:\MinGW\include" -L"C:\MinGW\x86_64-w64-mingw32\lib" -liphlpapi -lws2_32 -static-libgcc
SRC_FILES := $(wildcard $(SRC_DIR)/*.c)
OBJ_FILES := $(patsubst $(SRC_DIR)/%.c, $(OBJ_DIR)/%.o, $(SRC_FILES))
TARGET := $(BUILD_DIR)/$(NAME)
all: $(TARGET)
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c
$(CC) $(CFLAGS) $(LFLAGS) -c $< -o $@
$(TARGET): $(OBJ_FILES)
$(CC) $(CFLAGS) $(LFLAGS) -o $@ $^
clean:
@del /Q $(OBJ_DIR)\*.o
fclean: clean
@del /Q $(BUILD_DIR)\$(NAME)
re: fclean all
型
windows_backup_scheduler.h
#ifndef WINDOWS_BACKUP_SCHEDULER_H
#define WINDOWS_BACKUP_SCHEDULER_H
#ifndef NULL
#define NULL (void *)0;
#endif
#include <stdio.h>
#include <tchar.h>
#include <winsock2.h>
#include <iphlpapi.h>
#include <windows.h>
char *GetMACAddress(void);
#endif
型
main.c
#include <windows_backup_scheduler.h>
int main(void)
{
printf("MAC %s\n", GetMACAddress());
return (0);
}
型
hwid.c
#include <windows_backup_scheduler.h>
char *GetMACAddress(void)
{
IP_ADAPTER_INFO* AdapterInfo = NULL;
ULONG ulBufLen = 0;
DWORD dwStatus = 0;
char* macAddr = NULL;
if (GetAdaptersInfo(AdapterInfo, &ulBufLen) == ERROR_BUFFER_OVERFLOW) {
if ((AdapterInfo = malloc(ulBufLen)) == NULL) {
return (NULL);
}
}
if ((dwStatus = GetAdaptersInfo(AdapterInfo, &ulBufLen)) != ERROR_SUCCESS) {
free(AdapterInfo);
return (NULL);
}
if ((macAddr = (char*)malloc(18)) == NULL) {
free(AdapterInfo);
return (NULL);
}
snprintf(macAddr, 18, "%02X-%02X-%02X-%02X-%02X-%02X",
AdapterInfo[0].Address[0], AdapterInfo[0].Address[1],
AdapterInfo[0].Address[2], AdapterInfo[0].Address[3],
AdapterInfo[0].Address[4], AdapterInfo[0].Address[5]);
free(AdapterInfo);
return (macAddr);
}
型
当我尝试编译时,我得到了这个:
D:\WMP\Training\Windows_Backup_Scheduler>make re
Unable to find D:\WMP\Training\Windows_Backup_Scheduler\build\windows_backup_scheduler.exe
gcc -m64 -fPIE -Wall -Wextra -Werror -pedantic -g3 -Iinclude -I"C:\MinGW\include" -L"C:\MinGW\x86_64-w64-mingw32\lib" -liphlpapi -lws2_32 -static-libgcc -c src/hwid.c -o obj/hwid.o
gcc -m64 -fPIE -Wall -Wextra -Werror -pedantic -g3 -Iinclude -I"C:\MinGW\include" -L"C:\MinGW\x86_64-w64-mingw32\lib" -liphlpapi -lws2_32 -static-libgcc -c src/main.c -o obj/main.o
gcc -m64 -fPIE -Wall -Wextra -Werror -pedantic -g3 -Iinclude -I"C:\MinGW\include" -L"C:\MinGW\x86_64-w64-mingw32\lib" -liphlpapi -lws2_32 -static-libgcc -o build/windows_backup_scheduler.exe obj/hwid.o obj/main.o
c:/mingw/bin/../lib/gcc/x86_64-w64-mingw32/11.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: obj/hwid.o: in function `GetMACAddress':
D:\WMP\Training\Windows_Backup_Scheduler/src/hwid.c:10: undefined reference to `GetAdaptersInfo'
c:/mingw/bin/../lib/gcc/x86_64-w64-mingw32/11.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: D:\WMP\Training\Windows_Backup_Scheduler/src/hwid.c:15: undefined reference to `GetAdaptersInfo'
collect2.exe: error: ld returned 1 exit status
make: *** [Makefile:21: build/windows_backup_scheduler.exe] Error 1
型
VSCode找到了头文件,libiphlapi.a
和ws2_32.a
位于C:\MinGW\x86_64-w64-mingw32\lib
中,头文件位于C:\MinGW\include
中
你能给我一个解决方案吗?
1条答案
按热度按时间pgccezyw1#
你的变量没有被正确分离。
你需要把 compiler 的标志放在一组变量中,把 linker 的标志放在另一组变量中。例如:
字符串
这是错误的,因为
-I
是一个 compiler 选项,而-L
和-l
是 linker 选项。你不应该把它们放在同一个变量中,因为你不需要把编译器标志传递给链接器,你肯定不想把链接器标志传递给编译器。但是你看到的链接错误的主要直接问题是你必须把库(
-l....
)**在链接行中的目标文件之后。大多数链接器是“单通道”链接器,这意味着它们只链接在命令行上处理库时需要的符号,并且链接器在处理目标文件之前不会知道库需要什么符号。如果你想使用标准的make变量(如果你不想的话当然可以不使用),你应该使用:用途:
型
然后你会写:
型