Skip to content

Instantly share code, notes, and snippets.

@SofijaErkin
Last active March 21, 2022 03:11
Show Gist options
  • Save SofijaErkin/43e1725831d067a4e0dbc06a95d3b576 to your computer and use it in GitHub Desktop.
Save SofijaErkin/43e1725831d067a4e0dbc06a95d3b576 to your computer and use it in GitHub Desktop.
C/C++ Function main directory differ from Sources Directory manually makefile

C/C++ Main Directory Differ Sources Directory Makefile Manually

This is a Makefile about Function main directory differing from sources directory.

Amazing Notice:

Please double check the filename of the VSCode configuration file.

e.g:

tasks.json

launch.json

c_cpp_properties.json

settings.json

A week ago, I made a mistake: I wrote "tasks.json" as "task.json". As a result,

VSCode always reports the error "cannot find tasks.json file". I always thought:

I wrote "task.json", why there is no "tasks.json". It took a week to change the

configuration file, only to find out today that there is a problem with the file

naming. Oh! I am silly.

Notice:

This is my workspace environment!

Clang: 9.0.0;

Llvm-gcc: 4.2.1;

Visual Studio Code v1.63.2;

Code Runner v0.11.6 (Author: Jun Han);

CodeLLDB v1.4.5 or v1.5.0 (Author: Vadim Chugunov).

Now:

This workspace named bodyAndFit, including 5 directories, 8 files.

The Architecture of workspace bodyAndFit are:

bodyAndFit

|

|_.vscode

|     |__c_cpp_properties.json

|     |__launch.json

|     |__settings.json

|     |__tasks.json

|__Makefile

|__build

|__inc

|     |__bodyandfit.h

|__common

      |__main.cpp

|__src

     |__bodyandfit.cpp

src: source file folder.

bodyandfit.cpp: This project connected source function.

common: main file folder.

main.cpp: This project main function.

inc: source file folder.

bodyandfit.h: This project connected include function.

build: build task folder, Debug folder, Executable file.

Makefile: Makefile to manually build bodyAndFit program.

.vscode: VSCode configuration folder.

tasks.json: This task will invoke the Clang C++ compiler to create an

executable file from the source code.

settings.json: Workspace Settings.

launch.json: configure VS Code to launch the LLDB debugger when you press

F5 to debug the program.

c_cpp_properties.json: allows you to change settings such as the path to

the compiler, include paths.

Big hanker manually Notice:

1.The best way to debug Makefile is using "

.PHONY: all
all:
echo $(variable)

". eg:

.PHONY: all

all:

echo $(CXX)

echo $(CXX_FLAGS)

echo $(BUILD_DIR)

echo $(SRC_DIRS)

echo $(LIBDIR)

echo $(LIBS)

echo $(TARGET)

echo $(SRCS)

echo $(OBJS)

echo $(DEPS)

echo $(INC_DIRS)

echo $(INC_FLAGS)

echo $(CPP_FLAGS)

2.Multiple separated sources directory generate object files:

If all the sources files including the main function are separated directory,

Then you need to generate the object files via one by one directory.

