Makefile for shared library that only compiles changed files? - c++

I am working on a project where I am creating a .so object as my output that contains several operators for use in another program. I was given a Makefile that works just fine, except it always recompiles every file whenever I run make. Originally this was not an issue, but now that there are upwards of five or more operators in the library, running make is prohibitively slow. The trouble is that for the life of me, I can't figure out how to change this Makefile into one that behaves the way I want since I've never dealt with Makefiles in this format before:
BOOST_LOCATION=/usr/local/boost_1_54_0
CFLAGS=-pedantic -W -Wextra -Wall -Wno-strict-aliasing -Wno-long-long -Wno-unused-parameter -fPIC -D__STDC_FORMAT_MACROS -Wno-system-headers -isystem -O2 -g -DNDEBUG -ggdb3 -D__STDC_LIMIT_MACROS
INC=-I. -DPROJECT_ROOT="\"$(IN_SOURCE_DIR)\"" -I"$(IN_SOURCE_DIR)/include" -I"$(BOOST_LOCATION)"
LIBS=-L"$(IN_SOURCE_DIR)/lib" -shared -Wl,-soname,libname.so -L. -lm
all:
#if test ! -d "$(IN_SOURCE_DIR)"; then echo "Error. Try:\n\nmake IN_SOURCE_DIR=<PATH TO SOURCE TRUNK>"; exit 1; fi
$(CXX) $(CFLAGS) $(INC) -o plugin.cpp.o -c plugin.cpp
$(CXX) $(CFLAGS) $(INC) -o LogicalFile1.cpp.o -c File1/LogicalFile1.cpp
$(CXX) $(CFLAGS) $(INC) -o PhysicalFile1.cpp.o -c File1/PhysicalFile1.cpp
$(CXX) $(CFLAGS) $(INC) -o LogicalFile2.cpp.o -c File2/LogicalFile2.cpp
$(CXX) $(CFLAGS) $(INC) -o PhysicalFile2.cpp.o -c File2/PhysicalFile2.cpp
### etc.
$(CXX) $(CFLAGS) $(INC) -o libname.so \
plugin.cpp.o \
LogicalFile1.cpp.o \
PhysicalFile1.cpp.o \
LogicalFile2.cpp.o \
PhysicalFile2.cpp.o \
### etc \
$(LIBS)
clean:
rm -f *.o *.so
The biggest issue I have is that there is only one rule (all), and I cannot find an example of a Makefile that does this or how to split it into multiple rules.

In this case, it's actually pretty straightforward. Right now, you just have an all target that's doing all the building. You need to break out the compiler invocations and link step into their own rules, and you should be off to the races:
BOOST_LOCATION=/usr/local/boost_1_54_0
CFLAGS=-pedantic -W -Wextra -Wall -Wno-strict-aliasing -Wno-long-long -Wno-unused-parameter -fPIC -D__STDC_FORMAT_MACROS -Wno-system-headers -isystem -O2 -g -DNDEBUG -ggdb3 -D__STDC_LIMIT_MACROS
INC=-I. -DPROJECT_ROOT="\"$(IN_SOURCE_DIR)\"" -I"$(IN_SOURCE_DIR)/include" -I"$(BOOST_LOCATION)"
LIBS=-L"$(IN_SOURCE_DIR)/lib" -shared -Wl,-soname,libname.so -L. -lm
all: plugin.cpp.o LogicalFile1.cpp.o PhysicalFile1.cpp.o LogicalFile2.cpp.o PhysicalFile2.cpp.o
$(CXX) $(CFLAGS) $(INC) -o libname.so \
plugin.cpp.o \
LogicalFile1.cpp.o \
PhysicalFile1.cpp.o \
LogicalFile2.cpp.o \
PhysicalFile2.cpp.o \
### etc \
$(LIBS)
plugin.cpp.o: plugin.cpp | test
$(CXX) $(CFLAGS) $(INC) -o plugin.cpp.o -c plugin.cpp
LogicalFile1.cpp.o: File1/LogicalFile1.cpp | test
$(CXX) $(CFLAGS) $(INC) -o LogicalFile1.cpp.o -c File1/LogicalFile1.cpp
PhysicalFile1.cpp.o: File1/PhysicalFile1.cpp | test
$(CXX) $(CFLAGS) $(INC) -o PhysicalFile1.cpp.o -c File1/PhysicalFile1.cpp
LogicalFile2.cpp.o: File2/LogicalFile2.cpp | test
$(CXX) $(CFLAGS) $(INC) -o LogicalFile2.cpp.o -c File2/LogicalFile2.cpp
PhysicalFile2.cpp.o: File2/PhysicalFile2.cpp | test
$(CXX) $(CFLAGS) $(INC) -o PhysicalFile2.cpp.o -c File2/PhysicalFile2.cpp
test:
#if test ! -d "$(IN_SOURCE_DIR)"; then echo "Error. Try:\n\nmake IN_SOURCE_DIR=<PATH TO SOURCE TRUNK>"; exit 1; fi
clean:
rm -f *.o *.so
.PHONY: all clean test
From this point, you can simplify further, too. You could consolidate all of the compile lines into a single pattern rule, for example.

