CMake-Compiler-Flags – Targets individuell kompilieren - CodingWithMagga (2024)

()

Compiler bieten eine riesige Anzahl von Compiler-Flags, die verschiedenen Optionen beim Erstellen von Build-Dateien ermöglichen. Bei direkter Verwendung des Compilers übergibt man die Compiler-Flags direkt auf der Kommandozeile. Verwendet man jedoch CMake, gibt es dort verschiedenen Befehle, um Compiler-Flags zu übergeben. In diesem Beitrag stelle ich euch diese Befehle vor, gebe dazu mehrere Beispiele und gehe auch auf verschiedene Compiler ein. Zumeist übernimmt CMake auch die Aufgabe, zwischen verschiedenen Compilern zu unterscheiden.

Diesen und andere Beiträge von mir kannst du als sauber formatierte PDF-Datei zum Ausdrucken oder offline Lesen erwerben. Mehr Informationen dazu findest du hier.

Inhaltsverzeichnis

Nötige Vorkenntnisse

  • CMake Grundkenntnisse: Dazu gehört etwa die Erstellung und Kompilierung eines ausführbaren Programms mit CMake. Ihr solltet dahin gehend auch mit den CMake-Befehlen cmake_minimum_required(), project() und add_executable() vertraut sein. Solltet ihr nicht wissen, wie ihr ein Programm mit CMake erstellt und kompiliert, schaut euch am besten zuvor diesen Artikel oder dieses YouTube-Video von mir an.
  • CMake-Variablen: CMake-Variablen stelle ich sowohl in einem Artikel als auch in einem YouTube-Video vor. Zudem findet sich eine Erklärung zu CMake-Variablen auch in der CMake-Dokumentation.
  • CMake-Properties: In diesem Video auf YouTube gehe ich auf Properties in CMake ein. Zudem findet man eine Auflistung von Properties in der CMake-Dokumentation, eine genauere Erläuterung, was Properties eigentlich sind, fehlt hier jedoch.
  • CMake-Listen: Listen sind in CMake ein einzelner zusammenhängender, langer String, in der die einzelnen Werte mittels eines Semikolons getrennt werden. Mehr Informationen zur Handhabung von Listen findet ihr in diesem YouTube-Video oder in der CMake-Dokumentation.
  • PUBLIC, PRIVATE, INTERFACE: Diese Keywords dienen dazu, den Scope der übergebenen Flags zu definieren. Sie kommen in vielen CMake-Befehlen, wie target_include_directories() oder target_link_libraries() zum Einsatz. In der CMake-Dokumentation zu diesen Befehlen oder in diesem YouTube-Video findet ihr dazu mehr Informationen.
  • C++-Sprachstandard: In Beispiel 2 setze ich den C++-Sprachstandard einmal über CMake-Variablen und einmal durch eine Compiler-Flag. In diesem Beitrag habe ich ausführlich über die Verwendung des C++-Standards in CMake geschrieben. Ebenfalls wird man dazu in der CMake-Dokumentation oder in meinem YouTube-Video über Properties fündig.
  • If-Verzweigungen: If-Verzweigungen in CMake unterscheiden sich generell nicht von if-Verzweigungen in anderen Programmiersprachen und sollten daher wohl den meisten Lesern geläufig sein. If-Verzweigungen in CMake erwähne ich kurz in diesem YouTube-Video, ansonsten hilft hier natürlich auch wieder die CMake-Dokumentation weiter.

Compilerspezifische Target-Properties

Jedes Target enthält eine Vielzahl von Properties, die die Übergabe von Flags an den Compiler des Targets beeinflussen. Die vier wichtigsten sind INCLUDE_DIRECTORIES, COMPILE_DEFINITIONS,
COMPILE_FEATURES und COMPILE_OPTIONS. In der Property INCLUDE_DIRECTORIES wird die Liste der Ordner gespeichert, die dem Compiler als Suchpfade für Dateien übergeben werden. Dies geschieht bei den meisten Compilern mittels -I Ordner respektive /I Ordner. Üblicherweise sollte dies über den CMake-Befehl target_include_directories() gehandhabt werden. Da diese Property und der target_include_directories()-Befehl thematisch eher in den Bereich Bibliotheken und Projektstrukturierung passen, gehe ich in diesem Beitrag nicht weiter darauf ein. Bleiben die drei letztgenannten Properties, auf die ich mich in diesem Beitrag konzentrieren werde.

