如何在C++ Makefile中处理.cpp与.cxx混合源文件的规则?
Great start on structuring your Makefile with separate source and object directories! Let's build out the rules to handle both .cpp and .cxx files smoothly. Here's a step-by-step breakdown and complete example:
1. Collect All Source Files
First, we'll grab every .cpp and .cxx file across your source subfolders using wildcard and foreach:
# Collect all .cpp and .cxx sources across all source subfolders SRCS = $(foreach dir, $(SRCSUBFOLDERS), $(wildcard $(dir)/*.cpp $(dir)/*.cxx))
2. Map Sources to Object Files
Next, convert those source paths to corresponding .o files in your OBJDIR (replacing src/ with obj/ and swapping the source extensions for .o):
# Convert source files to object files (preserve directory structure) OBJS = $(patsubst $(SRCDIR)/%.cpp, $(OBJDIR)/%.o, $(filter %.cpp, $(SRCS))) \ $(patsubst $(SRCDIR)/%.cxx, $(OBJDIR)/%.o, $(filter %.cxx, $(SRCS)))
3. Ensure Object Directories Exist
We need to make sure all the subdirectories in OBJDIR exist before compiling. Use an order-only prerequisite (the | syntax) so Make doesn't recompile files just because the directory was touched:
# Create object subdirectories if they don't exist $(OBJSUBFOLDERS): mkdir -p $@
4. Compilation Rules for Both Extensions
Write pattern rules to handle compiling .cpp and .cxx files separately (they'll use the same compiler flags, since both are C++ sources):
# Compiler and flags (adjust these to your project needs) CXX = g++ CXXFLAGS = -Wall -Wextra -g -O2 # Rule for .cpp -> .o $(OBJDIR)/%.o: $(SRCDIR)/%.cpp | $(OBJSUBFOLDERS) $(CXX) $(CXXFLAGS) -c $< -o $@ # Rule for .cxx -> .o $(OBJDIR)/%.o: $(SRCDIR)/%.cxx | $(OBJSUBFOLDERS) $(CXX) $(CXXFLAGS) -c $< -o $@
5. Link the Executable
Finally, add a rule to link all your object files into the final executable:
# Define your target executable name TARGET = my_project # Link object files to create the executable $(TARGET): $(OBJS) $(CXX) $(CXXFLAGS) $^ -o $@
6. Add a Clean Rule
Don't forget a clean rule to tidy up object files and the executable:
# Phony target to avoid conflicts with files named "clean" .PHONY: clean clean: rm -rf $(OBJDIR) $(TARGET)
Full Combined Makefile
Here's how it all fits with your existing setup:
# Folders SRCDIR = src OBJDIR = obj SUBFOLDERS = test test/test2 OBJSUBFOLDERS = $(OBJDIR) $(addprefix $(OBJDIR)/, $(SUBFOLDERS)) SRCSUBFOLDERS = $(SRCDIR) $(addprefix $(SRCDIR)/, $(SUBFOLDERS)) # Collect sources SRCS = $(foreach dir, $(SRCSUBFOLDERS), $(wildcard $(dir)/*.cpp $(dir)/*.cxx)) # Map to objects OBJS = $(patsubst $(SRCDIR)/%.cpp, $(OBJDIR)/%.o, $(filter %.cpp, $(SRCS))) \ $(patsubst $(SRCDIR)/%.cxx, $(OBJDIR)/%.o, $(filter %.cxx, $(SRCS))) # Compiler setup CXX = g++ CXXFLAGS = -Wall -Wextra -g -O2 # Target executable TARGET = my_project # Create object directories $(OBJSUBFOLDERS): mkdir -p $@ # Compile .cpp files $(OBJDIR)/%.o: $(SRCDIR)/%.cpp | $(OBJSUBFOLDERS) $(CXX) $(CXXFLAGS) -c $< -o $@ # Compile .cxx files $(OBJDIR)/%.o: $(SRCDIR)/%.cxx | $(OBJSUBFOLDERS) $(CXX) $(CXXFLAGS) -c $< -o $@ # Link target $(TARGET): $(OBJS) $(CXX) $(CXXFLAGS) $^ -o $@ # Cleanup .PHONY: clean clean: rm -rf $(OBJDIR) $(TARGET)
This setup will automatically find all your .cpp and .cxx files, compile them to the correct object directories, and link everything into your target executable. Adjust CXXFLAGS and TARGET to match your project's needs!
内容的提问来源于stack exchange,提问作者code_fodder