If you're willing to use the standard formats and built-in rules for make, you can write your entire makefile as easily as this:
ifeq (,$(wildcard $(IN_SOURCE_DIR)/.))
$(error Try: make IN_SOURCE_DIR=<PATH TO SOURCE TRUNK>)
endif
OBJECTS = plugin.o LogicalFile1.o PhysicalFile1.o LogicalFile2.o PhysicalFile2.o ### etc
BOOST_LOCATION = /usr/local/boost_1_54_0
CPPFLAGS = -DNDEBUG -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I. -DPROJECT_ROOT="\"$(IN_SOURCE_DIR)\"" -I"$(IN_SOURCE_DIR)/include" -I"$(BOOST_LOCATION)"
CXXFLAGS = -pedantic -W -Wextra -Wall -Wno-strict-aliasing -Wno-long-long -Wno-unused-parameter -fPIC -Wno-system-headers -isystem -O2 -g -ggdb3
LDFLAGS = -L"$(IN_SOURCE_DIR)/lib" -L.
LDLIBS = -shared -Wl,-soname,libname.so -lm
all: libname.so
libname.so: $(OBJECTS)
$(LINK.cc) $^ $(LDLIBS) -o $#
clean:
rm -f *.o *.so
.PHONY: all clean

Related

Make file building all objects files from same source file

