Add conditional test compilation and split matrix instantiations

This commit adds the ability to conditionally compile tests. To
implement this, common source files needed to be moved to a subdirectory
`common`.

Additionally, this commit splits each `mat` template instantiation into
a separate source file. This enables the linker to discard unused
instantations. If each instantiation is placed in the same file and also
into the .iwram section, the linker will include every symbol in the
resulting binary, leading to an extremely high IWRAM usage. To introduce
this split, a new header file "mat_impl.hpp" was added containing
implementation details for the template instantiations. "mat_impl.hpp"
should ONLY be included by the source files containing explicit
instantiations of `mat`.
This commit is contained in:
Madeline Busig 2024-10-07 23:49:01 -07:00
parent 094a4731c5
commit a449c4f749
11 changed files with 74 additions and 18 deletions

View File

@ -3,15 +3,18 @@ cmake_minimum_required(VERSION 3.5)
project(mtl LANGUAGES CXX C ASM) project(mtl LANGUAGES CXX C ASM)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
option(BUILD_TESTS "Build tests" ON)
message("Compiling MTL for ${CMAKE_SYSTEM_PROCESSOR}") message("Compiling MTL for ${CMAKE_SYSTEM_PROCESSOR}")
# CONFIGURE_DEPENDS option was added in CMake v3.12. This option allows the # CONFIGURE_DEPENDS option was added in CMake v3.12. This option allows the
# build system to automatically re-run CMake if the glob changes, solving the # build system to automatically re-run CMake if the glob changes, solving the
# major issue with globbing. May have a performance impact, but it should be # major issue with globbing. May have a performance impact, but it should be
# negligible compared to the time spent building. # negligible compared to the time spent building.
file(GLOB mtl_sources_common LIST_DIRECTORIES false CONFIGURE_DEPENDS src/*.cpp src/*.c src/*.s src/tests/*.cpp) file(GLOB mtl_sources_common LIST_DIRECTORIES false CONFIGURE_DEPENDS src/common/*.cpp src/common/*.c src/common/*.s)
file(GLOB mtl_sources_armv4t LIST_DIRECTORIES false CONFIGURE_DEPENDS src/armv4t/*.cpp src/armv4t/*.c src/armv4t/*.s) file(GLOB mtl_sources_armv4t LIST_DIRECTORIES false CONFIGURE_DEPENDS src/armv4t/*.cpp src/armv4t/*.c src/armv4t/*.s)
file(GLOB mtl_sources_gba LIST_DIRECTORIES false CONFIGURE_DEPENDS src/gba/*.cpp src/gba/*.c src/gba/*.s) file(GLOB mtl_sources_gba LIST_DIRECTORIES false CONFIGURE_DEPENDS src/gba/*.cpp src/gba/*.c src/gba/*.s)
file(GLOB mtl_sources_test LIST_DIRECTORIES false CONFIGURE_DEPENDS src/tests/*.cpp)
set(mtl_include_common "include") set(mtl_include_common "include")
set(mtl_include_gba "include/gba") set(mtl_include_gba "include/gba")
@ -39,6 +42,12 @@ if (CMAKE_SYSTEM_PROCESSOR STREQUAL "armv4t")
target_link_libraries(${PROJECT_NAME} PUBLIC ${PROJECT_NAME}_armv4t) target_link_libraries(${PROJECT_NAME} PUBLIC ${PROJECT_NAME}_armv4t)
endif() endif()
if (BUILD_TESTS STREQUAL "ON")
add_library(${PROJECT_NAME}_test OBJECT)
target_sources(${PROJECT_NAME}_test PRIVATE "${mtl_sources_test}")
target_link_libraries(${PROJECT_NAME} PUBLIC ${PROJECT_NAME}_test)
endif()
target_sources(${PROJECT_NAME}_common PRIVATE "${mtl_sources_common}") target_sources(${PROJECT_NAME}_common PRIVATE "${mtl_sources_common}")
target_include_directories(${PROJECT_NAME}_common PUBLIC "${mtl_include_common}") target_include_directories(${PROJECT_NAME}_common PUBLIC "${mtl_include_common}")
target_link_libraries(${PROJECT_NAME} PUBLIC ${PROJECT_NAME}_common) target_link_libraries(${PROJECT_NAME} PUBLIC ${PROJECT_NAME}_common)

View File

@ -1,3 +1,8 @@
/*
* This file should only be included by files that explicitly instantiate
* matrix classes.
*/
#pragma once
#pragma GCC push_options #pragma GCC push_options
#pragma GCC optimize("unroll-loops") #pragma GCC optimize("unroll-loops")
@ -125,23 +130,6 @@ mat<4, 4> mat<4, 4>::translation(const vec<D - 1>& v) {
return r; return r;
} }
template class mat<2, 2>;
template class mat<3, 3>;
template class mat<4, 4>;
template class mat<1, 2>;
template class mat<1, 3>;
template class mat<1, 4>;
template mat<2, 2> operator*(const vec<2>&, const mat<1, 2>&);
template mat<3, 3> operator*(const vec<3>&, const mat<1, 3>&);
template mat<4, 4> operator*(const vec<4>&, const mat<1, 4>&);
template mat<4, 4> mat<4, 4>::operator*(const mat<4, 4>&) const;
template mat<3, 3> mat<3, 3>::operator*(const mat<3, 3>&) const;
template mat<2, 2> mat<2, 2>::operator*(const mat<2, 2>&) const;
template mat<4, 4> mat<4, 4>::translation<4, true>(const vec<3>&);
} // namespace mtl } // namespace mtl
#pragma GCC pop_options #pragma GCC pop_options

