I have a C project that combines multiple .c and .h files. Previously I just had all of these files in the top level directory, along with the following 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. I changed the Makefile to the following:
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. When I cross-compile for windows (make win
), I get the following error:
`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:
#include"lib1.h"
#include"lib2.h"
....
and is located in the src
folder
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. Can anyone point me in the right direction? If any information is missing, please let me know so I can fix it.
The reason in file io.h. When you moved io.h to subdirectory, dirent.h wants to include your file instead of system one.
#include <io.h>
To resolve this situation, just rename your io.h.