Reputation: 23
Vulkan SDK hosts a C++ header-only C-wrapped library. Problem is, it is really a heavy header, so it wastes a lot of compilation time.
So I looked into using a make file for my Vulkan project, which I never did before. I decided to programatically generate all the dependencies. Probably I messed up this part as well, making it too difficult to understand.
It does kind of work, probably there is an easier way to do the same thing(s). Here comes the part I can't really work out with:
... And here is where I have several problems about this procedure:
I am using MSYS2 MINGW_64 release, if it makes a difference. I'd be glad if someone could give me a tip or two about make files and, in particular, if there is something I completely misunderstood about the compilation process.
# Methods
define uniq =
$(eval seen :=)
$(foreach _,$1,$(if $(filter $_,${seen}),,$(eval seen += $_)))
${seen}
endef
# Compilation flags
_COMPILER := g++ -std=c++17
_FLAGS_WARNING := -Wall -Wextra -Wshadow
_FLAGS_COMPILE := -g -O0
_FLAGS_VULKAN := -lglfw3 -lvulkan
# Custom Flags
_FLAGS_DEBUG := -D _DEBUG -D _DEBUG_SEVERITY=0 -D _DEBUG_TYPE=0
# Output
_OUTPUT_NAME := test
# Directories
_TMP_DIR := _tmp
_O_DIR := ${_TMP_DIR}\.o
_GCH_DIR := ${_TMP_DIR}\.gch
_SOURCE_DIR := src
_BUILD_DIR := build
_DEBUG_DIR := ${_BUILD_DIR}\debug
_RELEASE_DIR := ${_BUILD_DIR}\release
# Files
_VULKAN_HPP := C:/VulkanSDK/1.2.148.1/Include/vulkan/vulkan.hpp
_GLFW_HPP := C:/msys64/mingw64/include/GLFW/glfw3.h
# Grouping Files
# .cpp & .o
_CPP_LIST := ${wildcard ${_SOURCE_DIR}/*.cpp ${_SOURCE_DIR}/*/*.cpp}
_CPP_LIST_NAME := ${notdir ${_CPP_LIST}}
_O_LIST := ${addprefix ${_O_DIR}/, ${patsubst %.cpp, %.o, ${_CPP_LIST_NAME}}}
# .hpp & .gch
_HPP_LIST := ${wildcard ${_SOURCE_DIR}/*.hpp ${_SOURCE_DIR}/*/*.hpp} ${_VULKAN_HPP}
_HPP_LIST_NAME := ${notdir ${_HPP_LIST}}
_GCH_LIST := ${addprefix ${_GCH_DIR}/, ${patsubst %.hpp, %.gch, ${_HPP_LIST_NAME}}}
# .h & .gch
_H_LIST := ${_GLFW_HPP}
_H_LIST_NAME := ${notdir ${_H_LIST}}
_C_GCH_LIST := ${addprefix ${_GCH_DIR}/, ${patsubst %.h, %.gch, ${_H_LIST_NAME}}}
_COMPILATION_BUNDLE_CPP = ${_FLAGS_WARNING} ${_FLAGS_COMPILE} ${_FLAGS_VULKAN} ${_FLAGS_DEBUG} -I ${_GCH_DIR}
_COMPILATION_BUNDLE_HPP = ${_FLAGS_COMPILE} -x c++-header ${_FLAGS_DEBUG} -I ${_GCH_DIR}
${_DEBUG_DIR}/${_OUTPUT_NAME}: ${_GCH_LIST} ${_C_GCH_LIST} ${_O_LIST}
${_COMPILER} ${_COMPILATION_BUNDLE_CPP} ${_O_LIST} ${addprefix -include , ${_GCH_LIST}} ${addprefix -include , ${_C_GCH_LIST}} -o $@
vpath %.cpp $(call uniq, ${dir ${_CPP_LIST}})
${_O_DIR}/%.o: %.cpp
${_COMPILER} ${_COMPILATION_BUNDLE_CPP} -c $< -o $@
vpath %.hpp $(call uniq, ${dir ${_HPP_LIST}})
${_GCH_DIR}/%.gch: %.hpp
${_COMPILER} ${_COMPILATION_BUNDLE_HPP} $< -o $@
vpath %.h $(call uniq, ${dir ${_H_LIST}})
${_GCH_DIR}/%.gch: %.h
${_COMPILER} ${_COMPILATION_BUNDLE_HPP} $< -o $@
The execution on a clean project (thus easier to follow along):
g++ -std=c++17 -g -O0 -x c++-header -D _DEBUG -D _DEBUG_SEVERITY=0 -D _DEBUG_TYPE=0 -I _tmp\.gch src/helper/helper.hpp -o _tmp\.gch/helper.gch
g++ -std=c++17 -g -O0 -x c++-header -D _DEBUG -D _DEBUG_SEVERITY=0 -D _DEBUG_TYPE=0 -I _tmp\.gch src/renderer/renderer.hpp -o _tmp\.gch/renderer.gch
g++ -std=c++17 -g -O0 -x c++-header -D _DEBUG -D _DEBUG_SEVERITY=0 -D _DEBUG_TYPE=0 -I _tmp\.gch C:/VulkanSDK/1.2.148.1/Include/vulkan/vulkan.hpp -o _tmp\.gch/vulkan.gch
g++ -std=c++17 -g -O0 -x c++-header -D _DEBUG -D _DEBUG_SEVERITY=0 -D _DEBUG_TYPE=0 -I _tmp\.gch C:/msys64/mingw64/include/GLFW/glfw3.h -o _tmp\.gch/glfw3.gch
g++ -std=c++17 -Wall -Wextra -Wshadow -g -O0 -lglfw3 -lvulkan -D _DEBUG -D _DEBUG_SEVERITY=0 -D _DEBUG_TYPE=0 -I _tmp\.gch -c src/main.cpp -o _tmp\.o/main.o
g++ -std=c++17 -Wall -Wextra -Wshadow -g -O0 -lglfw3 -lvulkan -D _DEBUG -D _DEBUG_SEVERITY=0 -D _DEBUG_TYPE=0 -I _tmp\.gch -c src/helper/helper.cpp -o _tmp\.o/helper.o
g++ -std=c++17 -Wall -Wextra -Wshadow -g -O0 -lglfw3 -lvulkan -D _DEBUG -D _DEBUG_SEVERITY=0 -D _DEBUG_TYPE=0 -I _tmp\.gch -c src/renderer/renderer.cpp -o _tmp\.o/renderer.o
g++ -std=c++17 -Wall -Wextra -Wshadow -g -O0 -lglfw3 -lvulkan -D _DEBUG -D _DEBUG_SEVERITY=0 -D _DEBUG_TYPE=0 -I _tmp\.gch _tmp\.o/main.o _tmp\.o/helper.o _tmp\.o/renderer.o -include _tmp\.gch/helper.gch -include _tmp\.gch/renderer.gch -include _tmp\.gch/vulkan.gch -include _tmp\.gch/glfw3.gch -o build\debug/test
Upvotes: 0
Views: 411
Reputation: 16321
Using pre-compiled headers is actually fairly straight forward. It might be easiest to break it down into manual steps. You can even retro fit to an existing project pretty easily. The steps could be:
So lets try a practical example:
g++ -I. <other flags> src1.cpp -o src1.o
pch.hpp
(or whatever)g++ -I. <other flags> pch.hpp
(same flags as the previous compile). This generates the pch.hpp.gch file.g++ -I. <other flags> src1.cpp -o src1.o -Winvalid-pch -include pch.hpp
Couple of things to note:
-include pch.hpp
not -include pch.hpp.gch
since g++ will figure that out. You can see that retro fitting it is easy - since you just append the include flags to your compiler lines.Upvotes: 1