Makefile dependencies and Timestamps - c

I have a makefile that I am using to generate artifacts using a third party IDL compiler (rtiddsgen). This takes in idl files and spits out C/Ada files relating to them. The C files are then compiled and put into a library (idl_dds_types.a)
I have the IDL files listed in the IDL_TYPES variable. Each IDL_TYPES file will generate (through rtiddsgen) files of the following form (For example with alerts.idl):
alerts.c
alerts.h
alerts_idl.ads
alerts_idl.adb
So, what I want to happen is when alerts.idl's timestamp is newer than the alerts.c (or the obj.Linux-i686/alerts.o) file, then the alerts.c file is regenerated. This doesn't seem to be happening. Any ideas what I need to do to make this happen? I've tested by "touch"-ing the idl file and then re-running make.
Here is the makefile:
DDS_OUT_DIR = $(MY_HOME)/DDS/DDS_Types/src
IDL_DIR=$(MY_HOME)/DDS/DDS_Types/IDL
IDL_TYPES=common.idl alerts.idl summary.idl
GENERATED_SOURCES = $(IDL_TYPES:%.idl=%.c)
GENERATED_HEADERS = $(IDL_TYPES:%.idl=%.h)
LIBNAME = idl_dds_types
OBJS_DIR = obj.$(CPUTYPE)
GENERATED_OBJS = $(GENERATED_SOURCES:%.c=$(OBJS_DIR)/%.o)
LIBDIR = $(DDS_OUT_DIR)/../../lib.$(CPUTYPE)
BINDIR = $(DDS_OUT_DIR)/../../../../bin.$(CPUTYPE)
CC = $(C_COMPILER)
CXX = $(CPP_COMPILER)
OS = $(shell uname)
DDSCOMMON = $(DDS_OUT_DIR)/../../Common/src
CFLAGS = -m32 -g -DRTI_UNIX -DRTI_32BIT
CXXFLAGS = -m32 -g
LDFLAGS = -m32 -static-libgcc
SYSLIBS = -ldl -lnsl -lpthread -lm -lc
DEFINES_ARCH_SPECIFIC = -DRTI_UNIX
DEFINES = $(DEFINES_ARCH_SPECIFIC) $(cxx_DEFINES_ARCH_SPECIFIC)
INCLUDES = -I. -I$(NDDSHOME)/include -I$(NDDSHOME)/include/ndds
INCLUDES += -I$(DDSCOMMON)
LIBS = -L$(NDDSLIBDIR) -L$(LIBDIR) -lrt \
-lnddscppz -lnddscz -lnddscorez $(SYSLIBS) $(OS_SPECIFIC_LIBS)
COMMONLIBSRC = $(DDSCOMMON)/dds_common.cxx
COMMONLIBOBJS = $(DDSCOMMON)/obj.$(CPUTYPE)/%.o
$(shell mkdir -p $(OBJS_DIR) $(DDSCOMMON)/obj.$(CPUTYPE) $(DDS_CPP_DIR))
default: $(GENERATED_OBJS) $(LIBDIR)/lib$(LIBNAME).a
$(OBJS_DIR)/%.o : %.idl $(DDSCOMMON)/dds_common.h
$(C_COMPILER) -o $(OBJS_DIR)/$(*F).o $(DEFINES) $(INCLUDES) $(CFLAGS) -c $(*F).c; \
$(C_COMPILER) -o $(OBJS_DIR)/$(*F)Support.o $(DEFINES) $(INCLUDES) $(CFLAGS) -c $(*F)Support.c; \
$(C_COMPILER) -o $(OBJS_DIR)/$(*F)Plugin.o $(DEFINES) $(INCLUDES) $(CFLAGS) -c $(*F)Plugin.c; \
$(LIBDIR)/lib$(LIBNAME).a: $(GENERATED_OBJS) $(CPP_OBJS)
#echo "Adding these to lib: " $(OBJS_DIR)/*.o; \
mkdir -p $(LIBDIR)
rm -f $(LIBDIR)/lib$(LIBNAME).a
$(AR) -cr $(LIBDIR)/lib$(LIBNAME).a $(OBJS_DIR)/*.o
ranlib $(LIBDIR)/lib$(LIBNAME).a
%.idl:
#echo "Generating C and Ada from $# ..."; \
$(NDDSHOME)/scripts/rtiddsgen ${IDL_DIR}/$# -d $(DDS_OUT_DIR) -I ${IDL_DIR} -replace -language Ada; # -example i86Linux2.6gcc4.1.2;
clean:
rm -rf $(LIBDIR)/lib$(LIBNAME).a; \
rm -rf $(DDS_OUT_DIR)/*.h; \
rm -rf $(DDS_OUT_DIR)/*.c; \
rm -rf $(DDS_OUT_DIR)/*.gpr; \
rm -rf $(DDS_OUT_DIR)/samples; \
rm -rf $(DDS_OUT_DIR)/*.xml; \
rm -rf $(DDS_OUT_DIR)/makefile_*; \
rm -rf $(DDS_OUT_DIR)/bin; \
rm -rf $(DDS_OUT_DIR)/summary_idl*; \
rm -rf $(DDS_OUT_DIR)/common_idl*; \
rm -rf $(DDS_OUT_DIR)/alerts_idl*; \
rm -rf $(DDS_OUT_DIR)/$(OBJS_DIR);

A rule like your %.idl: rule tells make how to generate .idl files, not how to generate things from .idl files. You want to change this to %.c: %.idl -- how to generate .c files from .idl files.
That will do most of what you want -- the only problem is if you ever want to be able to generate .ads/.adb files WITHOUT generating .c files or rebuilding the library.

Related

Makefile : How do I compile my .c functions in a temporary directory?

I'm creating my own libc library named libft and I'm currently doing the Makefile that will create the libft.a .
I understood that I'm compiling my .c functions into .o files and then archiving all the .o files in a single file named libft.a. Correct me if I'm wrong, I basically learnt Makefile this morning.
My current Makefile is working but it is creating all the .o files in my main directory, but I want to compile them in a separate folder named obj for example, and that is not working.
Here is my working code that is not compiling in a different folder :
SRCB are "bonus" functions for my school.
NAME = libft.a
SRCS = ft_strlen.c \
ft_strrchr.c \
ft_atoi.c \
ft_bzero.c \
ft_calloc.c \
...
SRCB = ft_lstadd_back.c \
ft_lstadd_front.c \
ft_lstclear.c \
ft_lstdelone.c \
...
CC = gcc
CFLAGS = -Wall -Wextra -Werror
RM = rm -rf
AR = ar rcs
MKDIR = mkdir
O = obj/
ODIR = $(MKDIR) $(O)
#Turning the .c into .o
OBJS = $(SRCS:.c=.o)
OBJB = $(SRCB:.c=.o)
#Creating 'libft.a' containing all the .o
$(NAME): $(OBJS)
$(AR) $(NAME) $(OBJS)
bonus: $(OBJB)
$(AR) $(NAME) $(OBJB)
all: $(NAME)
clean:
$(RM) $(OBJS) $(OBJB)
fclean: clean
$(RM) $(NAME)
re: fclean $(NAME)
And I have tested a bunch of different things like creating an obj directory and move the .o in there :
NAME = libft.a
AR = ar rcs
MKDIR = mkdir
O = obj
ODIR = $(MKDIR) $(O)
OBJS = $(SRCS:.c=.o)
OBJB = $(SRCB:.c=.o)
$(NAME): $(OBJS)
$(AR) $(NAME) $(OBJS) | $(ODIR) | mv *.o $(O)
I also tried to create a new folder THEN compile my functions in that folder but my makefile won't work doing this :
#Turning the .c into .o
MKDIR = mkdir
O = obj
ODIR = $(MKDIR) $(O)
OBJS = $(ODIR) | $(SRCS:.c=$(O).o)
OBJB = $(ODIR) | $(SRCB:.c=$(O).o)
And the terminal is telling me : make: *** No rule to make target 'mkdir', needed by 'libft.a'. Stop.
Any help is much appreciated, thank you !

I cannot include my own libft.h and i don't know why

I want to include in a random test.c file my own library to test if it works but I can't do it.
Even a simple make all doesn't work, but I'm supposed to have done everything right. I have the impression that my makefile doesn't even compile my .c files in .o
here is my make file:
SRCS = ft_atoi.c ft_isascii.c ft_memchr.c ft_putchar_fd.c ft_strchr.c ft_strlen.c ft_strtrim.c \
ft_bzero.c ft_isdigit.c ft_memcmp.c ft_putendl_fd.c ft_strdup.c ft_strmapi.c ft_substr.c \
ft_calloc.c ft_isprint.cft_memcpy.c ft_putnbr_fd.c ft_strjoin.c ft_strncmp.c ft_tolower.c \
ft_isalnum.c ft_itoa.c ft_memmove.c ft_putstr_fd.c ft_strlcat.c ft_strnstr.c ft_toupper.c \
ft_isalpha.c ft_memccpy.c ft_memset.c ft_split.c ft_strlcpy.c ft_strrchr.c \
\
CC = gcc
CFLAGS = -Wall -Wextra -Werror
HEADER = libft.h
OBJS = $(SRCS:.c=.o)
RM = rm -f
NAME = libft.a
.c.o:
$(CC) $(CFLAGS) -c $< -o ${<:.c=.o}
$(NAME): $(OBJS) $(HEADER)
ar rcs $(NAME) $(OBJS)
all: $(NAME)
clean:
$(RM) $(OBJS)
fclean: clean
$(RM) $(NAME)
re: fclean all
.PHONY: all clean fclean re

how can I solve my compiling problem with makefile

I am trying to compile a simple C function to handle two stacks of ints and sorting them with specific rules.
I had no problem compiling earlier but I can't anymore. and receive this error message :
make: *** No rule to make target `objs/main.c', needed by `push_swap'. Stop.
Below is my code;
NAME = push_swap
SRC_DIR = srcs
SRC = main.c \
instructions/swap.c \
instructions/rotate.c \
instructions/push.c \
instructions/reverse.c \
utils/check_duplicate.c \
utils/chunk_clear.c \
utils/chunk.c \
utils/ft_error.c \
utils/ft_split.c \
utils/highest.c \
utils/init_stack.c \
utils/is_sorted.c \
utils/lowest.c \
utils/num.c \
utils/tab.c \
sort/five.c \
sort/small.c \
sort/sorter.c \
OBJ_DIR = objs
OBJ = $(addprefix $(OBJ_DIR)/, $(SRC:.c =.o))
HEADER_FOLDER = inc
CC = gcc
CFLAGS = -Werror -Wextra -Wall -I$(HEADER_FOLDER) -g
RM = rm -rf
all: $(NAME)
$(OBJ_DIR):
#mkdir -p $(OBJ_DIR)
#mkdir -p $(OBJ_DIR)/operations
#mkdir -p $(OBJ_DIR)/sorters
#mkdir -p $(OBJ_DIR)/utils
$(NAME): $(OBJ_DIR) $(OBJ)
#cd libft && make && cd ../
#echo "making push_swap ... \033[32mok\033[0m"
#$(CC) $(CFLAGS) -o $(NAME) $(OBJ) $(HEADER)
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c
#echo "Compiling ... $# \033[32mok\033[0m"
#$(CC) $(CFLAGS) -c $< -o $#
clean:
#cd libft && make clean && cd ../
#echo "Removing object files ... \033[32mok\033[0m"
#$(RM) $(OBJ) $(OBJ_DIR)
fclean:
#cd libft && make fclean && cd ../
#echo "Removing files and program ... \033[32mok\033[0m"
#$(RM) $(NAME) $(OBJ) $(OBJ_DIR)
re: fclean all
.PHONY: all re fclean clean
The problem is that $(SRC:.c =.o) doesn't work because of that space (there are no SRC names ending with ".c " (including the last space).
It should be $(SRC:.c=.o).

Makefile - Compile object with different library

I´m trying to create a Makefile that build a lib and compile the file. My problem is that depending on the %.c file I need to compile with different lib.
The SRC_MLX need the $(LFLAGS) and the SRC don´t. So the gcc compiler don´t allow me to compile the SRC with the LFLAGS. That´s the reason I need to separate.
I´ve tried this way:
SRCS = $(DIR_SRC)/ft_utils.c \
$(DIR_SRC)/ft_adt.c \
$(DIR_SRC)/ft_circle.c \
$(DIR_SRC)/ft_line.c \
$(DIR_SRC)/ft_trgb.c \
$(DIR_SRC)/ft_quadrilateral.c \
$(DIR_SRC)/ft_player.c \
$(DIR_SRC)/ft_color.c
SRCS_MLX = $(DIR_SRC)/win_update.c \
$(DIR_SRC)/ft_vars.c \
$(DIR_SRC)/ft_image.c \
$(DIR_SRC)/ft_map.c
$(NAME): $(LIB_NAME)
$(CC) $(CFLAGS) main.c -I. -I$(DIR_MLX) -L$(DIR_MLX) -L. $(LFLAGS) $(LIB_FLAG) -o $# -g
$(DIR_OBJ)/$(OBJ).o: $(DIR_SRC)/$(SRCS).c
mkdir -p $(DIR_OBJ)
$(CC) $(CFLAGS) -c $< -I. -I$(DIR_MLX) -o $#
$(DIR_OBJ)/$(OBJ_MLX).o: $(DIR_SRC)/$(SRCS_MLX).c
mkdir -p $(DIR_OBJ)
$(CC) $(CFLAGS) -c $< -I. -I$(DIR_MLX) -L$(DIR_MLX) $(LFLAGS) -o $#
$(LIB_NAME): $(OBJ_MLX) LIB_OBJ
$(AR) $(LIB_NAME) $(OBJ)
ranlib $(LIB_NAME)
LIB_OBJ: $(OBJ)
$(AR) $(LIB_NAME) $(OBJ)
In the example above I´ve tried to create a lib with one kind of files and after that create a lib with the first lib with the others files. But I keep getting this error:
Makefile:41: warning: overriding recipe for target '.objs/'
Makefile:37: warning: ignoring old recipe for target '.objs/'
make: Warning: File 'Makefile' has modification time 454 s in the future
rm -f .objs/ft_utils.o .objs/ft_adt.o .objs/ft_circle.o .objs/ft_line.o .objs/ft_trgb.o .objs/ft_quadrilateral.o .objs/ft_player.o .objs/ft_color.o
rm -f libcub3d.a
rm -f main
make: *** No rule to make target 'src/src/win_update.c', needed by '.objs/win_update.o'. Stop.
How can I compile this objects with different lib?
P.S. Those are my variables:
DIR_OBJ = .objs
DIR_SRC = src
DIR_LIB = lib
DIR_MLX = ./minilibx-linux
NAME = main
LIB_NAME = libcub3d.a
OBJ = $(patsubst $(DIR_SRC)/%.c, $(DIR_OBJ)/%.o, $(SRCS))
OBJ_MLX = $(patsubst $(DIR_SRC)/%.c, $(DIR_OBJ)/%.o, $(SRCS_MLX))
CC = clang
CFLAGS = -Wall -Werror -Wextra
LFLAGS = -lmlx -lm -lX11 -lXext -lbsd
LIB_FLAG = -lcub3d
AR = ar -rc
RM = rm -f
These lines are definitely not right:
$(DIR_OBJ)/$(OBJ).o: $(DIR_SRC)/$(SRCS).c
...
$(DIR_OBJ)/$(OBJ_MLX).o: $(DIR_SRC)/$(SRCS_MLX).c
along with the way you've defined SRCS and SRCS_MLX and these:
OBJ = $(patsubst $(DIR_SRC)/%.c, $(DIR_OBJ)/%.o, $(SRCS))
OBJ_MLX = $(patsubst $(DIR_SRC)/%.c, $(DIR_OBJ)/%.o, $(SRCS_MLX))
Just expand the variables in the rule in your head, or else ask make to expand it for you with the info function, and you'll see it's definitely not right:
$(info output is '$(DIR_OBJ)/$(OBJ).o: $(DIR_SRC)/$(SRCS).c')

I cannot link fortran code to my own C code on my laptop

I know this issue has been discussed several times here, but I cannot find help from the previous threads.
Here's the deal. I use a code written in fortran and I link it to my code in C by my makefile. The fortran makefile is ready to handle the compatibility, in fact, I got the command
CDEFS: -DAdd_
On my work machine everything seems fine. I do the link and run my own code.
However, I just tried to use the same code on my laptop and I got the classical linker error like:
undefined reference to 'dtrsm_' or
undefined reference to 'dcopy_'
refering to the fortran program. Nevertheless, the compilers are the same gcc and f95 for both machines and I didn't touch anything from the makefile.
How come I got this error?
thanks for help me.
EDIT1: sure, this is my makefile and MUMPS is the fortran code that uses a own makefile.
ROOT = $(addprefix $(PWD), /)
BUILDS_DIR = $(addprefix $(ROOT), builds/)
SRCS_DIR = $(addprefix $(ROOT), src/)
INCS_DIR = $(addprefix $(ROOT), src/)
OBJS_DIR = $(addprefix $(SRCS_DIR), objects/)
LIBS_DIR = ./
MUMPS_DIR = $(MUMPS_ROOT)
MUMPS_INCS_DIR = $(addprefix $(MUMPS_DIR), /include)
MUMPS_LIB_DIR = $(addprefix $(MUMPS_DIR), /lib)
MUMPS_MPI_DIR = $(addprefix $(MUMPS_DIR), /libseq)
SRCS = $(wildcard $(SRCS_DIR)*.c)
OBJS = $(SRCS:$(SRCS_DIR)%.c=$(OBJS_DIR)%.o)
MUMPS = MUMPS
TARGET = APOGEE
EXES = $(addprefix $(BUILDS_DIR), $(TARGET))
CC = gcc
CFLAGS = -O3 -MD -DTRILIBRARY
INCLUDES = -I$(INCS_DIR) -I$(MUMPS_INCS_DIR)
# CL = gcc
FL = f95
LFLAGS = -O
LIBS = -L$(LIBS_DIR) -lm -lblas -lpthread
LIBS += -L$(MUMPS_LIB_DIR) -ldmumps -lmumps_common -lpord -L$(MUMPS_MPI_DIR) -lmpiseq
RM = rm -f
.PHONY: all $(MUMPS) $(TARGET) distclean clean
default: $(MUMPS) $(TARGET)
$(TARGET): $(OBJS)
#echo -e "\n\n\t\t*** Compiled $(TARGET) successfully! ***\n" ;
$(FL) $(LFLAGS) -o $(BUILDS_DIR)$# \
$(OBJS) \
$(LIBS)
#echo -e "\n\n\t\t*** Linking $(TARGET) completed! ***\n"
$(OBJS): $(OBJS_DIR)%.o : $(SRCS_DIR)%.c
$(CC) $(CFLAGS) $(INCLUDES) \
-c $<\
-o $#
$(MUMPS):
(cd $(MUMPS_DIR) ; $(MAKE) ; cd $(ROOT)) ;
#echo -e "\n\n\t\t*** Compiled $(MUMPS) successfully! ***\n" ;
distclean: clean
$(RM) $(EXES)
(cd $(MUMPS_DIR) ; $(MAKE) clean ; cd $(ROOT)) ;
#echo -e "\n\n\t\t*** Purge $(MUMPS) and $(TARGET) completed! ***\n"
clean:
$(RM) $(OBJS_DIR)*.o \
$(SRCS_DIR)*~
#echo -e "\n\n\t\t*** Cleanup $(TARGET) completed! ***\n"
depend: $(SRCS)
makedepend $(INCLUDES) $^
EDIT2: chunks of the MUMPS makefile is here
include Makefile.inc
mumps_lib: requiredobj
(cd src ; $(MAKE) $(ARITH))
requiredobj: Makefile.inc $(LIBSEQNEEDED) $(libdir)/libpord$(PLAT)$(LIBEXT)
# dummy MPI library (sequential version)
libseqneeded:
(cd libseq; $(MAKE))
# Build the libpord.a library and copy it into $(topdir)/lib
$(libdir)/libpord$(PLAT)$(LIBEXT):
if [ "$(LPORDDIR)" != "" ] ; then \
cd $(LPORDDIR); \
$(MAKE) CC="$(CC)" CFLAGS="$(OPTC)" AR="$(AR)" RANLIB="$(RANLIB)" OUTC=$(OUTC) LIBEXT=$(LIBEXT); \
fi;
if [ "$(LPORDDIR)" != "" ] ; then \
cp $(LPORDDIR)/libpord$(LIBEXT) $#; \
fi;
and in Makefile.inc we got:
PLAT =
LIBEXT = .a
OUTC = -o
OUTF = -o
RM = /bin/rm -f
CC = cc
FC = f95
FL = f95
AR = ar vr
RANLIB = ranlib
INCSEQ = -I$(topdir)/libseq
LIBSEQ = -L$(topdir)/libseq -lmpiseq
LIBBLAS = -lblas
LIBOTHERS = -lpthread
CDEFS = -DAdd_
OPTF = -O
OPTC = -O -I.
OPTL = -O
INCS = $(INCSEQ)
LIBS = $(LIBSEQ)
LIBSEQNEEDED = libseqneeded

Resources