ninja&make/mac: Give loadable_modules type MH_BUNDLE.

BUG=chromium:280718
R=mark@chromium.org, mmoss@chromium.org

Review URL: https://codereview.chromium.org/23789004

git-svn-id: http://gyp.googlecode.com/svn/trunk@1716 78cadc50-ecff-11dd-a971-7dbc132099af
diff --git a/pylib/gyp/generator/make.py b/pylib/gyp/generator/make.py
index c55c261..ab04721 100644
--- a/pylib/gyp/generator/make.py
+++ b/pylib/gyp/generator/make.py
@@ -166,15 +166,11 @@
 quiet_cmd_link = LINK($(TOOLSET)) $@
 cmd_link = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o "$@" $(LD_INPUTS) $(LIBS)
 
-# TODO(thakis): Find out and document the difference between shared_library and
-# loadable_module on mac.
 quiet_cmd_solink = SOLINK($(TOOLSET)) $@
 cmd_solink = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o "$@" $(LD_INPUTS) $(LIBS)
 
-# TODO(thakis): The solink_module rule is likely wrong. Xcode seems to pass
-# -bundle -single_module here (for osmesa.so).
 quiet_cmd_solink_module = SOLINK_MODULE($(TOOLSET)) $@
-cmd_solink_module = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ $(filter-out FORCE_DO_CMD, $^) $(LIBS)
+cmd_solink_module = $(LINK.$(TOOLSET)) -bundle $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ $(filter-out FORCE_DO_CMD, $^) $(LIBS)
 """
 
 LINK_COMMANDS_ANDROID = """\
diff --git a/pylib/gyp/generator/ninja.py b/pylib/gyp/generator/ninja.py
index b840474..b7dbd52 100644
--- a/pylib/gyp/generator/ninja.py
+++ b/pylib/gyp/generator/ninja.py
@@ -1643,6 +1643,7 @@
     cc = 'gcc'
     cxx = 'g++'
     ld = '$cxx'
+    ld_c = '$cc'
     ld_host = '$cxx_host'
 
   cc_host = None
@@ -1895,7 +1896,7 @@
 
     # Record the public interface of $lib in $lib.TOC. See the corresponding
     # comment in the posix section above for details.
-    solink_base = '$ld -shared $ldflags -o $lib %(suffix)s'
+    solink_base = '$ld %(type)s $ldflags -o $lib %(suffix)s'
     mtime_preserving_solink_base = (
         'if [ ! -e $lib -o ! -e ${lib}.TOC ] || '
              # Always force dependent targets to relink if this library
@@ -1914,20 +1915,19 @@
               '{ otool -l $lib | grep LC_ID_DYLIB -A 5; '
               'nm -gP $lib | cut -f1-2 -d\' \' | grep -v U$$; true; }'})
 
-    # TODO(thakis): The solink_module rule is likely wrong. Xcode seems to pass
-    # -bundle -single_module here (for osmesa.so).
     solink_suffix = '$in $solibs $libs$postbuilds'
     master_ninja.rule(
       'solink',
       description='SOLINK $lib, POSTBUILDS',
       restat=True,
-      command=mtime_preserving_solink_base % {'suffix':solink_suffix},
+      command=mtime_preserving_solink_base % {'suffix': solink_suffix,
+                                              'type': '-shared'},
       pool='link_pool')
     master_ninja.rule(
       'solink_notoc',
       description='SOLINK $lib, POSTBUILDS',
       restat=True,
-      command=solink_base % {'suffix':solink_suffix},
+      command=solink_base % {'suffix':solink_suffix, 'type': '-shared'},
       pool='link_pool')
 
     solink_module_suffix = '$in $solibs $libs$postbuilds'
@@ -1935,13 +1935,14 @@
       'solink_module',
       description='SOLINK(module) $lib, POSTBUILDS',
       restat=True,