#include "../bin/bank.h"
#include <chrono>
#include <cstdlib>
#include <iostream>
#include <algorithm>
// #include <algorithm>
// std::sort(work_quque_, work_queue_ + queue_number_,
// [](const std::quque<QueueNode> &q1,
// const std::queue<QueueNode> $q2) -> bool
// {return q1.size() < q2.size();});
Bank::Bank(int window_numbers, int close_time)
: queue_number_(window_numbers), close_time_(close_time),
total_time_(0), customer_number_(0) {
work_queue_ = new std::queue<QueueNode>[window_numbers];
srand(std::chrono::system_clock
::to_time_t(std::chrono::system_clock::now()));
}
Bank::~Bank() {
delete[] work_queue_;
}
void Bank::OpenForDay() {
Event event_push_back_list;
event_push_back_list.occur_time = 0;
event_push_back_list.type = 0;
event_list_.push_back(event_push_back_list);
// event_list_.push_back({0,0});
// //the first customer arrived
}
// the event of arrivalling customer
// Do the below things:
// one: rand the time for customer's duration
// two: rand the time for the next customer arrivalling
// three: push back the arrivalling customer into the shortest working queue
void Bank::CustomerArrived(Event *event) {
++customer_number_;
int duration_time, inter_time;
// the durating time of the arrivalling customer
duration_time = rand() % 1800 + 1; //the biggest duration is 30minutes
// the next customer arrivalling after event->occur_time+inter_time
inter_time = rand() % 600 + 1; // inter_time <= 10 minutes
// the arrivalling time of next customer
int next_customer_arrival_time = event->occur_time + inter_time;
// if the bank openning
if(next_customer_arrival_time < close_time_) {
Event customer_arrival_event;
customer_arrival_event.occur_time = next_customer_arrival_time;
customer_arrival_event.type = 0;
event_list_.push_back(customer_arrival_event);
// event_list_.push_back({next_customer_arrival_time, 0});
// sort the list of eveent via the time of arrival, first in first out
SortEventList();
}
// chose the shortest queue to push back
int number_shortest_queue;
number_shortest_queue = FindShortestQueue();
QueueNode customer_push_queue;
customer_push_queue.arrival_time = event->occur_time;
customer_push_queue.duration_time = duration_time;
work_queue_[number_shortest_queue].push(customer_push_queue);
//work_queue_[number_shortest_queue].push({event->occur_time, duration_time});
if(work_queue_[number_shortest_queue].size() == 1) {
// the number of shortest queue :first customer's departure event
// occurring
Event first_customer_departure_event;
first_customer_departure_event.occur_time = event->occur_time + duration_time;
first_customer_departure_event.type = number_shortest_queue +1;
event_list_.push_back(first_customer_departure_event);
// event_list_.push_back(
// {event->occur_time + duration_time, number_shortest_queue + 1});
SortEventList();
}
}
void Bank::CustomerDeparture(Event *event) {
int rest_event_type = event->type - 1;
QueueNode leaving_customer;
//finish the event of departuration, customer leaving
leaving_customer = work_queue_[rest_event_type].front();
work_queue_[rest_event_type].pop();
total_time_ += event->occur_time - leaving_customer.arrival_time;
// the departuring event of the rest_event_type times queue
if(!work_queue_[rest_event_type].empty()) {
leaving_customer = work_queue_[rest_event_type].front();
Event leaving_event;
leaving_event.occur_time = leaving_customer.duration_time + event->occur_time;
leaving_event.type = rest_event_type + 1;
event_list_.push_back(leaving_event);
// event_list_.push_back(
// {leaving_customer.duration_time + event->occur_time,
// rest_event_type + 1});
SortEventList();
}
}
int Bank::FindShortestQueue() {
int num_shortest_queue = 0;
for (int i = 0; i < queue_number_; ++i) {
if(work_queue_[num_shortest_queue].size() > work_queue_[i].size())
num_shortest_queue = i;
}
return num_shortest_queue;
}
void Bank::SortEventList() {
// std::sort(event_list_.begin(), event_list_.end(),
// [](const Event &event1, const Event &event2){
// return event1.occur_time < event2.occur_time;
// }
//);
//struct event_lessThan{
// bool operator()(Event const &event1, Event const &event2) const{
// return event1.occur_time < event2.occur_time;
// }
//};
//sort(event_list_.begin(), event_list_.end(), event_lessThan());
// bool operator<(const Event &e2,const Event &e2);
//bool opeartor<(const Event &event1, const Event &const2) {
// return event1.occur_time < event2.occur_time;
//}
//event_list_.sort(event_list_.begin(), event_list_.end() );
event_list_.sort();
// Lambda expression:
// event_list_.sort(
// [](const Event &event1, const Event &event2) -> bool
// {return event1.occur_time < event2.occur_time;});
// write a function to compare two struct event
// turn Lambda expression into a function
// as the paramter of sort();
// Also, struct Event::operator<:
//
//bool return_lambda = operator<(const Event &event1);
//event_list_.sort(event_list_.begin(), event_list_.end(), return_lambda);
}
void Bank::Simulation() {
OpenForDay();
Event front_event_list;
while(!event_list_.empty()) {
front_event_list = event_list_.front();
event_list_.pop_front();
if(front_event_list.type == 0) // arrival event
CustomerArrived(&front_event_list);
else
CustomerDeparture(&front_event_list);
}
// calculate and output the average time of staying in Bank
//std::cout << L"the number of customer:" << customer_number_ << std::endl
// << L"the total time of staying(hour):" << (double)total_time_ / 3600.0
// << std::endl
// << L"the average time of staying(minutes):"
// << (double)total_time_ / (double)(customer_number_ * 60)
// << std::endl;
std::cout << "the number of customer:" << customer_number_ << std::endl
<< "the total time of staying(hour):" << (double)total_time_ / 3600.0
<< std::endl
<< "the average time of staying(miniutes):"
<< (double)total_time_ / (double)(customer_number_ * 60)
<< std::endl;
}
#ifndef _BANK_H_
#define _BANK_H_
#include <queue>
#include <list>
struct Event {
int occur_time; // the time of occurring event
int type; // the type of event, arrive via 0, back via from 1 to 4
bool operator<(const Event &rhs) const {
return this->occur_time < rhs.occur_time;
}
/*
bool operator()(const Event &ths, const Event &rhs) const {
return ths.occur_time < rhs.occur_time;
}
*/
};
struct QueueNode {
int arrival_time; // the time of arrivalling customer
int duration_time; //the time of customer's suration
};
class Bank {
public:
explicit Bank(int window_numbers = 4, int close_time = 8 * 3600);
~Bank();
void Simulation();
private:
int queue_number_; // the number of queue
int close_time_; // the time of close
int total_time_; // the total time of customer
int customer_number_; // the number of customer
std::list<Event> event_list_; // the list of event
std::queue<QueueNode> *work_queue_; // the queue of work
void OpenForDay();
void CustomerArrived(Event *event);
void CustomerDeparture(Event *event);
int FindShortestQueue();
void SortEventList();
};
#endif
{
"configurations": [
{
"name": "Mac",
"includePath": [
"${workspaceFolder}/**",
// This is the include files directory
"${workspaceFolder}/inc/**", // Have Change
"/Library/Developer/CommandLineTools/usr/include",
"/Library/Developer/CommandLineTools/usr/lib/clang/9.0.0/include",
"/usr/local/include",
"/Library/Developer/CommandLineTools/usr/include/c++/v1",
"/usr/include"
],
"defines": [],
"macFrameworkPath": [
"/System/Library/Frameworks",
"/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks",
"/Library/Frameworks"
],
// Just use Clang compiler
"compilerPath": "/usr/bin/clang", // Have Change
"cStandard": "c11",
"cppStandard": "c++11",
"intelliSenseMode": "clang-x64"
}
],
"version": 4
}
.PHONY: all