COMPILE_DEFINITIONS

Diese Property ist eine CMake-Liste, in der Definitionen gespeichert sind, die auf der Kommandozeile übergeben werden sollen. Eine Definition hat entweder die Form DEF oder DEF=Wert. CMake konvertiert die angegebenen Definitionen dann in die entsprechende Compiler-Flag, die vorwiegend die Form -D DEF respektive -D DEF=WERT hat. Im C++-Code können diese Definitionen, oft auch als Symbole bezeichnet, beispielsweise mittels des Makros #ifdef überprüft werden.

COMPILE_FEATURES

CMake ermöglicht die Angabe einzelner sogenannter „Features“ von Sprachstandards (zum Beispiel C++11) für Targets. Ein solches Feature sind etwa die „constant expressions“ (constexpr) aus dem C++11-Standard. Auch die Angabe des Sprachstandards ist an dieser Stelle möglich. CMake übernimmt die Aufgabe, den korrekten Sprachstandard anhand der gegebenen Features zu ermitteln und dem Compiler zu übergeben. Bei Überschneidungen nimmt CMake immer den höheren C++-Standard. In der globalen CMake-Property CMAKE_CXX_KNOWN_FEATURES ist eine Liste aller verfügbaren C++-Features gespeichert. Zusätzlich findet man diese in der CMake-Dokumentation. Welche C++-Features der verwendete Compiler unterstützt, wird in der CMake-Variablen CMAKE_CXX_COMPILE_FEATURES gespeichert.

COMPILE_OPTIONS

In dieser Property werden alle übrigen Compiler-Flags in einer CMake-Liste gespeichert, die nicht in die beiden obigen Properties passen. Diese Liste wird dann exakt so an den Compiler übergeben. Im Gegensatz zu anderen Aufgaben, wie das Einbinden von Ordnern oder das Verlinken von Bibliotheken über die entsprechenden CMake-Befehle, wandelt CMake direkt übergebene Compiler-Flags über diese Property nicht automatisch in die korrekte Form für jeden Compiler um. Bei Verwendung von unterschiedlichen Compilern, insbesondere des MSVC-Compilers, muss also auf die unterschiedliche Form der Compiler-Flags geachtet werden.

Weitere Informationen

Die vier genannten Target-Properties haben jeweils auch ein Gegenstück, das den Präfix INTERFACE_ trägt, also zum Beispiel INTERFACE_COMPILE_DEFINITIONS. Diese haben den gleichen Effekt wie ihre Namensvetter, beziehen sich aber nur auf verlinkte Targets. Damit können Anforderungen an verlinkte Targets vorgegeben werden, die von diesem Target benötigt werden.

Dadurch, dass jedes Target seine eigenen Properties besitzt, kann jedes Target kann mit einem unterschiedlichen Satz von Compiler-Flags kompiliert werden, spezifiziert durch die zugehörigen Properties. So können etwa Targets mit unterschiedlichen Definitionen und unterschiedlichen C++-Sprachstandards kompiliert werden.

Übergabe von Flags an den Compiler

Wenden wir uns nun der Möglichkeit zu, Flags an den Compiler für ein bestimmtes Target zu übergeben. Für die im Folgenden targetspezifischen Befehle gibt es jeweils auch einen global wirkenden Befehl, der sich auf alle Targets auswirkt. Wie in CMake ab Version 3.0 üblich sollten jedoch die targetspezifischen Befehle verwendet werden. Daher gehe ich an dieser Stelle auch nicht weiter auf die globalen Befehle ein.

