简体   繁体   English

为什么在 Windows 上使用 dirent.h 时出现类型不完整的错误?

[英]Why am I getting an incomplete type error when using dirent.h on Windows?

I have a C project that combines multiple.c and.h files.我有一个 C 项目,它结合了多个.c 和.h 文件。 Previously I just had all of these files in the top level directory, along with the following Makefile:以前我只是在顶级目录中拥有所有这些文件,以及以下 Makefile:

O = o
E =
CC = gcc
OUT = cusum$E
CFLAGS = -D_GNU_SOURCE -O3 -Wall -Wextra --static
DEPS = bessel.h detector.h io.h stepfit.h lmmin_int64.h utils.h
ODIR = obj
_OBJ = main.$O bessel.$O detector.$O io.$O lmmin_int64.$O stepfit.$O utils.$O
OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ))
LIBS = -lm

$(ODIR)/%.$O: %.c $(DEPS)
    $(CC) -c -o $@ $< $(CFLAGS) $(LIBS)

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

.PHONY: clean win

clean:
    rm -f $(OUT) $(ODIR)/*.$O *~ core $(INCDIR)/*~
    rm -f $(OUT).exe w$(ODIR)/*.obj *~ core $(INCDIR)/*~

win:
    $(MAKE) CC=x86_64-w64-mingw32-gcc E=.exe O=obj ODIR=wobj

This works fine as far as I can tell.据我所知,这很好用。

I then reorganized things, putting the .c files in a src folder and the .h files in a lib folder.然后我重新组织了一些东西,将.c文件放在src文件夹中,将.h文件放在lib文件夹中。 I changed the Makefile to the following:我将 Makefile 更改为以下内容:

O = o
E =
CC = gcc
OUT = dist/cusum$E
CFLAGS = -D_GNU_SOURCE -O3 -Wall -Wextra --static
INCDIR = lib/
DEPS = lib/*.h
ODIR = build/obj
_OBJ = main.$O bessel.$O detector.$O io.$O lmmin_int64.$O stepfit.$O utils.$O
OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ))
LIBS = -lm

$(ODIR)/%.$O: src/%.c $(DEPS)
    $(CC) -c -o $@ $< $(CFLAGS) -I$(INCDIR) $(LIBS)

$(OUT): $(OBJ)
    $(CC) -o $@ $^ $(CFLAGS) -I$(INCDIR) $(LIBS)

.PHONY: clean win cleanwin

clean:
    rm -f $(OUT) $(ODIR)/*.$(O) *~ core $(INCDIR)/*~

win:
    $(MAKE) CC=x86_64-w64-mingw32-gcc E=.exe O=obj ODIR=build/wobj
    
cleanwin:
    $(MAKE) clean CC=x86_64-w64-mingw32-gcc E=.exe O=obj ODIR=build/wobj

Now, when I compile for Linux ( make ), it works OK.现在,当我为 Linux ( make ) 编译时,它工作正常。 When I cross-compile for windows ( make win ), I get the following error:当我为 windows ( make win ) 进行交叉编译时,出现以下错误:

`make[1]: Entering directory '[...]'

x86_64-w64-mingw32-gcc -c -o build/wobj/main.obj src/main.c -D_GNU_SOURCE -O3 -Wall -Wextra --static -Ilib/ -lm

In file included from lib/io.h:31:0,
                 from src/main.c:21:

/usr/share/mingw-w64/include/dirent.h:41:21: error: field ‘dd_dta’ has incomplete type
  struct _finddata_t dd_dta;
                     ^~~~~~

/usr/share/mingw-w64/include/dirent.h:88:22: error: field ‘dd_dta’ has incomplete type
  struct _wfinddata_t dd_dta;

` `

main.c includes all the libraries via: main.c通过以下方式包含所有库:

#include"lib1.h"
#include"lib2.h"
....

and is located in the src folder并且位于src文件夹中

If I return the folder structure to what it was before and use the old Makefile, it works and tests fine, so I think the issue lies in the Makefile rather than the code itself.如果我将文件夹结构恢复到以前的状态并使用旧的 Makefile,它可以正常工作并测试,所以我认为问题在于 Makefile 而不是代码本身。 Can anyone point me in the right direction?谁能指出我正确的方向? If any information is missing, please let me know so I can fix it.如果缺少任何信息,请告诉我,以便我修复。

So it seems that the windows version of MinGW has some definition issues.所以看起来MinGW的windows版本有一些定义问题。 The following code added to my compiler's version of include/dirent.h fixed the problem for me.添加到我的编译器版本的include/dirent.h中的以下代码为我解决了这个问题。 Editing library functions is probably a bad idea generally, so only use this if you're feeling adventurous... I make no claims that this won't break all the things elsewhere.一般来说,编辑库函数可能不是一个好主意,所以只有在你喜欢冒险的时候才使用它……我不声称这不会破坏其他地方的所有东西。

#ifndef _FSIZE_T_DEFINED
typedef unsigned long   _fsize_t;
#define _FSIZE_T_DEFINED
#endif

struct _finddata_t
{
    unsigned    attrib;     /* Attributes, see constants above. */
    time_t      time_create;
    time_t      time_access;    /* always midnight local time */
    time_t      time_write;
    _fsize_t    size;
    char        name[FILENAME_MAX]; /* may include spaces. */
};

struct _wfinddata_t
{
    unsigned    attrib;     /* Attributes, see constants above. */
    time_t      time_create;
    time_t      time_access;    /* always midnight local time */
    time_t      time_write;
    size_t  size;
    wchar_t     name[FILENAME_MAX]; /* may include spaces. */
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM