diff --git a/examples/cmake_relpath/CMakeLists.txt b/examples/cmake_relpath/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..e7727d8546599117afdbe5efcd26064b37f9bbfc
--- /dev/null
+++ b/examples/cmake_relpath/CMakeLists.txt
@@ -0,0 +1,18 @@
+cmake_minimum_required(VERSION 2.8)
+project(NANOPB_CMAKE_SIMPLE C)
+
+set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../extra)
+find_package(Nanopb REQUIRED)
+include_directories(${NANOPB_INCLUDE_DIRS})
+
+nanopb_generate_cpp(PROTO_SRCS PROTO_HDRS RELPATH proto
+	proto/simple.proto proto/sub/unlucky.proto)
+
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+#add_custom_target(generate_proto_sources DEPENDS ${PROTO_SRCS} ${PROTO_HDRS})
+set_source_files_properties(${PROTO_SRCS} ${PROTO_HDRS}
+    PROPERTIES GENERATED TRUE)
+
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror -g -O0")
+
+add_executable(simple simple.c ${PROTO_SRCS} ${PROTO_HDRS})
diff --git a/examples/cmake_relpath/README.txt b/examples/cmake_relpath/README.txt
new file mode 100644
index 0000000000000000000000000000000000000000..aa0f3f3a771766d9328c5ed20068caa78ec4c4ab
--- /dev/null
+++ b/examples/cmake_relpath/README.txt
@@ -0,0 +1,18 @@
+Nanopb example "simple" using CMake
+=======================
+
+This example is the same as the simple nanopb example but built using CMake.
+
+Example usage
+-------------
+
+On Linux, create a build directory and then call cmake:
+
+    nanopb/examples/cmake_simple$ mkdir build
+    nanopb/examples/cmake_simple$ cd build/
+    nanopb/examples/cmake_simple/build$ cmake ..
+    nanopb/examples/cmake_simple/build$ make
+
+After that, you can run it with the command: ./simple
+
+On other platforms supported by CMake, refer to CMake instructions.
diff --git a/examples/cmake_relpath/proto/simple.proto b/examples/cmake_relpath/proto/simple.proto
new file mode 100644
index 0000000000000000000000000000000000000000..3bf4ad1def6da42d9cbd203a0aee9c1e00b992cb
--- /dev/null
+++ b/examples/cmake_relpath/proto/simple.proto
@@ -0,0 +1,11 @@
+// A very simple protocol definition, consisting of only
+// one message.
+syntax = "proto2";
+
+import "sub/unlucky.proto";
+
+message SimpleMessage {
+    required int32 lucky_number = 1;
+    required UnluckyNumber unlucky = 2;
+}
+
diff --git a/examples/cmake_relpath/proto/sub/unlucky.proto b/examples/cmake_relpath/proto/sub/unlucky.proto
new file mode 100644
index 0000000000000000000000000000000000000000..97a42c9cde0532d2fb5f6fb20375c3823f4755e1
--- /dev/null
+++ b/examples/cmake_relpath/proto/sub/unlucky.proto
@@ -0,0 +1,5 @@
+syntax = "proto2";
+
+message UnluckyNumber {
+	required uint32 number = 1;
+}
diff --git a/examples/cmake_relpath/simple.c b/examples/cmake_relpath/simple.c
new file mode 100644
index 0000000000000000000000000000000000000000..231886c28b746cdda07acf4b349d34f5ab5127a8
--- /dev/null
+++ b/examples/cmake_relpath/simple.c
@@ -0,0 +1,73 @@
+#include <stdio.h>
+#include <pb_encode.h>
+#include <pb_decode.h>
+#include "simple.pb.h"
+
+int main()
+{
+    /* This is the buffer where we will store our message. */
+    uint8_t buffer[128];
+    size_t message_length;
+    bool status;
+    
+    /* Encode our message */
+    {
+        /* Allocate space on the stack to store the message data.
+         *
+         * Nanopb generates simple struct definitions for all the messages.
+         * - check out the contents of simple.pb.h!
+         * It is a good idea to always initialize your structures
+         * so that you do not have garbage data from RAM in there.
+         */
+        SimpleMessage message = SimpleMessage_init_zero;
+        
+        /* Create a stream that will write to our buffer. */
+        pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer));
+        
+        /* Fill in the lucky number */
+        message.lucky_number = 13;
+        message.unlucky.number = 42;
+        
+        /* Now we are ready to encode the message! */
+        status = pb_encode(&stream, SimpleMessage_fields, &message);
+        message_length = stream.bytes_written;
+        
+        /* Then just check for any errors.. */
+        if (!status)
+        {
+            printf("Encoding failed: %s\n", PB_GET_ERROR(&stream));
+            return 1;
+        }
+    }
+    
+    /* Now we could transmit the message over network, store it in a file or
+     * wrap it to a pigeon's leg.
+     */
+
+    /* But because we are lazy, we will just decode it immediately. */
+    
+    {
+        /* Allocate space for the decoded message. */
+        SimpleMessage message = SimpleMessage_init_zero;
+        
+        /* Create a stream that reads from the buffer. */
+        pb_istream_t stream = pb_istream_from_buffer(buffer, message_length);
+        
+        /* Now we are ready to decode the message. */
+        status = pb_decode(&stream, SimpleMessage_fields, &message);
+        
+        /* Check for errors... */
+        if (!status)
+        {
+            printf("Decoding failed: %s\n", PB_GET_ERROR(&stream));
+            return 1;
+        }
+        
+        /* Print the data contained in the message. */
+        printf("Your lucky number was %d!\n", message.lucky_number);
+        printf("Your unlucky number was %u!\n", message.unlucky.number);
+    }
+    
+    return 0;
+}
+
diff --git a/extra/FindNanopb.cmake b/extra/FindNanopb.cmake
index 749999d197b974c577e5a63d0beb7defc1aeebec..dda63f63441f1fd66e3236a0a7ac0d66fb19ccae 100644
--- a/extra/FindNanopb.cmake
+++ b/extra/FindNanopb.cmake
@@ -28,17 +28,22 @@
 #  ====================================================================
 #
 # NANOPB_GENERATE_CPP (public function)
-#   SRCS = Variable to define with autogenerated
-#          source files
-#   HDRS = Variable to define with autogenerated
-#          header files
-#   ARGN = proto files
+# NANOPB_GENERTAE_CPP(SRCS HDRS [RELPATH <root-path-of-proto-files>] 
+#                     <proto-files>...)
+#   SRCS = Variable to define with autogenerated source files
+#   HDRS = Variable to define with autogenerated header files
+#   If you want to use relative paths in your import statements use the RELPATH
+#   option. The argument to RELPATH should be the directory that all the
+#   imports will be relative to.
+#   When RELPATH is not specified then all proto files can be imported without
+#   a path. 
+#
 #
 #  ====================================================================
 #  Example:
 #
 #   set(NANOPB_SRC_ROOT_FOLDER "/path/to/nanopb")
-#   set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${NANOPB_SRC_ROOT_FOLDER}/cmake)
+#   set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${NANOPB_SRC_ROOT_FOLDER}/extra)
 #   find_package( Nanopb REQUIRED )
 #   include_directories(${NANOPB_INCLUDE_DIRS})
 #
@@ -47,6 +52,19 @@
 #   include_directories(${CMAKE_CURRENT_BINARY_DIR})
 #   add_executable(bar bar.cc ${PROTO_SRCS} ${PROTO_HDRS})
 #
+#  Example with RELPATH:
+#   Assume we have a layout like:
+#    .../CMakeLists.txt
+#    .../bar.cc
+#    .../proto/
+#    .../proto/foo.proto  (Which contains: import "sub/bar.proto"; )
+#    .../proto/sub/bar.proto
+#   Everything would be the same as the previous example, but the call to
+#   NANOPB_GENERATE_CPP would change to:
+# 
+#   NANOPB_GENERATE_CPP(PROTO_SRCS PROTO_HDRS RELPATH proto
+#                       proto/foo.proto proto/sub/bar.proto)
+# 
 #  ====================================================================
 
 #=============================================================================
@@ -92,35 +110,35 @@
 
 
 function(NANOPB_GENERATE_CPP SRCS HDRS)
-  if(NOT ARGN)
+  cmake_parse_arguments(NANOPB_GENERATE_CPP "" "RELPATH" "" ${ARGN})
+  if(NOT NANOPB_GENERATE_CPP_UNPARSED_ARGUMENTS)
     return()
   endif()
 
   if(NANOPB_GENERATE_CPP_APPEND_PATH)
     # Create an include path for each file specified
-    foreach(FIL ${ARGN})
+    foreach(FIL ${NANOPB_GENERATE_CPP_UNPARSED_ARGUMENTS})
       get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
       get_filename_component(ABS_PATH ${ABS_FIL} PATH)
-
-      list(FIND _nanobp_include_path ${ABS_PATH} _contains_already)
-      if(${_contains_already} EQUAL -1)
-          list(APPEND _nanobp_include_path -I ${ABS_PATH})
-      endif()
+      list(APPEND _nanobp_include_path "-I${ABS_PATH}")
     endforeach()
   else()