Übergabe von Definitionen -D

Blicken wir jetzt einmal auf den CMake-Befehl target_compile_definitions(), mit dessen Hilfe Definitionen mittels des Compilers übergeben werden können. Diese Definitionen können dann im C++-Code überprüft oder verwendet werden.

target_compile_definitions( <TargetName> <INTERFACE|PUBLIC|PRIVATE> [<Definition1> ...] [<INTERFACE|PUBLIC|PRIVATE> [<Definition2> ...] ...])

Nach der Angabe des Targets <TargetName> an den die Definition übergeben werden soll, folgt eines der drei Keywords INTERFACE, PUBLIC oder PRIVATE. Bei Angabe des Keywords PRIVATE wird die übergebene Definition <Definition1> in die Property COMPILE_DEFINITIONS geschrieben, womit diese Definition nur für das Target <TargetName> gültig ist. Bei Verwendung des Keywords INTERFACE wird die Definition <Definition1> in der Interface Property INTERFACE_COMPILE_DEFINITIONS gespeichert. Somit ist diese Definition nur für verlinkte Targets relevant. Bei Verwendung des Keywords PUBLIC wird die Definition <Definition1> in beide Properties geschrieben.

Die Definitionen <Definition1>, <Definition2> usw. müssen die Form DEFINITION oder DEFINITION=Wert haben. Es sind zwar auch Kleinbuchstaben möglich, doch die Verwendung dieser ist sehr ungewöhnlich. Wie im obigen Befehl zu sehen, ist es möglich mehrere Definitionen auf einmal mit einem der Keywords INTERFACE, PUBLIC oder PRIVATE zu setzen und/oder mehrere Keywords mit verschiedenen Definitionen zu verwenden.

Beispiel 1: Übergabe und Verwendung von Definitionen

In diesem Beispiel übergebe ich zwei Definitionen mittels des Compilers an eine ausführbare Datei. Innerhalb der ausführbaren Datei greife ich auf die übergebenen Definitionen zu. Schauen wir dazu zunächst die CMakeLists.txt-Datei an:

cmake_minimum_required(VERSION 3.8...3.26)project(compiler_flag_1 LANGUAGES CXX)add_executable(def_test main.cpp)target_compile_definitions( def_test PRIVATE PRINT NUMBER=1)

In den ersten Zeilen passiert erst einmal nichts Spezielles, wir erstellen lediglich die ausführbare Datei def_test aus der Source-Datei main.cpp in Zeile 5. Dieser ausführbaren Datei fügen wir nun die beiden Definitionen PRINT und NUMBER=1 unter dem Keyword PRIVATE hinzu. Da das Target def_test nicht weiter verlinkt wird und keine anderen Targets involviert sind, ist das Keyword PRIVATE an dieser Stelle die richtige Wahl. Diese beiden Definitionen verwenden wir nun in der Source-Datei main.cpp:

#include <iostream>int main() {#ifdef PRINT std::cout << "PRINT is defined." << std::endl;#else std::cout << "PRINT not defined." << std::endl;#endif std::cout << "NUMBER: " << NUMBER << std::endl; return 0;}

In den Zeilen 5 bis 9 wird mittels der Makros #ifdef, #else und #endif überprüft, ob das Symbol PRINT an dieser Stelle definiert ist oder nicht. Je nachdem wird an dann von dem Programm „PRINT is defined.“ oder „PRINT not defined.“ ausgegeben. In Zeile 11 wird dann die Zahl ausgegeben, die in der Definition NUMBER gespeichert ist. Sollte NUMBER an dieser Stelle nicht definiert sein, wird ein Fehler vom Compiler ausgegeben. Ich spare mit an dieser Stelle die Ausgabe der Kompilierung des Programms, da für dieses Beispiel keine relevante zusätzliche Ausgabe erfolgt. Die Ausgabe des Programms def_test ist dann wie folgt:

$ ./def_test PRINT is defined.NUMBER: 1

Übergabe von Compiler-Features

