Add option to disable implicit include directories. Closes #2139.
diff --git a/docs/markdown/Reference-manual.md b/docs/markdown/Reference-manual.md
index 1a98c4c..ebd7b39 100644
--- a/docs/markdown/Reference-manual.md
+++ b/docs/markdown/Reference-manual.md
@@ -250,6 +250,7 @@
 - `build_by_default` causes, when set to true, to have this target be built by default, that is, when invoking plain `ninja`, the default value is true for all built target types, since 0.38.0
 - `override_options` takes an array of strings in the same format as `project`'s `default_options` overriding the values of these options for this target only, since 0.40.0
 - `implib` when set to true, an import library is generated for the executable (the name of the import library is based on *exe_name*).  Alternatively, when set to a string, that gives the base name for the import library.  The import library is used when the returned build target object appears in `link_with:` elsewhere.  Only has any effect on platforms where that is meaningful (e.g. Windows).  Since 0.42.0
+- `implicit_include_directories` is a boolean telling whether Meson adds the current source and build directories to the include path, defaults to `true`, since 0.42.0
 
 The list of `sources`, `objects`, and `dependencies` is always flattened, which means you can freely nest and add lists while creating the final list. As a corollary, the best way to handle a 'disabled dependency' is by assigning an empty list `[]` to it and passing it like any other dependency to the `dependencies:` keyword argument.
 
diff --git a/docs/markdown/Release-notes-for-0.42.0.md b/docs/markdown/Release-notes-for-0.42.0.md
index f0ea534..4a23af5 100644
--- a/docs/markdown/Release-notes-for-0.42.0.md
+++ b/docs/markdown/Release-notes-for-0.42.0.md
@@ -83,3 +83,9 @@
 recommended because having multiple rpath causes them to stomp on each
 other. This warning will become a hard error in some future release.
 
+## Disable implicit include directories
+
+By default Meson adds the current source and build directories to the
+header search path. On some rare occasions this is not desired. Setting
+the `implicit_include_directories` keyword argument to `false` these
+directories are not used.
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index 5fc6d6b..7b2cdb1 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -2033,9 +2033,11 @@
         # srcdir == builddir Autotools build in their source tree. Many
         # projects that are moving to Meson have both Meson and Autotools in
         # parallel as part of the transition.
-        commands += self.get_source_dir_include_args(target, compiler)
+        if target.implicit_include_directories:
+            commands += self.get_source_dir_include_args(target, compiler)
         commands += self.get_custom_target_dir_include_args(target, compiler)
-        commands += self.get_build_dir_include_args(target, compiler)
+        if target.implicit_include_directories:
+            commands += self.get_build_dir_include_args(target, compiler)
         # Finally add the private dir for the target to the include path. This
         # must override everything else and must be the final path added.
         commands += compiler.get_include_args(self.get_target_private_dir(target), False)
diff --git a/mesonbuild/backend/vs2010backend.py b/mesonbuild/backend/vs2010backend.py
index 4a92155..28c0f76 100644
--- a/mesonbuild/backend/vs2010backend.py
+++ b/mesonbuild/backend/vs2010backend.py
@@ -793,9 +793,13 @@
         # target private dir, target build dir, generated sources include dirs,
         # target source dir
         for args in file_args.values():
-            t_inc_dirs = ['.', self.relpath(self.get_target_private_dir(target),
-                                            self.get_target_dir(target))]
-            t_inc_dirs += generated_files_include_dirs + [proj_to_src_dir]
+            t_inc_dirs = [self.relpath(self.get_target_private_dir(target),
+                                       self.get_target_dir(target))]
+            if target.implicit_include_directories:
+                t_inc_dirs += ['.']
+            t_inc_dirs += generated_files_include_dirs
+            if target.implicit_include_directories:
+                t_inc_dirs += [proj_to_src_dir]
             args += ['-I' + arg for arg in t_inc_dirs]
 
         # Split preprocessor defines and include directories out of the list of
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
index 58cf987..98929a1 100644
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -41,6 +41,7 @@
                       'link_depends': True,
                       'link_with': True,
                       'link_whole': True,
+                      'implicit_include_directories': True,
                       'include_directories': True,
                       'dependencies': True,
                       'install_dir': True,
@@ -760,6 +761,9 @@
                 self.pic = kwargs.get('pic', False)
                 if not isinstance(self.pic, bool):
                     raise InvalidArguments('Argument pic to static library {!r} must be boolean'.format(self.name))
+        self.implicit_include_directories = kwargs.get('implicit_include_directories', True)
+        if not isinstance(self.implicit_include_directories, bool):
+            raise InvalidArguments('Implicit_include_directories must be a boolean.')
 
     def get_filename(self):
         return self.filename
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
index 1858e8c..1a537a4 100644
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -1249,6 +1249,7 @@
                           'link_whole',
                           'link_args',
                           'link_depends',
+                          'implicit_include_directories',
                           'include_directories',
                           'install',
                           'install_rpath',
diff --git a/test cases/common/157 dotinclude/dotproc.c b/test cases/common/157 dotinclude/dotproc.c
new file mode 100644
index 0000000..5e65f7b
--- /dev/null
+++ b/test cases/common/157 dotinclude/dotproc.c
@@ -0,0 +1,10 @@
+#include"stdio.h"
+
+#ifndef WRAPPER_INCLUDED
+#error The wrapper stdio.h was not included.
+#endif
+
+int main(int argc, char **argv) {
+    printf("Eventually I got printed.\n");
+    return 0;
+}
diff --git a/test cases/common/157 dotinclude/meson.build b/test cases/common/157 dotinclude/meson.build
new file mode 100644
index 0000000..e0c2cd7
--- /dev/null
+++ b/test cases/common/157 dotinclude/meson.build
@@ -0,0 +1,5 @@
+project('dotinclude', 'c')
+
+executable('dotproc', 'dotproc.c',
+  implicit_include_directories : false)
+
diff --git a/test cases/common/157 dotinclude/stdio.h b/test cases/common/157 dotinclude/stdio.h
new file mode 100644
index 0000000..b6bd09f
--- /dev/null
+++ b/test cases/common/157 dotinclude/stdio.h
@@ -0,0 +1,6 @@
+// There is no #pragma once because we _want_ to cause an eternal loop
+// if this wrapper invokes itself.
+
+#define WRAPPER_INCLUDED
+
+#include<stdio.h>