all:

echo $(CXX)

echo $(CXX_FLAGS)

echo $(BUILD_DIR)

echo $(SRC_DIRS)

echo $(LIBDIR)

echo $(LIBS)

echo $(TARGET)

echo $(SRCS)

echo $(OBJS)

echo $(DEPS)

echo $(INC_DIRS)

echo $(INC_FLAGS)

echo $(CPP_FLAGS)


.PHONY: all

all:

echo $(CXX)

echo $(CXX_FLAGS)

echo $(BUILD_DIR)

echo $(SRC_DIRS)

echo $(SRC_DIRS_COMMON)

echo $(LIBDIR)

echo $(LIBS)

echo $(TARGET)

echo $(SRCS)

echo $(SRCS_COMMON)

echo $(OBJS)

echo $(OBJS_COMMON)

echo $(DEPS)

echo $(DEPS_COMMON)

echo $(INC_DIRS)

echo $(INC_FLAGS)

echo $(CPP_FLAGS)

.PHONY: all

all:

echo $(CXX)

echo $(CXX_FLAGS)

echo $(BUILD_DIR)

echo $(SRC_DIRS)

echo $(SRC_DIRS_SRC)

echo $(LIBDIR)

echo $(LIBS)

echo $(TARGET)

echo $(SRCS)

echo $(SRCS_SRC)

echo $(OBJS)

echo $(OBJS_SRC)

echo $(DEPS)

echo $(DEPS_SRC)

echo $(INC_DIRS)

echo $(INC_FLAGS)