Der CMake-Befehl target_compile_features() ist genauso aufgebaut wie der target_compile_definitions()-Befehl. Mithilfe dieses CMake-Befehls können der benötigte Sprachstandard oder aber auch einzelne Features eines Standards aktiviert werden. Diese „Aktivierung“ erfolgt durch die Übergabe der korrekten Flags an den Compiler, wobei CMake selbst die benötigten Flags und die Art wie diese dem Compiler übergeben werden ermittelt.

target_compile_features( <TargetName> <INTERFACE|PUBLIC|PRIVATE> [<Feature1> ...] [<INTERFACE|PUBLIC|PRIVATE> [<Feature2> ...] ...])

Wie auch beim target_compile_definitions()-Befehl, bestimmt die Verwendung des Keywords INTERFACE, PUBLIC oder PRIVATE, ob das Feature <Feature1>, <Feature2> usw. in die Property COMPILE_FEATURES oder INTERFACE_COMPILE_FEATURES geschrieben wird. Die Property COMPILE_FEATURES ist für das angegebene Target <TargetName> relevant, während die Property INTERFACE_COMPILE_FEATURES für verlinkte Targets relevant ist.

In der CMake-Variablen CMAKE_CXX_KNOWN_FEATURES ist eine Liste aller verfügbaren C++-Features gespeichert. Zusätzlich findet man diese in der CMake-Dokumentation. Welche C++-Features der verwendete Compiler unterstützt, wird in der CMake-Variablen CMAKE_CXX_COMPILE_FEATURES gespeichert. Ab C++17 existieren keine individuellen Features mehr, stattdessen sollen die High-Level-Features für den Sprachstandard wie cxx_std_17, cxx_std_20 usw. verwendet werden. Dies gilt allgemein auch für frühere C++-Standards, auch wenn für diese spezifische Sprachfeatures zur Verfügung stehen. In meinem Beitrag zum C++-Standard habe ich noch ausführlicher über die Verwendung von Compiler-Features geschrieben, insbesondere über die individuellen Features.

Beispiel 2: Verwendung von C++-17 durch Compiler-Features

In diesem Beispiel setze ich den C++-Sprachstandard einmal über CMake-Variablen und einmal über den oben gezeigten Befehl target_compile_features(). Schauen wir dazu zunächst auf die CMakeLists.txt-Datei.

cmake_minimum_required(VERSION 3.8...3.26)project(compiler_flag_2 LANGUAGES CXX) set(CMAKE_CXX_STANDARD 11)set(CMAKE_CXX_STANDARD_REQUIRED ON)set(CMAKE_CXX_EXTENSIONS OFF)add_executable(cpp17_exe main.cpp)target_compile_features( cpp17_exe PRIVATE cxx_std_17)

In den Zeilen 5–7 wird mittels der bekannten CMake-Variablen der C++11-Standard für alle Targets gesetzt. Die erzeugte ausführbare Datei cpp17_exe (ein Target) in Zeile 9 benötigt jedoch den C++17-Standard, wie wir gleich in der zugehörigen main.cpp-Datei sehen werden. Um nur speziell dieses Target mit dem C++17-Standard zu kompilieren, verwenden wir in Zeile 11–14 den target_compile_features()-Befehl. In diesem geben wir den C++17-Standard mittels des Compiler-Feature cxx_std_17 an. Blicken wir nun in die main.cpp-Datei:

#include <iostream>int main() { int position[2] = {1, 2}; auto [x, y] = position; std::cout << x << " " << y << std::endl; return 0;}

In Zeile 7 werden sogenannte „structured bindings“ aus dem C++17-Standard verwendet. Dabei werden den Variablen x und y die Werte aus dem Array position zugewiesen. Anschließend werden die Variablen x und y in Zeile 8 ausgegeben. Die Ausgabe des Programm cpp17_exe sieht dann wie folgt aus, wobei ich erneut auf die Ausgabe der Kompilierung verzichte:

$ ./cpp17_exe 1 2

