diff --git a/makefile b/makefile
index 5e3248655c14b86509d44eff39e2b60699e3d692..6f87edc3ce13d2ba6e368a66714ee359756683ba 100644
--- a/makefile
+++ b/makefile
@@ -1,7 +1,30 @@
-transpose_2D:
-	mpic++ transp.cpp \
+MPICXX  = mpicxx
+LINKER  = mpicxx
+DEFINES =
+CFLAGS  =
+
+LIBS = -lfftw3_mpi \
+	   -lfftw3 \
+	   -lfftw3f_mpi \
+	   -lfftw3f
+
+vpath %.cpp ./src/
+
+src := \
+	transp.cpp \
+	field_descriptor.cpp
+
+obj := $(patsubst %.cpp, ./obj/%.cpp.o, ${src})
+
+./obj/%.cpp.o: %.cpp
+	${MPICXX} ${DEFINES} \
+		${CFLAGS} \
+		-c $^ -o $@
+
+transpose_2D: ${obj}
+	${LINKER} \
+		${obj} \
 		-o t2D \
-		-lfftw3_mpi \
-		-lfftw3 \
-		-lfftw3f_mpi \
-		-lfftw3f
+		${LIBS} \
+		${NULL}
+
diff --git a/src/field_descriptor.cpp b/src/field_descriptor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..505f5e9c6d33f2dc623408b44f29c7b20083b125
--- /dev/null
+++ b/src/field_descriptor.cpp
@@ -0,0 +1,111 @@
+#include "field_descriptor.hpp"
+
+
+int field_descriptor::initialize(
+        int ndims,
+        int *n,
+        MPI_Datatype element_type)
+{
+    this->ndims = ndims;
+    this->sizes    = (int*)malloc(ndims*sizeof(int));
+    this->subsizes = (int*)malloc(ndims*sizeof(int));
+    this->starts   = (int*)malloc(ndims*sizeof(int));
+    this->sizes[0] = n[0];
+    this->subsizes[0] = n[0]/nprocs;
+    this->starts[0] = myrank*(n[0]/nprocs);
+    this->mpi_dtype = element_type;
+    this->local_size = this->subsizes[0];
+    this->full_size = this->sizes[0];
+    for (int i = 1; i < this->ndims; i++)
+    {
+        this->sizes[i] = n[i];
+        this->subsizes[i] = n[i];
+        this->starts[i] = 0;
+        this->local_size *= this->subsizes[i];
+        this->full_size *= this->sizes[i];
+    }
+    MPI_Type_create_subarray(
+            ndims,
+            this->sizes,
+            this->subsizes,
+            this->starts,
+            MPI_ORDER_C,
+            this->mpi_dtype,
+            &this->mpi_array_dtype);
+    MPI_Type_commit(&this->mpi_array_dtype);
+    return EXIT_SUCCESS;
+}
+
+int field_descriptor::finalize()
+{
+    free((void*)this->sizes);
+    free((void*)this->subsizes);
+    free((void*)this->starts);
+    MPI_Type_free(&this->mpi_array_dtype);
+    return EXIT_SUCCESS;
+}
+
+int field_descriptor::read(
+        const char *fname,
+        void *buffer)
+{
+    MPI_Info info;
+    MPI_Info_create(&info);
+    MPI_File f;
+
+    MPI_File_open(
+            MPI_COMM_WORLD,
+            fname,
+            MPI_MODE_RDONLY,
+            info,
+            &f);
+    MPI_File_set_view(
+            f,
+            0,
+            this->mpi_dtype,
+            this->mpi_array_dtype,
+            "native", //this needs to be made more general
+            info);
+    MPI_File_read_all(
+            f,
+            buffer,
+            this->local_size,
+            this->mpi_dtype,
+            MPI_STATUS_IGNORE);
+    MPI_File_close(&f);
+
+    return EXIT_SUCCESS;
+}
+
+int field_descriptor::write(
+        const char *fname,
+        void *buffer)
+{
+    MPI_Info info;
+    MPI_Info_create(&info);
+    MPI_File f;
+
+    MPI_File_open(
+            MPI_COMM_WORLD,
+            fname,
+            MPI_MODE_CREATE | MPI_MODE_WRONLY,
+            info,
+            &f);
+    MPI_File_set_view(
+            f,
+            0,
+            this->mpi_dtype,
+            this->mpi_array_dtype,
+            "native", //this needs to be made more general
+            info);
+    MPI_File_write_all(
+            f,
+            buffer,
+            this->local_size,
+            this->mpi_dtype,
+            MPI_STATUS_IGNORE);
+    MPI_File_close(&f);
+
+    return EXIT_SUCCESS;
+}
+
diff --git a/src/field_descriptor.hpp b/src/field_descriptor.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..e24e4fc4898aab9f9121b0a46580c104ef5b3629
--- /dev/null
+++ b/src/field_descriptor.hpp
@@ -0,0 +1,40 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <mpi.h>
+#include <fftw3-mpi.h>
+
+#ifndef __FIELD_DESCRIPTOR__
+
+#define __FIELD_DESCRIPTOR__
+
+extern int myrank, nprocs;
+
+/**********************************************************************/
+class field_descriptor
+{
+    public:
+        int *sizes;
+        int *subsizes;
+        int *starts;
+        int ndims;
+        int local_size, full_size;
+        MPI_Datatype mpi_array_dtype, mpi_dtype;
+
+        field_descriptor(){}
+        ~field_descriptor(){}
+        int initialize(
+                int ndims,
+                int *n,
+                MPI_Datatype element_type);
+        int finalize();
+        int read(
+                const char *fname,
+                void *buffer);
+        int write(
+                const char *fname,
+                void *buffer);
+};
+
+#endif//__FIELD_DESCRIPTOR__
+
diff --git a/transp.cpp b/src/transp.cpp
similarity index 52%
rename from transp.cpp
rename to src/transp.cpp
index 04ab4799e64c6e0a9e535053e57939ef61e5e530..9985b91ed6fe331e70d62e4f9710c7c4fd2c584e 100644
--- a/transp.cpp
+++ b/src/transp.cpp
@@ -1,146 +1,7 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <math.h>
-#include <mpi.h>
-#include <fftw3-mpi.h>
+#include "field_descriptor.hpp"
 
 int myrank, nprocs;
 
-/**********************************************************************/
-class field_descriptor
-{
-    public:
-        int *sizes;
-        int *subsizes;
-        int *starts;
-        int ndims;
-        int local_size, full_size;
-        MPI_Datatype mpi_array_dtype, mpi_dtype;
-        /****/
-        field_descriptor(){}
-        ~field_descriptor(){}
-        int initialize(
-                int ndims,
-                int *n,
-                MPI_Datatype element_type);
-        int finalize();
-        int read(
-                const char *fname,
-                void *buffer);
-        int write(
-                const char *fname,
-                void *buffer);
-};
-
-int field_descriptor::initialize(
-        int ndims,
-        int *n,
-        MPI_Datatype element_type)
-{
-    this->ndims = ndims;
-    this->sizes    = (int*)malloc(ndims*sizeof(int));
-    this->subsizes = (int*)malloc(ndims*sizeof(int));
-    this->starts   = (int*)malloc(ndims*sizeof(int));
-    this->sizes[0] = n[0];
-    this->subsizes[0] = n[0]/nprocs;
-    this->starts[0] = myrank*(n[0]/nprocs);
-    this->mpi_dtype = element_type;
-    this->local_size = this->subsizes[0];
-    this->full_size = this->sizes[0];
-    for (int i = 1; i < this->ndims; i++)
-    {
-        this->sizes[i] = n[i];
-        this->subsizes[i] = n[i];
-        this->starts[i] = 0;
-        this->local_size *= this->subsizes[i];
-        this->full_size *= this->sizes[i];
-    }
-    MPI_Type_create_subarray(
-            ndims,
-            this->sizes,
-            this->subsizes,
-            this->starts,
-            MPI_ORDER_C,
-            this->mpi_dtype,
-            &this->mpi_array_dtype);
-    MPI_Type_commit(&this->mpi_array_dtype);
-    return EXIT_SUCCESS;
-}
-
-int field_descriptor::finalize()
-{
-    free((void*)this->sizes);
-    free((void*)this->subsizes);
-    free((void*)this->starts);
-    MPI_Type_free(&this->mpi_array_dtype);
-    return EXIT_SUCCESS;
-}
-
-int field_descriptor::read(
-        const char *fname,
-        void *buffer)
-{
-    MPI_Info info;
-    MPI_Info_create(&info);
-    MPI_File f;
-
-    MPI_File_open(
-            MPI_COMM_WORLD,
-            fname,
-            MPI_MODE_RDONLY,
-            info,
-            &f);
-    MPI_File_set_view(
-            f,
-            0,
-            this->mpi_dtype,
-            this->mpi_array_dtype,
-            "native", //this needs to be made more general
-            info);
-    MPI_File_read_all(
-            f,
-            buffer,
-            this->local_size,
-            this->mpi_dtype,
-            MPI_STATUS_IGNORE);
-    MPI_File_close(&f);
-
-    return EXIT_SUCCESS;
-}
-
-int field_descriptor::write(
-        const char *fname,
-        void *buffer)
-{
-    MPI_Info info;
-    MPI_Info_create(&info);
-    MPI_File f;
-
-    MPI_File_open(
-            MPI_COMM_WORLD,
-            fname,
-            MPI_MODE_CREATE | MPI_MODE_EXCL | MPI_MODE_WRONLY,
-            info,
-            &f);
-    MPI_File_set_view(
-            f,
-            0,
-            this->mpi_dtype,
-            this->mpi_array_dtype,
-            "native", //this needs to be made more general
-            info);
-    MPI_File_write_all(
-            f,
-            buffer,
-            this->local_size,
-            this->mpi_dtype,
-            MPI_STATUS_IGNORE);
-    MPI_File_close(&f);
-
-    return EXIT_SUCCESS;
-}
-/**********************************************************************/
-
 int transpose_2D(
         int n[],
         const char *fname0,