I have 2 .c files to build. I'd like to run them together (if possible. Or can I compile here then run in bash script?), and then run a .sh file to compare their output to expected (for testing).
My MakeFile currently:
CC=gcc
CFLAGS=-Wall -Werror -Wvla -std=gnu11 -fsanitize=address
PFLAGS=-fprofile-arcs -ftest-coverage
DFLAGS=-g
p1: file_1.c file_2.c file_1.h
$(CC) $(CFLAGS) $(PFLAGS) $^ -o $#
p2: p1
bash t.sh
Please find below code which will allow you to test and run a shell script along with parallel compilation.
.SILENT:
.PHONY:compile objs
TARGET = program.exe
CC=gcc
# INC variable contains path where your header files are available. Compiler will # search header files in this directory.
INC = ./inc
CFLAGS=-Wall -Werror -Wvla -std=gnu11 -fsanitize=address -I$(INC)
PFLAGS=-fprofile-arcs -ftest-coverage
DFLAGS=-g
SOURCES = file_1.c file_2.c
OBJ_FILES:= $(SOURCES:.c=.o)
objs: $(OBJ_FILES)
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $#
all: test
# Enable parallel compilation
compile:
make -j ${NUMBER_OF_PROCESSORS} -O objs
link : compile $(TARGET)
$(TARGET): $(OBJ_FILES)
$(CC) $(CFLAGS) $(OBJ_FILES) -o $#
test: link
# Execute test script
echo "Executing test script"
bash t.sh
Execute the command : make test or make all
Related
I am writing an makefile and I need to set up env.
I use source /opt/intel/oneapi/setvars.sh to set up my env but I want to make it in my Makefile.
I search for how to use source in Makefile and I learn to write this:
SHELL=/bin/bash
s:
source /opt/intel/oneapi/setvars.sh
CC = mpicc
OPT = -Ofast
CFLAGS = -Wall -std=c99 $(OPT) -fopenmp -march=native
LDFLAGS = -Wall -fopenmp
LDLIBS = $(LDFLAGS)
targets = benchmark-naive benchmark-omp benchmark-mpi
objects = check.o benchmark.o stencil-naive.o stencil-omp.o stencil-mpi.o
.PHONY : default
default : all
.PHONY : all
all : clean $(targets)
benchmark-naive : check.o benchmark.o stencil-naive.o
$(CC) -o $# $^ $(LDLIBS)
benchmark-omp : check.o benchmark.o stencil-omp.o
$(CC) -o $# $^ $(LDLIBS)
benchmark-mpi : check.o benchmark.o stencil-mpi.o
$(CC) -o $# $^ $(LDLIBS)
%.o : %.c common.h
$(CC) -c $(CFLAGS) $< -o $#
.PHONY: clean
clean:
rm -rf $(targets) $(objects)
But after run make it just load my env and do nothing. Can anyone help me to put my source in my makefile while keep my previous makefile content?
You have to call make with the env set recursively if it wasn't set:
ifndef <some test to see if env is missing>
%:
source /opt/intel/oneapi/setvars.sh $(MAKE) $(MAKECMDGOALS)
else
<normal makefile>
endif
You can look at the following makefile:
# makefile
all: prog
prog:
export ASD=asd
echo $$ASD
export ASD=asd; echo $$ASD
The output is:
export ASD=asd
echo $ASD
export ASD=asd; echo $ASD
asd
A makefile is not a bash script. 'make' is processing a makefile and it creates a child process for each line to run a shell to execute the statements. The variable that you set in a line is only valid for that child process, it will not be inherited back to the parent or to subsequent child processes.
I know this does not solve your issue, but at least it is some kind of an explanation why it does not work.
Can you try this :
SHELL=/bin/bash --rcfile /opt/intel/oneapi/setvars.sh
I'm trying to link a .h file from a folder into a Makefile using a .mk file. Folder with .h file (include) is in the same folder as Makefile.
When I run from terminal: make memory.o or make memory.o PLATFORM=MSP432 I get the following error
make: *** No rule to make target '-I./include', needed by 'memory.o'. Stop.
My .mk folder looks like this:
# Add your Source files to this variable
SOURCES = \
./main.c \
./memory.c
# Add your include paths to this variable
INCLUDES =-I./include
My Make file looks like this:
include sources.mk
# Platform Overrides
PLATFORM =
# Architectures Specific Flags
LINKER_FILE = msp432p401r.lds
CPU = cortex-m0plus
ARCH = thumb
SPECS = nosys.specs
# Compiler Flags and Defines
CC = arm-none-eabi-gcc
LD = arm-none-eabi-ld
TARGET= c1m2
LDFLAGS = -Wl, -Map=$(TARGET).map -T $(LINKER_FILE)
CFLAGS = -Wall -Werror -g -O0 -std=c99 -mcpu=$(CPU) -m$(ARCH) --specs=$(SPECS)
CPPFLAGs =
ifeq ($(PLATFORM),MSP)
CPU=cortex-m4
CC=arm-none-eabi-gcc
endif
ifeq ($(PLATFORM),HOST)
CC=gcc
endif
OBJS = $(SOURCES:.c=.o)
%.o : %.c $(INCLUDES)
$(CC) -c $< $(CFLAGS) -o $#
.PHONY: build
build: all
.PHONY: all
all: $(TARGET).out
$(TARGET).out: $(OBJS) $(INCLUDES)
$(CC) $(OBJS) $(CFLAGS) $(LDFLAGS) -o $#
.PHONY: clean
clean:
rm -f $(OBJS) $(TARGET).out $(TARGET).map
Can anybody help?
You shouldn't put $(INCLUDES) as a prerequisite of your .o file. This is not right:
%.o : %.c $(INCLUDES)
$(CC) -c $< $(CFLAGS) -o $#
INCLUDES contains options that need to be passed to the compiler (-I...). Prerequisites of targets need to be files that are used during the build. I suppose you want this:
%.o : %.c
$(CC) -c $< $(CFLAGS) $(INCLUDES) -o $#
What should I do for my makefile to not only build and compile "test" but actually run it when typing "make test" in terminal, so I wouldn't have to do ./test every time?
LDFLAGS = -lm -L. -lhashi
CFLAGS = -g -Wall -std=c99
SRC=$(wildcard *.c)
OBJETS = $(SRC:.c=.o)
all : prog1 prog2 test
...
test : test_game1.o test_toolbox.o libhashi.a
$(CC) $^ $(LDFLAGS) -o $#
test_game1.o : test_game1.c game.h node.h test_toolbox.h test_game_eliott.c test_game_flo.c test_game_iana.c test_game_remi.c
test_toolbox.o : test_toolbox.c test_toolbox.h
clean :
rm -f ... test_game1.o test_toolbox.o test ...
You need a phony target. (https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html).
For example:
.PHONY: run-test
run-test: test
./test
test: test_game1.o test_toolbox.o libhashi.a
$(CC) $^ $(LDFLAGS) -o $#
Having a different target to run the test keeps the possibility to build the test without executing it.
If I have 3 files, function.h, function.c and my_program.c which calls a method in function.h all in the same directory, what would be the best way to write a makefile so that I end up with a my_program.bc that would actually run when I type in lli my_program.bc? (I need to run a user defined pass that would insert stuff into the functions - should I run the pass on function.bc and test.bc, or should I link before running the pass?)
I've tried llvm-link function.bc my_program.bc with no luck. I feel I'm either missing something simple or going about the whole thing wrong.
Current terrible none-working makefile:
.PHONY: all clean
CC = clang
CFLAGS = -std=gnu99 -D_POSIX_C_SOURCE=200809L -g -Wall
IRFLAGS = -O3 -emit-llvm
TARGET = test
DEPS = functions.h
all: $(TARGET)
bc: test2
%.o: %.c $(DEPS)
$(CC) -c -o $# $< $(CFLAGS)
%.bc: %.c $(DEPS)
$(CC) $(IRFLAGS) -c -o $# $<
test2: test.bc functions.bc
llvm-link -o test2.bc $< functions.bc
test: test.o functions.o
$(CC) $(CFLAGS) -o $# $^
clean:
$(RM) $(TARGET) *.o *.bc
Why not just write a normal Makefile to produce the desired executable,
then use wllvm?
Shameless plug for wllvm:
https://github.com/SRI-CSL/whole-program-llvm
I do not use lli, so I would be interested to hear about how it resolved
any reliance on stdlibc that your program may have.
so I learned what a Makefile was some time ago, created a template Makefile and all I do is copy and alter the same file for every program I'm doing. I changed it a few times, but it's still a very crude Makefile. How should I improve it? This is an example of my current version:
CC = g++
CFLAGS = -std=gnu++0x -m64 -O3 -Wall
IFLAGS = -I/usr/include/igraph
LFLAGS = -ligraph -lgsl -lgslcblas -lm
DFLAGS = -g -pg
# make all
all: run test
# make a fresh compilation from scratch
fresh: clean test
#makes the final executable binary
run: main.o foo1.o foo2.o
$(CC) $(CFLAGS) $(LFLAGS) $^ -o $#
#makes the test executable with debugging and profiling tags
test: test.o foo1.o foo2.o
$(CC) $(DFLAGS) $(CFLAGS) $(LFLAGS) $^ -o $#
#makes teste.o
teste.o: teste.cpp
$(CC) $(CFLAGS) $(IFLAGS) -c $^ -o $#
#makes main.o
main.o: main.cpp
$(CC) $(CFLAGS) $(IFLAGS) -c $^ -o $#
#file foo1
foo1.o: foo1.cpp
$(CC) $(CFLAGS) $(IFLAGS) -c $^ -o $#
#file foo2
foo2.o: foo2.cpp
$(CC) $(CFLAGS) $(IFLAGS) -c $^ -o $#
clean: clean-test clean-o clean-annoying
clean-test:
rm test-rfv
clean-o:
rm *.o -rfv
clean-annoying:
rm *~ -rfv
Just by visually comparing with other makefiles I saw around in the web, this seems to be not a very bright Makefile. I don't know how they work, but I can see there's significantly less boilerplate and more generic code in them.
Can this can be made better, safer, and easier to particularize for each project?
You don't want to name specific files in a makefile if you can get away with it, and 99% of the time you can. This page shows how to develop a very general makefile. The following is my own makefile, based on that page's info:
SHELL := bash
PROG := pathed.exe
OUTDIRS := bin/debug bin/rel obj/debug obj/rel
PROG_REL := bin/rel/$(PROG)
PROG_DEBUG := bin/debug/$(PROG)
SRCFILES := $(wildcard src/*.cpp)
OBJFILES_REL := $(patsubst src/%.cpp,obj/rel/%.o,$(SRCFILES))
OBJFILES_DEBUG := $(patsubst src/%.cpp,obj/debug/%.o,$(SRCFILES))
DEPFILES := $(patsubst src/%.cpp,obj/%.d,$(SRCFILES))
CFLAGS := -Iinc -Wall -Wextra -MMD -MP
DBFLAGS := -g
RELFLAGS :=
CC := g++
.PHONY: default all testmake debug release clean dirs
default: debug
all: dirs clean debug release
dirs:
#mkdir -p $(OUTDIRS)
debug: $(PROG_DEBUG)
release: $(PROG_REL)
testmake:
#echo OBJFILES_REL = $(OBJFILES_REL)
#echo OBJFILES_DEBUG = $(OBJFILES_DEBUG)
#echo SRCFILES = $(SRCFILES)
#echo DEPFILES = $(DEPFILES)
clean:
rm -f $(OBJFILES_REL) $(OBJFILES_DEBUG) $(DEPFILES) $(PROG)
$(PROG_REL): $(OBJFILES_REL)
$(CC) $(OBJFILES_REL) -o $(PROG_REL)
strip $(PROG_REL)
#echo "---- created release binary ----"
$(PROG_DEBUG): $(OBJFILES_DEBUG)
$(CC) $(OBJFILES_DEBUG) -o $(PROG_DEBUG)
#echo "---- created debug binary ----"
-include $(DEPFILES)
obj/rel/%.o: src/%.cpp
$(CC) $(RELFLAGS) $(CFLAGS) -MF $(patsubst obj/rel/%.o, obj/%.d,$#) -c $< -o $#
obj/debug/%.o: src/%.cpp
$(CC) $(DBFLAGS) $(CFLAGS) -MF $(patsubst obj/debug/%.o, obj/%.d,$#) -c $< -o $#
Do NOT use CC for the C++ compiler. The standard convention is that CC is the C compiler, CXX is the C++ compiler. CFLAGS are flags for the C compiler, CXXFLAGS are flags for the C++ compiler, and CPPFLAGS are flags for the pre-processor (eg, -I or -D flags). Use LDFLAGS for -L flags to the linker, and LDLIBS (or LOADLIBES) for -l flags.
Using the standard conventions is good not just because it makes things easier for others to understand, but also because it allows you to take advantage of implicit rules. If make needs to make a .o file from a .c file and you have not provided a rule, it will use a standard rule and honor the settings of CC, CFLAGS, and CPPFLAGS. If CC is a C++ compiler, things will probably not work.