aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2017-12-01 13:05:42 -0500
committerJack Lloyd <[email protected]>2017-12-01 13:05:42 -0500
commit2ef76a1b235bb2559a4bdfca2de5a3e990346d34 (patch)
treecf8f5db867451a255b306ac89ff38e572dd82b9b
parenta201a07ea17b003bd0b373eadbfbc7711610505e (diff)
parentba843d795772f72a4f3ecf9649c9b58f6422b3d3 (diff)
Merge GH #1325 Merge makefile types
-rwxr-xr-xconfigure.py125
-rw-r--r--src/build-data/cc/clang.txt6
-rw-r--r--src/build-data/cc/ekopath.txt4
-rw-r--r--src/build-data/cc/gcc.txt10
-rw-r--r--src/build-data/cc/hpcc.txt4
-rw-r--r--src/build-data/cc/icc.txt4
-rw-r--r--src/build-data/cc/msvc.txt7
-rw-r--r--src/build-data/cc/pgi.txt6
-rw-r--r--src/build-data/cc/sunstudio.txt4
-rw-r--r--src/build-data/cc/xlc.txt2
-rw-r--r--src/build-data/makefile.in116
-rw-r--r--src/build-data/makefile/gmake.in67
-rw-r--r--src/build-data/makefile/header.in57
-rw-r--r--src/build-data/makefile/nmake.in42
-rw-r--r--src/build-data/os/darwin.txt2
15 files changed, 201 insertions, 255 deletions
diff --git a/configure.py b/configure.py
index 24283d8b3..76887a4d1 100755
--- a/configure.py
+++ b/configure.py
@@ -175,7 +175,6 @@ class SourcePaths(object):
# subdirs of src/
self.sphinx_config_dir = os.path.join(self.configs_dir, 'sphinx')
- self.makefile_dir = os.path.join(self.build_data_dir, 'makefile')
class BuildPaths(object): # pylint: disable=too-many-instance-attributes
@@ -436,11 +435,6 @@ def process_command_line(args): # pylint: disable=too-many-locals
choices=link_methods,
help='choose how links to include headers are created (%s)' % ', '.join(link_methods))
- makefile_styles = ['gmake', 'nmake']
- build_group.add_option('--makefile-style', metavar='STYLE', default=None,
- choices=makefile_styles,
- help='makefile type (%s)' % ' or '.join(makefile_styles))
-
build_group.add_option('--with-local-config',
dest='local_config', metavar='FILE',
help='include the contents of FILE into build.h')
@@ -1099,7 +1093,8 @@ class CompilerInfo(InfoObject): # pylint: disable=too-many-instance-attributes
'binary_name': None,
'linker_name': None,
'macro_name': None,
- 'output_to_option': '-o ',
+ 'output_to_object': '-o ',
+ 'output_to_exe': '-o ',
'add_include_dir_option': '-I',
'add_lib_dir_option': '-L',
'add_lib_option': '-l',
@@ -1117,9 +1112,9 @@ class CompilerInfo(InfoObject): # pylint: disable=too-many-instance-attributes
'maintainer_warning_flags': '',
'visibility_build_flags': '',
'visibility_attribute': '',
- 'ar_command': None,
- 'ar_options': None,
- 'makefile_style': ''
+ 'ar_command': '',
+ 'ar_options': '',
+ 'ar_output_to': '',
})
self.add_framework_option = lex.add_framework_option
@@ -1128,6 +1123,7 @@ class CompilerInfo(InfoObject): # pylint: disable=too-many-instance-attributes
self.add_lib_dir_option = lex.add_lib_dir_option
self.ar_command = lex.ar_command
self.ar_options = lex.ar_options
+ self.ar_output_to = lex.ar_output_to
self.binary_link_commands = force_to_dict(lex.binary_link_commands)
self.binary_name = lex.binary_name
self.compile_flags = lex.compile_flags
@@ -1139,9 +1135,9 @@ class CompilerInfo(InfoObject): # pylint: disable=too-many-instance-attributes
self.mach_abi_linking = force_to_dict(lex.mach_abi_linking)
self.macro_name = lex.macro_name
self.maintainer_warning_flags = lex.maintainer_warning_flags
- self.makefile_style = lex.makefile_style
self.optimization_flags = lex.optimization_flags
- self.output_to_option = lex.output_to_option
+ self.output_to_object = lex.output_to_object
+ self.output_to_exe = lex.output_to_exe
self.sanitizer_flags = lex.sanitizer_flags
self.shared_flags = lex.shared_flags
self.size_optimization_flags = lex.size_optimization_flags
@@ -1326,12 +1322,14 @@ class OsInfo(InfoObject): # pylint: disable=too-many-instance-attributes
'static_suffix': 'a',
'ar_command': 'ar',
'ar_options': '',
+ 'ar_output_to': '',
'install_root': '/usr/local',
'header_dir': 'include',
'bin_dir': 'bin',
'lib_dir': 'lib',
'doc_dir': 'share/doc',
- 'building_shared_supported': 'yes'
+ 'building_shared_supported': 'yes',
+ 'so_post_link_command': '',
})
if lex.ar_command == 'ar' and lex.ar_options == '':
@@ -1374,6 +1372,7 @@ class OsInfo(InfoObject): # pylint: disable=too-many-instance-attributes
self.program_suffix = lex.program_suffix
self.static_suffix = lex.static_suffix
self.target_features = lex.target_features
+ self.so_post_link_command = lex.so_post_link_command
def defines(self, options):
r = []
@@ -1494,7 +1493,7 @@ def process_template(template_file, variables):
v = match.group(1)
if v in self.vals:
return str(self.vals.get(v))
- raise KeyError("Unknown template variable '%s'" % (v))
+ raise KeyError(v)
lines = template.splitlines()
@@ -1531,9 +1530,9 @@ def process_template(template_file, variables):
try:
return SimpleTemplate(variables).substitute(read_textfile(template_file))
except KeyError as e:
- raise InternalError('Unbound var %s in template %s' % (e, template_file))
- except Exception as e:
- raise InternalError('Exception %s in template %s' % (e, template_file))
+ logging.error('Unbound var %s in template %s' % (e, template_file))
+ except Exception as e: # pylint: disable=broad-except
+ logging.error('Exception %s during template processing file %s' % (e, template_file))
def makefile_list(items):
separator = " \\\n" + 16*" "
@@ -1891,7 +1890,7 @@ class MakefileListsGenerator(object):
name = name.replace('.cpp', obj_suffix)
yield os.path.join(obj_dir, name)
- def _build_commands(self, sources, obj_dir, objects, flags):
+ def _build_commands(self, sources, obj_dir, objects, is_lib):
"""
Form snippets of makefile for building each source file
"""
@@ -1902,19 +1901,22 @@ class MakefileListsGenerator(object):
includes += ' ' + self._cc.add_include_dir_option + self._options.with_external_includedir
is_fuzzer = obj_dir.find('fuzzer') != -1
+ fuzzer_link = '' if self._options.fuzzer_lib is None \
+ else '%s%s' % (self._cc.add_lib_option, self._options.fuzzer_lib)
for (obj_file, src) in zip(objects, sources):
isa_specific_flags_str = "".join([" %s" % flagset for flagset in sorted(self._isa_specific_flags(src))])
yield '%s: %s\n\t$(CXX)%s $(%s_FLAGS) %s %s %s %s$@\n' % (
- obj_file, src, isa_specific_flags_str, flags,
- includes, self._cc.compile_flags, src, self._cc.output_to_option)
+ obj_file, src, isa_specific_flags_str, 'LIB' if is_lib else 'EXE',
+ includes, self._cc.compile_flags, src, self._cc.output_to_object)
if is_fuzzer:
fuzz_basename = os.path.basename(obj_file).replace('.' + self._osinfo.obj_suffix, '')
fuzz_bin = self._build_paths.fuzzer_output_dir
- yield '%s: %s $(LIBRARIES)\n\t$(FUZZER_LINK_CMD) %s $(FUZZER_LINKS_TO) %s$@\n' % (
- os.path.join(fuzz_bin, fuzz_basename), obj_file, obj_file, self._cc.output_to_option)
+ yield '%s: %s $(LIBRARIES)\n\t$(EXE_LINK_CMD) %s $(EXE_LINKS_TO) %s %s$@\n' % (
+ os.path.join(fuzz_bin, fuzz_basename), obj_file, obj_file, fuzzer_link,
+ self._cc.output_to_object)
def generate(self):
out = {}
@@ -1934,7 +1936,7 @@ class MakefileListsGenerator(object):
out['fuzzer_bin'] = makefile_list(self._fuzzer_bin_list(objects, self._build_paths.fuzzer_output_dir))
build_key = '%s_build_cmds' % (t)
- out[build_key] = '\n'.join(self._build_commands(src_list, src_dir, objects, t.upper()))
+ out[build_key] = '\n'.join(self._build_commands(src_list, src_dir, objects, t == 'lib'))
return out
@@ -1971,7 +1973,7 @@ class HouseEccCurve(object):
return "\\\n" + ' \\\n'.join(lines)
-def create_template_vars(source_paths, build_config, options, modules, cc, arch, osinfo): #pylint: disable=too-many-locals,too-many-branches
+def create_template_vars(source_paths, build_config, options, modules, cc, arch, osinfo): #pylint: disable=too-many-locals,too-many-branches,too-many-statements
"""
Create the template variables needed to process the makefile, build.h, etc
"""
@@ -1980,7 +1982,7 @@ def create_template_vars(source_paths, build_config, options, modules, cc, arch,
return '\n'.join(['#define BOTAN_' + macro for macro in macros])
def external_link_cmd():
- return ' ' + cc.add_lib_dir_option + options.with_external_libdir if options.with_external_libdir else ''
+ return (' ' + cc.add_lib_dir_option + options.with_external_libdir) if options.with_external_libdir else ''
def link_to(module_member_name):
"""
@@ -2023,8 +2025,6 @@ def create_template_vars(source_paths, build_config, options, modules, cc, arch,
main_executable = os.path.basename(sys.argv[0])
return ' '.join([main_executable] + sys.argv[1:])
- bin_link_cmd = cc.binary_link_command_for(osinfo.basename, options) + external_link_cmd()
-
variables = {
'version_major': Version.major(),
'version_minor': Version.minor(),
@@ -2033,19 +2033,20 @@ def create_template_vars(source_paths, build_config, options, modules, cc, arch,
'abi_rev': Version.so_rev(),
'version': Version.as_string(),
- 'version_packed': Version.packed(),
'release_type': Version.release_type(),
'version_datestamp': Version.datestamp(),
'distribution_info': options.distribution_info,
+ 'darwin_so_compat_ver': '%s.%s.0' % (Version.packed(), Version.so_rev()),
+ 'darwin_so_current_ver': '%s.%s.%s' % (Version.packed(), Version.so_rev(), Version.patch()),
+
'base_dir': source_paths.base_dir,
'src_dir': source_paths.src_dir,
'doc_dir': source_paths.doc_dir,
'command_line': configure_command_line(),
'local_config': read_textfile(options.local_config),
- 'makefile_style': options.makefile_style or cc.makefile_style,
'makefile_path': os.path.join(build_config.build_dir, '..', 'Makefile'),
@@ -2064,9 +2065,12 @@ def create_template_vars(source_paths, build_config, options, modules, cc, arch,
'scripts_dir': source_paths.scripts_dir,
'build_static_lib': options.build_static_lib,
- 'build_shared_lib': options.build_shared_lib,
'build_fuzzers': options.build_fuzzers,
+ 'build_shared_lib': options.build_shared_lib,
+ 'build_unix_shared_lib': options.build_shared_lib and options.compiler != 'msvc',
+ 'build_msvc_shared_lib': options.build_shared_lib and options.compiler == 'msvc',
+
'libobj_dir': build_config.libobj_dir,
'cliobj_dir': build_config.cliobj_dir,
'testobj_dir': build_config.testobj_dir,
@@ -2095,14 +2099,13 @@ def create_template_vars(source_paths, build_config, options, modules, cc, arch,
'cc_lang_flags': cc.cc_lang_flags(),
'cc_compile_flags': cc.cc_compile_flags(options),
'cc_warning_flags': cc.cc_warning_flags(options),
+ 'output_to_exe': cc.output_to_exe,
'shared_flags': cc.gen_shared_flags(options),
'visibility_attribute': cc.gen_visibility_attribute(options),
'lib_link_cmd': cc.so_link_command_for(osinfo.basename, options) + external_link_cmd(),
- 'cli_link_cmd': bin_link_cmd,
- 'test_link_cmd': bin_link_cmd,
- 'fuzzer_link_cmd': bin_link_cmd,
+ 'exe_link_cmd': cc.binary_link_command_for(osinfo.basename, options) + external_link_cmd(),
'link_to': ' '.join(
[cc.add_lib_option + lib for lib in link_to('libs')] +
@@ -2123,11 +2126,11 @@ def create_template_vars(source_paths, build_config, options, modules, cc, arch,
'unsafe_fuzzer_mode_define': '#define BOTAN_UNSAFE_FUZZER_MODE' if options.unsafe_fuzzer_mode else '',
'fuzzer_type': '#define BOTAN_FUZZER_IS_%s' % (options.build_fuzzers.upper()) if options.build_fuzzers else '',
- 'fuzzer_libs': '' if options.fuzzer_lib is None else '%s%s' % (cc.add_lib_option, options.fuzzer_lib),
'python_exe': sys.executable,
'ar_command': options.ar_command or cc.ar_command or osinfo.ar_command,
'ar_options': cc.ar_options or osinfo.ar_options,
+ 'ar_output_to': cc.ar_output_to,
'lib_prefix': 'lib' if options.os != 'windows' else '',
@@ -2160,7 +2163,6 @@ def create_template_vars(source_paths, build_config, options, modules, cc, arch,
variables['static_lib_name'] = variables['lib_basename'] + '.' + variables['static_suffix']
if options.build_shared_lib:
-
if osinfo.soname_pattern_base != None:
variables['soname_base'] = osinfo.soname_pattern_base.format(**variables)
variables['shared_lib_name'] = variables['soname_base']
@@ -2172,25 +2174,36 @@ def create_template_vars(source_paths, build_config, options, modules, cc, arch,
if osinfo.soname_pattern_patch != None:
variables['soname_patch'] = osinfo.soname_pattern_patch.format(**variables)
+ variables['lib_link_cmd'] = variables['lib_link_cmd'].format(**variables)
+ else:
+ variables['lib_link_cmd'] = ''
+
if options.os == 'darwin' and options.build_shared_lib:
# In order that these executables work from the build directory,
# we need to change the install names
- variables['cli_post_link_cmd'] = \
- 'install_name_tool -change "$(INSTALLED_LIB_DIR)/$(SONAME_ABI)" "@executable_path/$(SONAME_ABI)" $(CLI)'
- variables['test_post_link_cmd'] = \
- 'install_name_tool -change "$(INSTALLED_LIB_DIR)/$(SONAME_ABI)" "@executable_path/$(SONAME_ABI)" $(TEST)'
+ variables['post_link_cmd'] = osinfo.so_post_link_command.format(**variables)
else:
- variables['cli_post_link_cmd'] = ''
- variables['test_post_link_cmd'] = ''
+ variables['post_link_cmd'] = ''
variables.update(MakefileListsGenerator(build_config, options, modules, cc, arch, osinfo).generate())
- if options.os == 'llvm':
- # llvm-link doesn't understand -L or -l flags
- variables['link_to_botan'] = '%s/lib%s.a' % (variables['out_dir'], variables['libname'])
- elif options.compiler == 'msvc':
- # Nmake makefiles do something completely different here...
- variables['link_to_botan'] = ''
+ if options.os == 'windows':
+ # For historical reasons? the library does not have the major number on Windows
+ # This should probably be fixed in a future major release.
+ variables['libname'] = 'botan'
+ variables['lib_basename'] = variables['libname']
+ variables['cli_exe'] = os.path.join(variables['out_dir'], 'botan-cli' + variables['program_suffix'])
+ else:
+ variables['libname'] = 'botan-%d' % (Version.major())
+ variables['lib_basename'] = 'lib' + variables['libname']
+ variables['cli_exe'] = os.path.join(variables['out_dir'], 'botan' + variables['program_suffix'])
+ variables['botan_pkgconfig'] = os.path.join(build_config.build_dir, PKG_CONFIG_FILENAME)
+
+ variables['static_lib_name'] = variables['lib_basename'] + '.' + variables['static_suffix']
+
+ if options.os == 'llvm' or options.compiler == 'msvc':
+ # llvm-link and msvc require just naming the file directly
+ variables['link_to_botan'] = os.path.join(variables['out_dir'], variables['static_lib_name'])
else:
variables['link_to_botan'] = '%s%s %s%s' % (
cc.add_lib_dir_option, variables['out_dir'],
@@ -2204,8 +2217,6 @@ def create_template_vars(source_paths, build_config, options, modules, cc, arch,
variables['library_targets'] = ' '.join([os.path.join(variables['out_dir'], variables[t]) for t in lib_targets])
- variables["header_in"] = process_template(os.path.join(source_paths.makefile_dir, 'header.in'), variables)
-
return variables
class ModulesChooser(object):
@@ -3033,7 +3044,9 @@ def canonicalize_options(options, info_os, info_arch):
else:
raise UserError('Unknown or unidentifiable processor "%s"' % (options.cpu))
- if options.build_shared_lib and not info_os[options.os].building_shared_supported:
+ shared_libs_supported = options.os in info_os and info_os[options.os].building_shared_supported
+
+ if options.build_shared_lib and not shared_libs_supported:
logging.warning('Shared libs not supported on %s, disabling shared lib support' % (options.os))
options.build_shared_lib = False
@@ -3044,7 +3057,7 @@ def canonicalize_options(options, info_os, info_arch):
if options.os == 'windows' and options.build_static_lib:
pass
else:
- options.build_shared_lib = info_os[options.os].building_shared_supported
+ options.build_shared_lib = shared_libs_supported
if options.build_static_lib is None:
if options.os == 'windows' and options.build_shared_lib:
@@ -3118,8 +3131,8 @@ def validate_options(options, info_os, info_cc, available_module_policies):
raise UserError('Using --with-sphinx plus --without-documentation makes no sense')
# Warnings
- if options.os == 'windows' and options.compiler == 'gcc':
- logging.warning('Detected GCC on Windows; use --os=cygwin or --os=mingw?')
+ if options.os == 'windows' and options.compiler != 'msvc':
+ logging.warning('The windows target is oriented towards MSVC; maybe you want cygwin or mingw')
def prepare_configure_build(info_modules, source_paths, options,
cc, cc_min_version, arch, osinfo, module_policy):
@@ -3131,7 +3144,7 @@ def prepare_configure_build(info_modules, source_paths, options,
template_vars = create_template_vars(source_paths, build_config, options, using_mods, cc, arch, osinfo)
- makefile_template = os.path.join(source_paths.makefile_dir, '%s.in' % (template_vars['makefile_style']))
+ makefile_template = os.path.join(source_paths.build_data_dir, 'makefile.in')
logging.debug('Using makefile template %s' % (makefile_template))
return using_mods, build_config, template_vars, makefile_template
@@ -3301,10 +3314,6 @@ def main(argv):
logging.info('Target is %s:%s-%s-%s-%s' % (
options.compiler, cc_min_version, options.os, options.arch, options.cpu))
- if options.build_shared_lib and not osinfo.building_shared_supported:
- logging.warning('Shared libs not supported on %s, disabling shared lib support' % (osinfo.basename))
- options.build_shared_lib = False
-
main_action_configure_build(info_modules, source_paths, options,
cc, cc_min_version, arch, osinfo, module_policy)
return 0
diff --git a/src/build-data/cc/clang.txt b/src/build-data/cc/clang.txt
index cfff2e2eb..ec4da317d 100644
--- a/src/build-data/cc/clang.txt
+++ b/src/build-data/cc/clang.txt
@@ -19,13 +19,11 @@ stack_protector_flags "-fstack-protector"
visibility_build_flags "-fvisibility=hidden"
visibility_attribute '__attribute__((visibility("default")))'
-makefile_style gmake
-
<so_link_commands>
-darwin -> "$(CXX) -dynamiclib -fPIC -install_name $(INSTALLED_LIB_DIR)/$(SONAME_ABI) -current_version $(DARWIN_CURRENT_VER) -compatibility_version $(DARWIN_COMPATIBILITY_VER)"
+darwin -> "$(CXX) -dynamiclib -fPIC -install_name $(INSTALLED_LIB_DIR)/{soname_abi} -current_version {darwin_so_current_ver} -compatibility_version {darwin_so_compat_ver}"
# The default works for GNU ld and several other Unix linkers
-default -> "$(CXX) -shared -fPIC -Wl,-soname,$(SONAME_ABI)"
+default -> "$(CXX) -shared -fPIC -Wl,-soname,{soname_abi}"
</so_link_commands>
<binary_link_commands>
diff --git a/src/build-data/cc/ekopath.txt b/src/build-data/cc/ekopath.txt
index c127b78f8..dedbaaf61 100644
--- a/src/build-data/cc/ekopath.txt
+++ b/src/build-data/cc/ekopath.txt
@@ -12,10 +12,8 @@ ar_options "-ar -o"
shared_flags "-fPIC"
-makefile_style gmake
-
<so_link_commands>
-default -> "$(CXX) -shared -fPIC -Wl,-soname,$(SONAME_ABI)"
+default -> "$(CXX) -shared -fPIC -Wl,-soname,{soname_abi}"
</so_link_commands>
<mach_opt>
diff --git a/src/build-data/cc/gcc.txt b/src/build-data/cc/gcc.txt
index 88e7089ce..17b477db8 100644
--- a/src/build-data/cc/gcc.txt
+++ b/src/build-data/cc/gcc.txt
@@ -25,16 +25,14 @@ sanitizer_flags "-D_GLIBCXX_DEBUG -fsanitize=address"
visibility_build_flags "-fvisibility=hidden"
visibility_attribute '__attribute__((visibility("default")))'
-makefile_style gmake
-
<so_link_commands>
# The default works for GNU ld and several other Unix linkers
-default -> "$(CXX) -shared -fPIC -Wl,-soname,$(SONAME_ABI)"
+default -> "$(CXX) -shared -fPIC -Wl,-soname,{soname_abi}"
# Darwin, HP-UX and Solaris linkers use different syntax
-darwin -> "$(CXX) -dynamiclib -fPIC -install_name $(LIBDIR)/$(SONAME_ABI)"
-hpux -> "$(CXX) -shared -fPIC -Wl,+h,$(SONAME_ABI)"
-solaris -> "$(CXX) -shared -fPIC -Wl,-h,$(SONAME_ABI)"
+darwin -> "$(CXX) -dynamiclib -fPIC -install_name $(INSTALLED_LIB_DIR)/{soname_abi}"
+hpux -> "$(CXX) -shared -fPIC -Wl,+h,{soname_abi}"
+solaris -> "$(CXX) -shared -fPIC -Wl,-h,{soname_abi}"
# AIX and OpenBSD don't use sonames at all
aix -> "$(CXX) -shared -fPIC"
diff --git a/src/build-data/cc/hpcc.txt b/src/build-data/cc/hpcc.txt
index aa305bf82..cbe50c37d 100644
--- a/src/build-data/cc/hpcc.txt
+++ b/src/build-data/cc/hpcc.txt
@@ -7,8 +7,6 @@ optimization_flags "+O2"
warning_flags "+w"
shared_flags "+Z"
-makefile_style gmake
-
<mach_abi_linking>
hppa1.0 -> "+DAportable"
hppa1.1 -> "+DA1.1"
@@ -16,5 +14,5 @@ hppa2.0 -> "+DA2.0W"
</mach_abi_linking>
<so_link_commands>
-default -> "$(CXX) +Z -b -Wl,+h,$(SONAME_ABI)" # Documented in cc(1), but not CC(1) (?)
+default -> "$(CXX) +Z -b -Wl,+h,{soname_abi}" # Documented in cc(1), but not CC(1) (?)
</so_link_commands>
diff --git a/src/build-data/cc/icc.txt b/src/build-data/cc/icc.txt
index cdc250187..f50ea6d11 100644
--- a/src/build-data/cc/icc.txt
+++ b/src/build-data/cc/icc.txt
@@ -9,8 +9,6 @@ lang_flags "-std=c++0x"
warning_flags "-w1"
shared_flags "-fPIC"
-makefile_style gmake
-
<mach_opt>
pentium3 -> "-march=pentium3"
pentium4 -> "-march=pentium4"
@@ -23,5 +21,5 @@ westmere -> "-march=core2"
</mach_opt>
<so_link_commands>
-default -> "$(CXX) -fPIC -shared -Wl,-soname,$(SONAME_ABI)"
+default -> "$(CXX) -fPIC -shared -Wl,-soname,{soname_abi}"
</so_link_commands>
diff --git a/src/build-data/cc/msvc.txt b/src/build-data/cc/msvc.txt
index 51608dcfa..6df218a4f 100644
--- a/src/build-data/cc/msvc.txt
+++ b/src/build-data/cc/msvc.txt
@@ -3,7 +3,9 @@ macro_name MSVC
binary_name cl
linker_name link
-output_to_option "/Fo"
+output_to_object "/Fo"
+output_to_exe "/OUT:"
+
add_include_dir_option "/I"
add_lib_dir_option "/LIBPATH:"
add_lib_option ""
@@ -27,8 +29,7 @@ visibility_attribute "__declspec(dllimport)"
ar_command lib
ar_options "/nologo"
-
-makefile_style nmake
+ar_output_to "/OUT:"
<isa_flags>
sse2 -> ""
diff --git a/src/build-data/cc/pgi.txt b/src/build-data/cc/pgi.txt
index e8c65ea3a..213a69d27 100644
--- a/src/build-data/cc/pgi.txt
+++ b/src/build-data/cc/pgi.txt
@@ -5,11 +5,9 @@ binary_name pgCC
optimization_flags "-fast -Minline"
shared_flags "-fPIC"
-makefile_style gmake
-
<so_link_commands>
-linux -> "$(CXX) -shared -fPIC -Wl,-soname,$(SONAME_ABI)"
-solaris -> "$(CXX) -G -fPIC -Wl,-h,$(SONAME_ABI)"
+linux -> "$(CXX) -shared -fPIC -Wl,-soname,{soname_abi}"
+solaris -> "$(CXX) -G -fPIC -Wl,-h,{soname_abi}"
</so_link_commands>
<mach_opt>
diff --git a/src/build-data/cc/sunstudio.txt b/src/build-data/cc/sunstudio.txt
index fd87533a5..38f9d828c 100644
--- a/src/build-data/cc/sunstudio.txt
+++ b/src/build-data/cc/sunstudio.txt
@@ -11,10 +11,8 @@ lang_flags "-std=c++11 +p -features=extensions -D__FUNCTION__=__func__"
ar_command CC
ar_options "-xar -o"
-makefile_style gmake
-
<so_link_commands>
-default -> "$(CXX) -G -h$(SONAME_ABI)"
+default -> "$(CXX) -G -h{soname_abi}"
</so_link_commands>
<mach_opt>
diff --git a/src/build-data/cc/xlc.txt b/src/build-data/cc/xlc.txt
index 28620b7e1..c28fdb1a0 100644
--- a/src/build-data/cc/xlc.txt
+++ b/src/build-data/cc/xlc.txt
@@ -6,8 +6,6 @@ optimization_flags "-O2"
lang_flags "-std=c++11"
-makefile_style gmake
-
<mach_opt>
power8 -> "-qarch=pwr8"
power9 -> "-qarch=pwr9"
diff --git a/src/build-data/makefile.in b/src/build-data/makefile.in
new file mode 100644
index 000000000..89098c466
--- /dev/null
+++ b/src/build-data/makefile.in
@@ -0,0 +1,116 @@
+# Paths to relevant programs
+
+CXX = %{cxx} %{cxx_abi_flags}
+LINKER = %{linker}
+AR = %{ar_command}
+PYTHON_EXE = %{python_exe}
+
+# Compiler Flags
+
+LANG_FLAGS = %{cc_lang_flags}
+CXXFLAGS = %{cc_compile_flags}
+WARN_FLAGS = %{cc_warning_flags}
+SO_OBJ_FLAGS = %{shared_flags}
+
+LIB_LINK_CMD = %{lib_link_cmd}
+EXE_LINK_CMD = %{exe_link_cmd}
+
+LIB_LINKS_TO = %{link_to}
+EXE_LINKS_TO = %{link_to_botan} $(LIB_LINKS_TO)
+
+LIB_FLAGS = $(SO_OBJ_FLAGS) $(LANG_FLAGS) $(CXXFLAGS) $(WARN_FLAGS)
+EXE_FLAGS = $(LANG_FLAGS) $(CXXFLAGS) $(WARN_FLAGS)
+
+SCRIPTS_DIR = %{scripts_dir}
+INSTALLED_LIB_DIR = %{prefix}/%{libdir}
+
+POST_LINK_CMD = %{post_link_cmd}
+
+# The primary target
+all: libs cli tests
+
+# Executable targets
+CLI = %{cli_exe}
+TEST = %{test_exe}
+LIBRARIES = %{library_targets}
+
+cli: $(CLI)
+tests: $(TEST)
+libs: $(LIBRARIES)
+
+# Misc targets
+
+clean:
+ $(PYTHON_EXE) $(SCRIPTS_DIR)/cleanup.py --build-dir="%{build_dir}"
+
+distclean:
+ $(PYTHON_EXE) $(SCRIPTS_DIR)/cleanup.py --build-dir="%{build_dir}" --distclean
+
+install: $(CLI) docs
+ $(PYTHON_EXE) $(SCRIPTS_DIR)/install.py --prefix=%{prefix} --build-dir="%{build_dir}" --bindir=%{bindir} --libdir=%{libdir} --docdir=%{docdir} --includedir=%{includedir}
+
+docs:
+%{build_doc_commands}
+
+# Object Files
+LIBOBJS = %{lib_objs}
+
+CLIOBJS = %{cli_objs}
+
+TESTOBJS = %{test_objs}
+
+# Build Commands
+%{lib_build_cmds}
+
+%{cli_build_cmds}
+
+%{test_build_cmds}
+
+# Library targets
+
+$(CLI): $(LIBRARIES) $(CLIOBJS)
+ $(EXE_LINK_CMD) $(LDFLAGS) $(CLIOBJS) $(EXE_LINKS_TO) %{output_to_exe}$@
+ $(POST_LINK_CMD)
+
+$(TEST): $(LIBRARIES) $(TESTOBJS)
+ $(EXE_LINK_CMD) $(LDFLAGS) $(TESTOBJS) $(EXE_LINKS_TO) %{output_to_exe}$@
+ $(POST_LINK_CMD)
+
+%{if build_static_lib}
+
+%{out_dir}/%{static_lib_name}: $(LIBOBJS)
+ $(AR) %{ar_options} %{ar_output_to}$@ $(LIBOBJS)
+
+%{endif}
+
+%{if build_unix_shared_lib}
+
+%{out_dir}/%{shared_lib_name}: $(LIBOBJS)
+ $(LIB_LINK_CMD) $(LDFLAGS) $(LIBOBJS) $(LIB_LINKS_TO) %{output_to_exe}$@
+ cd %{out_dir} && ln -fs %{shared_lib_name} %{soname_base}
+ cd %{out_dir} && ln -fs %{shared_lib_name} %{soname_patch}
+
+%{endif}
+
+%{if build_msvc_shared_lib}
+
+%{out_dir}/%{shared_lib_name}: $(LIBOBJS)
+ $(LIB_LINK_CMD) $(LDFLAGS) $(LIBOBJS) $(LIB_LINKS_TO) %{output_to_exe}$@
+
+%{endif}
+
+%{if build_fuzzers}
+
+%{fuzzer_build_cmds}
+
+FUZZERS=%{fuzzer_bin}
+
+fuzzers: libs $(FUZZERS)
+
+fuzzer_corpus:
+ git clone --depth=1 https://github.com/randombit/crypto-corpus.git fuzzer_corpus
+
+fuzzer_corpus_zip: fuzzer_corpus
+ ./src/scripts/create_corpus_zip.py fuzzer_corpus %{fuzzobj_dir}
+
+%{endif}
diff --git a/src/build-data/makefile/gmake.in b/src/build-data/makefile/gmake.in
deleted file mode 100644
index 97084c7d8..000000000
--- a/src/build-data/makefile/gmake.in
+++ /dev/null
@@ -1,67 +0,0 @@
-%{header_in}
-
-# Object Files
-LIBOBJS = %{lib_objs}
-
-CLIOBJS = %{cli_objs}
-
-TESTOBJS = %{test_objs}
-
-# Build Commands
-%{lib_build_cmds}
-
-%{cli_build_cmds}
-
-%{test_build_cmds}
-
-# Library targets
-
-$(CLI): $(LIBRARIES) $(CLIOBJS)
- $(CLI_LINK_CMD) $(LDFLAGS) $(CLIOBJS) $(CLI_LINKS_TO) -o $(CLI)
- $(CLI_POST_LINK_CMD)
-
-$(TEST): $(LIBRARIES) $(TESTOBJS)
- $(TEST_LINK_CMD) $(LDFLAGS) $(TESTOBJS) $(TEST_LINKS_TO) -o $(TEST)
- $(TEST_POST_LINK_CMD)
-
-%{if build_static_lib}
-
-%{out_dir}/%{static_lib_name}: $(LIBOBJS)
- $(AR) %{ar_options} $@ $(LIBOBJS)
-
-%{endif}
-
-%{if build_shared_lib}
-
-SONAME_ABI = %{soname_abi}
-DARWIN_COMPATIBILITY_VER = %{version_packed}.%{abi_rev}.0
-DARWIN_CURRENT_VER = %{version_packed}.%{abi_rev}.%{version_patch}
-
-%{out_dir}/%{shared_lib_name}: $(LIBOBJS)
- $(LIB_LINK_CMD) $(LDFLAGS) $(LIBOBJS) $(LIB_LINKS_TO) -o $@
- cd %{out_dir} && ln -fs %{shared_lib_name} %{soname_base}
- cd %{out_dir} && ln -fs %{shared_lib_name} %{soname_patch}
-
-%{endif}
-
-%{if build_fuzzers}
-
-# Fuzzer build commands
-
-FUZZER_LINK_CMD = %{fuzzer_link_cmd}
-FUZZER_LINKS_TO = %{link_to_botan} $(LIB_LINKS_TO) %{fuzzer_libs}
-FUZZER_FLAGS = $(LANG_FLAGS) $(CXXFLAGS) $(WARN_FLAGS)
-
-%{fuzzer_build_cmds}
-
-FUZZERS=%{fuzzer_bin}
-
-fuzzers: libs $(FUZZERS)
-
-fuzzer_corpus:
- git clone --depth=1 https://github.com/randombit/crypto-corpus.git fuzzer_corpus
-
-fuzzer_corpus_zip: fuzzer_corpus
- ./src/scripts/create_corpus_zip.py fuzzer_corpus %{fuzzobj_dir}
-
-%{endif}
diff --git a/src/build-data/makefile/header.in b/src/build-data/makefile/header.in
deleted file mode 100644
index 95f39aca5..000000000
--- a/src/build-data/makefile/header.in
+++ /dev/null
@@ -1,57 +0,0 @@
-# Paths to relevant programs
-
-CXX = %{cxx} %{cxx_abi_flags}
-LINKER = %{linker}
-AR = %{ar_command}
-PYTHON_EXE = %{python_exe}
-
-# Compiler Flags
-
-LANG_FLAGS = %{cc_lang_flags}
-CXXFLAGS = %{cc_compile_flags}
-WARN_FLAGS = %{cc_warning_flags}
-SO_OBJ_FLAGS = %{shared_flags}
-
-LIB_LINK_CMD = %{lib_link_cmd}
-CLI_LINK_CMD = %{cli_link_cmd}
-TEST_LINK_CMD = %{test_link_cmd}
-
-LIB_LINKS_TO = %{link_to}
-CLI_LINKS_TO = %{link_to_botan} $(LIB_LINKS_TO)
-TEST_LINKS_TO = %{link_to_botan} $(LIB_LINKS_TO)
-
-LIB_FLAGS = $(SO_OBJ_FLAGS) $(LANG_FLAGS) $(CXXFLAGS) $(WARN_FLAGS)
-CLI_FLAGS = $(LANG_FLAGS) $(CXXFLAGS) $(WARN_FLAGS)
-TEST_FLAGS = $(LANG_FLAGS) $(CXXFLAGS) $(WARN_FLAGS)
-
-SCRIPTS_DIR = %{scripts_dir}
-INSTALLED_LIB_DIR = %{prefix}/%{libdir}
-
-CLI_POST_LINK_CMD = %{cli_post_link_cmd}
-TEST_POST_LINK_CMD = %{test_post_link_cmd}
-
-# The primary target
-all: libs cli tests
-
-# Executable targets
-CLI = %{cli_exe}
-TEST = %{test_exe}
-LIBRARIES = %{library_targets}
-
-cli: $(CLI)
-tests: $(TEST)
-libs: $(LIBRARIES)
-
-# Misc targets
-
-clean:
- $(PYTHON_EXE) $(SCRIPTS_DIR)/cleanup.py --build-dir="%{build_dir}"
-
-distclean:
- $(PYTHON_EXE) $(SCRIPTS_DIR)/cleanup.py --build-dir="%{build_dir}" --distclean
-
-install: $(CLI) docs
- $(PYTHON_EXE) $(SCRIPTS_DIR)/install.py --prefix=%{prefix} --build-dir="%{build_dir}" --bindir=%{bindir} --libdir=%{libdir} --docdir=%{docdir} --includedir=%{includedir}
-
-docs:
-%{build_doc_commands}
diff --git a/src/build-data/makefile/nmake.in b/src/build-data/makefile/nmake.in
deleted file mode 100644
index dbd1a5af7..000000000
--- a/src/build-data/makefile/nmake.in
+++ /dev/null
@@ -1,42 +0,0 @@
-%{header_in}
-
-# Object Files
-LIBOBJS = %{lib_objs}
-
-CLIOBJS = %{cli_objs}
-
-TESTOBJS = %{test_objs}
-
-# Build Commands
-%{lib_build_cmds}
-
-%{cli_build_cmds}
-
-%{test_build_cmds}
-
-# LIB_FILENAME is always the .lib file, that is either a static lib or a
-# by-product of the DLL creation used to link the DLL into applications
-LIB_FILENAME = %{out_dir}/%{static_lib_name}
-
-# Link Commands
-$(CLI): $(LIBRARIES) $(CLIOBJS)
- $(CLI_LINK_CMD) /OUT:$@ $(CLIOBJS) $(LIB_FILENAME) $(CLI_LINKS_TO)
- $(CLI_POST_LINK_CMD)
-
-$(TEST): $(LIBRARIES) $(TESTOBJS)
- $(TEST_LINK_CMD) /OUT:$@ $(TESTOBJS) $(LIB_FILENAME) $(TEST_LINKS_TO)
- $(TEST_POST_LINK_CMD)
-
-%{if build_shared_lib}
-
-%{out_dir}/%{shared_lib_name}: $(LIBOBJS)
- $(LIB_LINK_CMD) /OUT:$@ $(LIBOBJS) $(LIB_LINKS_TO)
-
-%{endif}
-
-%{if build_static_lib}
-
-%{out_dir}/%{static_lib_name}: $(LIBOBJS)
- $(AR) %{ar_options} /OUT:$@ $(LIBOBJS)
-
-%{endif}
diff --git a/src/build-data/os/darwin.txt b/src/build-data/os/darwin.txt
index 78ad4a948..4c8ba2c47 100644
--- a/src/build-data/os/darwin.txt
+++ b/src/build-data/os/darwin.txt
@@ -4,6 +4,8 @@ soname_pattern_base "libbotan-{version_major}.dylib"
soname_pattern_abi "libbotan-{version_major}.{abi_rev}.dylib"
soname_pattern_patch "libbotan-{version_major}.{abi_rev}.{version_minor}.{version_patch}.dylib"
+so_post_link_command "install_name_tool -change '$(INSTALLED_LIB_DIR)/{soname_abi}' '@executable_path/{soname_abi}' $@"
+
doc_dir doc
<target_features>