8
src/common/mat_1x2.cpp Normal file
View File

@ -0,0 +1,8 @@
#include "mtl/mat_impl.hpp"
namespace mtl {
template class mat<1, 2>;
}

8
src/common/mat_1x3.cpp Normal file
View File

@ -0,0 +1,8 @@
#include "mtl/mat_impl.hpp"
namespace mtl {
template class mat<1, 3>;
}

8
src/common/mat_1x4.cpp Normal file
View File

@ -0,0 +1,8 @@
#include "mtl/mat_impl.hpp"
namespace mtl {
template class mat<1, 4>;
}

11
src/common/mat_2x2.cpp Normal file
View File

@ -0,0 +1,11 @@
#include "mtl/mat_impl.hpp"
namespace mtl {
template class mat<2, 2>;
template mat<2, 2> operator*(const vec<2>&, const mat<1, 2>&);
template mat<2, 2> mat<2, 2>::operator*(const mat<2, 2>&) const;
}

11
src/common/mat_3x3.cpp Normal file
View File

@ -0,0 +1,11 @@
#include "mtl/mat_impl.hpp"
namespace mtl {
template class mat<3, 3>;
template mat<3, 3> operator*(const vec<3>&, const mat<1, 3>&);
template mat<3, 3> mat<3, 3>::operator*(const mat<3, 3>&) const;
}

12
src/common/mat_4x4.cpp Normal file
View File

@ -0,0 +1,12 @@
#include "mtl/mat_impl.hpp"
namespace mtl {
template class mat<4, 4>;
template mat<4, 4> operator*(const vec<4>&, const mat<1, 4>&);
template mat<4, 4> mat<4, 4>::operator*(const mat<4, 4>&) const;
template mat<4, 4> mat<4, 4>::translation<4, true>(const vec<3>&);
}

View File

@ -2,6 +2,7 @@
#include <cstddef> #include <cstddef>
#include <cstring> #include <cstring>
#include <algorithm>
#include "mtl/utility.hpp" #include "mtl/utility.hpp"
#include "mtl/string_view.hpp" #include "mtl/string_view.hpp"