I have a project that contains a obj and a src subfolder.
When I run make with the following Makefile, it builds each .o with the same src.
CXX = g++
CXXINCDIRS = -I./ext/glui/include -I.
CXXLIBDIR = /usr/lib/
SRCDIR = ./src
OBJDIR = ./obj
INCDIR = ./include
BINDIR = ./bin
EXE = $(BINDIR)/brushwork
CXXFLAGS += -W -Wall -Wextra -Weffc++ -std=c++11 $(CXXINCDIRS)
SRC_CXX = $(wildcard $(SRCDIR)/*.cc)
OBJECTS_CXX = $(patsubst $(SRCDIR)/%.cc, $(OBJDIR)/%.o, $(SRC_CXX))
LIBRARY_CXX = -lglut -lGL -lGLU -L/usr/lib -lglui
$(OBJDIR)/%.o: $(SRCDIR)/%.cc
g++ -o $# -c $<
$(EXE): $(OBJECTS_CXX) | $(BINDIR)
$(CXX) $(CXXFLAGS) $(CXXINCDIRS) -o $# $^ $(CXXLIBDIR) $(LIBRARY_CXX)
$(OBJECTS_CXX): $(SRC_CXX) | $(OBJDIR)
$(CXX) $(CXXFLAGS) -c -o $# $<
$(OBJDIR)/%.o: $(SRC_CXX) $(INCDIR)/%.h | $(OBJDIR)
$(CXX) $(CXXFLAGS) -c -o $# $<
$(BINDIR) $(OBJDIR):
mkdir -p $#
When I run the command
make -B -n
I get
mkdir -p obj
g++ -W -Wall -Wextra -Weffc++ -std=c++11 -I./ext/glui/include -I. -c -o obj/tool.o src/tool.cc
g++ -W -Wall -Wextra -Weffc++ -std=c++11 -I./ext/glui/include -I. -c -o obj/base_gfx_app.o src/tool.cc
g++ -W -Wall -Wextra -Weffc++ -std=c++11 -I./ext/glui/include -I. -c -o obj/color_data.o src/tool.cc
g++ -W -Wall -Wextra -Weffc++ -std=c++11 -I./ext/glui/include -I. -c -o obj/main.o src/tool.cc
g++ -W -Wall -Wextra -Weffc++ -std=c++11 -I./ext/glui/include -I. -c -o obj/pixel_buffer.o src/tool.cc
g++ -W -Wall -Wextra -Weffc++ -std=c++11 -I./ext/glui/include -I. -c -o obj/brushwork_app.o src/tool.cc
mkdir -p bin
g++ -W -Wall -Wextra -Weffc++ -std=c++11 -I./ext/glui/include -I. -I./ext/glui/include -I. -o bin/brushwork obj/tool.o obj/base_gfx_app.o obj/color_data.o obj/main.o obj/pixel_buffer.o obj/brushwork_app.o /usr/lib/ -lglut -lGL -lGLU -L/usr/lib -lglui
I am not sure why each obj file is being built with the same src file.
I have tried $(SRCDIR)/%.cc but make complains that there is no recipe for $(SRCDIR)/%.cc
How can I have make build each src file it's respective src file?
For this:
$(OBJDIR)/%.o: $(SRC_CXX) $(INCDIR)/%.h | $(OBJDIR)
$(CXX) $(CXXFLAGS) -c -o $# $<
I think you need this:
$(OBJDIR)/%.o: $(SRCDIR)/%.cc $(INCDIR)/%.h
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -o $# $<
I'm not sure what this does:
$(OBJECTS_CXX): $(SRC_CXX) | $(OBJDIR)
$(CXX) $(CXXFLAGS) -c -o $# $<
I suspect you should remove it.
And I think you should also remove this:
$(OBJDIR)/%.o: $(SRCDIR)/%.cc
g++ -o $# -c $<
It looks like you had 3 different rules to build your objects (unless I read it wrong).

How to compile arduino core library with makefile?

I want to create library files (.a) of the arduino core library, eventually also the other libraries (SPI, ...), with a makefile, but I can't get it to work!
This is my makefile:
CC=avr-gcc
CPP=avr-g++
MCU=-mmcu=atmega328p
CPU_SPEED=-DF_CPU=16000000UL
CFLAGS=$(MCU) $(CPU_SPEED) -g2 -gstabs -Os -Wall \
-ffunction-sections -fdata-sections -fno-exceptions
INCLUDE=-I./arduinoCORE
CFILES=$(wildcard ./arduinoCORE/*.c)
CPPFILES=$(wildcard ./arduinoCORE/*.cpp)
OBJ=$(CFILES:.c=.o) $(CPPFILES:.cpp=.o)
default: $(OBJ)
avr-ar -r libarduinoUNO.a $^
%.o : %.c
$(CC) $< $(CFLAGS) -c -o $#
%.o : %.cpp
$(CPP) $< $(CFLAGS) -c -o $#
(all header and source files are in arduinoCORE; even pins_arduino.h)
After $ make in directory above arduinoCORE I get this error message:
avr-g++ arduinoCORE/CDC.cpp -mmcu=atmega328p -DF_CPU=16000000UL -g2 -gstabs -Os -Wall -ffunction-sections -fdata-sections -fno-exceptions -c -o arduinoCORE/CDC.o
In file included from arduinoCORE/Print.h:27:0,
from arduinoCORE/Stream.h:26,
from arduinoCORE/HardwareSerial.h:28,
from arduinoCORE/Arduino.h:193,
from arduinoCORE/Platform.h:15,
from arduinoCORE/CDC.cpp:19:
arduinoCORE/Printable.h:23:17: fatal error: new.h: No such file or directory
#include <new.h>
^
compilation terminated.
make: *** [arduinoCORE/CDC.o] Error 1
The problem is, that new.h is actually in arduinoCORE!
Does anyone know how to manage this?
I had a different error with your code. It displayed Arduino.h as not being present. I fixed it after actually adding the INCLUDE variable to CFLAGS and CPPFLAGS (yours was defined but not added).
I also used CFLAGS and CPPFLAGS as per the Arduino Specification. The code is:
CC=avr-gcc
CPP=avr-g++
MCU=-mmcu=atmega328p
CPU_SPEED=-DF_CPU=16000000UL
INCLUDE=-I./
CFLAGS = -c -g -Os -w -ffunction-sections -fdata-sections -MMD $(MCU) $(CPU_SPEED) $(INCLUDE)
CPPFLAGS = -c -g -Os -w -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD $(MCU) $(CPU_SPEED) $(INCLUDE)
CFILES=$(wildcard ./*.c)
CPPFILES=$(wildcard ./*.cpp)
OBJ=$(CFILES:.c=.o) $(CPPFILES:.cpp=.o)
default: $(OBJ)
avr-ar rcs core.a $^
%.o : %.c
$(CC) $< $(CFLAGS) -c -o $#
%.o : %.cpp
$(CPP) $< $(CPPFLAGS) -c -o $#
Which creates the archive successfully (not tested, just created).

Updating Makefile to fit today standards

I have been provided the following Makefile. I am supposed to compile a somewhat complicated project but the Makefile itself doesn't do it, even though I am trying to modify it to make it work. I am studying the GNU manual but the Makefile I have is written in a very old style and I am not able to fix it. Could someone help me translating it to today standards while maintaining functionality?
The line:
$(EXE): $(OBJS)
bla=;
for file in $(OBJS); do bla="$$bla ` $$file`"; done; \
$(CXX) $(CXXLINKFLAGS) $(CXXFLAGS) -o $# $$bla $(ADDLIBS) $(LIBS)
Is the one I am mainly interested in.
This is the complete Makefile:
# //////////////// NOMBRE DEL PROYECTO ///////////////////
#
P=project
#
EXE=$(P)
OBJS=main.o model.o param.o head.h
ADDLIBS=-D.
ADDINCFLAGS=-I.
SRCDIR=/root/projects/project
##########
CXX=g++
CXXFLAGS=-O3 -fomit-frame-pointer -pipe -DNDEBUG -pedantic-errors -Wparentheses -Wreturn-type -Wcast-qual -Wall -Wpointer-arith -Wwrite-strings -Wconversion -I$(COININCDIR)
CXXLINKFLAGS=-Wl,--rpath -Wl,/installed/CoinAll/lib
CC=gcc
CFLAGS=-03 -fomit-frame-pointer -pipe -DNDEBUG -pedantic-errors -Wimplicit -Wparentheses -Wsequence-point -Wreturn-type -Wcast-qual -Wall
COININCDIR=/installed/CoinAll/include/coin
COINLIBDIR=/installed/CoinAll/lib
LIBS=-L$(COINLIBDIR) -lCbc -lCgl -lOsiClp -lOsi -lClp -lCoinUtils -lm \
`cat $(COINLIBDIR)/cgl_addlibs.txt` \
`cat $(COINLIBDIR)/clp_addlibs.txt` \
`cat $(COINLIBDIR)/coinutils_addlibs.txt`
# LIBS=-L$(COINLIBDIR) -lClp -lCoinUtils \
# -lm `cat $(COINLIBDIR)/coinutils_addlibs.txt`
INCL=-I`$(COININCDIR)`$(ADDINCFLAGS)
all: $(EXE)
.SUFFIXES: .cpp .c .o .obj
$(EXE): $(OBJS)
bla=;
for file in $(OBJS); do bla="$$bla ` $$file`"; done; \
$(CXX) $(CXXLINKFLAGS) $(CXXFLAGS) -o $# $$bla $(ADDLIBS) $(LIBS)
.cpp.o:
$(CXX) $(CXXFLAGS) $(INCL) -c -o $# `test -f '$<' || echo '$(SRCDIR)/'`$<
.cpp.obj:
$(CXX) $(CXXFLAGS) $(INCL) -c -o $# `if test -f '$<'; then '$<'; else '$(SRCDIR)/$<'; fi`
.c.o:
$(CC) $(CFLAGS) $(INCL) -c -o $# `test -f '$<' || echo '$(SRCDIR)/'`$<
.c.obj:
$(CC) $(CFLAGS) $(INCL) -c -o $# `if test -f '$<'; then '$<'; else '$(SRCDIR)/$<'; fi`
The first question is are the entries in `$(OBJS) really commands that are intended to be run for their output and then have their output used in the link line?
Because if not then the backticks are incorrect and the entire loop can be dropped and that body replaced with:
$(CXX) $(CXXLINKFLAGS) $(CXXFLAGS) -o $# $(OBJS) $(ADDLIBS) $(LIBS)
Given that the value of $(OBJS) is main.o model.o param.o head.h (and ignoring the fact that having a .h file in a list of objects is bizarre) I think that the above is likely correct.
But, just for completeness, let us assume that it isn't and that those objects do, in fact, wish to be executed for output. In that case the body could be replaced by:
$(CXX) $(CXXLINKFLAGS) $(CXXFLAGS) -o $# $(patsubst %,`%`,$(OBJS)) $(ADDLIBS) $(LIBS)
Two last comments. There is no reason to have the space inside the backticks (assuming they are correct in the first place) and there is likely no reason to pre-declare $bla= like that.

creating a makefile for multiple targets

i have created a Makefile which i would change so, that it will generate more then one target when i run make.
In my program i use self predefined macros (e.g. TIME, REG and _DEBUG ) and i would like to have my Makefile i that way that it will generate one target with out predefined macros, one with REG and another one with REG and TIME.
I hope that what i wish is a reasonable wish from Makefile, if not, then please let me know.
P.S.:
recommendations would be gladly excepted
I am using
Here is my Makefile:
CXX = g++
SOURCES = random.cpp
OBJECTS = $(SOURCES:.cpp=.o)
EXECUTABLE = random-64bit
DEBUG = -g -p -ggdb
CXXFLAGS = -Wall -ansi -pedantic -W -pipe -O3 -std=gnu++0x -march=native \
--fast-math -ftree-vectorize -ffast-math -D NDEBUG \
-D TIME -D REG -D _DEBUG
#CXXFLAGS+=$(DEBUG)
DEPS = def_type.hpp \
ls_regression.hpp \
network.hpp \
statistics.hpp \
knot.hpp \
nachbarn.hpp \
$(SOURCES:.cpp=.hpp) \
zufallszahlengenerator.hpp
INCLUDES = -I/home/phymihsa/eigen/ -I/home/phymihsa/boost_1_48_0
LIBPATH = -L/usr/local/lib64
LDFLAGS = -lm
all: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS) $(DEPS)
$(CXX) $(LIBPATH) $(OBJECTS) -o $#
.cpp.o: $<
$(CXX) $(LIBPATH) $(INCLUDES) $(LDFLAGS) $(CXXFLAGS) -c $<
%.o: %.cpp
$(CXX) $(LIBPATH) $(INCLUDES) $(LDFLAGS) $(CXXFLAGS) -c $<
.PHONY: clean
clean:
rm -rf $(OBJECTS) $(EXECUTABLE) *~ p1 *.o
EDIT
Based on the answer of #trojanfoe, i would to know if it is possible to use arrays
OBJECTS = $(SOURCES:.cpp=_none.o) $(SOURCES:.cpp=_reg.o) $(SOURCES:.cpp=_reg_time.o)
EXECUTABLE = $(SOURCES:.cpp=_none) $(SOURCES:.cpp=_reg) $(SOURCES:.cpp=_reg_time)
instead of each one writing each one specific?
Here is what i was searching for:
CXX = g++
OPTIONS := none reg reg_inter reg_time
none_CXXFLAGS :=
reg_CXXFLAGS := -D REG
reg_inter_CXXFLAGS := $(reg_CXXFLAGS) -D INTERMEDIATE_STEP
reg_time_CXXFLAGS := $(reg_CXXFLAGS) -D TIME
EXECUTABLES = $(addprefix random_,$(OPTIONS))
DEBUG = -g3 -p -ggdb
CXXFLAGS = -Wall -ansi -pedantic -W -pipe -O3 -std=gnu++0x -march=core2 -mtune=core2 \
--fast-math -ftree-vectorize -ffast-math -D NDEBUG
CXXFLAGS+=$(DEBUG)
DEPS = def_type.hpp \
ls_regression.hpp \
network.hpp \
statistics.hpp \
knot.hpp \
nachbarn.hpp \
zufallszahlengenerator.hpp
INCFLAGS = -I/usr/include/eigen3 -I/usr/include/boost_1_48
LIBPATH = -L/usr/lib64
LDFLAGS = -lm
.PHONY: all
all: $(EXECUTABLES)
random_%: random_%.o
$(CXX) $(LDFLAGS) $(LIBPATH) $^ -o $#
random_%.o : random.cpp $(DEPS)
$(CXX) $(INCFLAGS) $(CXXFLAGS) $($*_CXXFLAGS) -c $< -o $#
.PHONY: clean
clean:
rm -rf $(OBJECTS) $(EXECUTABLES) *~ p1 *.o
in this solution there is a use of variables instead of writing each time the all text
regards
You'll need to generate 3 different versions of the object file from random.cpp and 3 different executables. Note $(CXXFLAGS) contains flags common across all 3 targets and I've also moved $(DEPS) to be a dependency of the object files, not the executable.
CXX = g++
SOURCES = random.cpp
OBJECTS = $(SOURCES:.cpp=.o)
EXECUTABLE = random-64bit
DEBUG = -g -p -ggdb
CXXFLAGS = -Wall -ansi -pedantic -W -pipe -O3 -std=gnu++0x -march=native \
--fast-math -ftree-vectorize -ffast-math -D NDEBUG -D _DEBUG
#CXXFLAGS+=$(DEBUG)
DEPS = def_type.hpp \
ls_regression.hpp \
network.hpp \
statistics.hpp \
knot.hpp \
nachbarn.hpp \
$(SOURCES:.cpp=.hpp) \
zufallszahlengenerator.hpp
INCLUDES = -I/home/phymihsa/eigen/ -I/home/phymihsa/boost_1_48_0
LIBPATH = -L/usr/local/lib64
LDFLAGS = -lm
all: random_none random_reg random_reg_time
random_none: random_none.o
$(CXX) $(LDFLAGS) $(LIBPATH) random_none.o -o $#
random_reg: random_reg.o
$(CXX) $(LDFLAGS) $(LIBPATH) random_reg.o -o $#
random_reg_time: random_reg_time.o
$(CXX) $(LDFLAGS) $(LIBPATH) random_reg_time.o -o $#
random_none.o: random.cpp $(DEPS)
$(CXX) $(INCLUDES) $(CXXFLAGS) -c $<
random_reg.o: random.cpp $(DEPS)
$(CXX) $(INCLUDES) $(CXXFLAGS) -D REG -c $<
random_reg_time.o: random.cpp $(DEPS)
$(CXX) $(INCLUDES) $(CXXFLAGS) -D REG -D TIME -c $<
.PHONY: clean
clean:
rm -rf *.o random_none random_reg random_reg_time *~ p1
For each file, create one target per compile flag variant.
Say you have a program that depends on two files, foo.cc and bar.cc. You want to compile a debug and a release version. You'll do something like this:
DEBUG = -g -Wall -D DEBUG
RELEASE = ...
foo_debug.o: foo.cc
g++ -o foo_debug.o -c foo.cc $(DEBUG)
foo_release.o: foo.cc
g++ -o foo_release.o -c foo.cc $(RELEASE)
# Same thing for bar ...
main_debug: foo_debug.o bar_debug.o
g++ -o main_debug foo_debug.o bar_debug.o
main_release: foo_release.o bar_release.o
g++ -o main_release foo_release.o bar_release.o

makefile to compile multiple sources, with different flags

I have the following makefile:
CC = gcc
SRC = source1.c
EXE = source1
FLAGS = -fopenmp
all: $(src)
$(CC) -o $(EXE) $(SRC) $(FLAGS)
clean:
rm $(EXE)
How can I modify it so I can use multiple sources, some of them compiled with the flag -fopenmp, some of them compiled without. Thanks a lot.
This should get you started: Note how -fopenmp gets added just for source2.c
CC=gcc
SRC=source1.c source2.c
OBJ=$(patsubst %.c,%.o,$(SRC))
EXE=source1
FLAGS= -g -O2
source2.o: FLAGS+=-fopenmp
all: $(EXE)
$(EXE): $(OBJ)
$(CC) -o $# $^ $(FLAGS)
%.o: %.c
$(CC) -c -o $# $^ $(FLAGS)
clean:
rm $(EXE)$
Output of make -Bsn:
gcc -o source1.o source1.c -g -O2
gcc -o source2.o source2.c -g -O2 -fopenmp
gcc -o source1 source1.o source2.o -g -O2
You can define for example, EXTFLAGS=$(FLAGS) -fopenmp, and use EXTFLAGS for some rules.