-      command=mtime_preserving_solink_base % {'suffix':solink_module_suffix},
+      command=mtime_preserving_solink_base % {'suffix': solink_module_suffix,
+                                              'type': '-bundle'},
       pool='link_pool')
     master_ninja.rule(
       'solink_module_notoc',
       description='SOLINK(module) $lib, POSTBUILDS',
       restat=True,
-      command=solink_base % {'suffix':solink_module_suffix},
+      command=solink_base % {'suffix': solink_module_suffix, 'type': '-bundle'},
       pool='link_pool')
 
     master_ninja.rule(
diff --git a/pylib/gyp/xcode_emulation.py b/pylib/gyp/xcode_emulation.py
index 5e8f2b7..2ced319 100644
--- a/pylib/gyp/xcode_emulation.py
+++ b/pylib/gyp/xcode_emulation.py
@@ -609,7 +609,7 @@
     ldflags.append('-L' + product_dir)
 
     install_name = self.GetInstallName()
-    if install_name:
+    if install_name and self.spec['type'] != 'loadable_module':
       ldflags.append('-install_name ' + install_name.replace(' ', r'\ '))
 
     for rpath in self._Settings().get('LD_RUNPATH_SEARCH_PATHS', []):
diff --git a/test/mac/gyptest-loadable-module.py b/test/mac/gyptest-loadable-module.py
index e5e022c..3564aac 100755
--- a/test/mac/gyptest-loadable-module.py
+++ b/test/mac/gyptest-loadable-module.py
@@ -11,23 +11,28 @@
 import TestGyp
 
 import os
+import struct
 import sys
 
 if sys.platform == 'darwin':
   test = TestGyp.TestGyp(formats=['ninja', 'make', 'xcode'])
 
-  test.run_gyp('test.gyp', chdir='loadable-module')
-  test.build('test.gyp', test.ALL, chdir='loadable-module')
+  CHDIR = 'loadable-module'
+  test.run_gyp('test.gyp', chdir=CHDIR)
+  test.build('test.gyp', test.ALL, chdir=CHDIR)
 
   # Binary.
-  test.built_file_must_exist(
+  binary = test.built_file_path(
       'test_loadable_module.plugin/Contents/MacOS/test_loadable_module',
-      chdir='loadable-module')
+      chdir=CHDIR)
+  test.must_exist(binary)
+  MH_BUNDLE = 8
+  if struct.unpack('4I', open(binary, 'rb').read(16))[3] != MH_BUNDLE:
+    test.fail_test()
 
   # Info.plist.
   info_plist = test.built_file_path(
-      'test_loadable_module.plugin/Contents/Info.plist',
-      chdir='loadable-module')
+      'test_loadable_module.plugin/Contents/Info.plist', chdir=CHDIR)
   test.must_exist(info_plist)
   test.must_contain(info_plist, """
 	<key>CFBundleExecutable</key>
@@ -36,10 +41,8 @@
 
   # PkgInfo.
   test.built_file_must_not_exist(
-      'test_loadable_module.plugin/Contents/PkgInfo',
-      chdir='loadable-module')
+      'test_loadable_module.plugin/Contents/PkgInfo', chdir=CHDIR)
   test.built_file_must_not_exist(
-      'test_loadable_module.plugin/Contents/Resources',
-      chdir='loadable-module')
+      'test_loadable_module.plugin/Contents/Resources', chdir=CHDIR)
 
   test.pass_test()
diff --git a/test/module/src/module.gyp b/test/module/src/module.gyp
index 7fbfbb0..2bc398b 100644
--- a/test/module/src/module.gyp
+++ b/test/module/src/module.gyp
@@ -36,7 +36,6 @@
       'type': 'loadable_module',
       'product_name': 'lib1',
       'product_prefix': '',
-      'xcode_settings': {'OTHER_LDFLAGS': ['-dynamiclib'], 'MACH_O_TYPE': ''},
       'sources': [
         'lib1.c',
       ],
@@ -46,7 +45,6 @@
       'product_name': 'lib2',
       'product_prefix': '',
       'type': 'loadable_module',
-      'xcode_settings': {'OTHER_LDFLAGS': ['-dynamiclib'], 'MACH_O_TYPE': ''},
       'sources': [
         'lib2.c',
       ],