Can read project version from a file.
diff --git a/docs/markdown/Reference-manual.md b/docs/markdown/Reference-manual.md
index f758e71..6cc4895 100644
--- a/docs/markdown/Reference-manual.md
+++ b/docs/markdown/Reference-manual.md
@@ -1432,7 +1432,9 @@
 
 - `version`: which is a free form string describing the version of
   this project. You can access the value in your Meson build files
-  with `meson.project_version()`.
+  with `meson.project_version()`. Since 0.57.0 this can also be a
+  `File` object. Meson will set the version number to the first line
+  of text in the file (whitespace stripped from both ends).
 
 ### run_command()
 
diff --git a/docs/markdown/snippets/versionfile.md b/docs/markdown/snippets/versionfile.md
new file mode 100644
index 0000000..b0d5e30
--- /dev/null
+++ b/docs/markdown/snippets/versionfile.md
@@ -0,0 +1,11 @@
+## Project version can be specified with a file
+
+Meson can be instructed to load project's version string from an
+external file like this:
+
+```meson
+project('foo', 'c' version: files('VERSION'))
+```
+
+The version string would be set to the first line of the `VERSION`
+file. Leading and trailing whitespace on the file is stripped.
\ No newline at end of file
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
index be0309e..1583697 100644
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -1,4 +1,4 @@
-# Copyright 2012-2019 The Meson development team
+# Copyright 2012-2021 The Meson development team
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
 # You may obtain a copy of the License at
@@ -3169,9 +3169,24 @@
         if not self.is_subproject():
             self.build.project_name = proj_name
         self.active_projectname = proj_name
-        self.project_version = kwargs.get('version', 'undefined')
-        if not isinstance(self.project_version, str):
-            raise InvalidCode('The version keyword argument must be a string.')
+        version = kwargs.get('version', 'undefined')
+        if isinstance(version, list):
+            if len(version) != 1:
+                raise InvalidCode('Version argument is an array with more than one entry.')
+            version = version[0]
+        if isinstance(version, mesonlib.File):
+            self.add_build_def_file(version)
+            ifname = version.absolute_path(self.environment.source_dir,
+                                           self.environment.build_dir)
+            try:
+                with open(ifname, 'r') as versionfile:
+                    self.project_version = versionfile.readline().strip()
+            except FileNotFoundError:
+                raise InterpreterException('Version file not found.')
+        elif isinstance(version, str):
+            self.project_version = version
+        else:
+            raise InvalidCode('The version keyword argument must be a string or a file.')
         if self.build.project_version is None:
             self.build.project_version = self.project_version
         proj_license = mesonlib.stringlistify(kwargs.get('license', 'unknown'))
diff --git a/run_unittests.py b/run_unittests.py
index ffd20d5..e2c108f 100755
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -5212,6 +5212,12 @@
             os.utime(str(cmakefile))
         self.assertReconfiguredBuildIsNoop()
 
+    def test_version_file(self):
+        srcdir = os.path.join(self.common_test_dir, '2 cpp')
+        self.init(srcdir)
+        projinfo = self.introspect('--projectinfo')
+        self.assertEqual(projinfo['version'], '1.0.0')
+
 
 class FailureTests(BasePlatformTests):
     '''
diff --git a/test cases/common/2 cpp/VERSION b/test cases/common/2 cpp/VERSION
new file mode 100644
index 0000000..3eefcb9
--- /dev/null
+++ b/test cases/common/2 cpp/VERSION
@@ -0,0 +1 @@
+1.0.0
diff --git a/test cases/common/2 cpp/meson.build b/test cases/common/2 cpp/meson.build
index de8b98e..47cb7c5 100644
--- a/test cases/common/2 cpp/meson.build
+++ b/test cases/common/2 cpp/meson.build
@@ -1,4 +1,4 @@
-project('c++ test', 'cpp')
+project('c++ test', 'cpp', version: files('VERSION'))
 
 cpp = meson.get_compiler('cpp')
 if cpp.get_id() == 'intel'