I'm trying to integrate a new file into my program compilation. I'm thoroughly confused about the "routed.o:" line. My program has one main file called "routed" and two support files that contain functions that are called by the main file. Can anyone help me understand how to compile this into a single program? Thank you!
EDIT: I figured this out. For the sake of posterity, I've commented out my "stupid" lines and replace them with something that works.
CC = gcc
CFLAGS = -c -g -Wall -Wextra
DEPS = routed.h
all: routed_LS
%.o: %.c $(DEPS)
$(CC) -c -o $# $< $(CFLAGS)
helper_funcs.o: helper_funcs.c
$(CC) -c helper_funcs.c -o helper_funcs.o
dijkstra.o: dijkstra.c
$(CC) -c dijkstra.c -o dijkstra.o
# routed.o: routed.c helper_funcs.o dijkstra.o
# $(CC) -c routed.c -o routed.o -o dijkstra.o
routed.o: routed.c
$(CC) -c routed.c
# routed: routed.o helper_funcs.o dijkstra.o
# $(CC) -o routed routed.o helper_funcs.o dijkstra.o
routed: routed.o dijkstra.o helper_funcs.o
$(CC) -o routed routed.o dijkstra.o helper_funcs.o
clean:
rm -f *.o
rm -f routed
Here is the terminal output:
rm -f *.o
rm -f routed
gcc -c helper_funcs.c -o helper_funcs.o
gcc -c dijkstra.c -o dijkstra.o
gcc -c routed.c -o routed.o -o dijkstra.o
gcc -o routed routed.o helper_funcs.o dijkstra.o
i686-apple-darwin11-llvm-gcc-4.2: routed.o: No such file or directory
make: *** [routed] Error 1
This command:
$(CC) -c routed.c -o routed.o -o dijkstra.o
doesn't do what you think it does. I'm not entirely certain what you were attempting here, but the compiler sets the name of the output file to "routed.o", and then dutifully sets it to "dijkstra.o". The command produces an object file called "dijkstra.o", and that's all. The routed.o rule doesn't actually produce a file called routed.o, and when the linker reaches for that object file, it can't find it.
I really didn't understand what I was doing, as you can clearly tell. The way that I fixed this was with the following changes:
# routed.o: routed.c helper_funcs.o dijkstra.o
# $(CC) -c routed.c -o routed.o -o dijkstra.o
routed.o: routed.c
$(CC) -c routed.c
# routed: routed.o helper_funcs.o dijkstra.o
# $(CC) -o routed routed.o helper_funcs.o dijkstra.o
Related
I apologize if this is a somewhat noobish question, I have been searching for a while and haven't found the answer.
I am new to makefiles, and am trying to create one which compiles multiple source files in various directories into object files in a single directory and then link them.
It works, but it always recompiles all the files even if I haven't changed them. To my understanding, it should only do this if the dependencies are older than the targets. What am I doing wrong?
Here is my makefile:
CC = mpic++
CCU = nvcc
ARCH = -arch=sm_52
SOURCEDIR = ./source
SOLVERDIR = $(SOURCEDIR)/solvers
OBJECTDIR = ./bin
INCLUDE = -I./include -I/home/alexander/.openmpi/include -I/usr/local/cuda-7.5/include
LIBRARY = -L/usr/local/cuda-7.5/lib64 -lcublas -lcudart
OUT = cgsolve
CDEPS = $(OBJECTDIR)/main.o $(OBJECTDIR)/timer.o $(OBJECTDIR)/cgMPIFuncs.o
compileC: $(CDEPS)
$(CC) $(INCLUDE) -c $(SOURCEDIR)/main.cpp -o $(OBJECTDIR)/main.o
$(CC) $(INCLUDE) -c $(SOURCEDIR)/timer.cpp -o $(OBJECTDIR)/timer.o
$(CC) $(INCLUDE) -c $(SOURCEDIR)/cgMPIFuncs.cpp -o $(OBJECTDIR)/cgMPIFuncs.o
CUDEPS = $(OBJECTDIR)/BiCGStab.o $(OBJECTDIR)/CG.o $(OBJECTDIR)/solverUtil.o $(OBJECTDIR)/cudaKernels.o
compileCU: $(CUDEPS)
$(CCU) $(ARCH) $(INCLUDE) -c $(SOLVERDIR)/BiCGStab.cu -o $(OBJECTDIR)/BiCGStab.o
$(CCU) $(ARCH) $(INCLUDE) -c $(SOLVERDIR)/CG.cu -o $(OBJECTDIR)/CG.o
$(CCU) $(ARCH) $(INCLUDE) -c $(SOURCEDIR)/solverUtil.cu -o $(OBJECTDIR)/solverUtil.o
$(CCU) $(ARCH) $(INCLUDE) -c $(SOURCEDIR)/cudaKernels.cu -o $(OBJECTDIR)/cudaKernels.o
OBJDEPS = $(OBJECTDIR)/main.o $(OBJECTDIR)/BiCGStab.o $(OBJECTDIR)/CG.o $(OBJECTDIR)/solverUtil.o $(OBJECTDIR)/cudaKernels.o $(OBJECTDIR)/timer.o $(OBJECTDIR)/cgMPIFuncs.o
build:
$(CC) $(OBJDEPS) $(LIBRARY) -o $(OUT)
all: compileC compileCU build
And again, sorry if this is a repeat or something. I haven't been able to find a previous version of this question. Thanks for the help!
Instead of setting rules explicitly altogether, please try pattern-rule like below, also it's better to add OBJDEPS as pre-requisite for build target (then no need for compileC and compileCU, unless you want to keep those targets)
compileC: $(CDEPS)
compileCU: $(CUDEPS)
build: $(OBJDEPS)
$(CC) $^ $(LIBRARY) -o $(OUT)
$(OBJECTDIR)/%.o : $(SOURCEDIR)/%.cpp
$(CC) $(INCLUDE) -c $^ -o $#
$(OBJECTDIR)/%.o : $(SOLVERDIR)/%.cu
$(CCU) $(ARCH) $(INCLUDE) -c $^ -o $#
Solution found. See below:
I'm trying to get my makefile to compile three c programs into one executable, but I get the following error:
cachesim.o: could not read symbols: File in wrong format
Yes, I'm using make clean every time I use it. The make file is as follow
CC = gcc
CFLAGS = -Wall -m32 -O -g
all: cachesim cache trace_file_parser
gcc -o cachesim cachesim.o cache.o trace_file_parser.o
cachesim: cachesim.c
$(CC) -c -o cachesim.o cachesim.c $(CFLAGS)
cache: cache.c
$(CC) -c -o cache.o cache.c $(CFLAGS)
trace_file_parser: trace_file_parser.c
$(CC) -c -o trace_file_parser.o trace_file_parser.c $(CFLAGS)
clean:
rm -f *.o
I cannot figure out why this is....
I'm using make clean every time.
Attempting to compile:
[katiea#mumble-15] (34)$ make clean
rm -f *.o
[katiea#mumble-15] (35)$ ls
cache.c cache.h cachesim.c~ gcc_trace Makefile~ trace_file_parser.c
cache.c~ cachesim.c cache_structs.h Makefile strgen_trace trace_file_parser.h
[katiea#mumble-15] (36)$ make
gcc -c -o cachesim.o cachesim.c -Wall -m32 -O -g
gcc -c -o cache.o cache.c -Wall -m32 -O -g
gcc -c -o trace_file_parser.o trace_file_parser.c -Wall -m32 -O -g
gcc -o cachesim cachesim.o cache.o trace_file_parser.o
cachesim.o: could not read symbols: File in wrong format
collect2: ld returned 1 exit status
make: *** [all] Error 1
SOLUTION
CC = gcc
CFLAGS = -Wall -m32 -O -g
all: cachesim.c cache.c trace_file_parser.c
$(CC) -o cachesim cachesim.c cache.c trace_file_parser.c $(CFLAGS)
cachesim: cachesim.c
$(CC) -c -o cachesim.o cachesim.c $(CFLAGS)
cache: cache.c
$(CC) -c -o cache.o cache.c $(CFLAGS)
trace_file_parser: trace_file_parser.c
$(CC) -c -o trace_file_parser.o trace_file_parser.c $(CFLAGS)
clean:
rm -f *.o
Please read an intro to makefiles. This looks like homework to me.
One of the most basic tenets of makefiles is that the target should be the actual file you're building. These rules are all bogus:
cachesim: cachesim.c
$(CC) -c -o cachesim.o cachesim.c $(CFLAGS)
(etc.) because the target is cachesim but the recipe (command line) builds the file cachesim.o.
Your makefile can be written as easily as this (taking advantage of make's built-in rules):
CC = gcc
CFLAGS = -Wall -m32 -O -g
LDFLAGS = -m32 -O -g
cachesim: cachesim.o cache.o trace_file_parser.o
clean:
rm -f *.o
That's all you need.
As for your error, it seems to me that the file cachesim.o must be in some bizarre format, maybe from back before you had the makefile set up properly.
If you run make clean then make again, do you get the same error? If so please show the compile and link lines.
ETA: use the -m32 flag on the link line as well as the compile line, if you want to create a 32bit program.
Here is my makefile, i have object files in obj/ directory, and i need to compile them into binaries in bin/ folder, but somehow it doesn't work as i wanted it to work, any ideas?
SOURCES= $(wildcard *.c)
OBJECTS:= $(patsubst %.c, %.o, $(SOURCES))
OBJECTS:= $(addprefix obj/,$(OBJECTS))
NAMES:= $(patsubst %.c, %, $(SOURCES))
NAMES:= $(addprefix bin/,$(NAMES))
CC=gcc
CFLAGS= -Wall -c -o
DIRS = bin obj
all: $(DIRS) $(NAMES)
$(NAMES): $(OBJECTS)
$(CC) -o $# $<
obj/%.o: %.c
$(CC) $(CFLAGS) $# $<
$(DIRS):
mkdir -p $#
clean:
rm -rf $(DIRS)
Actual output:
mkdir -p bin
mkdir -p obj
gcc -Wall -c -o obj/task1.o task1.c
gcc -Wall -c -o obj/task2.o task2.c
gcc -Wall -c -o obj/task3.o task3.c
gcc -o bin/task1 obj/task1.o
gcc -o bin/task2 obj/task1.o
gcc -o bin/task3 obj/task1.o
Expected output:
mkdir -p bin
mkdir -p obj
gcc -Wall -c -o obj/task1.o task1.c
gcc -Wall -c -o obj/task2.o task2.c
gcc -Wall -c -o obj/task3.o task3.c
gcc -o bin/task1 obj/task1.o
gcc -o bin/task2 obj/task2.o
gcc -o bin/task3 obj/task3.o
In this rule:
$(NAMES): $(OBJECTS)
$(CC) -o $# $<
each executable depends on all objects. And since $< grabs only the first prerequisite, all you see is obj/task1.o.
Do it this way:
bin/%: obj/%.o
$(CC) -o $# $<
or this way:
$(NAMES): bin/% : obj/%.o
$(CC) -o $# $<
I am trying to add a project's (call it b) code to a different project(call it a). Both projects are compile and run separately. I just copied the folder of project b into project a's folder. In project a's Makefile, I added the lines to compile project b with it. It compiles fine. Now I want to use b's code. But when I try to #include "/bfolder/somefile.h", it cannot find the file. What am I missing about this? If I can just #include "somefileinsamedirectory.h", why can't I do #include "/bfolder/somefile.h"?`
This is a 's Makefile that I have edited to include the irobot_driver code.
INCLUDE = -I/usr/X11R6/include -I/home/sterling/irobot_driver
CC=g++
CFLAGS=-w -D LINUX -fpermissive
CFLAGS_R= -w -D LINUX -O3 -fpermissive
CFLAGS_D=-w -D LINUX -fpermissive
OBJ= obj
OBJ_DEBUG= obj_debug
OBJDIR= release
SRCDIR= src
LDFLAGS= -L/usr/X11R6/lib$(LIBSELECT) -lGL -lfltk -lfltk_gl -lXext -lX11 -lglut -lGLU -lfltk_images
SOURCES_RAW=codeprofiler.cpp gametimer.cpp timer.cpp timeprofile.cpp vector4.cpp matrix.cpp agent.cpp agentcontroller.cpp dummy.cpp evader.cpp pursuer.cpp goal.cpp player.cpp graphdata.cpp graph.cpp cubiccoefs.cpp segment.cpp trajectory.cpp anode.cpp arrayvector4.cpp color.cpp drawcomponent.cpp drawcontroller.cpp flags.cpp global.cpp map_analyzer.cpp minheap.cpp node.cpp quadtree.cpp queue.cpp results.cpp sensor.cpp settings.cpp utility.cpp world.cpp gui.cpp main.cpp logger.cpp parameters.cpp counter.cpp polygon.cpp line.cpp
TARGET:= pursuit_evasion
TARGETD:= pursuit_evasion_d
TARGETP:= pursuit_evasion_p
TARGETW32:= pursuit_evasion_w32
OBJECTS:=$(SOURCES_RAW:.cpp=.o)
OBJECTS:=$(patsubst %.o,$(OBJDIR)/%.o, $(OBJECTS))
SOURCES:=$(SOURCES_RAW)
SOURCES:=$(patsubst %.cpp,$(SRCDIR)/%.cpp, $(SOURCES))
OBJ_DEBUG:=$(SOURCES_RAW:.cpp=.o)
OBJ_DEBUG:=$(patsubst %.o,debug/%.o, $(OBJ_DEBUG))
OBJECTS_P:=$(SOURCES_RAW:.cpp=.o)
OBJECTS_P:=$(patsubst %.o,profile/%.o, $(OBJECTS_P))
OBJDIR=obj
all: $(TARGET)
#--- Release
$(TARGET): $(OBJECTS)
$(CC) -w -D LINUX $(INCLUDE) $^ -o $# $(LDFLAGS)
cd /home/sterling/irobot_driver; sudo make -j2
release/%.o: src/%.cpp
$(CC) -c $< $(CFLAGS_R) -o $#
#--- Debug
debug: $(TARGETD)
$(TARGETD): $(OBJ_DEBUG)
$(CC) -w -D LINUX $(INCLUDE) $^ -o $# $(LDFLAGS)
cd /home/sterling/irobot_driver; sudo make -j2
debug/%.o: src/%.cpp
$(CC) -c -g $< $(CFLAGS)-o $#
#-- Profile
profile: $(TARGETP)
$(TARGETP): $(OBJECTS_P)
$(CC) -w -g -pg -D LINUX $(INCLUDE) $^ -o $# $(LDFLAGS)
profile/%.o: src/%.cpp
$(CC) -c -g -pg $< $(CFLAGS)-o $#
win32: $(TARGETW32)
$(TARGETW32): $(OBJECTS)
$(CC) -w -D WIN32 $(INCLUDE_W32) $^ -o $# $(LDFLAGS)
.PHONY : clean
clean:
rm -f release/*.o
rm -f debug/*.o
rm -f profile/*.o
rm -f $(TARGET) $(TARGETD) $(TARGETP)
cd /home/sterling/irobot_driver; make clean;
The #include "/the/whole/path/to/a/file" that works is -
#include "/home/sterling/irobot_driver/robot_driver_agent.h"
You can, but when you declare the path starting with /some/path/to/file.h it's going to really look for the file at /some/path/to/file.h. If instead you want the bfolder/somefile.h, remove the / from the beginning.
Also, in general, if b is a library that you want to use, it is best to keep it in whatever folder it resides, and include and link using the -I, -L and -l options of gcc, or similar options of other compilers. This way, if you update b you don't need to copy it to every project that uses it.
Try
#include "bfolder/somefile.h"
You are including a leading slash in "/bfolder/somefile.h", which means /bfolder would be in the root directory.
#include "/bfolder/..." would be implying that bfolder is in the root directory of your computer's file system. If bfolder is in the same directory as your source code, then you would just want #include "bfolder/somefile.h"
Why does
$(OBJDIR)\%.o:$(SRDDIR)\%.s
$(GCC) -c -g -I$(SRCDIR) $(ASFLAGS) $< -o $#
$(OBJDIR)\%.o:$(SRDDIR)\%.c
$(GCC) -c -g -I$(SRCDIR) $(CFLAGS) $< -o $#
gives warning (says ignoring the first rule)
where as
%.o:%.s
$(GCC) -c -g -I$(SRCDIR) $(ASFLAGS) $< -o $#
%.o:%.c
$(GCC) -c -g -I$(SRCDIR) $(CFLAGS) $< -o $#
works fine but I will have all my sources and objs in the same directory.
I would like to put the objs (generated from assembly files and c files) in a separate directory( and I am running make on windows).
Try using forward slashes ("/") instead of backward ones ("\").
The -o flag of GCC determines where the output file are made.
So this may work if you change:
%.o:%.s $(GCC) -c -g -I$(SRCDIR) $(ASFLAGS) $< -o $#
TO
%.o:%.s $(GCC) -c -g -I$(SRCDIR) $(ASFLAGS) $< -o myoutputdir/$#