echo $(CPP_FLAGS)
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Debug With LLDB",
"type": "lldb",
"request": "launch",
// "program" is the target file diretory
"program": "${workspaceFolder}/build/${fileBasenameNoExtension}", // Have changed
"args": [],
"stopAtEntry": true,
//"cwd": "${workspaceFolder}/../build",// Have changed
//"cwd": "${fileDirName}", ${workspaceFolder}/../build
// Changes the current working directory directive ("cwd") to the folder
// where main.cpp is.
// This "cwd" is the same as "cwd" in the tasks.json
// That's the source files directory
"cwd": "${workspaceFolder}/common", // Have changed
"environment": [],
"externalConsole": false,
"preLaunchTask": "Compile With clang++"
}
]
}
#include "../bin/bank.h"
#include <iostream>
#include <clocale>
int main(int argc, char *argv[], char*env[]) {
std::setlocale(LC_ALL, "");
// std::setlocale(LC_ALL, L"");
Bank bank;
bank.Simulation();
return 0;
}
# -Only Separatedly Generate Object Files But Generate Main Object Add Directory Makefile-
# BIG BIG BIG NEWS
# This Makefile file : generate object file one by one directory
# Also add main object sources files directory to generate main object
# ----------------------------------------------------------------------------------------
# This is a Makefile fot separated multiple sources to build with VSCode on mac
# Thanks, Job Vranish.
# (https://spin.atomicobject.com/2016/08/26/makefile-c-projects/)
# Reference: Makefile Tutorial
# (https://makefiletutorial.com/)
# Reference: @yagiyuki from Qiita
# (https://qiita.com/yagiyuki/items/ff343d381d9477e89f3b)
# Reference: simonsso from Github
# (https://github.com/simonsso/empty-cpp-project/blob/master/Makefile)
# Reference: Chinese Website blogger CDNS
# (https://blog.csdn.net/qq_22073849/article/details/88893201)
# (1)Compiler
# clang++
CXX = clang++
# CXX = g++
# (2)Compile options
# -Wall -Wextra -std=c++11 -g
CXX_FLAGS = -Wall -Wextra -std=c++11 -g
# (3)Build task directory path
# I do care about out-of-source builds
# ./build
BUILD_DIR ?= ./build
# (4)Source files directory path
# ./src
SRC_DIRS ?= .
SRC_DIRS_SRC ?= ./src
# (5)Library files directory path
LIBDIR :=
# (6)Add library files
LIBS :=
# (7)Target file, excutable file.
#TARGET := main
#TARGET := ${BUILD_DIR}/main
# main
TARGET ?= main
# BUILD_TARGET = ${BUILD_DIR}/${TARGET}
# (8)Source files(code), to be compiled
# Find source files we want to compile
# *expression must around by single quotos
# SRCS = $(wildcard ./src/*.cpp)
# ./src/bank.cpp ./src/main.cpp
SRCS := $(shell find $(SRC_DIRS) -name '*.cpp' -or -name '*.c' -or -name '*.s')
SRCS_SRC := $(shell find $(SRC_DIRS_SRC) -name '*.cpp' -or -name '*.c' -or -name '*.s')
# (9)Object files
# String substituion for every C/C++ file
# e.g: ./src/bank.cpp turns into ./build/bank.cpp.o
#
# ./src/bank..o ./src/main..o
# OBJS = $(patsubst %cpp,%.o,$(SRCS))
# Just prepend a $(BUILD_DIR)/ and append a .o to every source file path:
# ./build/../src/bank.cpp.o
# OBJS := $(SRCS:%=$(BUILD_DIR)/.%.o)
# ./src/bank.cpp.o ./src/main.cpp.o
# OBJS := $(subst $(SRCS),$(BUILD_DIR),$(SRCS:.cpp=.cpp.o))
# ./build/bank.cpp.o ./build/main.cpp.o
# OBJS := $(SRCS:$(SRC_DIRS)/%.cpp=$(BUILD_DIR)/%.cpp.o)
# ./build/bank.o ./build/main.o
# OBJS := $(SRCS:$(SRC_DIRS)/%.cpp=$(BUILD_DIR)/%.o)
# ./build/bank.cpp.o ./build/main.cpp.o
OBJS := $(patsubst %.cpp, ${BUILD_DIR}/%.cpp.o, $(notdir $(SRCS)))
OBJS_SRC := $(patsubst %.cpp, ${BUILD_DIR}/%.cpp.o, $(notdir $(SRCS_SRC)))
# make: *** build: Is a directory. Stop.
# OBJS := $(patsubst %.cpp, ${BUILD_DIR}/%.cpp.o, $(notdir $(BUILD_DIR)))
# (10)Dependency files
# which will generate a .d file next to the .o file. Then to use the .d files,
# you just need to find them all:
#
DEPS := $(OBJS:.o=.d)
DEPS_SRC := $(OBJS_SRC:.o=.d)
# (11)Include files directory path
# Every folder in ./src find include files to be passed via clang
# INCDIR = -I./inc
# INC_DIR = ./inc
# ./inc
INC_DIRS := ./bin
# If use below this , include files should be at the same directory
# with sources files.
# INC_DIRS := $(shell find $(SRC_DIRS) -type d)
# (12)Include files add together a prefix, clang make sense that -I flag
# INCS = -I$(INC_DIR)
INC_FLAGS := $(addprefix -I,$(INC_DIRS))
# LIBS_FLAGS := $(addprefix -L,$(LIBS))
# (13)Make Makefiles output Dependency files
# That -MMD and -MP flags together to generate Makefiles
# That generated Makefiles will take .o as .d to the output
# That "-MMD" and "-MP" To generate the dependency files, all you have to do is
# add some flags to the compile command (supported by both Clang and GCC):
CPP_FLAGS ?= $(INC_FLAGS) -MMD -MP
# Link: Generate executable file from object file
# make your target depend on the objects files:
${BUILD_DIR}/${TARGET} : $(OBJS)
#${BUILD_DIR}/${TARGET} : $(OBJS) $(OBJS_SRC)
$(CXX) $^ -o $@
# $(CXX) $^ -o $@ $(LIBS_FLAGS)
# $(CXX) $(OBJS) $(OBJS_SRC) -o ${TARGET}
# Compile: Generate object files from source files
# $@ := {TARGET}
# $< := THE first file
# $^ all the dependency
# C++ Sources
#
# BREAK NEWS!!!
# If all the sources files including the main function are separated directory,
# Then you need to generate the object files via one by one directory
#
# clang++ -I./inc -MMD -MP -Wall -Wextra -std=c++11 -g -c main.cpp src/bank.cpp -o build/main.cpp.o
# clang: error: cannot specify -o when generating multiple output files
# make: *** [build/main.cpp.o] Error 1
#$(OBJS) : $(SRCS)
# make: *** No rule to make target `build/main.cpp.o', needed by `build/main'. Stop.
# $(BUILD_DIR)/%.cpp.o : $(SRC_DIRS)/%.cpp
$(BUILD_DIR)/%.cpp.o : $(SRC_DIRS)/common/%.cpp
$(MKDIR_P) $(dir $@)
$(CXX) $(CPP_FLAGS) $(CXX_FLAGS) -c $^ -o $@
$(BUILD_DIR)/%.cpp.o : $(SRC_DIRS_SRC)/%.cpp
$(CXX) $(CPP_FLAGS) $(CXX_FLAGS) -c $^ -o $@
# C Language Sources
# # CC := clang
# # C_FLAGS = -Wall -Wextra -std=c11 -g
# $(BUILD_DIR)/%.c.o: $(SRC_DIRS)/%.c
# $(MKDIR_P) $(dir $@)
# $(CC) $(CPPFLAGS) $(C_FLAGS) -c $< -o $@
# Assembly Langusge Sources
# # AS := NASM/
# # ASFLAGS := # I DO NOT KNOW
# $(BUILD_DIR)/%.s.o: $(SRC_DIRS)/%.s
# $(MKDIR_P) $(dir $@)
# $(AS) $(ASFLAGS) -c $< -o $@
.PHONY: clean
clean:
# rm ./build/./build/bank.cpp.d ./build/main.cpp.d ./build/ ./build/bank.cpp.o ./build/main.cpp.o ./build/main
# rm: ./build/./build/bank.cpp.d: No such file or directory
# rm: ./build/: is a directory
# make: *** [clean] Error 1
#rm ${BUILD_DIR}/$(DEPS) ${BUILD_DIR}/$(OBJS) ${BUILD_DIR}/${TARGET}
# ld: can't open output file for writing: /Users/yq/VSCode/CppProject/fitBodyFarm/build/main, errno=2 for architecture x86_64
# clang: error: linker command failed with exit code 1 (use -v to see invocation)
# $(RM) -r $(BUILD_DIR)
$(RM) $(DEPS) $(OBJS) ${BUILD_DIR}/${TARGET}
-include $(DEPS)
MKDIR_P ?= mkdir -p
# Just use ".PHONY: all" to debug my Makefile.
# Just use "all:" to debug my Makefile.
# Just use "echo $(variable)" to debug my Makefile.
# eg:
# .PHONY: all
# all:
# echo $(CXX)
# echo $(CXX_FLAGS)
# echo $(BUILD_DIR)
# echo $(SRC_DIRS)
# echo $(LIBDIR)
# echo $(LIBS)
# echo $(TARGET)
# echo $(SRCS)
# echo $(OBJS)
# echo $(DEPS)
# echo $(INC_DIRS)
# echo $(INC_FLAGS)
# echo $(CPP_FLAGS)
#
# OR
# .PHONY: all
# all:
# echo $(CXX)
# echo $(CXX_FLAGS)
# echo $(BUILD_DIR)
# echo $(SRC_DIRS)
# echo $(SRC_DIRS_SRC)
# echo $(LIBDIR)
# echo $(LIBS)
# echo $(TARGET)
# echo $(SRCS)
# echo $(SRCS_SRC)
# echo $(OBJS)
# echo $(OBJS_SRC)
# echo $(DEPS)
# echo $(DEPS_SRC)
# echo $(INC_DIRS)
# echo $(INC_FLAGS)
# echo $(CPP_FLAGS)
# --------Separated Generated Object Merge To Generate Target Makefile---------
# BIG BIG BIG NEWS
# This Makefile file : generate object file one by one directory
# Also Merge object files to generate target file
# -----------------------------------------------------------------------------
# This is a Makefile fot separated multiple sources to build with VSCode on mac
# Thanks, Job Vranish.
# (https://spin.atomicobject.com/2016/08/26/makefile-c-projects/)
# Reference: Makefile Tutorial
# (https://makefiletutorial.com/)
# Reference: @yagiyuki from Qiita
# (https://qiita.com/yagiyuki/items/ff343d381d9477e89f3b)
# Reference: simonsso from Github
# (https://github.com/simonsso/empty-cpp-project/blob/master/Makefile)
# Reference: Chinese Website blogger CDNS
# (https://blog.csdn.net/qq_22073849/article/details/88893201)
# (1)Compiler
# clang++
CXX = clang++
# CXX = g++
# (2)Compile options
# -Wall -Wextra -std=c++11 -g
CXX_FLAGS = -Wall -Wextra -std=c++11 -g
# (3)Build task directory path
# I do care about out-of-source builds
# ./build
BUILD_DIR ?= ./build
# (4)Source files directory path
# ./src
SRC_DIRS ?= ./common
SRC_DIRS_SRC ?= ./src
# (5)Library files directory path
LIBDIR :=
# (6)Add library files
LIBS :=
# (7)Target file, excutable file.
#TARGET := main
#TARGET := ${BUILD_DIR}/main
# main
TARGET ?= main
# BUILD_TARGET = ${BUILD_DIR}/${TARGET}
# (8)Source files(code), to be compiled
# Find source files we want to compile
# *expression must around by single quotos
# SRCS = $(wildcard ./src/*.cpp)
# ./src/bank.cpp ./src/main.cpp
SRCS := $(shell find $(SRC_DIRS) -name '*.cpp' -or -name '*.c' -or -name '*.s')
SRCS_SRC := $(shell find $(SRC_DIRS_SRC) -name '*.cpp' -or -name '*.c' -or -name '*.s')
# (9)Object files
# String substituion for every C/C++ file
# e.g: ./src/bank.cpp turns into ./build/bank.cpp.o
#
# ./src/bank..o ./src/main..o
# OBJS = $(patsubst %cpp,%.o,$(SRCS))
# Just prepend a $(BUILD_DIR)/ and append a .o to every source file path:
# ./build/../src/bank.cpp.o
# OBJS := $(SRCS:%=$(BUILD_DIR)/.%.o)
# ./src/bank.cpp.o ./src/main.cpp.o
# OBJS := $(subst $(SRCS),$(BUILD_DIR),$(SRCS:.cpp=.cpp.o))
# ./build/bank.cpp.o ./build/main.cpp.o
# OBJS := $(SRCS:$(SRC_DIRS)/%.cpp=$(BUILD_DIR)/%.cpp.o)
# ./build/bank.o ./build/main.o
# OBJS := $(SRCS:$(SRC_DIRS)/%.cpp=$(BUILD_DIR)/%.o)
# ./build/bank.cpp.o ./build/main.cpp.o
OBJS := $(patsubst %.cpp, ${BUILD_DIR}/%.cpp.o, $(notdir $(SRCS)))
OBJS_SRC := $(patsubst %.cpp, ${BUILD_DIR}/%.cpp.o, $(notdir $(SRCS_SRC)))
# make: *** build: Is a directory. Stop.
# OBJS := $(patsubst %.cpp, ${BUILD_DIR}/%.cpp.o, $(notdir $(BUILD_DIR)))
# (10)Dependency files
# which will generate a .d file next to the .o file. Then to use the .d files,
# you just need to find them all:
#
DEPS := $(OBJS:.o=.d)
DEPS_SRC := $(OBJS_SRC:.o=.d)
# (11)Include files directory path
# Every folder in ./src find include files to be passed via clang
# INCDIR = -I./inc
# INC_DIR = ./inc
# ./inc
INC_DIRS := ./bin
# If use below this , include files should be at the same directory
# with sources files.
# INC_DIRS := $(shell find $(SRC_DIRS) -type d)
# (12)Include files add together a prefix, clang make sense that -I flag
# INCS = -I$(INC_DIR)
INC_FLAGS := $(addprefix -I,$(INC_DIRS))
# LIBS_FLAGS := $(addprefix -L,$(LIBS))
# (13)Make Makefiles output Dependency files
# That -MMD and -MP flags together to generate Makefiles
# That generated Makefiles will take .o as .d to the output
# That "-MMD" and "-MP" To generate the dependency files, all you have to do is
# add some flags to the compile command (supported by both Clang and GCC):
CPP_FLAGS ?= $(INC_FLAGS) -MMD -MP
# Link: Generate executable file from object file
# make your target depend on the objects files:
#${BUILD_DIR}/${TARGET} : $(OBJS)
${BUILD_DIR}/${TARGET} : $(OBJS) $(OBJS_SRC)
$(CXX) $^ -o $@
# $(CXX) $^ -o $@ $(LIBS_FLAGS)
# $(CXX) $(OBJS) $(OBJS_SRC) -o ${TARGET}
# Compile: Generate object files from source files
# $@ := {TARGET}
# $< := THE first file
# $^ all the dependency
# C++ Sources
#
# BREAK NEWS!!!
# If all the sources files including the main function are separated directory,
# Then you need to generate the object files via one by one directory
#
# clang++ -I./inc -MMD -MP -Wall -Wextra -std=c++11 -g -c main.cpp src/bank.cpp -o build/main.cpp.o
# clang: error: cannot specify -o when generating multiple output files
# make: *** [build/main.cpp.o] Error 1
#$(OBJS) : $(SRCS)
$(BUILD_DIR)/%.cpp.o : $(SRC_DIRS)/%.cpp
$(MKDIR_P) $(dir $@)
$(CXX) $(CPP_FLAGS) $(CXX_FLAGS) -c $^ -o $@
$(BUILD_DIR)/%.cpp.o : $(SRC_DIRS_SRC)/%.cpp
$(CXX) $(CPP_FLAGS) $(CXX_FLAGS) -c $^ -o $@
# C Language Sources
# # CC := clang
# # C_FLAGS = -Wall -Wextra -std=c11 -g
# $(BUILD_DIR)/%.c.o: $(SRC_DIRS)/%.c
# $(MKDIR_P) $(dir $@)
# $(CC) $(CPPFLAGS) $(C_FLAGS) -c $< -o $@
# Assembly Langusge Sources
# # AS := NASM/
# # ASFLAGS := # I DO NOT KNOW
# $(BUILD_DIR)/%.s.o: $(SRC_DIRS)/%.s
# $(MKDIR_P) $(dir $@)
# $(AS) $(ASFLAGS) -c $< -o $@
.PHONY: clean
clean:
# rm ./build/./build/bank.cpp.d ./build/main.cpp.d ./build/ ./build/bank.cpp.o ./build/main.cpp.o ./build/main
# rm: ./build/./build/bank.cpp.d: No such file or directory
# rm: ./build/: is a directory
# make: *** [clean] Error 1
#rm ${BUILD_DIR}/$(DEPS) ${BUILD_DIR}/$(OBJS) ${BUILD_DIR}/${TARGET}
# ld: can't open output file for writing: /Users/yq/VSCode/CppProject/fitBodyFarm/build/main, errno=2 for architecture x86_64
# clang: error: linker command failed with exit code 1 (use -v to see invocation)
# $(RM) -r $(BUILD_DIR)
$(RM) $(DEPS) $(DEPS_SRC) $(OBJS) $(OBJS_SRC) ${BUILD_DIR}/${TARGET}
-include $(DEPS) $(DEPS_SRC)
MKDIR_P ?= mkdir -p
# Just use ".PHONY: all" to debug my Makefile.
# Just use "all:" to debug my Makefile.
# Just use "echo $(variable)" to debug my Makefile.
# eg:
# .PHONY: all
# all:
# echo $(CXX)
# echo $(CXX_FLAGS)
# echo $(BUILD_DIR)
# echo $(SRC_DIRS)
# echo $(SRC_DIRS_SRC)
# echo $(LIBDIR)
# echo $(LIBS)
# echo $(TARGET)
# echo $(SRCS)
# echo $(SRCS_SRC)
# echo $(OBJS)
# echo $(OBJS_SRC)
# echo $(DEPS)
# echo $(DEPS_SRC)
# echo $(INC_DIRS)
# echo $(INC_FLAGS)
# echo $(CPP_FLAGS)
{
"files.defaultLanguage": "c++",
"editor.suggest.snippetsPreventQuickSuggestions": false,
"editor.acceptSuggestionOnEnter": "off",
"code-runner.runInTerminal": true,
"code-runner.executorMap": {
// // 0.Only One Simple C/C++ file build, compile, debug...
//"c": "cd $dir && gcc -std=c11 -stdlib=libc++ $fileName -o $fileNameWithoutExt && $dir$fileNameWithoutExt",
//"cpp": "cd $dir && g++ -std=c++11 -stdlib=libc++ $fileName -o $fileNameWithoutExt && $dir$fileNameWithoutExt"
//"c": "cd $dir && make && ./fileNameWithoutExt && make clean",
//"cpp": "cd $dir && make && ./fileNmaeWithoutExt && make clean"
// "c": "cd $dir && make main && ../build/main && make clean",
// "cpp": "cd $dir && make main && ../build/main && make clean"
// 1.0 Reference
// Thanks chinese website blogger!
// (Configure multiple c file compilation with vscode on Mac os)
// https://blog.csdn.net/songjun007/article/details/117641162
//"c": "cd $dir && gcc -std=c11 -stdlib=libc++ -I ${workspaceFolder}/inc ${workspaceFolder}/*.c -o ${workspaceFolder}/build/${fileBasenameNoExtension} && $dir$fileNameWithoutExt",
//"cpp": "cd $dir && g++ -std=c++11 -stdlib=libc++ -I ${workspaceFolder}/inc ${workspaceFolder}/*.cpp -o ${workspaceFolder}/build/${fileBasenameNoExtension} && $dir$fileNameWithoutExt"
// 1.1Use gcc or g++
// "c": "cd $dir && gcc -std=c11 -stdlib=libc++ $dir/../src/*.c -o $dir/../build/$fileNameWithoutExt && $dir/../build/$fileNameWithoutExt",
//"cpp": "cd $dir && g++ -std=c++11 -stdlib=libc++ $dir/../src/*.cpp -o $dir/../build/$fileNameWithoutExt && $dir/../build/$fileNameWithoutExt"
//
// clang -g /Users/marryme/VSCode/CppProject/fitBody/src/bank.cpp /Users/marryme/VSCode/CppProject/fitBody/src/main.cpp -o /Users/marryme/VSCode/CppProject/fitBody/build/main
// 1.2Use clang or clang++
//"c": "cd $dir && clang -std=c11 -stdlib=libc++ $dir/../src/*.c -o $dir/../build/$fileNameWithoutExt && $dir/../build/$fileNameWithoutExt",
//"cpp": "cd $dir && clang++ -std=c++11 -stdlib=libc++ $dir/../src/*.cpp -o $dir/../build/$fileNameWithoutExt && $dir/../build/$fileNameWithoutExt"
"c": "cd $dir/../ && make && $dir/../build/$fileNameWithoutExt && make clean",
"cpp": "cd $dir/../ && make && $dir/../build/$fileNameWithoutExt && make clean"
},
"code-runner.saveFileBeforeRun": true,
"code-runner.preserveFocus": false,
"code-runner.clearPreviousOutput": false,
"code-runner.ignoreSelection": true,
"C_Cpp.clang_format_sortIncludes": true,
"editor.formatOnType": true,
"clang.cxxflags": [
"-std=c++11"
],
"clang.cflags": [
"-std=c11"
],
"C_Cpp.updateChannel": "Insiders",
"[makefile]": {
"editor.insertSpaces": true
},
"C_Cpp.default.includePath": [
"${workspaceFolder}/inc"
],
"clang.completion.enable": true
}
{
"version": "2.0.0",
"tasks": [
{
"type": "shell",
"label": "Compile With clang++",
// Just use clang compiler
//"command": "clang++",/usr/bin/clang++
"command": "/usr/bin/clang++", // Have changed
"args": [
"-std=c++11",
"-stdlib=libc++",
// My project fitBodyBootCamp were under
// /Users/marryme/VSCode/CppProject/fitBody
// So ${workspcaeFolder} also were
// /Users/marryme/VSCode/CppProject/fitBody
// all the *.cpp files were under
// /Users/marryme/VSCode/CppProject/fitBody/src
// this is the source files diretory
"${workspaceFolder}/common/*.cpp", // Have changed
"${workspaceFolder}/src/*.cpp", // Have changed
"-o",
// Thanks those chiense website bloggers!
// 1.mac vscode compile c++ multi-directory code demo
// https://blog.csdn.net/fangfengzhen115/article/details/121496770?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-4.pc_relevant_default&spm=1001.2101.3001.4242.3&utm_relevant_index=7
// 2.Compile and debug c++ multi-folder project under VSCode (non-makefile)
// https://blog.csdn.net/BaiRuichang/article/details/106463035
// I also put the main.o under my build folder directory ../build
// This after "-o" is the target file main.o or main.out or main
"${workspaceFolder}/build/${fileBasenameNoExtension}", // Have changed
"-I",
"${workspaceFolder}/inc",
"-Wall",
"-g"
],
"options": {
// "cwd" is the source files directory
"cwd": "${workspaceFolder}/common" // Have changed
},
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment