aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/markdown/Precompiled-headers.md5
-rw-r--r--mesonbuild/backend/backends.py17
-rw-r--r--mesonbuild/backend/ninjabackend.py17
-rw-r--r--mesonbuild/backend/vs2010backend.py27
-rw-r--r--mesonbuild/build.py2
-rw-r--r--test cases/common/13 pch/c/meson.build2
-rw-r--r--test cases/common/13 pch/c/pch/prog_pch.c5
-rw-r--r--test cases/common/13 pch/cpp/meson.build2
-rw-r--r--test cases/common/13 pch/cpp/pch/prog_pch.cc5
-rw-r--r--test cases/common/13 pch/generated/meson.build2
-rw-r--r--test cases/common/13 pch/generated/pch/prog_pch.c5
-rw-r--r--test cases/common/13 pch/meson.build1
-rw-r--r--test cases/common/13 pch/mixed/meson.build15
-rw-r--r--test cases/common/13 pch/mixed/pch/func_pch.c1
-rw-r--r--test cases/common/13 pch/mixed/pch/main_pch.cc1
-rw-r--r--test cases/common/13 pch/userDefined/meson.build10
-rw-r--r--test cases/common/13 pch/userDefined/pch/pch.c5
-rw-r--r--test cases/common/13 pch/userDefined/pch/pch.h1
-rw-r--r--test cases/common/13 pch/userDefined/prog.c8
-rw-r--r--test cases/common/13 pch/withIncludeDirectories/meson.build2
-rw-r--r--test cases/common/13 pch/withIncludeDirectories/pch/prog_pch.c5
21 files changed, 84 insertions, 54 deletions
diff --git a/docs/markdown/Precompiled-headers.md b/docs/markdown/Precompiled-headers.md
index 3f7d4b4..8dfb438 100644
--- a/docs/markdown/Precompiled-headers.md
+++ b/docs/markdown/Precompiled-headers.md
@@ -75,8 +75,11 @@ executable('multilang', sources : srclist,
Using precompiled headers with MSVC
--
+Since Meson version 0.50.0, precompiled headers with MSVC work just like
+with GCC. Meson will automatically create the matching pch implementation
+file for you.
-MSVC is a bit trickier, because in addition to the header file, it
+Before version 0.50.0, in addition to the header file, Meson
also requires a corresponding source file. If your header is called
`foo_pch.h`, the corresponding source file is usually called
`foo_pch.cpp` and it resides in the same `pch` subdirectory as the
diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py
index 14b189b..5062767 100644
--- a/mesonbuild/backend/backends.py
+++ b/mesonbuild/backend/backends.py
@@ -515,6 +515,23 @@ class Backend:
args += compiler.get_pch_use_args(pchpath, p[0])
return includeargs + args
+ def create_msvc_pch_implementation(self, target, lang, pch_header):
+ # We have to include the language in the file name, otherwise
+ # pch.c and pch.cpp will both end up as pch.obj in VS backends.
+ impl_name = 'meson_pch-%s.%s' % (lang, lang)
+ pch_rel_to_build = os.path.join(self.get_target_private_dir(target), impl_name)
+ # Make sure to prepend the build dir, since the working directory is
+ # not defined. Otherwise, we might create the file in the wrong path.
+ pch_file = os.path.join(self.build_dir, pch_rel_to_build)
+ os.makedirs(os.path.dirname(pch_file), exist_ok=True)
+
+ content = '#include "%s"' % os.path.basename(pch_header)
+ pch_file_tmp = pch_file + '.tmp'
+ with open(pch_file_tmp, 'w') as f:
+ f.write(content)
+ mesonlib.replace_if_different(pch_file, pch_file_tmp)
+ return pch_rel_to_build
+
@staticmethod
def escape_extra_args(compiler, args):
# No extra escaping/quoting needed when not running on Windows
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index 5958af8..1e0bb8b 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -2252,22 +2252,28 @@ rule FORTRAN_DEP_HACK%s
return [os.path.join(self.get_target_dir(lt), lt.get_filename()) for lt in target.link_targets]
def generate_msvc_pch_command(self, target, compiler, pch):
- if len(pch) != 2:
- raise MesonException('MSVC requires one header and one source to produce precompiled headers.')
header = pch[0]
- source = pch[1]
pchname = compiler.get_pch_name(header)
dst = os.path.join(self.get_target_private_dir(target), pchname)
commands = []
commands += self.generate_basic_compiler_args(target, compiler)
+
+ if len(pch) == 1:
+ # Auto generate PCH.
+ source = self.create_msvc_pch_implementation(target, compiler.get_language(), pch[0])
+ pch_header_dir = os.path.dirname(os.path.join(self.build_to_src, target.get_source_subdir(), header))
+ commands += compiler.get_include_args(pch_header_dir, False)
+ else:
+ source = os.path.join(self.build_to_src, target.get_source_subdir(), pch[1])
+
just_name = os.path.basename(header)
(objname, pch_args) = compiler.gen_pch_args(just_name, source, dst)
commands += pch_args
commands += self._generate_single_compile(target, compiler)
commands += self.get_compile_debugfile_args(compiler, target, objname)
dep = dst + '.' + compiler.get_depfile_suffix()
- return commands, dep, dst, [objname]
+ return commands, dep, dst, [objname], source
def generate_gcc_pch_command(self, target, compiler, pch):
commands = self._generate_single_compile(target, compiler)
@@ -2296,8 +2302,7 @@ rule FORTRAN_DEP_HACK%s
raise InvalidArguments(msg)
compiler = target.compilers[lang]
if isinstance(compiler, VisualStudioCCompiler):
- src = os.path.join(self.build_to_src, target.get_source_subdir(), pch[-1])
- (commands, dep, dst, objs) = self.generate_msvc_pch_command(target, compiler, pch)
+ (commands, dep, dst, objs, src) = self.generate_msvc_pch_command(target, compiler, pch)
extradep = os.path.join(self.build_to_src, target.get_source_subdir(), pch[0])
elif compiler.id == 'intel':
# Intel generates on target generation
diff --git a/mesonbuild/backend/vs2010backend.py b/mesonbuild/backend/vs2010backend.py
index 2a50dd2..dd99125 100644
--- a/mesonbuild/backend/vs2010backend.py
+++ b/mesonbuild/backend/vs2010backend.py
@@ -12,6 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+import copy
import os
import pickle
import xml.dom.minidom
@@ -1035,13 +1036,18 @@ class Vs2010Backend(backends.Backend):
continue
pch_node.text = 'Use'
if compiler.id == 'msvc':
- if len(pch) != 2:
- raise MesonException('MSVC requires one header and one source to produce precompiled headers.')
- pch_sources[lang] = [pch[0], pch[1], lang]
+ if len(pch) == 1:
+ # Auto generate PCH.
+ src = os.path.join(down, self.create_msvc_pch_implementation(target, lang, pch[0]))
+ pch_header_dir = os.path.dirname(os.path.join(proj_to_src_dir, pch[0]))
+ else:
+ src = os.path.join(proj_to_src_dir, pch[1])
+ pch_header_dir = None
+ pch_sources[lang] = [pch[0], src, lang, pch_header_dir]
else:
# I don't know whether its relevant but let's handle other compilers
# used with a vs backend
- pch_sources[lang] = [pch[0], None, lang]
+ pch_sources[lang] = [pch[0], None, lang, None]
if len(pch_sources) == 1:
# If there is only 1 language with precompiled headers, we can use it for the entire project, which
# is cleaner than specifying it for each source file.
@@ -1205,14 +1211,19 @@ class Vs2010Backend(backends.Backend):
self.add_preprocessor_defines(lang, inc_cl, file_defines)
self.add_include_dirs(lang, inc_cl, file_inc_dirs)
for lang in pch_sources:
- header, impl, suffix = pch_sources[lang]
+ impl = pch_sources[lang][1]
if impl:
- relpath = os.path.join(proj_to_src_dir, impl)
- inc_cl = ET.SubElement(inc_src, 'CLCompile', Include=relpath)
+ inc_cl = ET.SubElement(inc_src, 'CLCompile', Include=impl)
self.create_pch(pch_sources, lang, inc_cl)
self.add_additional_options(lang, inc_cl, file_args)
self.add_preprocessor_defines(lang, inc_cl, file_defines)
- self.add_include_dirs(lang, inc_cl, file_inc_dirs)
+ pch_header_dir = pch_sources[lang][3]
+ if pch_header_dir:
+ inc_dirs = copy.deepcopy(file_inc_dirs)
+ inc_dirs[lang] = [pch_header_dir] + inc_dirs[lang]
+ else:
+ inc_dirs = file_inc_dirs
+ self.add_include_dirs(lang, inc_cl, inc_dirs)
if self.has_objects(objects, additional_objects, gen_objs):
inc_objs = ET.SubElement(root, 'ItemGroup')
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
index 2187d3e..9a1d158 100644
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -1096,6 +1096,8 @@ You probably should put it in link_with instead.''')
if (os.path.dirname(pchlist[0]) != os.path.dirname(pchlist[1])):
raise InvalidArguments('PCH files must be stored in the same folder.')
+
+ mlog.warning('PCH source files are deprecated, only a single header file should be used.')
elif len(pchlist) > 2:
raise InvalidArguments('PCH definition may have a maximum of 2 files.')
for f in pchlist:
diff --git a/test cases/common/13 pch/c/meson.build b/test cases/common/13 pch/c/meson.build
index cb8349d..fe4ac68 100644
--- a/test cases/common/13 pch/c/meson.build
+++ b/test cases/common/13 pch/c/meson.build
@@ -5,4 +5,4 @@ if cc_id == 'lcc'
endif
exe = executable('prog', 'prog.c',
-c_pch : ['pch/prog_pch.c', 'pch/prog.h'])
+c_pch : 'pch/prog.h')
diff --git a/test cases/common/13 pch/c/pch/prog_pch.c b/test cases/common/13 pch/c/pch/prog_pch.c
deleted file mode 100644
index 4960505..0000000
--- a/test cases/common/13 pch/c/pch/prog_pch.c
+++ /dev/null
@@ -1,5 +0,0 @@
-#if !defined(_MSC_VER)
-#error "This file is only for use with MSVC."
-#endif
-
-#include "prog.h"
diff --git a/test cases/common/13 pch/cpp/meson.build b/test cases/common/13 pch/cpp/meson.build
index 802c3e1..b01cd58 100644
--- a/test cases/common/13 pch/cpp/meson.build
+++ b/test cases/common/13 pch/cpp/meson.build
@@ -1 +1 @@
-exe = executable('prog', 'prog.cc', cpp_pch : ['pch/prog.hh', 'pch/prog_pch.cc'])
+exe = executable('prog', 'prog.cc', cpp_pch : 'pch/prog.hh')
diff --git a/test cases/common/13 pch/cpp/pch/prog_pch.cc b/test cases/common/13 pch/cpp/pch/prog_pch.cc
deleted file mode 100644
index aff1225..0000000
--- a/test cases/common/13 pch/cpp/pch/prog_pch.cc
+++ /dev/null
@@ -1,5 +0,0 @@
-#if !defined(_MSC_VER)
-#error "This file is only for use with MSVC."
-#endif
-
-#include "prog.hh"
diff --git a/test cases/common/13 pch/generated/meson.build b/test cases/common/13 pch/generated/meson.build
index 372a00e..1ef771b 100644
--- a/test cases/common/13 pch/generated/meson.build
+++ b/test cases/common/13 pch/generated/meson.build
@@ -13,4 +13,4 @@ generated_generator = generator(find_program('gen_generator.py'),
arguments: ['@INPUT@', '@OUTPUT@'])
exe = executable('prog', 'prog.c', generated_customTarget, generated_generator.process('generated_generator.in'),
- c_pch: ['pch/prog_pch.c', 'pch/prog.h'])
+ c_pch: 'pch/prog.h')
diff --git a/test cases/common/13 pch/generated/pch/prog_pch.c b/test cases/common/13 pch/generated/pch/prog_pch.c
deleted file mode 100644
index 4960505..0000000
--- a/test cases/common/13 pch/generated/pch/prog_pch.c
+++ /dev/null
@@ -1,5 +0,0 @@
-#if !defined(_MSC_VER)
-#error "This file is only for use with MSVC."
-#endif
-
-#include "prog.h"
diff --git a/test cases/common/13 pch/meson.build b/test cases/common/13 pch/meson.build
index 43129c9..4438c9e 100644
--- a/test cases/common/13 pch/meson.build
+++ b/test cases/common/13 pch/meson.build
@@ -3,6 +3,7 @@ project('pch test', 'c', 'cpp')
subdir('c')
subdir('cpp')
subdir('generated')
+subdir('userDefined')
subdir('withIncludeDirectories')
if meson.backend() == 'xcode'
diff --git a/test cases/common/13 pch/mixed/meson.build b/test cases/common/13 pch/mixed/meson.build
index f0c3eca..cbb7bac 100644
--- a/test cases/common/13 pch/mixed/meson.build
+++ b/test cases/common/13 pch/mixed/meson.build
@@ -1,17 +1,6 @@
exe = executable(
'prog',
files('main.cc', 'func.c'),
- c_pch : ['pch/func.h', 'pch/func_pch.c'],
- cpp_pch : ['pch/main_pch.cc', 'pch/main.h'],
+ c_pch : ['pch/func.h'],
+ cpp_pch : ['pch/main.h'],
)
-
-# test pch when only a header is given (not supported by msvc)
-cc = meson.get_compiler('c')
-if not ['msvc', 'clang-cl'].contains(cc.get_id())
- exe2 = executable(
- 'prog2',
- files('main.cc', 'func.c'),
- c_pch : 'pch/func.h',
- cpp_pch : 'pch/main.h',
- )
-endif
diff --git a/test cases/common/13 pch/mixed/pch/func_pch.c b/test cases/common/13 pch/mixed/pch/func_pch.c
deleted file mode 100644
index 5566739..0000000
--- a/test cases/common/13 pch/mixed/pch/func_pch.c
+++ /dev/null
@@ -1 +0,0 @@
-#include"func.h"
diff --git a/test cases/common/13 pch/mixed/pch/main_pch.cc b/test cases/common/13 pch/mixed/pch/main_pch.cc
deleted file mode 100644
index acd3f57..0000000
--- a/test cases/common/13 pch/mixed/pch/main_pch.cc
+++ /dev/null
@@ -1 +0,0 @@
-#include"main.h"
diff --git a/test cases/common/13 pch/userDefined/meson.build b/test cases/common/13 pch/userDefined/meson.build
new file mode 100644
index 0000000..9b60572
--- /dev/null
+++ b/test cases/common/13 pch/userDefined/meson.build
@@ -0,0 +1,10 @@
+cc = meson.get_compiler('c')
+cc_id = cc.get_id()
+
+# User supplied PCH implementation should override the auto
+# generated one. PCH implementations are only supported for
+# msvc and generally should not be used at all. Support for
+# them is only kept for backwards compatibility.
+if cc_id == 'msvc'
+ exe = executable('prog', 'prog.c', c_pch : ['pch/pch.h', 'pch/pch.c'])
+endif
diff --git a/test cases/common/13 pch/userDefined/pch/pch.c b/test cases/common/13 pch/userDefined/pch/pch.c
new file mode 100644
index 0000000..c107b1a
--- /dev/null
+++ b/test cases/common/13 pch/userDefined/pch/pch.c
@@ -0,0 +1,5 @@
+#include "pch.h"
+
+int foo() {
+ return 0;
+}
diff --git a/test cases/common/13 pch/userDefined/pch/pch.h b/test cases/common/13 pch/userDefined/pch/pch.h
new file mode 100644
index 0000000..5d5f8f0
--- /dev/null
+++ b/test cases/common/13 pch/userDefined/pch/pch.h
@@ -0,0 +1 @@
+int foo();
diff --git a/test cases/common/13 pch/userDefined/prog.c b/test cases/common/13 pch/userDefined/prog.c
new file mode 100644
index 0000000..eb068d9
--- /dev/null
+++ b/test cases/common/13 pch/userDefined/prog.c
@@ -0,0 +1,8 @@
+// No includes here, they need to come from the PCH
+
+int main(int argc, char **argv) {
+ // Method is implemented in pch.c.
+ // This makes sure that we can properly handle user defined
+ // pch implementation files and not only auto-generated ones.
+ return foo();
+}
diff --git a/test cases/common/13 pch/withIncludeDirectories/meson.build b/test cases/common/13 pch/withIncludeDirectories/meson.build
index 2ab2cd8..68e544b 100644
--- a/test cases/common/13 pch/withIncludeDirectories/meson.build
+++ b/test cases/common/13 pch/withIncludeDirectories/meson.build
@@ -6,4 +6,4 @@ endif
exe = executable('prog', 'prog.c',
include_directories: 'include',
- c_pch : ['pch/prog_pch.c', 'pch/prog.h'])
+ c_pch : 'pch/prog.h')
diff --git a/test cases/common/13 pch/withIncludeDirectories/pch/prog_pch.c b/test cases/common/13 pch/withIncludeDirectories/pch/prog_pch.c
deleted file mode 100644
index 4960505..0000000
--- a/test cases/common/13 pch/withIncludeDirectories/pch/prog_pch.c
+++ /dev/null
@@ -1,5 +0,0 @@
-#if !defined(_MSC_VER)
-#error "This file is only for use with MSVC."
-#endif
-
-#include "prog.h"