Übergabe von Compiler-Optionen

Der Befehl target_compile_options() ermöglicht die Übergabe von Compiler-Flags, die nicht über die beiden erstgenannten Befehle in diesem Beitrag abgedeckt werden. Zudem muss man bei diesem Befehl darauf achten, dass die übergebenen Compiler-Flags nicht automatisch an den verwendeten Compiler angepasst werden.

target_compile_options( <TargetName> [BEFORE] <INTERFACE|PUBLIC|PRIVATE> [<Option1> ...] [<INTERFACE|PUBLIC|PRIVATE> [<Option2> ...] ...])

Der Befehl target_compile_options() bietet, im Gegensatz zu den anderen beiden Befehlen, noch das optionale Keyword BEFORE. Bei Verwendung dieses Keywords wird die übergebene Option <Option1>, <Option2> usw. nicht an das Ende der Property COMPILE_OPTIONS bzw. INTERFACE_COMPILE_OPTIONS gehangen und damit an das Ende des Compiler-Aufrufs, sondern direkt an den Anfang. Wie bei den anderen beiden Befehlen auch, entscheidet die Verwendung der Keywords INTERFACE, PUBLIC oder PRIVATE darüber, in welche Properties die übergebenen Compiler-Optionen geschrieben werden.

Beispiel 3: Aktivierung von Compiler-Warnungen

In diesem Beispiel setze ich eine Compiler-Flag, um die zusätzliche Warnungen des Compilers zu aktiveren. Ich verwende zusätzlich eine if-Verzweigung, um unterschiedliche Compiler abzudecken. Schauen wir dazu zunächst auf die CMakeLists.txt-Datei:

cmake_minimum_required(VERSION 3.8...3.26)project(compiler_flag_3 LANGUAGES CXX) add_executable(warning_test main.cpp)if(MSVC) target_compile_options( warning_test PRIVATE "/W4" )else() target_compile_options( warning_test PRIVATE "-Wall" )endif()

In Zeile 5 wird die ausführbare Datei warning_test aus der Source-Datei main.cpp erstellt. Für dieses Target wollen wir nun Compiler-Warnungen aktivieren. Bei den meisten Compilern kann dazu die Compiler-Flag -Wall verwendet werden, die eine große Anzahl an Warnungen aktiviert. Die Verwendung dieser Compiler-Flag ist zwar auch mit dem MSVC-Compiler möglich, erzeugt jedoch eine große Menge an Warnungen aus inkludierten Header-Dateien, die man nicht kontrollieren kann. Zudem ist die Syntax für Compiler-Flags im MSVC-Compiler etwas anders. Daher wird für den MSVC-Compiler die Compiler-Flag /W4 verwendet. Eine entsprechende if-Verzweigung in den Zeilen 7–17 steuert die Übergabe der korrekten Compiler-Flags mittels des target_compile_options()-Befehls. Blicken wir nun in die main.cpp-Datei:

#include <iostream>int main() { int unused; std::cout << "Hello Reader" << std::endl; return 0;}

In Zeile 4 wird die Integer-Variable unused definiert, die im weiteren Verlauf nicht verwendet wird. Der CMake-Aufruf und die spätere Ausgabe der ausführbaren Datei warning_test sind an dieser Stelle nicht von Bedeutung. Interessant ist jedoch der Aufruf des Compilers, hier beispielhaft mittels make auf Ubuntu 20.04:

$ makeScanning dependencies of target warning_test[ 50%] Building CXX object CMakeFiles/warning_test.dir/main.cpp.o/blog_code/CMake/cmake_compiler_flags/Beispiel_3/main.cpp: In function ‘int main()’:/blog_code/CMake/cmake_compiler_flags/Beispiel_3/main.cpp:4:7: warning: unused variable ‘unused’ [-Wunused-variable] 4 | int unused; | ^~~~~~[100%] Linking CXX executable warning_test[100%] Built target warning_test