-    set(_nanobp_include_path -I ${CMAKE_CURRENT_SOURCE_DIR})
+    set(_nanobp_include_path "-I${CMAKE_CURRENT_SOURCE_DIR}")
+  endif()
+
+  if(NANOPB_GENERATE_CPP_RELPATH)
+    list(APPEND _nanobp_include_path "-I${NANOPB_GENERATE_CPP_RELPATH}")
   endif()
 
   if(DEFINED NANOPB_IMPORT_DIRS)
     foreach(DIR ${NANOPB_IMPORT_DIRS})
       get_filename_component(ABS_PATH ${DIR} ABSOLUTE)
-      list(FIND _nanobp_include_path ${ABS_PATH} _contains_already)
-      if(${_contains_already} EQUAL -1)
-          list(APPEND _nanobp_include_path -I ${ABS_PATH})
-      endif()
+      list(APPEND _nanobp_include_path -I ${ABS_PATH})
     endforeach()
   endif()
 
+  list(REMOVE_DUPLICATES _nanobp_include_path)
+
   set(${SRCS})
   set(${HDRS})
 
@@ -162,10 +180,27 @@ function(NANOPB_GENERATE_CPP SRCS HDRS)
         VERBATIM)
   endforeach()
 
-  foreach(FIL ${ARGN})
+  if(NANOPB_GENERATE_CPP_RELPATH)
+      get_filename_component(ABS_ROOT ${NANOPB_GENERATE_CPP_RELPATH} ABSOLUTE)
+  endif()
+  foreach(FIL ${NANOPB_GENERATE_CPP_UNPARSED_ARGUMENTS})
     get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
     get_filename_component(FIL_WE ${FIL} NAME_WE)
     get_filename_component(FIL_DIR ${FIL} PATH)
+    set(FIL_PATH_REL)
+    if(ABS_ROOT)
+      # Check that the file is under the given "RELPATH"
+      string(FIND ${ABS_FIL} ${ABS_ROOT} LOC)
+      if (${LOC} EQUAL 0)
+        string(REPLACE "${ABS_ROOT}/" "" FIL_REL ${ABS_FIL})
+        get_filename_component(FIL_PATH_REL ${FIL_REL} PATH)
+        file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${FIL_PATH_REL})
+      endif()
+    endif()
+    if(NOT FIL_PATH_REL)
+      set(FIL_PATH_REL ".")
+    endif()
+
     set(NANOPB_OPTIONS_FILE ${FIL_DIR}/${FIL_WE}.options)
     set(NANOPB_OPTIONS)
     if(EXISTS ${NANOPB_OPTIONS_FILE})
@@ -174,26 +209,28 @@ function(NANOPB_GENERATE_CPP SRCS HDRS)
         set(NANOPB_OPTIONS_FILE)
     endif()
 
-    list(APPEND ${SRCS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.c")
-    list(APPEND ${HDRS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.h")
+    set(GEN_C_FILE )
+
+    list(APPEND ${SRCS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_PATH_REL}/${FIL_WE}.pb.c")
+    list(APPEND ${HDRS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_PATH_REL}/${FIL_WE}.pb.h")
 
     add_custom_command(
-      OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb"
+      OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${FIL_PATH_REL}/${FIL_WE}.pb"
       COMMAND  ${PROTOBUF_PROTOC_EXECUTABLE}
       ARGS -I${GENERATOR_PATH} -I${GENERATOR_CORE_DIR}
         -I${CMAKE_CURRENT_BINARY_DIR} ${_nanobp_include_path}
-        -o${FIL_WE}.pb ${ABS_FIL}
+        -o${FIL_PATH_REL}/${FIL_WE}.pb ${ABS_FIL}
       DEPENDS ${ABS_FIL} ${GENERATOR_CORE_PYTHON_SRC}
       COMMENT "Running C++ protocol buffer compiler on ${FIL}"
       VERBATIM )
 
     add_custom_command(
-      OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.c"
-             "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.h"
+      OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${FIL_PATH_REL}/${FIL_WE}.pb.c"
+             "${CMAKE_CURRENT_BINARY_DIR}/${FIL_PATH_REL}/${FIL_WE}.pb.h"
       COMMAND ${PYTHON_EXECUTABLE}
-      ARGS ${NANOPB_GENERATOR_EXECUTABLE} ${FIL_WE}.pb ${NANOPB_OPTIONS}
-      DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb" ${NANOPB_OPTIONS_FILE}
-      COMMENT "Running nanopb generator on ${FIL_WE}.pb"
+      ARGS ${NANOPB_GENERATOR_EXECUTABLE} ${FIL_PATH_REL}/${FIL_WE}.pb ${NANOPB_OPTIONS}
+      DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/${FIL_PATH_REL}/${FIL_WE}.pb" ${NANOPB_OPTIONS_FILE}
+      COMMENT "Running nanopb generator on ${FIL_PATH_REL}/${FIL_WE}.pb"
       VERBATIM )
   endforeach()