# Copyright (c) 2023-2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

BOUNDS_CHECK_DIR:=$(subst /,\, $(abspath ..\..\..\..\..\third_party\bounds_checking_function))
INCLUDES:=-I $(PWD) -I $(BOUNDS_CHECK_DIR)\include

CODEGEN_HDI_SOURCE_DIR := $(PWD)\codegen\HDI
CODEGEN_HDI_SOURCE := $(wildcard $(CODEGEN_HDI_SOURCE_DIR)/*.cpp)
CODEGEN_HDI_OBJ_DIR := $(BUILD_DIR)\codegen\HDI
CODEGEN_HDI_OBJS := $(addprefix $(CODEGEN_HDI_OBJ_DIR)\, $(patsubst %.cpp, %.o, $(notdir $(CODEGEN_HDI_SOURCE))))

CODEGEN_HDITYPE_SOURCE_DIR := $(PWD)\codegen\HDI\type
CODEGEN_HDITYPE_SOURCE := $(wildcard $(CODEGEN_HDITYPE_SOURCE_DIR)/*.cpp)
CODEGEN_HDITYPE_OBJ_DIR := $(BUILD_DIR)\codegen\HDI\type
CODEGEN_HDITYPE_OBJS := $(addprefix $(CODEGEN_HDITYPE_OBJ_DIR)\, $(patsubst %.cpp, %.o, $(notdir $(CODEGEN_HDITYPE_SOURCE))))

CODEGEN_HDIC_SOURCE_DIR := $(PWD)\codegen\HDI\c
CODEGEN_HDIC_SOURCE := $(wildcard $(CODEGEN_HDIC_SOURCE_DIR)/*.cpp)
CODEGEN_HDIC_OBJ_DIR := $(BUILD_DIR)\codegen\HDI\c
CODEGEN_HDIC_OBJS := $(addprefix $(CODEGEN_HDIC_OBJ_DIR)\, $(patsubst %.cpp, %.o, $(notdir $(CODEGEN_HDIC_SOURCE))))

CODEGEN_HDICPP_SOURCE_DIR := $(PWD)\codegen\HDI\cpp
CODEGEN_HDICPP_SOURCE := $(wildcard $(CODEGEN_HDICPP_SOURCE_DIR)/*.cpp)
CODEGEN_HDICPP_OBJ_DIR := $(BUILD_DIR)\codegen\HDI\cpp
CODEGEN_HDICPP_OBJS := $(addprefix $(CODEGEN_HDICPP_OBJ_DIR)\, $(patsubst %.cpp, %.o, $(notdir $(CODEGEN_HDICPP_SOURCE))))

CODEGEN_HDIJAVA_SOURCE_DIR := $(PWD)\codegen\HDI\java
CODEGEN_HDIJAVA_SOURCE := $(wildcard $(CODEGEN_HDIJAVA_SOURCE_DIR)/*.cpp)
CODEGEN_HDIJAVA_OBJ_DIR := $(BUILD_DIR)\codegen\HDI\java
CODEGEN_HDIJAVA_OBJS := $(addprefix $(CODEGEN_HDIJAVA_OBJ_DIR)\, $(patsubst %.cpp, %.o, $(notdir $(CODEGEN_HDIJAVA_SOURCE))))

CODEGEN_SA_SOURCE_DIR := $(PWD)\codegen\SA
CODEGEN_SA_SOURCE := $(wildcard $(CODEGEN_SA_SOURCE_DIR)/*.cpp)
CODEGEN_SA_OBJ_DIR := $(BUILD_DIR)\codegen\SA
CODEGEN_SA_OBJS := $(addprefix $(CODEGEN_SA_OBJ_DIR)\, $(patsubst %.cpp, %.o, $(notdir $(CODEGEN_SA_SOURCE))))

CODEGEN_SATYPE_SOURCE_DIR := $(PWD)\codegen\SA\type
CODEGEN_SATYPE_SOURCE := $(wildcard $(CODEGEN_SATYPE_SOURCE_DIR)/*.cpp)
CODEGEN_SATYPE_OBJ_DIR := $(BUILD_DIR)\codegen\SA\type
CODEGEN_SATYPE_OBJS := $(addprefix $(CODEGEN_SATYPE_OBJ_DIR)\, $(patsubst %.cpp, %.o, $(notdir $(CODEGEN_SATYPE_SOURCE))))

CODEGEN_SACPP_SOURCE_DIR := $(PWD)\codegen\SA\cpp
CODEGEN_SACPP_SOURCE := $(wildcard $(CODEGEN_SACPP_SOURCE_DIR)/*.cpp)
CODEGEN_SACPP_OBJ_DIR := $(BUILD_DIR)\codegen\SA\cpp
CODEGEN_SACPP_OBJS := $(addprefix $(CODEGEN_SACPP_OBJ_DIR)\, $(patsubst %.cpp, %.o, $(notdir $(CODEGEN_SACPP_SOURCE))))

CODEGEN_SATS_SOURCE_DIR := $(PWD)\codegen\SA\ts
CODEGEN_SATS_SOURCE := $(wildcard $(CODEGEN_SATS_SOURCE_DIR)/*.cpp)
CODEGEN_SATS_OBJ_DIR := $(BUILD_DIR)\codegen\SA\ts
CODEGEN_SATS_OBJS := $(addprefix $(CODEGEN_SATS_OBJ_DIR)\, $(patsubst %.cpp, %.o, $(notdir $(CODEGEN_SATS_SOURCE))))

CODEGEN_SARUST_SOURCE_DIR := $(PWD)\codegen\SA\rust
CODEGEN_SARUST_SOURCE := $(wildcard $(CODEGEN_SARUST_SOURCE_DIR)/*.cpp)
CODEGEN_SARUST_OBJ_DIR := $(BUILD_DIR)\codegen\SA\rust
CODEGEN_SARUST_OBJS := $(addprefix $(CODEGEN_SARUST_OBJ_DIR)\, $(patsubst %.cpp, %.o, $(notdir $(CODEGEN_SARUST_SOURCE))))

CODEGEN_SOURCE_DIR := $(PWD)\codegen
CODEGEN_SOURCE := $(wildcard $(CODEGEN_SOURCE_DIR)/*.cpp)
CODEGEN_OBJ_DIR := $(BUILD_DIR)\codegen
CODEGEN_OBJS := $(addprefix $(CODEGEN_OBJ_DIR)\, $(patsubst %.cpp, %.o, $(notdir $(CODEGEN_SOURCE))))

METADATA_SOURCE_DIR := $(PWD)\metadata
METADATA_SOURCE := $(wildcard $(METADATA_SOURCE_DIR)/*.cpp)
METADATA_OBJ_DIR := $(BUILD_DIR)\metadata
METADATA_OBJS := $(addprefix $(METADATA_OBJ_DIR)\, $(patsubst %.cpp, %.o, $(notdir $(METADATA_SOURCE))))

PARSER_SOURCE_DIR := $(PWD)\parser
PARSER_SOURCE := $(wildcard $(PARSER_SOURCE_DIR)/*.cpp)
PARSER_OBJS_DIR := $(BUILD_DIR)\parser
PARSER_OBJS := $(addprefix $(PARSER_OBJS_DIR)\, $(patsubst %.cpp, %.o, $(notdir $(PARSER_SOURCE))))

PREPROCESSOR_SOURCE_DIR := $(PWD)\preprocessor
PREPROCESSOR_SOURCE := $(wildcard $(PREPROCESSOR_SOURCE_DIR)/*.cpp)
PREPROCESSOR_OBJS_DIR := $(BUILD_DIR)\preprocessor
PREPROCESSOR_OBJS := $(addprefix $(PREPROCESSOR_OBJS_DIR)\, $(patsubst %.cpp, %.o, $(notdir $(PREPROCESSOR_SOURCE))))

LEXER_SOURCE_DIR := $(PWD)\lexer
LEXER_SOURCE := $(wildcard $(LEXER_SOURCE_DIR)/*.cpp)
LEXER_OBJS_DIR := $(BUILD_DIR)\lexer
LEXER_OBJS := $(addprefix $(LEXER_OBJS_DIR)\, $(patsubst %.cpp, %.o, $(notdir $(LEXER_SOURCE))))

AST_SOURCE_DIR := $(PWD)\ast
AST_SOURCE := $(wildcard $(AST_SOURCE_DIR)/*.cpp)
AST_OBJS_DIR := $(BUILD_DIR)\ast
AST_OBJS := $(addprefix $(AST_OBJS_DIR)\, $(patsubst %.cpp, %.o, $(notdir $(AST_SOURCE))))

AST_BASE_SOURCE_DIR := $(PWD)\ast\base
AST_BASE_SOURCE := $(wildcard $(AST_BASE_SOURCE_DIR)/*.cpp)
AST_BASE_OBJS_DIR := $(BUILD_DIR)\ast\base
AST_BASE_OBJS := $(addprefix $(AST_BASE_OBJS_DIR)\, $(patsubst %.cpp, %.o, $(notdir $(AST_BASE_SOURCE))))

HASH_SOURCE_DIR := $(PWD)\hash
HASH_SOURCE := $(wildcard $(HASH_SOURCE_DIR)/*.cpp)
HASH_OBJS_DIR := $(BUILD_DIR)\hash
HASH_OBJS := $(addprefix $(HASH_OBJS_DIR)\, $(patsubst %.cpp, %.o, $(notdir $(HASH_SOURCE))))

UTIL_SOURCE_DIR := $(PWD)\util
UTIL_SOURCE := $(wildcard $(UTIL_SOURCE_DIR)/*.cpp)
UTIL_OBJS_DIR := $(BUILD_DIR)\util
UTIL_OBJS := $(addprefix $(UTIL_OBJS_DIR)\, $(patsubst %.cpp, %.o, $(notdir $(UTIL_SOURCE))))

BOUNDS_CHECK_SOURCE_DIR := $(subst /,\, $(abspath ..\..\..\..\third_party\bounds_checking_function\src))
BOUNDS_CHECK_SOURCE := $(wildcard $(BOUNDS_CHECK_SOURCE_DIR)\*.c)
BOUNDS_CHECK_OBJS_DIR := $(BUILD_DIR)\bounds_checking_function
BOUNDS_CHECK_OBJS := $(addprefix $(BOUNDS_CHECK_OBJS_DIR)\, $(patsubst %.c, %.o, $(notdir $(BOUNDS_CHECK_SOURCE))))

MAIN_SOURCE := $(wildcard *.cpp)
MAIN_OBJS := $(addprefix $(BUILD_DIR)\, $(patsubst %.cpp, %.o, $(MAIN_SOURCE)))

CODEGEN_HDI_ALL_OBJS := $(CODEGEN_HDI_OBJS) $(CODEGEN_HDITYPE_OBJS) $(CODEGEN_HDIC_OBJS) $(CODEGEN_HDICPP_OBJS) $(CODEGEN_HDIJAVA_OBJS)
CODEGEN_SA_ALL_OBJS := $(CODEGEN_SA_OBJS) $(CODEGEN_SATYPE_OBJS) $(CODEGEN_SACPP_OBJS) $(CODEGEN_SATS_OBJS) $(CODEGEN_SARUST_OBJS)
CODEGEN_ALL_OBJS := $(CODEGEN_HDI_ALL_OBJS) $(CODEGEN_SA_ALL_OBJS) $(CODEGEN_OBJS)
AST_ALL_OBJS := $(AST_BASE_OBJS) $(AST_OBJS)

all:$(TARGET)

$(TARGET) : $(BOUNDS_CHECK_OBJS) $(UTIL_OBJS) $(HASH_OBJS) $(AST_ALL_OBJS) $(LEXER_OBJS) $(PREPROCESSOR_OBJS) $(PARSER_OBJS) $(METADATA_OBJS) $(CODEGEN_ALL_OBJS) $(MAIN_OBJS)
	$(Q) $(CXX) $(CXXFLAGS) $(INCLUDES) $^ -o $@
	$(Q) echo $(TARGET):build successful.

$(BUILD_DIR)\\%.o : %.cpp
	$(Q) if not exist $(BUILD_DIR) (mkdir $(BUILD_DIR))
	$(Q) $(CXX) $(CXXFLAGS) $(INCLUDES) -c $^ -o $@

$(CODEGEN_HDITYPE_OBJ_DIR)\\%.o : $(CODEGEN_HDITYPE_SOURCE_DIR)\\%.cpp
	$(Q) if not exist $(CODEGEN_HDITYPE_OBJ_DIR) (mkdir $(CODEGEN_HDITYPE_OBJ_DIR))
	$(Q) $(CXX) $(CXXFLAGS) $(INCLUDES) -c $^ -o $@

$(CODEGEN_HDIC_OBJ_DIR)\\%.o : $(CODEGEN_HDIC_SOURCE_DIR)\\%.cpp
	$(Q) if not exist $(CODEGEN_HDIC_OBJ_DIR) (mkdir $(CODEGEN_HDIC_OBJ_DIR))
	$(Q) $(CXX) $(CXXFLAGS) $(INCLUDES) -c $^ -o $@

$(CODEGEN_HDICPP_OBJ_DIR)\\%.o : $(CODEGEN_HDICPP_SOURCE_DIR)\\%.cpp
	$(Q) if not exist $(CODEGEN_HDICPP_OBJ_DIR) (mkdir $(CODEGEN_HDICPP_OBJ_DIR))
	$(Q) $(CXX) $(CXXFLAGS) $(INCLUDES) -c $^ -o $@

$(CODEGEN_HDIJAVA_OBJ_DIR)\\%.o : $(CODEGEN_HDIJAVA_SOURCE_DIR)\\%.cpp
	$(Q) if not exist $(CODEGEN_HDIJAVA_OBJ_DIR) (mkdir $(CODEGEN_HDIJAVA_OBJ_DIR))
	$(Q) $(CXX) $(CXXFLAGS) $(INCLUDES) -c $^ -o $@

$(CODEGEN_HDI_OBJ_DIR)\\%.o : $(CODEGEN_HDI_SOURCE_DIR)\\%.cpp
	$(Q) if not exist $(CODEGEN_HDI_OBJ_DIR) (mkdir $(CODEGEN_HDI_OBJ_DIR))
	$(Q) $(CXX) $(CXXFLAGS) $(INCLUDES) -c $^ -o $@

$(CODEGEN_SATYPE_OBJ_DIR)\\%.o : $(CODEGEN_SATYPE_SOURCE_DIR)\\%.cpp
	$(Q) if not exist $(CODEGEN_SATYPE_OBJ_DIR) (mkdir $(CODEGEN_SATYPE_OBJ_DIR))
	$(Q) $(CXX) $(CXXFLAGS) $(INCLUDES) -c $^ -o $@

$(CODEGEN_SACPP_OBJ_DIR)\\%.o : $(CODEGEN_SACPP_SOURCE_DIR)\\%.cpp
	$(Q) if not exist $(CODEGEN_SACPP_OBJ_DIR) (mkdir $(CODEGEN_SACPP_OBJ_DIR))
	$(Q) $(CXX) $(CXXFLAGS) $(INCLUDES) -c $^ -o $@

$(CODEGEN_SATS_OBJ_DIR)\\%.o : $(CODEGEN_SATS_SOURCE_DIR)\\%.cpp
	$(Q) if not exist $(CODEGEN_SATS_OBJ_DIR) (mkdir $(CODEGEN_SATS_OBJ_DIR))
	$(Q) $(CXX) $(CXXFLAGS) $(INCLUDES) -c $^ -o $@

$(CODEGEN_SARUST_OBJ_DIR)\\%.o : $(CODEGEN_SARUST_SOURCE_DIR)\\%.cpp
	$(Q) if not exist $(CODEGEN_SARUST_OBJ_DIR) (mkdir $(CODEGEN_SARUST_OBJ_DIR))
	$(Q) $(CXX) $(CXXFLAGS) $(INCLUDES) -c $^ -o $@

$(CODEGEN_SA_OBJ_DIR)\\%.o : $(CODEGEN_SA_SOURCE_DIR)\\%.cpp
	$(Q) if not exist $(CODEGEN_SA_OBJ_DIR) (mkdir $(CODEGEN_SA_OBJ_DIR))
	$(Q) $(CXX) $(CXXFLAGS) $(INCLUDES) -c $^ -o $@

$(CODEGEN_OBJ_DIR)\\%.o : $(CODEGEN_SOURCE_DIR)\\%.cpp
	$(Q) if not exist $(CODEGEN_OBJ_DIR) (mkdir $(CODEGEN_OBJ_DIR))
	$(Q) $(CXX) $(CXXFLAGS) $(INCLUDES) -c $^ -o $@

$(METADATA_OBJ_DIR)\\%.o : $(METADATA_SOURCE_DIR)\\%.cpp
	$(Q) if not exist $(METADATA_OBJ_DIR) (mkdir $(METADATA_OBJ_DIR))
	$(Q) $(CXX) $(CXXFLAGS) $(INCLUDES) -c $^ -o $@

$(PARSER_OBJS_DIR)\\%.o : $(PARSER_SOURCE_DIR)\\%.cpp
	$(Q) if not exist $(PARSER_OBJS_DIR) (mkdir $(PARSER_OBJS_DIR))
	$(Q) $(CXX) $(CXXFLAGS) $(INCLUDES) -c $^ -o $@

$(PREPROCESSOR_OBJS_DIR)\\%.o : $(PREPROCESSOR_SOURCE_DIR)\\%.cpp
	$(Q) if not exist $(PREPROCESSOR_OBJS_DIR) (mkdir $(PREPROCESSOR_OBJS_DIR))
	$(Q) $(CXX) $(CXXFLAGS) $(INCLUDES) -c $^ -o $@

$(LEXER_OBJS_DIR)\\%.o : $(LEXER_SOURCE_DIR)\\%.cpp
	$(Q) if not exist $(LEXER_OBJS_DIR) (mkdir $(LEXER_OBJS_DIR))
	$(Q) $(CXX) $(CXXFLAGS) $(INCLUDES) -c $^ -o $@

$(AST_BASE_OBJS_DIR)\\%.o : $(AST_BASE_SOURCE_DIR)\\%.cpp
	$(Q) if not exist $(AST_BASE_OBJS_DIR) (mkdir $(AST_BASE_OBJS_DIR))
	$(Q) $(CXX) $(CXXFLAGS) $(INCLUDES) -c $^ -o $@

$(AST_OBJS_DIR)\\%.o : $(AST_SOURCE_DIR)\\%.cpp
	$(Q) if not exist $(AST_OBJS_DIR) (mkdir $(AST_OBJS_DIR))
	$(Q) $(CXX) $(CXXFLAGS) $(INCLUDES) -c $^ -o $@

$(HASH_OBJS_DIR)\\%.o : $(HASH_SOURCE_DIR)\\%.cpp
	$(Q) if not exist $(HASH_OBJS_DIR) (mkdir $(HASH_OBJS_DIR))
	$(Q) $(CXX) $(CXXFLAGS) $(INCLUDES) -c $^ -o $@

$(UTIL_OBJS_DIR)\\%.o : $(UTIL_SOURCE_DIR)\\%.cpp
	$(Q) if not exist $(UTIL_OBJS_DIR) (mkdir $(UTIL_OBJS_DIR))
	$(Q) $(CXX) $(CXXFLAGS) $(INCLUDES) -c $^ -o $@

$(BOUNDS_CHECK_OBJS_DIR)\\%.o : $(BOUNDS_CHECK_SOURCE_DIR)\%.c
	$(Q) if not exist $(BOUNDS_CHECK_OBJS_DIR) (mkdir $(BOUNDS_CHECK_OBJS_DIR))
	$(Q) $(CXX) $(CXXFLAGS) $(INCLUDES) -c $^ -o $@

clean:
	$(Q) if exist $(TARGET) (del $(TARGET))
	$(Q) if exist $(BUILD_DIR) (rd /s /q $(BUILD_DIR))

.PHONY:all clean