Combing object files generated out of C and C++ projects - c++

I am trying to compile two projects together to create one executable. The first project is written in C and it uses the following portion of the makefile to generate the corresponding object files.
obj/%.o : %.c .dirs
$(CC) $(MKDEPEND) -w -c -o $# $(CFLAGS) $(INCDIRS) $<
The second project is written in C++ and it uses the following portion of the Makefile to generate the object file.
obj/%.o : %.cpp .dirs
$(CXX) $(MKDEPEND) -w -c -o $# $(CFLAGS) $(INCDIRS) $<
When I try to create the final executable, I receive an "undefined reference to function" for my C objects. What am I doing wrong? Any help is appreciated.
$(TARGET) : $(OOBJS) $(SUBTARGETS)
$(CXX) -w -o $(TMP_TARGET) $(OOBJS) $(LIBS) $(LFLAGS) $(SUBTARGETS) && mv -f $(TMP_TARGET) $#

Related

How can I use different rules in Makefile for two groups of files?

I have one Makefile to build an executable and a library. Executable consists of a lot of source files and library consists of one .cpp file. The difference between compilation of executable and library is -fPIC option.
There is a compilation rule:
%.o : %.cpp
$(CXX) -c $(CXXFLAGS) $< -o $#
all: $(TARGET) $(TARGET_LIB)
$(TARGET): $(OBJS)
$(CXX) $(LDFLAGS) -o $# $^
$(TARGET_LIB): $(LIBOBJS)
$(CXX) $(LDFLAGS) -fPIC -shared -o $# $^
I tried to add compilation rule for library and got this:
lib.o : lib.cpp
$(CXX) -fPIC -c $(CXXFLAGS) $< -o $#
%.o : %.cpp
$(CXX) -c $(CXXFLAGS) $< -o $#
all: $(TARGET) $(TARGET_LIB)
$(TARGET): $(OBJS)
$(CXX) $(LDFLAGS) -o $# $^
$(TARGET_LIB): $(LIBOBJS)
$(CXX) $(LDFLAGS) -fPIC -shared -o $# $^
Unfortunately, only lib is compiled in this case. Second rule is omitted.
How can I use a rule for one file and different rule for group of other files?
If you just run make without a target, the first target gets built. So just put all back at the top and it should work fine.

how to include and compile a library in a makefile

I'm trying to build this hello world project that includes a library with both .h and .cpp files (and hence the library needs to be compiled too). The directory structure is
helloworld/lib/StanfordCPPLib/console.h
/src/hello.h
/src/hello.cpp
You can see the project code here
When I run make with the following makefile, i get an error that console.h (which is included by hello.cpp) cannot be found
CC=gcc
CFLAGS=-I.
DEPS = hello.h
OBJ = hello.o
#console.h is in lib/StanfordCPPLib and it is included by hello.cpp
INC=-I../lib/StanfordCPPLib
%.o: %.c $(DEPS)
$(CC) -c -o $# $< $(CFLAGS)
hellomake: $(OBJ)
g++ -o $# $^ $(CFLAGS) $(INC)
How to include the StanfordLibrary in this makefile so that it is both included and compiled.
(note, I'm aware the original sourcecode contains a QT creator file, however, I'm trying to build it using make)
The main problem is that your rule for building objs:
%.o: %.c $(DEPS)
$(CC) -c -o $# $< $(CFLAGS)
doesn't use your include path in $(INC)
Another problem is that you are matching on the wrong file extension. e.g. %.c should be %.cpp.
You also have some extra redundant junk in there, so I suggest you update your makefile like this to get the idea:
CC=gcc
DEPS = hello.h
OBJ = hello.o
INC=-I. -I../lib/StanfordCPPLib
%.o: %.cpp $(DEPS)
$(CC) $(INC) -c $<
hellomake: $(OBJ)
g++ -o $# $^
This builds fine in my little mock setup.
Remember that it is actually necessary for you to use g++ under hellomake: for everything to link properly.

GNU makefile rules and dependencies

