aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mesonbuild/backend/backends.py6
-rw-r--r--mesonbuild/backend/vs2010backend.py41
-rw-r--r--mesonbuild/build.py2
-rw-r--r--test cases/common/145 whole archive/allofme/meson.build1
-rw-r--r--test cases/common/145 whole archive/exe/meson.build2
-rw-r--r--test cases/common/145 whole archive/exe2/meson.build1
-rw-r--r--test cases/common/145 whole archive/meson.build20
-rw-r--r--test cases/common/145 whole archive/shlib/meson.build4
-rw-r--r--test cases/common/145 whole archive/stlib/meson.build1
-rw-r--r--test cases/common/145 whole archive/wholeshlib/meson.build1
10 files changed, 58 insertions, 21 deletions
diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py
index 12fb3eb..960f2e2 100644
--- a/mesonbuild/backend/backends.py
+++ b/mesonbuild/backend/backends.py
@@ -155,6 +155,12 @@ class Backend:
dirname = 'meson-out'
return dirname
+ def get_target_dir_relative_to(self, t, o):
+ '''Get a target dir relative to another target's directory'''
+ target_dir = os.path.join(self.environment.get_build_dir(), self.get_target_dir(t))
+ othert_dir = os.path.join(self.environment.get_build_dir(), self.get_target_dir(o))
+ return os.path.relpath(target_dir, othert_dir)
+
def get_target_source_dir(self, target):
dirname = os.path.join(self.build_to_src, self.get_target_dir(target))
return dirname
diff --git a/mesonbuild/backend/vs2010backend.py b/mesonbuild/backend/vs2010backend.py
index 2d18b0e..e4e9696 100644
--- a/mesonbuild/backend/vs2010backend.py
+++ b/mesonbuild/backend/vs2010backend.py
@@ -344,6 +344,11 @@ class Vs2010Backend(backends.Backend):
def quote_arguments(self, arr):
return ['"%s"' % i for i in arr]
+ def add_project_reference(self, root, include, projid):
+ ig = ET.SubElement(root, 'ItemGroup')
+ pref = ET.SubElement(ig, 'ProjectReference', Include=include)
+ ET.SubElement(pref, 'Project').text = '{%s}' % projid
+
def create_basic_crap(self, target):
project_name = target.name
root = ET.Element('Project', {'DefaultTargets': "Build",
@@ -537,6 +542,8 @@ class Vs2010Backend(backends.Backend):
if lpath in lpaths:
lpaths.remove(lpath)
lpaths.append(lpath)
+ elif arg.startswith(('/', '-')):
+ other.append(arg)
# It's ok if we miss libraries with non-standard extensions here.
# They will go into the general link arguments.
elif arg.endswith('.lib') or arg.endswith('.a'):
@@ -907,20 +914,26 @@ class Vs2010Backend(backends.Backend):
# *_winlibs that we want to link to are static mingw64 libraries.
extra_link_args += compiler.get_option_link_args(self.environment.coredata.compiler_options)
(additional_libpaths, additional_links, extra_link_args) = self.split_link_args(extra_link_args.to_native())
- if len(extra_link_args) > 0:
- extra_link_args.append('%(AdditionalOptions)')
- ET.SubElement(link, "AdditionalOptions").text = ' '.join(extra_link_args)
- if len(additional_libpaths) > 0:
- additional_libpaths.insert(0, '%(AdditionalLibraryDirectories)')
- ET.SubElement(link, 'AdditionalLibraryDirectories').text = ';'.join(additional_libpaths)
# Add more libraries to be linked if needed
for t in target.get_dependencies():
lobj = self.build.targets[t.get_id()]
linkname = os.path.join(down, self.get_target_filename_for_linking(lobj))
if t in target.link_whole_targets:
- linkname = compiler.get_link_whole_for(linkname)[0]
- additional_links.append(linkname)
+ # /WHOLEARCHIVE:foo must go into AdditionalOptions
+ extra_link_args += compiler.get_link_whole_for(linkname)
+ # To force Visual Studio to build this project even though it
+ # has no sources, we include a reference to the vcxproj file
+ # that builds this target. Technically we should add this only
+ # if the current target has no sources, but it doesn't hurt to
+ # have 'extra' references.
+ trelpath = self.get_target_dir_relative_to(t, target)
+ tvcxproj = os.path.join(trelpath, t.get_id() + '.vcxproj')
+ tid = self.environment.coredata.target_guids[t.get_id()]
+ self.add_project_reference(root, tvcxproj, tid)
+ else:
+ # Other libraries go into AdditionalDependencies
+ additional_links.append(linkname)
for lib in self.get_custom_target_provided_libraries(target):
additional_links.append(self.relpath(lib, self.get_target_dir(target)))
additional_objects = []
@@ -929,6 +942,13 @@ class Vs2010Backend(backends.Backend):
additional_objects.append(o)
for o in custom_objs:
additional_objects.append(o)
+
+ if len(extra_link_args) > 0:
+ extra_link_args.append('%(AdditionalOptions)')
+ ET.SubElement(link, "AdditionalOptions").text = ' '.join(extra_link_args)
+ if len(additional_libpaths) > 0:
+ additional_libpaths.insert(0, '%(AdditionalLibraryDirectories)')
+ ET.SubElement(link, 'AdditionalLibraryDirectories').text = ';'.join(additional_libpaths)
if len(additional_links) > 0:
additional_links.append('%(AdditionalDependencies)')
ET.SubElement(link, 'AdditionalDependencies').text = ';'.join(additional_links)
@@ -1018,9 +1038,8 @@ class Vs2010Backend(backends.Backend):
ET.SubElement(root, 'Import', Project='$(VCTargetsPath)\Microsoft.Cpp.targets')
# Reference the regen target.
- ig = ET.SubElement(root, 'ItemGroup')
- pref = ET.SubElement(ig, 'ProjectReference', Include=os.path.join(self.environment.get_build_dir(), 'REGEN.vcxproj'))
- ET.SubElement(pref, 'Project').text = self.environment.coredata.regen_guid
+ regen_vcxproj = os.path.join(self.environment.get_build_dir(), 'REGEN.vcxproj')
+ self.add_project_reference(root, regen_vcxproj, self.environment.coredata.regen_guid)
self._prettyprint_vcxproj_xml(ET.ElementTree(root), ofname)
def gen_regenproj(self, project_name, ofname):
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
index 8c02d1d..5f5dd6b 100644
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -357,7 +357,7 @@ class BuildTarget(Target):
self.process_compilers()
self.process_kwargs(kwargs, environment)
self.check_unknown_kwargs(kwargs)
- if not self.sources and not self.generated and not self.objects:
+ if not any([self.sources, self.generated, self.objects, self.link_whole]):
raise InvalidArguments('Build target %s has no sources.' % name)
self.process_compilers_late()
self.validate_sources()
diff --git a/test cases/common/145 whole archive/allofme/meson.build b/test cases/common/145 whole archive/allofme/meson.build
new file mode 100644
index 0000000..f5c2027
--- /dev/null
+++ b/test cases/common/145 whole archive/allofme/meson.build
@@ -0,0 +1 @@
+stlib = static_library('allofme', '../libfile.c')
diff --git a/test cases/common/145 whole archive/exe/meson.build b/test cases/common/145 whole archive/exe/meson.build
new file mode 100644
index 0000000..f47a246
--- /dev/null
+++ b/test cases/common/145 whole archive/exe/meson.build
@@ -0,0 +1,2 @@
+exe = executable('prog', '../prog.c',
+ link_with : dylib)
diff --git a/test cases/common/145 whole archive/exe2/meson.build b/test cases/common/145 whole archive/exe2/meson.build
new file mode 100644
index 0000000..5365f03
--- /dev/null
+++ b/test cases/common/145 whole archive/exe2/meson.build
@@ -0,0 +1 @@
+exe2 = executable('prog2', '../prog.c', link_with : dylib2)
diff --git a/test cases/common/145 whole archive/meson.build b/test cases/common/145 whole archive/meson.build
index eadebf8..617ae03 100644
--- a/test cases/common/145 whole archive/meson.build
+++ b/test cases/common/145 whole archive/meson.build
@@ -1,5 +1,7 @@
project('whole archive', 'c')
+add_project_arguments('-I' + meson.source_root(), language : 'c')
+
cc = meson.get_compiler('c')
if cc.get_id() == 'msvc'
@@ -8,15 +10,15 @@ if cc.get_id() == 'msvc'
endif
endif
-stlib = static_library('allofme', 'libfile.c')
-
-# Nothing in dylib.c uses func1, so the linker would throw it
-# away and thus linking the exe would fail.
-dylib = shared_library('shlib', 'dylib.c',
- link_whole : stlib)
-
-exe = executable('prog', 'prog.c',
- link_with : dylib)
+subdir('allofme')
+subdir('shlib')
+subdir('exe')
test('prog', exe)
+# link_whole only
+subdir('stlib')
+subdir('wholeshlib')
+subdir('exe2')
+
+test('prog2', exe2)
diff --git a/test cases/common/145 whole archive/shlib/meson.build b/test cases/common/145 whole archive/shlib/meson.build
new file mode 100644
index 0000000..34a1b78
--- /dev/null
+++ b/test cases/common/145 whole archive/shlib/meson.build
@@ -0,0 +1,4 @@
+# Nothing in dylib.c uses func1, so the linker would throw it
+# away and thus linking the exe would fail.
+dylib = shared_library('shlib', '../dylib.c',
+ link_whole : stlib)
diff --git a/test cases/common/145 whole archive/stlib/meson.build b/test cases/common/145 whole archive/stlib/meson.build
new file mode 100644
index 0000000..07a434e
--- /dev/null
+++ b/test cases/common/145 whole archive/stlib/meson.build
@@ -0,0 +1 @@
+static = static_library('static', '../dylib.c')
diff --git a/test cases/common/145 whole archive/wholeshlib/meson.build b/test cases/common/145 whole archive/wholeshlib/meson.build
new file mode 100644
index 0000000..69a1995
--- /dev/null
+++ b/test cases/common/145 whole archive/wholeshlib/meson.build
@@ -0,0 +1 @@
+dylib2 = shared_library('link_whole', link_whole : [stlib, static])