diff --git a/.gitignore b/.gitignore
index 31c1c9ff0b64ea70fe05590c110658af89873337..7e22ad4c5d54c063bc463391a536809af72e30f8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
 *.swp
 *.swo
 .DS_Store
+build
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..e2352722e528f5fbfb99060eb6e66719376a4f29
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,18 @@
+cmake_minimum_required(VERSION 3.13) # 3.13 is required for target_link_options
+project(CompressedSensing CXX)
+
+if(NOT CMAKE_BUILD_TYPE)
+    set(CMAKE_BUILD_TYPE "Release")
+endif()
+message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
+
+find_package (Eigen3 3.3 REQUIRED NO_MODULE)
+
+include(cmake/shared_settings.cmake)
+
+add_executable(compressed_sensing
+    main.cpp
+    vector.h
+)
+target_link_libraries(compressed_sensing shared_settings Eigen3::Eigen)
+target_compile_features(compressed_sensing PUBLIC cxx_std_17)
diff --git a/cmake/shared_settings.cmake b/cmake/shared_settings.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..0a16a230041d5c36154e40631c0a1284511446c2
--- /dev/null
+++ b/cmake/shared_settings.cmake
@@ -0,0 +1,34 @@
+# This file defines an interface library used to add common compile flags to all targets.
+
+add_library(shared_settings INTERFACE)
+
+# Warning flags
+target_compile_options(shared_settings INTERFACE
+    -Wall
+    -Wcast-align
+    -Wcast-qual
+    -Wextra
+    -Wundef
+    -Wuseless-cast
+    -Wzero-as-null-pointer-constant
+    -pedantic
+)
+
+# Speed flags
+target_compile_options(shared_settings INTERFACE -march=native -ffast-math)
+
+# Build type for profile generation
+target_compile_options(shared_settings INTERFACE $<$<CONFIG:ProfileGenerate>:
+    -fprofile-generate
+    -O3
+    -DNDEBUG
+>)
+target_link_options(shared_settings INTERFACE $<$<CONFIG:ProfileGenerate>:-fprofile-generate>)
+
+# Build type for profile use
+target_compile_options(shared_settings INTERFACE $<$<CONFIG:ProfileUse>:
+    -fprofile-use
+    -O3
+    -DNDEBUG
+>)
+target_link_options(shared_settings INTERFACE $<$<CONFIG:ProfileUse>:-fprofile-use>)
diff --git a/main.cpp b/main.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..99fb5d758deb8f1d8fcd6d5e4898f589382386c4
--- /dev/null
+++ b/main.cpp
@@ -0,0 +1,11 @@
+#include <iostream>
+#include "vector.h"
+
+using namespace cs;
+
+//--------------------------------------------------------------------------------------------------
+int main() {
+    Vector<double> x = Vector<double>::Random(5);
+    std::cout << x << '\n';
+    return 0;
+}
diff --git a/vector.h b/vector.h
new file mode 100644
index 0000000000000000000000000000000000000000..cf7c07e5a25eeaf27d9b3d59cfc4e3119760998b
--- /dev/null
+++ b/vector.h
@@ -0,0 +1,18 @@
+#ifndef FUNSIM_VECTOR_H
+#define FUNSIM_VECTOR_H
+
+#include <Eigen/Core>
+
+namespace cs {
+
+//--------------------------------------------------------------------------------------------------
+template <typename T>
+using Vector = Eigen::Matrix<T, Eigen::Dynamic, 1>;
+
+//--------------------------------------------------------------------------------------------------
+template <typename T>
+using Matrix = Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>;
+
+}
+
+#endif