How to make object files into another directory - c

There are my main dir structure
push_swap
|helpers/ -> *.c files
|format_parsing/ -> *.c files
|push_swaph/ -> push_swap.c, sort_a.c
|libft/ -> *.c files, libft.h
|ft_printf/ -> *.c files, libftprintf.h
|includes/ -> header_push_swap.h
______________________________________________________
In which method in a makefile i can create an object files from all *.c files and put them into another directory like objs/?
NAME = push_swap
LIBFT = libft.a
PRINTF = libftprintf.a
HEADER = includes/header_push_swap.h
LIBFTHEADER = libft/libft.h
PRINTFHEADER = ft_printf/includes/header.h
OBJS_DIR = objs/
SRC = $(wildcard ./format_parsing/*.c) \
$(wildcard ./helpers/*.c) \
$(wildcard ./push_swaph/*.c)
OBJS = $(SRC:.c=.o)
CC = gcc
FLAGS = -Wall -Wextra -Werror
all: $(NAME)
$(NAME) : $(LIBFTHEADER) $(PRINTFHEADER) $(LIBFT) $(PRINTF) $(OBJS)
#$(CC) $(FLAGS) $(OBJS) -o $(NAME)
$(LIBFT) :
#cd ./libft && make
$(PRINTF) :
#cd ./ft_printf/ && make
clean :
#rm -rf $(OBJS_DIR)
#rm -f $(OBJS)
fclean : clean
#rm -rf $(OBJS)
#cd ./libft/ && make fclean
#cd ./ft_printf/ && make fclean
I made this makefile but it is still creates an object files inside of my C files directories.
And a second problem when i want to make $(NAME) it compiles all files and in last case it didn't found the references of functions in libft and ft_printf. But i put the header files also $(LIBFTHEADER) $(PRINTFHEADER).
/usr/bin/ld: ./format_parsing/parsing.o: in function `stack_nums_counter':
parsing.c:(.text+0x3b): undefined reference to `ft_strlen'
/usr/bin/ld: ./helpers/actions1.o: in function `pa':
actions1.c:(.text+0x60): undefined reference to `ft_printf'
/usr/bin/ld: ./helpers/actions1.o: in function `pb':
actions1.c:(.text+0xc9): undefined reference to `ft_printf'
/usr/bin/ld: ./helpers/actions1.o: in function `ra':
actions1.c:(.text+0x156): undefined reference to `ft_printf'
/usr/bin/ld: ./helpers/actions1.o: in function `rb':
actions1.c:(.text+0x1e3): undefined reference to `ft_printf'
/usr/bin/ld: ./helpers/actions2.o: in function `rr':
actions2.c:(.text+0x35): undefined reference to `ft_printf'
/usr/bin/ld: ./helpers/actions2.o:actions2.c:(.text+0x8e): more undefined references to `ft_printf' follow
/usr/bin/ld: ./helpers/helpers.o: in function `__store__':
helpers.c:(.text+0x4c): undefined reference to `ft_split'
/usr/bin/ld: helpers.c:(.text+0xd9): undefined reference to `ft_atoi'
/usr/bin/ld: ./helpers/helpers.o: in function `__check__collection':
helpers.c:(.text+0x342): undefined reference to `ft_printf'
collect2: error: ld returned 1 exit status
make: *** [Makefile:18: push_swap] Error 1

The easiest way is to specify the targets with directories and use VPATH to find the source files. There is no way to test your supplied Makefile you didn't supply a minimal reproducible example so here is a skeleton instead:
Makefile:
.PHONY: all clean
NAME = push_swap
VPATH = src
all: $(NAME)
clean:
rm -f objs/* $(MAME)
$(NAME): objs/push_swap.o
objs/%.o: %.c
$(CC) -o $# $<
and create a couple of directories:
mkdir objs src
and an example src file:
#include <stdio.h>
int main(void) {
printf("ok\n");
return 1;
}
You can now run make and the object files end up objs, and in this case the binary in the top-level directory:
$ ls objs/* push_swap
ls: cannot access 'objs/*': No such file or directory
ls: cannot access 'push_swap': No such file or directory
$ make
$ ls objs/* push_swap
objs/push_swap.o
push_swap

Related

multiple definition of `function' error occurring on the same line as "first defined here"

error log
paging.c: In function ‘setup_paging_structures’:
paging.c:7: warning: implicit declaration of function ‘printf’
rm -f bootimg
gcc -nostdlib -static boot.o paging.o x86_desc.o i8259.o kernel.o lib.o paging.o tests.o -Ttext=0x400000 -o bootimg
paging.o: In function `setup_paging_structures':
/workdirmain/work/mp3_group_31/student-distrib/paging.c:4: multiple definition of `setup_paging_structures'
paging.o:/workdirmain/work/mp3_group_31/student-distrib/paging.c:4: first defined here
paging.o: In function `initialize_paging':
/workdirmain/work/mp3_group_31/student-distrib/paging.c:13: multiple definition of `initialize_paging'
paging.o:/workdirmain/work/mp3_group_31/student-distrib/paging.c:13: first defined here
collect2: ld returned 1 exit status
make: *** [bootimg] Error 1
Here's what my paging.h file looks like:
#ifndef _PAGING_H
#define _PAGING_H
#include "types.h"
#define TOTAL_ENTRIES 1024
extern void setup_paging_structures();
extern void initialize_paging();
#endif
Paging.c below:
#include "paging.h" //include header files
void setup_paging_structures(){
int i;
for (i = 0; i < TOTAL_ENTRIES; i++){
printf("weird");
}
return;
}
void initialize_paging(){
setup_paging_structures();
return;
}
Note, I have not called the functions yet.
The command I'm using is "sudo make" (Makefile was given to me. I'm pretty sure I'm not supposed to modify it):
# Makefile for OS project
# To build, first `make dep`, them `make`. Everything should be automatic.
# Will compile all *.c and *.S files in the current directory.
# Flags to use when compiling, preprocessing, assembling, and linking
CFLAGS+=-Wall -fno-builtin -fno-stack-protector -nostdlib
ASFLAGS+=
LDFLAGS+=-nostdlib -static
CC=gcc
#If you have any .h files in another directory, add -I<dir> to this line
CPPFLAGS+=-nostdinc -g
# This generates the list of source files
SRC=$(wildcard *.S) $(wildcard *.c) $(wildcard */*.S) $(wildcard */*.c)
# This generates the list of .o files. The order matters, boot.o must be first
OBJS=boot.o
OBJS+=$(filter-out boot.o,$(patsubst %.S,%.o,$(filter %.S,$(SRC))))
OBJS+=$(patsubst %.c,%.o,$(filter %.c,$(SRC)))
bootimg: Makefile $(OBJS)
rm -f bootimg
$(CC) $(LDFLAGS) $(OBJS) -Ttext=0x400000 -o bootimg
sudo ./debug.sh
dep: Makefile.dep
Makefile.dep: $(SRC)
$(CC) -MM $(CPPFLAGS) $(SRC) > $#
.PHONY: clean
clean:
rm -f *.o */*.o Makefile.dep
ifneq ($(MAKECMDGOALS),dep)
ifneq ($(MAKECMDGOALS),clean)
include Makefile.dep
endif
endif
edit: I added updates to my post including the actual directories, the entire error log, and the contents of the Makefile I am using. This is also for a class that I'm currently taking, hence some of the things that were automatically given to me.

Linking is no occuring in my Makefile; returns 'undefined reference to `main'

This simple program (two .c files and one .h) compiles and links properly from the command line. However, my Makefile is throwing an error during the linking stage. Proper tab usage is in effect.
CC = gcc
BINDIR = bin/
OBJDIR = obj/
SRCDIR = src/
MKDIR = mkdir -p
RM = rm -rf
SRC = $(wildcard $(SRCDIR)*.c)
_OBJS = $(patsubst $(SRCDIR)%.c, %.o, $(SRC))
OBJS = $(addprefix $(OBJDIR), $(_OBJS))
CFLAGS = -Wall -g -Iinclude
.PHONY: all
all: $(BIN)
_BIN = a.out
BIN = $(addprefix $(BINDIR), $(_BIN))
$(BIN): $(OBJS) $(BINDIR)
$(CC) -o $# $(CFLAGS) $<
$(BINDIR):
$(MKDIR) $(BINDIR)
$(OBJS): $(SRC) $(OBJDIR)
$(CC) $(CFLAGS) -c $< -o $#
$(OBJDIR):
$(MKDIR) $(OBJDIR)
.PHONY: clean
clean:
#echo "Cleaning things up..."
$(RM) $(OBJDIR) $(BINDIR)
The program's files:
main.c
#include <stdio.h>
#include <stdlib.h>
#include "hellomake.h"
int main(void) {
myPrintHelloMake();
return EXIT_SUCCESS;
}
hellomake.c
#include <stdio.h>
#include "hellomake.h"
void myPrintHelloMake(void) {
puts("Hello makefiles!");
}
hellomake.h
#ifndef __HELLO_H__
#define __HELLO_H__
void myPrintHelloMake(void);
#endif
The .c files are in the src/ directory and the .h file is in the include/ directory. Makefile compiles the code, creates the obj/ directory, and places and main.o and hellomake.o therein. However, that is where things break down. Here is gcc's complaint:
$ make
mkdir -p obj/
gcc -Wall -g -Iinclude -c src/hellomake.c -o obj/hellomake.o gcc -Wall -g -Iinclude -c src/hellomake.c -o obj/main.o mkdir -p bin/ gcc -o bin/a.out -Wall -g -Iinclude
obj/hellomake.o /usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/10/../../../x86_64-linux-gnu/Scrt1.o: in function `_start': (.text+0x20): undefined reference to `main' collect2: error: ld returned 1 exit status make: *** [Makefile:34: bin/a.out] Error 1
There were a number of issues.
I'd leave off / from (e.g.) BINDIR et. al.
The patsubst was incorrect. It needed $(OBJDIR) in the the TO
Using _OBJS was unnecessary/harmful.
The rule for $(OBJS) was incorrect. It created the two .o files using the first prereq source, so [the function] main was defined twice. It needs a pattern rule instead.
Using $(BINDIR) as a prereq for $(BIN) added bin/ at the end of the gcc line [and it complained]
As M.Oehm mentioned, $< only gets the first prereq.
The all: was indented so it was not recognized properly
Anyway, here's the corrected Makefile:
CC = gcc
BINDIR = bin
OBJDIR = obj
SRCDIR = src
MKDIR = mkdir -p
RM = rm -rf
SRC = $(wildcard $(SRCDIR)/*.c)
###_OBJS = $(patsubst $(SRCDIR)%.c, %.o, $(SRC))
###OBJS = $(addprefix $(OBJDIR), $(_OBJS))
OBJS = $(patsubst $(SRCDIR)/%.c, $(OBJDIR)/%.o, $(SRC))
CFLAGS = -Wall -g -Iinclude
_BIN = a.out
BIN = $(addprefix $(BINDIR)/, $(_BIN))
.PHONY: all
all: $(BINDIR) $(OBJDIR) $(BIN)
####$(BIN): $(OBJS) $(BINDIR)
$(BIN): $(OBJS) $(BINDIR)
###$(CC) -o $# $(CFLAGS) $<
$(CC) -o $# $(CFLAGS) $(OBJS)
$(BINDIR):
$(MKDIR) $(BINDIR)
###$(OBJS): $(SRC) $(OBJDIR)
$(OBJDIR)/%.o: $(SRCDIR)/%.c
$(CC) $(CFLAGS) -c $< -o $#
$(OBJDIR):
$(MKDIR) $(OBJDIR)
.PHONY: clean
clean:
#echo "Cleaning things up..."
$(RM) $(OBJDIR) $(BINDIR)

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')

Trying to use matlab's libmat.dll, but the compiler doesn't recognize the function from the library

I am trying to use matlab libmat.dll in a C application. To compile my C application I use MinGW, for now I use matlab exemple "matcreate.c" and try to compile it, so the projects consist of only one file : main.c .
Here is the makefile I use :
MATINCLUDE = "C:\Program Files\MATLAB\R2010a\extern\include"
MATLIBRARY = "C:\Program Files\MATLAB\R2010a\bin\win64"
#
CC = gcc
LD = gcc
CFLAGS = -O3 -Wall
LFLAGS = -Wall -O3
LIBS = -I$(MATINCLUDE) -L$(MATLIBRARY)
#
PROG = matTest
LISTEOBJ = \
main.o
.c.o :
$(CC) -c $(CFLAGS) $(LIBS) -o $# $<
all : $(PROG)
$(PROG) : $(LISTEOBJ)
$(LD) -o $(PROG) $(LFLAGS) $(LISTEOBJ) $(LIBS)
clean :
rm -f *.obj
Here is what I get in the console
E:\Users\Desk\Dropbox\matTest>make
gcc -c -O3 -Wall -I"C:\Program Files\MATLAB\R2010a\extern\include" -L"C:\Pr
ogram Files\MATLAB\R2010a\bin\win64" -o main.o main.c
gcc -o Hello_world -Wall -O3 main.o -I"C:\Program Files\MATLAB\R2010a\extern\i
nclude" -L"C:\Program Files\MATLAB\R2010a\bin\win64"
main.o:main.c:(.text.startup+0x48): undefined reference to `matOpen'
main.o:main.c:(.text.startup+0x6e): undefined reference to `mxCreateDoubleMatrix
_730'
e:/mingw/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe: main.o: ba
d reloc address 0x6e in section `.text.startup'
e:/mingw/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe: final link
failed: Invalid operation
collect2.exe: error: ld returned 1 exit status
make: *** [Hello_world] Error 1
Why do I have "undefined reference to matOpen'" and "undefined reference to mxCreateDoubleMatrix" ?? those function are declared in mat.h. and I added #include "mat.h" to the begining of main.c
thank you
Looks like you have included the path to the matlab library, but not the library itself. You need to add a -l<libraryname> to your link line.

Getting compilation errors whn included a third party library

#include<stdio.h>
#include "flite.h"
cst_voice *register_cmu_us_kal();
int main()
{
cst_voice *v;
cst_wave *w;
char *text = "Hello world programming";
//Initialising the flite variables used
flite_init();
w = new_wave();
v = register_cmu_us_kal(NULL);
flite_text_to_speech(text,v,"hello_wave");
if(cst_wave_load_riff(w,"hello_wave")!=CST_OK_FORMAT){
printf("\nCompare_wave:Can read file or wrong format!\n");
}
else{
play_wave(w);
}
return 0;
}
Makefile
all:compile \
./compile
compile:eg1.o
gcc -o $# eg1.o
eg1.o:eg1.c $(LIBS_DIR) $(INC_DIR) $(LIBS)
gcc -c $<
LIBS_DIR = -L /home/b/flite-1.4-release/build/i386-linux-gnu/lib
INC_DIR = -I /home/b/flite-1.4-relase/include
LIBS = -lflite_cmu_us_slt -lflite -lflite_cmulex -lflite_cmu_time_awb -lflite_cmu_us_kal16 -lflite_cmu_us_kal -lflite_cmu_usenglish
INCLUDE:
clean:
rm -f *.o
I tried by giving he library and header file paths as LIBS_DIR = ../build/i386-linux-gnu/lib and INC_DIR = ../include
I tried the folowing c program by including a third party library. This program an a makefile is located in b\flite-1.4-release\Learnin_though_example folder. Th flite libraries are located in b\flite-1.4-release\build\i386-linux-gnu\lib and the header files are in b\flite-1.4-release\include .
I assume that i have given the makefile th correct path to search for the files. But its not identifyin it and i'm gettin an error as,
make clean all
rm -f *.o
gcc -c eg1.c
eg1.c:2:19: error: flite.h: No such file or directory
eg1.c:3: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘*’ token
eg1.c: In function ‘main’:
eg1.c:6: error: ‘cst_voice’ undeclared (first use in this function)
eg1.c:6: error: (Each undeclared identifier is reported only once
eg1.c:6: error: for each function it appears in.)
eg1.c:6: error: ‘v’ undeclared (first use in this function)
eg1.c:7: error: ‘cst_wave’ undeclared (first use in this function)
eg1.c:7: error: ‘w’ undeclared (first use in this function)
eg1.c:17: error: ‘CST_OK_FORMAT’ undeclared (first use in this function)
make: *** [eg1.o] Error 1
Please help me understand what is the mistake i'm doing
EDITED:
I modiied th makefile as per matt's guidance:
all:compile
compile:eg1.o
gcc $(INC_DIR) $(LIB_DIR) -o $# $^ $(LIBS)
eg1.o:eg1.c
gcc $(INC_DIR) -o $# -c $^
LIBS_DIR = -L../build/i386-linux-gnu/lib
INC_DIR = -I../include
LIBS = -lflite -lflite_cmulex -lflite_cmu_time_awb -lflite_cmu_us_kal16 -lflite_cmu_us_kal -lflite_cmu_usenglish -lflite_cmu_us_slt
clean:
rm -f *.o
but i'm getting ifferent error whn compiled with the command "make clean all" as,
rm -f *.o
gcc -I../include -o eg1.o -c eg1.c
gcc -I../include -o compile eg1.o -lflite -lflite_cmulex -lflite_cmu_time_awb -lflite_cmu_us_kal16 -lflite_cmu_us_kal -lflite_cmu_usenglish -lflite_cmu_us_slt
/usr/bin/ld: cannot find -lflite
collect2: ld returned 1 exit status
make: *** [compile] Error 1
EDITED:
rm -f *.o
gcc -I../include -o eg1.o -c eg1.c
gcc -I../include -L../build/i386-linux-gnu/lib -o compile eg1.o -lflite -lflite_cmulex -lflite_cmu_time_awb -lflite_cmu_us_kal16 -lflite_cmu_us_kal -lflite_usenglish -lflite_cmu_us_slt -lflite_cmu_us_rms
../build/i386-linux-gnu/lib/libflite.so: undefined reference to `sin'
../build/i386-linux-gnu/lib/libflite.so: undefined reference to `exp'
../build/i386-linux-gnu/lib/libflite.so: undefined reference to `sqrt'
../build/i386-linux-gnu/lib/libflite.so: undefined reference to `log'
../build/i386-linux-gnu/lib/libflite.so: undefined reference to `fmod'
../build/i386-linux-gnu/lib/libflite.so: undefined reference to `pow'
Your makefile is, I'm afraid to say, completely broken.
The basic Makefile syntax is:
target: pre-requisite(s)
<tab>Stuff to do to build target from pre-reqs (if required)
So this is wrong, eg1.o can't be a pre-requisite for building itself.
compile:eg1.o
gcc -o eg1.o
You should have:
eg1.o: eg1.c
gcc $(INC_DIR) -o $# -c $^
($# is the target, $^ all the pre-reqs.)
Then you can:
myexe: eg1.o
gcc $(INC_DIR) $(LIBS_DIR) -o $# $^ $(LIBS)
This will produce myexe from eg1.o. And your all rule should be all: myexe, with no recipe (no commands), and at the top as you have it.
Then you've got your include directories and library directories mixed up. -I is for include paths, -L for library paths.
Place your variable definitions before the rules, that's more common/usual. And don't put a space between -L/-I and the path that follows it.
The include directories to search is specified by -I flag, not -L.
Change:
LIBS_DIR = -I /home/b/flite-1.4-release/build/i386-linux-gnu/lib
INC_DIR = -L /home/b/flite-1.4-relase/include
to:
LIBS_DIR = -L /home/b/flite-1.4-release/build/i386-linux-gnu/lib
INC_DIR = -I /home/b/flite-1.4-relase/include

Resources