In den Zeilen 4–7 wird eine Warnung ausgegeben, dass die Variable unused nicht verwendet wird. Dies haben wir durch die Übergabe der entsprechenden Compiler-Flag -Wall oder /W4, falls der MSVC-Compiler verwendet wurde, erreicht.

Zusammenfassung

In diesem Beitrag habe ich euch verschiedene Befehle vorgestellt, mit denen Compiler-Flags übergeben werden können. CMake nimmt einem dabei häufig einen großen Teil der Arbeit und wandelt die Compiler-Flags korrekt für den jeweils verwendeten Compiler um. Nur bei Verwendung von Compiler-Flags, die nicht durch die CMake-Befehle target_compile_definitions(), target_compile_features() oder target_include_directories() abgedeckt werden, muss man selbst auf die korrekte Syntax achten.

Weitere Informationen

Den Code zu diesem Beitrag könnt ihr gerne weiter verwenden, ihr findet ihn dazu auf GitHub.

In meinem Buch „CMake für Einsteiger“ und in meinen Videos auf YouTube stelle ich dieses und weitere CMake Themen noch einmal detaillierter vor. Bei Fragen oder Anmerkungen schreibt mir gerne einen Kommentar. 🙂

Meine Webseite ist komplett werbefrei. Falls dir dieser Beitrag gefallen hat und du meine Arbeit gerne unterstützen möchtest, schau daher doch einmal auf meiner Support-Seite vorbei. Das würde mich sehr freuen :).

Wie hilfreich war dieser Beitrag?

Klicke auf die Sterne um zu bewerten!

Durchschnittliche Bewertung / 5. Anzahl Bewertungen:

Bisher keine Bewertungen! Sei der Erste, der diesen Beitrag bewertet.

CMake-Compiler-Flags – Targets individuell kompilieren - CodingWithMagga (2024)

FAQs

How to use compiler flags with CMake? ›

The source file property COMPILE_OPTIONS adds options to one source file. add_link_options() adds options for linking. CMAKE_<LANG>_FLAGS and CMAKE_<LANG>_FLAGS_<CONFIG> add language-wide flags passed to all invocations of the compiler. This includes invocations that drive compiling and those that drive linking.

How to check CMake flags? ›

How to see all the flags and definitions in a verbose build
  1. $ cmake --build build -- VERBOSE=1. But many people do this with Unix Makefiles:
  2. $ mkdir build $ cd build $ cmake .. $ make VERBOSE=1. Also this works (on Unix Makefiles):
  3. $ env VERBOSE=1 make. For Ninja:
  4. $ cmake --build build -- -v. Hands-on: Verbose compilation.

How does CMake identify the compiler? ›

When CMake is invoked to read a configuration file, temporary files are generated, including a cache and a CMakeFiles directory containing information specific to the environment. CMake uses this information to select the most appropriate compiler for the project.

How to set compiler flag? ›

Some flags can be generated from the compiler. These are governed by two settings: use_default_includes and target_compilers. These will run some command over a chosen compiler, parse the result for the flags specific to the compiler and will append these flags to the other ones.

What is a compiler flag in GCC? ›

Compiler flags are options you give to gcc when it compiles a file or set of files. You may provide these directly on the command line, or your development tools may generate them when they invoke gcc.

Does CMake need a compiler? ›

If you do not find precompiled binaries for your system, then you can build CMake from source. To build CMake, you will need a modern C++ compiler and the source distribution from the CMake Download page or Kitware's GitLab instance. To build CMake, follow the instructions in README. rst at the top of the source tree.

How to set the default compiler in CMake? ›

Pass -DCMAKE_C_COMPILER=<compiler> to cmake when configure the project. That way CMake will use this compiler instead of default one and on the project() call it will adjust all flags for the specified compiler. Set CC environment variable ( CXX for C++ compiler).

What is the difference between GCC and CMake? ›

CMake is a robust build system generator that uses configuration files to create cross-compiled binaries, and GCC is a toolchain that includes compilers for various programming languages, including C, C++, Objective C, and Fortran.

How to cross compile a CMake project? ›

