テンプレート makefile のカスタマイズ
テンプレート makefile (TMF) を設定またはカスタマイズする場合、make
コマンドの仕組みとこのコマンドが makefile (.mk
ファイル) を処理する方法を理解していなければなりません。また、makefile ビルドの規則に関する知識もなければなりません。これらのトピックの情報は、使用している make ユーティリティのドキュメンテーションを参照してください。
テンプレート makefile とトークン
テンプレート makefile にはトークンが含まれています。ビルド プロセスではトークンを拡張して makefile を作成します。
–– モデル コンポーネントから生成されたコードをコンパイルしリンクします。model
.mkrtwshared.mk
–– 生成された共有ユーティリティ コードをコンパイルします。
makefile (
) は、開発コンピューター固有のコマンドを使用します。model_or_sharedutils
.mk
テンプレート makefile トークン
make_rtw
コマンド (または一部のターゲットでは別のコマンド) によって、
の生成が指示されます。model_or_sharedutils
.mkmake_rtw
コマンドは、[コンフィギュレーション パラメーター] ダイアログ ボックスの [コード生成] ペインで指定されている TMF を処理します。make_rtw
によって、検出されたトークンを展開しながら TMF が行単位でコピーされます。make_rtw によって展開されるテンプレート makefile トークンには、トークンとその展開のリストがあります。
これらのトークンは、展開された makefile によって以下のようないくつかの方法で使用されます。
makefile 内の条件付き動作の制御。条件は、ソース ファイルのリスト、ライブラリ名、ビルドするターゲット、およびその他のビルド関連情報を制御するために使用されます。
-DINTEGER_CODE=1
など、ファイルのコンパイルに必要なマクロの定義を指定。
make_rtw によって展開されるテンプレート makefile トークン
トークン | 展開 |
---|---|
一般的な目的 | |
| ブロックによって自動的に追加されるリンカー フラグ。 |
| MATLAB® 実行可能ファイルへの代替絶対パス名。絶対パス名に空白が含まれている場合、値は、 |
| MATLAB インストールへの代替絶対パス名。絶対パス名に空白が含まれている場合、値は、 |
|
|
| モデル コンフィギュレーション パラメーター [1 つの出力/更新関数] を選択する場合は True (1)、しない場合は False (0)。マクロ定義 |
|
|
| コンピューターのタイプ。MATLAB |
|
対応する変数とトークンのペアがテンプレート makefile にある たとえば、一部のテンプレート makefile には次のステートメントが含まれます。 ... NUMST = |>NUMST<| ... CPP_REQ_DEFINES1 = ... -DNUMST=$(NUMST) ... NUMST = |>NUMST<| が含まれており、NUMST が buildInfo 内のプリプロセッサ マクロ定義である場合、ビルド プロセスは DEFINES_OTHER で展開されません。
|
| プリコンパイル済みのライブラリ ファイルの場所。 |
| ライブラリ名。例については、ビルド中のライブラリの位置および名前付けの制御とrtwmakecfg 用のテンプレート makefile の変更を参照してください。 |
| ライブラリ接尾辞。 |
| True (1) に設定すると、エクスターナル モード サポート コードの生成が有効になります。有効にしない場合は、False (0) に設定します。 |
| エクスターナル モード用のトランスポート メカニズム ( |
| エクスターナル モードに対して静的メモリ割り当てが選択されている場合は True (1)。動的メモリ割り当てが選択されている場合は False (0)。 |
| エクスターナル モード用の静的メモリ割り当てバッファーのサイズ。 |
| モデル コンフィギュレーション パラメーター [ブロックの作成] が [SIL] に設定されている場合は True (1)、そうでない場合は False (0)。ビルドの makefile ターゲットの制御に使用します。 |
| モデル コンフィギュレーション パラメーター [終了関数が必要] が選択されている場合は True (1)、そうでない場合は False (0)。マクロ定義 |
| モデル コンフィギュレーション パラメーター [サポート: 浮動小数点数] が選択されていない場合は True (1)、そうでない場合は False (0)。 |
|
|
| モデル コンフィギュレーション パラメーター [MAT ファイルのログ] が選択されている場合は True (1)、そうでない場合は False (0)。MAT_FILE は、ソース コードのコンパイル中に必須のマクロ定義です。また、ビルド プロセス内でログ コードのインクルードにも使用されます。 |
| MATLAB 実行可能プログラムの場所。 |
| MATLAB がインストールされている場所へのパス。 |
|
|
| MEX ファイルの拡張子。MATLAB |
| 追加の生成済みソース モジュール。たとえば、大きなモデルを 2 つのファイル |
| 生成された追加のソース モジュールに対応するオブジェクト ファイル名 ( |
| 現在ビルド中の Simulink® ブロック線図の名前。 |
| ソルバー モードがマルチタスクの場合は True (1)、それ以外の場合は False (0)。 |
| 連続状態の数。 |
| モデル内のサンプル時間の数。 |
| MATLAB リリース バージョン。 |
| リンク作成に使用できる S-Function ライブラリのリスト。 |
|
|
|
|
| ビルドの開始時点のコード生成フォルダー。 |
| モデル コンフィギュレーション パラメーター [言語] が |
| 連続タスクのサンプル レートと最初の離散タスクが同等な場合は True (1)、それ以外の場合は False (0)。 |
S-Function とビルド情報のサポート メモ この節のトークンの例は、rtwmakecfg 用のテンプレート makefile の変更を参照してください。 | |
| インクルード パスに追加するフォルダー名のリスト。さらに、INCLUDES 行に ADD_INCLUDES マクロを追加しなければなりません。 |
| ライブラリ名のリスト。 |
| |>START_EXPAND_LIBRARIES<| ライブラリ リストと |>START_PRECOMP_LIBRARIES<| ライブラリ リスト内のライブラリ モジュール名。 |
| makefile 規則。 |
| プリコンパイル済みライブラリ名のリスト。 |
モデル参照のサポート メモ この節のトークンの例は、TMF でのモデル参照のサポートを参照してください。 | |
| 現在のモデルに対して生成されたライブラリ ファイルの名前。 |
| 最上位モデルによって参照されるモデルのリスト。 |
| 最上位モデルがリンクする参照モデル ライブラリのリスト。 |
| 最上位モデルがリンクする応答ファイルの名前。このトークンは、リンカー応答ファイルをサポートするビルド環境に対してのみ有効です。使用方法の例は、 を参照してください。 |
| ビルド中のターゲットのタイプ。可能な値は以下のとおりです。
|
| 生成された makefile の場所から MATLAB 作業フォルダーへの相対パス。 |
これらのトークンは、ビルド プロセスに既知のパラメーター値を代入することによって展開されます。たとえば、ソース モデルに 2 つの異なるサンプル時間をもつブロックがある場合は、以下の TMF ステートメント
NUMST = |>NUMST<|
は次のように展開されます。
NUMST = 2
さらに、make_rtw
は、他のソースからもトークンを以下のように展開します。
[コンフィギュレーション パラメーター] ダイアログ ボックスのターゲット オプションで定義されているターゲットに固有なトークン
システム ターゲット ファイルの
rtwoptions
節にある構造体。フィールドmakevariable
を含むrtwoptions
構造体配列内の構造体が展開されます。
以下の例は、
からの抜粋です。matlabroot
/rtw/c/grt/grt.tlcBEGIN_RTW_OPTIONS
で開始される節には、rtwoptions
を設定する MATLAB コードが含まれています。以下の命令によって、|>EXT_MODE<|
トークンが、[エクスターナル モード] オプションの設定に応じて、1
(オン) または 0
(オフ) に展開されます。
rtwoptions(2).makevariable = 'EXT_MODE'
make ユーティリティの起動
make コマンド
を TMF から作成すると、ビルド プロセスは model_or_sharedutils
.mkmake
コマンドを実行します。make
を起動するために、ビルド プロセスはこのコマンドを発行します。
makecommand -f model_or_sharedutils.mk
は、システム ターゲット ファイルの TMF 内で makecommand
MAKECMD
マクロによって定義されています (テンプレート makefile の構造体を参照)。モデル コンフィギュレーション パラメーター [make コマンド] を使用して make
に追加のオプションを指定できます。(make コマンドの指定およびテンプレート makefile と make オプションの節を参照してください)。
たとえば、[make コマンド] フィールドに OPT_OPTS=-O2
を指定すると、make_rtw
が以下の make
コマンドを生成します。
makecommand -f model_or_sharedutils.mk OPT_OPTS=-O2
TMF の先頭にあるコメントは、使用できる make
コマンド オプションを指定します。これらのオプションでは柔軟性が足りない場合、独自の TMF を設定できます。
make ユーティリティのバージョン
make ユーティリティを使用すると、リアルタイム プログラムのビルドのほとんどすべての側面を制御できます。使用できる make
には、いくつかの異なるバージョンがあります。コード ジェネレーターは、UNIX®1
と PC プラットフォームの両方に Free Software Foundation の GNU® make
を、次のフォルダーの下にあるプラットフォーム固有のサブフォルダーで提供しています。
matlabroot/bin
コード ジェネレーターでは、GNU Make の使用をお勧めしますが、他のバージョンの make
を使用することもできます。コード ジェネレーターとの互換性を確保するには、使用するバージョンの make
が以下のコマンド形式をサポートしていることを確認します。
makecommand -f model_or_sharedutils.mk
テンプレート makefile の構造体
TMF には、次のような複数のセクションがあります。
Abstract
— makefile のターゲットを説明します。
の ERT TMF からの代表的な要約を以下に示します。matlabroot
/toolbox/coder/compile/tmf# Abstract: # Template makefile for building a Windows-based stand-alone embedded # real-time version of Simulink model using generated C code and the # Microsoft Visual C/C++ compiler for x64. # # Note that this template is automatically customized by the build # procedure to create "<model>.mk" # # The following defines can be used to modify the behavior of the # build: # OPT_OPTS - Optimization option. See DEFAULT_OPT_OPTS in # vctools.mak for default. # OPTS - User specific options. # CPP_OPTS - C++ compiler options. # USER_SRCS - Additional user sources, such as files needed by # S-functions. # USER_INCLUDES - Additional include paths # (i.e. USER_INCLUDES="-Iwhere-ever -Iwhere-ever2") # # To enable debugging: # set DEBUG_BUILD = 1, which will trigger OPTS=-Zi (may vary with # compiler version, see compiler doc) # # This template makefile is designed to be used with a system target # file that contains 'rtwgensettings.BuildDirSuffix' see ert.tlc
Macros read by make_rtw
セクション —make_rtw
にTMF の処理用法を指示するマクロを定義します。
の GRT TMF の代表的なmatlabroot
/toolbox/coder/compile/tmfMacros read by make_rtw
セクションを以下に示します。#------------------------ Macros read by make_rtw ----------------------------- # # The following macros are read by the build procedure: # # MAKECMD - This is the command used to invoke the make utility # HOST - What platform this template makefile is targeted for # (i.e. PC or UNIX) # BUILD - Invoke make from the build procedure (yes/no)? # SYS_TARGET_FILE - Name of system target file. MAKECMD = nmake HOST = PC BUILD = yes SYS_TARGET_FILE = any BUILD_SUCCESS = ^#^#^# Created # Opt in to simplified format by specifying compatible Toolchain TOOLCHAIN_NAME = [\ "Microsoft Visual C++ 2019 v16.0 | nmake (64-bit Windows)", \ "Microsoft Visual C++ 2017 v15.0 | nmake (64-bit Windows)", \ "Microsoft Visual C++ 2015 v14.0 | nmake (64-bit Windows)"]
このセクションのマクロには、次のようなものがあります。
MAKECMD
— make ユーティリティを起動するために使用されるコマンドを指定します。たとえば、MAKECMD
=mymake
の場合、起動されるmake
コマンドは次のようになります。mymake -f
model_or_sharedutils
.mkHOST
— この TMF のターゲットとなるプラットフォームを指定します。これは、PC
、UNIX
、
(MATLABcomputer_name
computer
コマンドを参照) またはANY
のいずれかになります。BUILD
—make_rtw
に対してmake
をビルド プロシージャから起動しなければならないかどうかを指示します。yes
またはno
を指定します。SYS_TARGET_FILE
— システム ターゲット ファイルの名前または値any
を指定します。これは、[コンフィギュレーション パラメーター] ダイアログ ボックスの [コード生成] ペインの [ターゲットの選択] パネルでシステム ターゲット ファイルが指定されているかどうか検証するためにmake_rtw
による整合性チェックで使用されます。any
を指定した場合、あらゆるシステム ターゲット ファイルを使用した TMF を使用できます。BUILD_SUCCESS
— makefile がスタティック ライブラリを作成する際に、たとえばert_vcx64.tmf
のルールによって定義されているように、BUILD_SUCCESS
文字列が作成されます。$(PRODUCT) : $(OBJS) $(LIBS) $(MODELREF_LINK_LIBS) @cmd /C "echo ### Linking ..." $(LD) $(LDFLAGS) $(LIBS) \ @$(CMD_FILE) @$(MODELREF_LINK_RSPFILE) -dll -def:$(MODEL).def -out:$@ @cmd /C "echo $(BUILD_SUCCESS) dynamically linked library $(PRODUCT)"
ビルド プロセスで
BUILD_SUCCESS
文字列が見つかると、更新されたスタティック ライブラリ ファイルの存在がポーリングされます。ビルド プロセスでは、更新されたタイムスタンプが付いたライブラリ ファイルの存在がファイル システム上で確認できるまで、ライブラリ ファイルの実行可能ファイルへのリンクは行われません。ビルド プロセスでコンパイル ログに
BUILD_SUCCESS
が見つからない場合、ビルド プロセスでは更新されたライブラリ アーカイブがファイル システム上で使用可能であると仮定します。必要であれば、ビルド プロセスでライブラリの実行可能ファイルへのリンクが行われます。
Tokens expanded by make_rtw
セクション —make_rtw
が展開するトークンを定義します。
の ERT TMF の代表的なmatlabroot
/toolbox/coder/compile/tmf/Tokens expanded by make_rtw
セクションからの簡潔な抜粋を以下に示します。#---------------------- Tokens expanded by make_rtw ---------------------------- # # The following tokens, when wrapped with "|>" and "<|" are expanded by the # build procedure. # # MODEL_NAME - Name of the Simulink block diagram # MODEL_MODULES - Any additional generated source modules # MAKEFILE_NAME - Name of makefile created from template makefile <model>.mk # MATLAB_ROOT - Path to where MATLAB is installed. ... MODEL = |>MODEL_NAME<| MODULES = |>MODEL_MODULES<| PRODUCT = |>PRODUCT<| MAKEFILE = |>MAKEFILE_NAME<| MATLAB_ROOT = |>MATLAB_ROOT<| ...
TMF トークンに関する詳細については、make_rtw によって展開されるテンプレート makefile トークンを参照してください。
これ以降のセクションは、コンパイラ、ホストおよびターゲットによって異なります。よく参照されるセクションとしては、
Model and reference models
、External mode
、Tool Specifications
またはTool Definitions
、Include Path
、C Flags
、Additional Libraries
およびSource Files
などがあります。Rules
セクション — 生成されたソース コードから実行可能ファイルをビルドするときに使用される make のルールが含まれます。ビルド規則は、通常、make のバージョンによって異なります。Rules
セクションの後には、Dependencies
などの関連するセクションが続く場合があります。
テンプレート makefiles のカスタマイズと作成
はじめに
この節では、カスタム テンプレート makefile (TMF) を設定する機構およびビルド プロセスへの組み込みを説明します。また、TMF および TMF に関連付けられた MATLAB ファイル機構を変更する手法についても説明します。
カスタム TMF を作成する前に、フォルダーおよびファイルの命名規則を読んで、フォルダー構造とカスタム ターゲットの MATLAB パス要件について理解しておいてください。
テンプレート makefile の設定
TMF のカスタマイズまたは TMF の新規作成を行うには、matlabroot
/toolbox/coder/compile/tmf
から既存の GRT または ERT TMF をコピーします。
関連付けられたシステム ターゲット ファイルと同じフォルダーにコピーを配置します。通常、これは、ターゲット フォルダー構造内の mytarget/mytarget
フォルダーです。次に、TMF の名前を変更して (mytarget.tmf
など)、ファイルを変更します。
目的の TMF がビルド プロセスで検出および選択されるように、システム ターゲット ファイル ヘッダーに情報を入力しなければなりません (システム ターゲット ファイル構造体を参照してください)。1 つの TMF を実装するターゲットの場合、ビルド プロセスで使用する TMF を指定する標準の方法は、システム ターゲット ファイル ヘッダーの TMF 命令を使用することです。
TMF: mytarget.tmf
テンプレート makefile でのマクロとパターン マッチング式の使用
この節では、例を使って、TMF 内でマクロとファイル パターン マッチング式を使用して
でコマンドを生成する方法を説明します。model_or_sharedutils
.mk
make ユーティリティは、
を処理して、model_or_sharedutils
.mk
で定義されている依存の規則に基づいてコマンドのセットを生成します。model_or_sharedutils
.mkmake
が test
のビルドまたはリビルドのための一連のコマンドを生成した後、make
がこれらのコマンドを実行します。
たとえば、test
というプログラムをビルドするには、make
はオブジェクト ファイルをリンクしなければなりません。しかし、オブジェクト ファイルが存在しない場合や古い場合は、make
はソース コードをコンパイルしなければなりません。したがって、ソースとオブジェクト ファイルの間に依存関係があります。
make
は、バージョンごとに機能と規則の定義方法が若干異なります。たとえば、file1.c
と file2.c
の 2 つのソースから作成される test
というプログラムを考えてみます。ほとんどのバージョンの make
では、依存の規則は次のようになります。
test: file1.o file2.o cc -o test file1.o file2.o file1.o: file1.c cc -c file1.c file2.o: file2.c cc -c file2.c
この例では、UNIX2 環境が前提となっています。PC 環境では、ファイル拡張子およびコンパイルとリンクのコマンドが異なります。
最初の規則を処理する場合について説明します。
test: file1.o file2.o
make
は、test
をビルドするために file1.o
と file2.o
をビルドする必要があることを認識します。file1.o
をビルドするために、make
が次の規則を処理します。
file1.o: file1.c
file1.o
が存在しない場合、または file1.o
が file1.c
よりも古い場合、make
は file1.c
をコンパイルします。
TMF の形式は、上の例と同じです。TMF は、マクロやファイル パターン マッチング式などの make
の追加機能を使用します。make
のほとんどのバージョンでは、マクロは次のように定義されます。
MACRO_NAME = value
マクロへの参照は、$(MACRO_NAME)
で作成されます。make
が、この式の形式を認識すると、$(MACRO_NAME)
の value
を置き換えます。
パターン マッチング式を使用して、依存の規則を一般化することができます。たとえば、GNU 3
Make を使用すると、"file1.o: file1.c
" と "file2.o: file2.c
" の 2 つの規則を 1 つの規則で置き換えることができます。
%.o : %.c cc -c $<
前の例における $<
は、依存ファイル (file1.c
または file2.c
) と同等の特殊なマクロです。したがって、マクロと "%
" パターン一致文字を使用すると、前の例は次のように短縮されます。
SRCS = file1.c file2.c OBJS = $(SRCS:.c=.o) test: $(OBJS) cc -o $@ $(OBJS) %.o : %.c cc -c $<
上記の $@
マクロは、現在の依存ターゲット (test
) の名前と同等の特殊なマクロです。
この例は、マクロ拡張のテキスト置換機能を使用することによって、ソース (SRCS
) のリストからオブジェクト (OBJS
) のリストを生成します。ソース ファイルの拡張子 (.c
など) がオブジェクト ファイルの拡張子(.o
) で置き換えられます。この例は、特殊な "$@
" マクロを使用するためにプログラム test
のビルド規則を一般化します。
生成済みの makefile を rtwmakecfg によってカスタマイズする
TMF は、生成された makefile に以下の項目を追加するトークンを提供します。
ソース フォルダー
インクルード フォルダー
ランタイム ライブラリ名
ランタイム モジュール オブジェクト
S-Function は、rtwmakecfg.m
ファイル関数を使用して、この情報を makefile に追加できます。この関数は、デバイス ドライバー ブロックなどの S-Function ブロックを 1 つ以上含むモデルを作成するときに特に便利です。
S-Function に関連する情報を makefile に追加するには、以下の手順に従います。
ファイル
rtwmakecfg.m
に関数rtwmakecfg
を作成します。コード ジェネレーターは、フォルダーの位置に基づいてこのファイルと S-Function を関連付けます。関数
rtwmakecfg
によって返される情報のマクロ拡張をサポートするようにターゲットの TMF を変更します。
ビルド プロセスの TLC フェーズの後、TMF から makefile を生成する際に、ビルド プロセスは S-Function コンポーネントを含んでいるフォルダー内で rtwmakecfg.m
ファイルを検索します。ファイルが検出された場合、ビルド プロセスは関数 rtwmakecfg
を呼び出します。詳細については、生成された makefile を rtwmakecfg.m API を使用してカスタマイズを参照してください。
カスタム ターゲットでの連続時間のサポート
カスタムの ERT ベースのターゲットで連続時間をサポートする場合、ターゲットのテンプレート makefile (TMF) と静的なメイン プログラム モジュール (mytarget_main.c
など) を更新しなければなりません。
テンプレート makefile の変更. 次に示すように、NCSTATES
トークン拡張を NUMST
トークン拡張の後に追加します。
NUMST = |>NUMST<| NCSTATES = |>NCSTATES<|
さらに、次の例に示すように、NCSTATES
を CPP_REQ_DEFINES
マクロに追加します。
CPP_REQ_DEFINES = -DMODEL=$(MODEL) -DNUMST=$(NUMST) -DNCSTATES=$(NCSTATES) \ -DMAT_FILE=$(MAT_FILE) -DINTEGER_CODE=$(INTEGER_CODE) \ -DONESTEPFCN=$(ONESTEPFCN) -DTERMFCN=$(TERMFCN) \ -DHAVESTDIO -DMULTI_INSTANCE_CODE=$(MULTI_INSTANCE_CODE) \
メイン プログラム モジュールの変更. メイン プログラム モジュールは、シングルレートおよびマルチレート モジュールのサポートされているタスク モードのタスク スケジューリングを管理する静的なメイン関数を定義します。NUMST
(モデル内のサンプル時間の数) は、メイン関数がマルチレート コードを呼び出すか、シングルレート コードを呼び出すかを決定します。しかし、モデルが連続時間を使用する場合は、NUMST
に直接依存しないでください。
モデルが連続時間をもち、フラグ TID01EQ
が真である場合、生成コードでは、連続時間と最速の離散時間の両方が 1 つのレートとして扱われます。最速の離散レートに関連付けられたコードは、メジャー タイム ステップ チェックによって保護されます。モデルのレートが 2 つだけで、TID01EQ
が真の場合、生成コードは、シングルレートの呼び出しインターフェイスをもちます。
連続時間をもつモジュールをサポートするには、次に示すように、静的なメイン モジュールを更新して、TID01EQ
を考慮に入れます。
ファイル内で
NUMST
が参照される前に、次のコードを追加します。#if defined(TID01EQ) && TID01EQ == 1 && NCSTATES == 0 #define DISC_NUMST (NUMST - 1) #else #define DISC_NUMST NUMST #endif
ファイル内にある
NUMST
のインスタンスをDISC_NUMST
で置き換えます。
モデル参照の注意事項
コード ジェネレーターのモデル参照機能をサポートするために行う必要のある TMF 変更に関する重要な情報については、モデル参照のサポートを参照してください。
メモ
変数 MODELREFS
を使用せずに TMF を使用している場合、そのファイルは Simulink ソフトウェアの以前のリリースで使用されたものかもしれません。TMF がモデル参照をサポートするようにするには、make ファイルに MODELREFS
を追加してください。
カスタムのテンプレート makefile を使用して共有ユーティリティ コードを作成するときのタイムアウト エラー
ビルド プロセスがカスタムのテンプレート makefile を使用して共有ユーティリティ コードの makefile を作成している場合、以下のすべての条件に該当すると、タイムアウト エラーが発生します。
コンフィギュレーション パラメーター
GenCodeOnly
が'off'
になっている。rtwshared.mk
に対するmake
呼び出し中にBUILD_SUCCESS
メッセージが出力される。rtwshared.mk
に対するmake
呼び出しが最終的な製品を更新しない (通常はrtwshared.lib
)。
エラーを回避するには、カスタムのテンプレート makefile を更新して、最終製品が生成される場合にのみ (make
変数 PRODUCT
で指定) make
呼び出しで BUILD_SUCCESS
メッセージが生成されるようにします。または、ビルド プロセスが生成された makefile を使用しない場合、コンフィギュレーション パラメーター GenerateMakefile
を 'off'
に設定して makefile の生成を無効にします。
関連するトピック
1 UNIX is a registered trademark of The Open Group in the United States and other countries.
2 UNIX is a registered trademark of The Open Group in the United States and other countries.
3 GNU is a registered trademark of the Free Software Foundation.