I've been doing a lot of reading on how to write makefiles to build an application on Linux but I'm massively confused about the many different ways to apparently achieve the same goal.
This is what I have come up with so far to build an archive.
SHELL = /bin/sh
CXX = g++
DEBUG = -g
CXXFLAGS = -std=c++11 -Wall -pedantic #-Wextra
CPPFLAGS = -I. \
-I./include
SOURCES = foo1.cpp \
foo2.cpp \
foo3.cpp
OBJECTS = $(SOURCES:.cpp=.o)
The following rule successfully compiles each source file into an object file and then creates an archive:
libfoo.a: $(OBJECTS)
ar rvcs $# $(OBJECTS)
%.o: src/%.cpp ./include/%.h
$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) -o $# $<
This also does the same thing:
libfoo.a: $(OBJECTS)
ar rvcs $# $(OBJECTS)
$(OBJECTS) : %.o:src/%.cpp
$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) -o $# $<
However, this fails with an error that there is no rule to make target 'foo1.o:%.h
libfoo.a: $(OBJECTS)
ar rvcs $# $(OBJECTS)
$(OBJECTS) : %.o:src/%.cpp %.o:%.h
$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) -o $# $<
Can someone please explain why it doesn't work and which approach is best?
The first option lists the header files as dependencies but the second option doesn't. That is my motivation for the third option.
How do I list the headers as dependencies using options 2 or 3?
TIA
The feature you're using in try #2 and try #3 is static pattern rules and the syntax looks like this:
<targets...> : <target-pattern> : <prerequisites...>
There can only be two colons, not three. You should write your try #3 above as:
$(OBJECTS) : %.o : src/%.cpp %.h
$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) -o $# $<
Note one critical thing: this rule will FAIL if you ever create any .cpp file which does not have an associated .h file. Just sayin'.

Makefile for c++ with one .o file and one .CPP file

I am trying to create a makefile to build a windows c++ project on linux. I have to compile .cpp in different directories, to create a library .so with the objects.
For that I have created a script to find the .cpp and put it in a file :
SOURCE= \
./Source/CHAINE.CPP\
./Source/CRACKCHN.CPP\
./Source/LISTEPTR.CPP\
Now my makefile looks like : (I know I will have to change the $(TARGET) : $(OBJECT) rule, but thats not my problem here i think)
-include sources.mk
OBJECT = $(SOURCE:%.CPP=%.o)
#
$(TARGET) : $(OBJECT)
$(CC) $(CFLAGS) -o $# $^ $(LIBS)
$(OBJECT) : $(SOURCE)
$(CC) $(CFLAG) $(PREPROC) -c $< -o $(OBJ_DIR)/$# $(INCLUDE)
But when i do the make command, all the objects are created with the first .CPP (CHAINE.CPP here) :
g++ -Wall -D _MSC_VER -D _GPP -c Source/CHAINE.CPP -o ./Source/CHAINE.o
===
g++ -Wall -D _MSC_VER -D _GPP -c Source/CHAINE.CPP -o ./Source/CRACKCHN.o
===
g++ -Wall -D _MSC_VER -D _GPP -c Source/CHAINE.CPP -o ./Source/LISTEPTR.o
This is the first time I have to create a makefile, and I have a lot of problems to solve it, if anybody have a solution?
$(OBJECT) is a list of all objects. With the last rule you seem to want to tell Make how to build a single .o from a single .cpp. It should have a for of:
%.o: %.cpp
$(CC) $(CFLAG) $(PREPROC) -c $< -o $(OBJ_DIR)/$# $(INCLUDE)

object files need to be placed in different directory

I would appreciate if anyone could help me with the Makefile error. I would like to compile a C++ application into a shared library and place the compiled object *.o files in ./sobjs directory like below. I followed several examples to do this, however I still have the problem to get this correct compilation and linker.
Makefile:
OBJS = a1.o a2.o a3.o a4.o a5.o
objects = sobj/$(OBJS)
all: $(objects)
$(CXX) $(CXX_FLAGS) $(objects) -shared -o libname.so
$(objects) : | sobjs
sobjs:
#mkdir -p $#
sobjs/%.o: %.cpp
#echo $<
$(CXX) -fPIC -c -o $# $< $(CXX_FLAGS) $(MY_FLAGS) $(INCLUDE_DIRS)
I made a mistake. Replace this
objects = sobj/$(OBJS)
with this
objects = $(patsubst %.o, sobjs/%.o,$(OBJS))
and it will now compile files correctly.