In order to cross-compile VTK, you need to:
  1. Install a toolchain and create a toolchain file for CMake.
  2. Build VTK natively for the build host.
  3. Run CMake for the target platform.
  4. Complete TryRunResults. cmake .
  5. Use the VTKCompileToolsConfig. cmake file from the native build.
  6. Build.

How do I pass compiler flags to Xcodebuild? ›

To set compiler flags with xcodebuild , you need to put them in the OTHER_CFLAGS option. Be aware that this will override any OTHER_CFLAGS set by the project. Glad you were able to get it to work -- now you can really make xcodebuild do even more for you without requiring changes of the target Xcode project!

What does add_compile_options do? ›

Adds options to the compilation of source files. Adds options to the compiler command line for targets in the current directory and below that are added after this command is invoked. See documentation of the directory and target COMPILE_OPTIONS properties.

References

Top Articles
Veronika Rajek Wiki, Age, Height, Married, Husband, Net Worth
Veronika Rajek's Net Worth, Bio, Personal Details, Career & More
Sarah Coughlan Boobs
London (Greater London) weather
Craigslist Cars For Sale San Francisco
United Center Section 305
Uptown Cheapskate Fort Lauderdale
Www. Kdarchitects .Net
Rent A Center Entertainment Center
What Is Flipping Straights Ted Lasso
Thomas Funeral Home Sparta Nc
Lubbock Avalanche Journal Newspaper Obituaries
Domino Near
Cherry Spa Madison
Rivers Edge Online Login Bonus
Craigslist Org Hattiesburg Ms
Townsend Funeral Home Dublin Ga Obituaries
Contenidos del nivel A2
2503 South Tacoma Way
Irela Torres Only Fans
Axolotls for Sale - 10 Online Stores You Can Buy an Axolotl - Axolotl Nerd
5128 Se Bybee Blvd
Los Garroberros Menu
Baby | Voeding | Voeding het eerste jaar; borstvoeding
Wolf Of Wall Street Tamil Dubbed Full Movie
Nsa Panama City Mwr
Think Up Elar Level 5 Answer Key Pdf
Nickelodeon Home Media
Biopark Prices
Craigslist Columbia Sc Com
Theater X Orange Heights Florida
Super Restore Vs Prayer Potion
Craigslist In Visalia California
فیلم 365 روز 1 نیکی مووی
Vuse Pod Serial Number Lookup
Paola Iezzi, chi è il compagno. L’uomo in comune con la sorella Chiara e le nozze 'congelate'
Strange World Showtimes Near Andover Cinema
Miracle Child Brandon Lake Chords
Youravon Comcom
Sheex Sheets Review (2024) | Mattress Nerd
5128 Se Bybee Blvd
DIRECT. France-Côte d'Ivoire U23: après Barcola, deux nouveaux forfaits pour les Espoirs
Daftpo
Sak Pase Rental Reviews
Russia Ukraine war live: Starmer meets Biden at White House but no decision on Ukraine missiles
Fifty Shades Of Gray 123Movies
Dawat Restaurant Novi
Jersey Mike's Subs: 16 Facts About The Sandwich Chain - The Daily Meal
Fapello.ckm
Yi Asian Chinese Union
Basketball Stars Unblocked 66 Ez
Latest Posts
Article information

Author: Twana Towne Ret

Last Updated:

Views: 5313

Rating: 4.3 / 5 (44 voted)

Reviews: 91% of readers found this page helpful

Author information

Name: Twana Towne Ret

Birthday: 1994-03-19

Address: Apt. 990 97439 Corwin Motorway, Port Eliseoburgh, NM 99144-2618

Phone: +5958753152963

Job: National Specialist

Hobby: Kayaking, Photography, Skydiving, Embroidery, Leather crafting, Orienteering, Cooking

Introduction: My name is Twana Towne Ret, I am a famous, talented, joyous, perfect, powerful, inquisitive, lovely person who loves writing and wants to share my knowledge and understanding with you.