How to use C++ modules with a Makefile? - c++

I have a Makefile which is minimal, yet complete. It is the following:
OUT = example
INSTALL_DIR = /usr/local/bin
OBJECT = ./obj
SOURCE = ./src
SRC := $(shell find $(SOURCE) -name *.cc)
OBJ := $(SRC:%=$(OBJECT)/%.o)
DEPS := $(OBJ:.o=.d)
INC_DIRS := $(shell find $(SOURCE) -type d)
INC_FLAGS := $(addprefix -I,$(INC_DIRS))
CC = gcc
CFLAGS = -pipe -fmodules-ts -std=c++2a
DEBUG_FLAGS := $(CFLAGS) -g -Wall -Wextra
RELEASE_FLAGS := $(CFLAGS) -O3 -flto
debug: $(OBJ)
#echo "Building the DEBUG binary..."
#$(CC) $(OBJ) -o $(OUT) $(DEBUG_FLAGS)
#echo "The binary was built successfully!"
release: $(OBJ)
#echo "Building the RELEASE binary..."
#$(CC) $(OBJ) -o $(OUT) $(RELEASE_FLAGS)
#echo "The binary was built successfully!"
install: $(OUT)
#cp $(OUT) $(INSTALL_DIR)
uninstall:
#rm $(INSTALL_DIR)/$(OUT)
$(OBJECT)/%.cc.o: %.cc
#mkdir -p $(dir $#)
#echo "Building $#..."
#$(CC) $(CFLAGS) -c $< -o $#
.PHONY: clean
clean:
rm -rf $(OBJECT) $(OUT)
-include $(DEPS)
There is a directory called "src" which includes the source files. When I'm running make, I will get a compilation error about having to first create modules before using them. If I do create them manually, then I will be able to use "Make" and it will work then it will work. Is there a way to automatically create them?

I recommend using g++-11 instead of just gcc, since versions <=10 do not really include module support asides from the deprecated TS. Then also, use flag -std=c++20.
Also, I have (painful) experience using dependency files with gcc, since that particular feature is not really fully implemented. Last I checked (beginning of nov '21) the dependency files don't actually do anything as pertains to modules.
That being said, what you write should work. And it would, if the compiler-support for modules was finished.

Related

Makefile compiling the good files without the dependencies

I have a problem with the dependencies in my Makefile.
There is no problem with the compilation, it compiles perfectly the good *.cc and *.hh but unfortunately, it does not re-compile the dependencies, thus there is no update in the executable.
Here is my makefile:
EXEC ?= program
SRCS = $(shell find -name *.cc)
DEP = $(SRCS:.cc=.d)
OBJDIR = objs
OBJS = $(SRCS:./%.cc=$(OBJDIR)/%.o)
CXX = g++
CFLAGS = -std=c++14 $(addprefix "-I", $(shell find -type d))
## Clean rule
.PHONY: clean
clean:
rm -rf $(OBJDIR)
rm -f $(EXEC)
$(EXEC) : $(OBJS)
#echo "Linking: $#"
$(CXX) $(OBJS) -o $#
-include $(DEP)
$(OBJDIR)/%.o : ./%.cc ./%.hh
#mkdir -p $(#D)
#echo "Compiling: $<"
#$(CXX) -c $(CFLAGS) -MT $# -MMD -MP -o $# $<
It is probably something related to the flag used by g++ but I do not manage to find the solution;
Thanks in advance for the help that you can provide on this issue,
If you do not specify the filename for the generated dependency files, it is going to be ${#:%.o=%.d} (compiler logic). I.e. your dependency files are in $(OBJDIR) and not in ./ where your makefile expects them to be.
Two alternative solutions:
DEP := $(OBJS:%.o=%.d).
#$(CXX) -c $(CFLAGS) -MT $# -MMD -MP -MF $(<:%.cc=%.d) -o $# $<

Recursive makefile for c++ source

I've been struggling with makefiles for a while now, since I don't really get how they work...
My directory structure is as followed:
--bin/
--build/
--includes/
--src/
----classes/
------somefiles.hpp
------somefiles.cpp
----states/
------somestates.hpp
----main.cpp
----few-other-files.cpp
--Makefile
--.gitignore
Which worked fine with my makefile, until I started adding those subdirs, classes and states
I can't seem to find how to include those subdirs in my makefile which is:
CC := g++
SRCDIR := src
BUILDDIR := build
TARGET := bin/game
SRCEXT := cpp
SOURCES := $(shell find $(SRCDIR) -type f -name *.$(SRCEXT))
OBJECTS := $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%,$(SOURCES:.$(SRCEXT)=.o))
CFLAGS := -g -Wall
LIB := -lsfml-audio -lsfml-graphics -lsfml-network -lsfml-system -lsfml-window
INC := -I includes -I /usr/local/include -L /usr/local/lib
$(TARGET): $(OBJECTS)
#echo "Linking..."
#echo "$(CC) $^ -o $(TARGET) $(LIB)"; $(CC) $^ -o $(TARGET) $(LIB)
$(BUILDDIR)/%.o: $(SRCDIR)/%.$(SRCEXT)
#mkdir -p $(BUILDDIR)
#echo "$(CC) $(CFLAGS) $(INC) -c -o $# $<"; $(CC) $(CFLAGS) $(INC) -c -o $# $<
clean:
#echo "Cleaning..."
#echo "$(RM) -r $(BUILDDIR) $(TARGET)"; $(RM) -r $(BUILDDIR) $(TARGET)
.PHONY: clean
Problem: Fatal error: can't create build/classes/stateManager.o: No such file or directory
Normally, the problem is that it can't build the directory. But I thought the mkdir -p would solve that.
Any help is greatly appreciated.
Replace:
mkdir -p $(BUILDDIR)
with
mkdir -p $(#:D)
Another way is to let make treat directories as targets and have them automatically created for you, so that you do not have to clutter your recipes with mkdir -p invocations:
.SECONDEXPANSION:
# Make the object file depend on its directory using order-only dependency.
$(BUILDDIR)/%.o: $(SRCDIR)/%.$(SRCEXT) | $$(dir $$#)
$(CC) $(CFLAGS) $(INC) -c -o $# $<
# Let make create the directories for your targets.
%/:
mkdir -p $#
# Do not remove the directories because they are "intermediate" targets.
.PRECIOUS : %/

How to add cap_net_raw capability via a Makefile to c++ executable file on linux

I have created a c++ that runs on Linux and on of its functionalities is to ping on a provided host. The ping has been based on relevant Poco libraries. However in order to run successfully on linux the produced c++ executable file should have the cap_net_raw capability set by giving
setcap cap_net_raw=ep /bin/C++_APP
I have also used the following Makefile based on an example I found by googling.
CC := g++
# Folders
SRCDIR := src
BUILDDIR := build
TARGETDIR := bin
# Targets
EXECUTABLE := C++_APP
TARGET := $(TARGETDIR)/$(EXECUTABLE)
SRCEXT := cpp
SOURCES := $(shell find $(SRCDIR) -type f -name *.$(SRCEXT))
OBJECTS := $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%,$(SOURCES:.$(SRCEXT)=.o))
CFLAGS := -c -Wall
INC := -I include -I /usr/local/include
LIB := -L /usr/local/lib -lPocoFoundation -lPocoNet -lPocoUtil
$(TARGET): $(OBJECTS)
#echo " Linking..."
#echo " $(CC) $^ -o $(TARGET) $(LIB)"; $(CC) $^ -o $(TARGET) $(LIB)
$(BUILDDIR)/%.o: $(SRCDIR)/%.$(SRCEXT)
#mkdir -p $(BUILDDIR)
#echo " $(CC) $(CFLAGS) $(INC) -c -o $# $<"; $(CC) $(CFLAGS) $(INC) -c -o $# $<
clean:
#echo " Cleaning...";
#echo " $(RM) -r $(BUILDDIR) $(TARGET)"; $(RM) -r $(BUILDDIR) $(TARGET)
.PHONY: clean
I added the following command as the last build command
#echo "Setting Capabilities"; sudo setcap cap_net_raw=ep $(TARGETDIR)/$(EXECUTABLE)
However I got the following error:
Failed to set capabilities on file `bin/NPT' (Invalid argument) The
value of the capability argument is not permitted for a file. Or the
file is not a regular (non-symlink) file
On the other hand when I give the command after the build of the c++ executable everything works fine. What am I doing wrong?
You added the command at the wrong place. You need to add it after the executable is made, not before. Try this:
$(TARGET): $(OBJECTS)
#echo " Linking..."
#echo " $(CC) $^ -o $(TARGET) $(LIB)"; $(CC) $^ -o $(TARGET) $(LIB)
#echo " Setting Capabilities"; sudo setcap cap_net_raw=ep $(TARGET)

Makefile for building C++ Google Protocol Buffers Project

I Just started fooling around using Google Protocol Buffers and I am trying to incorporate the C++ output files from the protocol buffer compiler into my project. I have Been using a simple makefile for my projects so far and it does the trick for building source files all sharing the same extension. I use ".cpp" for my source files but Google Protocol Buffers outputs its source as ".pb.cc" files. I need to be able to compile and link both types of source files into one executable.
I have been searching and fiddling around with my makefile for a few hours now and have had no success.
My Current Makefile:
PROGRAM_NAME=aserv
CC=gcc
CXX=g++
RM=rm -f
CPPFLAGS=-g --std=c++14 -O3 -I/usr/local/include/
LDFLAGS=-g -L/usr/local/lib -L/usr/local/lib/boost
LDLIBS= -lrtaudio -pthread -lboost_system -lprotobuf
INSTALL_DIR = /usr/local/bin/
SRCS=$(wildcard *.cpp)
OBJS=$(subst .cpp,.o,$(SRCS))
all: $(PROGRAM_NAME)
$(PROGRAM_NAME): $(OBJS)
$(CXX) $(LDFLAGS) -o $(PROGRAM_NAME) $(OBJS) $(LDLIBS)
depend: .depend
.depend: $(SRCS)
rm -f ./.depend
$(CXX) $(CPPFLAGS) -MM $^>>./.depend;
clean:
$(RM) $(OBJS) $(PROGRAM_NAME) .depend
install:
cp $(PROGRAM_NAME) $(INSTALL_DIR)$(PROGRAM_NAME)
uninstall:
$(RM) $(INSTALL_DIR)$(PROGRAM_NAME)
dist-clean: clean
$(RM) *~ .depend
include .depend
I am not too well versed in writing makefiles yet, so I just don't quite know what to do to make this work.
If it helps i have GNU make 4.1 and gcc 5.3.1 on Ubuntu 16.04 beta
I couldnt get your original Makefile to work so I changed a few things but I think the tricky part with this is the implicit rules that make generates to build your .o files. I think for the .pb.cc files you need to generate .pb.o objects so that the implicit rules can match them.
Try this:
PROGRAM_NAME = aserv
CC = gcc
CXX = g++
RM = rm -f
CXXFLAGS = --std=c++14 -pthread -g -O3 -MMD -MP
CPPFLAGS = -I/usr/local/include/
LDFLAGS = -L/usr/local/lib -L/usr/local/lib/boost
LDLIBS = -lrtaudio -lboost_system -lprotobuf
INSTALL_DIR = /usr/local/bin
SRCS = $(wildcard *.cpp) $(wildcard *.pb.cc)
OBJS = $(subst .pb.cc,.pb.o,$(subst .cpp,.o,$(SRCS)))
DEPS = $(subst .pb.cc,.pb.d,$(subst .cpp,.d,$(SRCS)))
all: $(PROGRAM_NAME)
$(PROGRAM_NAME): $(OBJS)
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -o $# $^ $(LDFLAGS) $(LDLIBS)
-include $(DEPS)
clean:
$(RM) $(OBJS) $(PROGRAM_NAME)
install:
cp $(PROGRAM_NAME) $(INSTALL_DIR)
uninstall:
$(RM) $(INSTALL_DIR)/$(PROGRAM_NAME)
dist-clean: clean
$(RM) *~ $(DEPS)
If you wanto to only strictly rely on Make, and not the surrounding shell you can add another set of SRC and OBJ variables, which will serve as a second set of dependencies.
Add these right below the first set:
SRC1=$(wildcard *.pb.cc)
OBJ1=$(subst .pb.cc,.o,$(SRC1))
And change the .depend and $(PROGRAM_NAME) rule:
.depend: $(SRCS) $(SRC1)
$(PROGRAM_NAME): $(OBJS) $(OBJ1)
$(CXX) $(LDFLAGS) $^ $(LDLIBS) -o $#
%.o: %.c
$(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) -c -o $# $<

Makefile C++11 - Compiling to static library

I am trying to compile my source files to a static library, however, it doesn't seem to want to work. Here is the code:
#-----------------------------------------------------------------------------
# Usage of make file
#-----------------------------------------------------------------------------
# Clean operation:
# make -f MakeClient clean
#
# Make operation:
# make -f MakeClient
#
#
#OBJ = $(SRC:.cpp=.o)
OBJ_DIR = ./obj
OUT_DIR= ../lib
OUT_FILE_NAME = libclient.a
# include directories
INCLUDES=-I. -I../common -I../../depends -I../../depends/zlib
# C++ compiler flags (-g -O2 -Wall)
CXXFLAGS := -Wall -Wextra -pedantic-errors -std+c++0x
# compiler
CCC = g++
# Enumerating of every *.cpp as *.o and using that as dependency
$(OUT_FILE_NAME): $(patsubst %.cpp,$(OBJ_DIR)/%.o,$(wildcard *.cpp))
$(CCC) -o $(OUT_DIR)/$# $^ -static $(LIB_DIR) $(LIBS) -std=c++11
#Compiling every *.cpp to *.o
$(OBJ_DIR)/%.o: %.cpp dircreation
$(CCC) -c $(INCLUDES) $(CCFLAGS) -o $# $<
dircreation:
#mkdir -p $(OUT_DIR)
#mkdir -p $(OBJ_DIR)
.PHONY : clean
clean:
rm -f $(OBJ_DIR)/*.o $(OUT_DIR)/$(OUT_FILE_NAME) Makefile.bak
The problem seems to be recognising that I'm using C++11 since the actual code does not compile.
Any ideas?
Replace CCFLAGS with CXXFLAGS, or vice versa.
And the flag is spelled -std=c++0x (thanks, #Pixelchemist).