diff --git a/haskell/haskell.bzl b/haskell/haskell.bzl index 5d912a86db..a9d0d84fd6 100644 --- a/haskell/haskell.bzl +++ b/haskell/haskell.bzl @@ -119,6 +119,9 @@ def _mk_binary_rule(**kwargs): allow_single_file = FileType([".hs", ".hsc", ".lhs"]), doc = "File containing `Main` module (deprecated).", ), + version = attr.string( + doc = "Executable version. Used as metadata.", + ), _dummy_static_lib = attr.label( default = Label("@io_tweag_rules_haskell//haskell:dummy_static_lib"), allow_single_file = True, diff --git a/haskell/lint.bzl b/haskell/lint.bzl index 88acfc3882..8d44223f99 100644 --- a/haskell/lint.bzl +++ b/haskell/lint.bzl @@ -53,7 +53,7 @@ def _haskell_lint_aspect_impl(target, ctx): "--make", ]) - args.add(expose_packages(build_info, lib_info, use_direct = False, use_my_pkg_id = None)) + args.add(expose_packages(build_info, lib_info, use_direct = False, use_my_pkg_id = None, version = ctx.rule.attr.version)) sources = set.to_list( lib_info.source_files if lib_info != None else bin_info.source_files, diff --git a/haskell/private/actions/compile.bzl b/haskell/private/actions/compile.bzl index 35868db7e9..9d4f0adf3f 100644 --- a/haskell/private/actions/compile.bzl +++ b/haskell/private/actions/compile.bzl @@ -65,7 +65,7 @@ def _process_hsc_file(hs, cc, hsc_file): return hs_out, idir -def _compilation_defaults(hs, cc, java, dep_info, srcs, import_dir_map, extra_srcs, compiler_flags, with_profiling, my_pkg_id = None): +def _compilation_defaults(hs, cc, java, dep_info, srcs, import_dir_map, extra_srcs, compiler_flags, with_profiling, my_pkg_id, version): """Declare default compilation targets and create default compiler arguments. Returns: @@ -123,7 +123,7 @@ def _compilation_defaults(hs, cc, java, dep_info, srcs, import_dir_map, extra_sr if hs.toolchain.is_darwin: ghc_args += ["-optl-Wl,-dead_strip_dylibs"] - ghc_args.extend(expose_packages(dep_info, lib_info = None, use_direct = True, use_my_pkg_id = my_pkg_id)) + ghc_args.extend(expose_packages(dep_info, lib_info = None, use_direct = True, use_my_pkg_id = my_pkg_id, version = version)) header_files = [] boot_files = [] @@ -263,7 +263,7 @@ def _compilation_defaults(hs, cc, java, dep_info, srcs, import_dir_map, extra_sr ), ) -def compile_binary(hs, cc, java, dep_info, srcs, ls_modules, import_dir_map, extra_srcs, compiler_flags, with_profiling, main_function): +def compile_binary(hs, cc, java, dep_info, srcs, ls_modules, import_dir_map, extra_srcs, compiler_flags, with_profiling, main_function, version): """Compile a Haskell target into object files suitable for linking. Returns: @@ -273,7 +273,7 @@ def compile_binary(hs, cc, java, dep_info, srcs, ls_modules, import_dir_map, ext modules: set of module names source_files: set of Haskell source files """ - c = _compilation_defaults(hs, cc, java, dep_info, srcs, import_dir_map, extra_srcs, compiler_flags, with_profiling) + c = _compilation_defaults(hs, cc, java, dep_info, srcs, import_dir_map, extra_srcs, compiler_flags, with_profiling, my_pkg_id = None, version = version) c.args.add(["-main-is", main_function]) hs.toolchain.actions.run_ghc( @@ -329,7 +329,7 @@ def compile_library(hs, cc, java, dep_info, srcs, ls_modules, other_modules, exp source_files: set of Haskell module files import_dirs: import directories that should make all modules visible (for GHCi) """ - c = _compilation_defaults(hs, cc, java, dep_info, srcs, import_dir_map, extra_srcs, compiler_flags, with_profiling, my_pkg_id = my_pkg_id) + c = _compilation_defaults(hs, cc, java, dep_info, srcs, import_dir_map, extra_srcs, compiler_flags, with_profiling, my_pkg_id = my_pkg_id, version = my_pkg_id.version) hs.toolchain.actions.run_ghc( hs, diff --git a/haskell/private/actions/link.bzl b/haskell/private/actions/link.bzl index 8107b52f3a..003f026053 100644 --- a/haskell/private/actions/link.bzl +++ b/haskell/private/actions/link.bzl @@ -84,7 +84,8 @@ def link_binary( compiler_flags, objects_dir, with_profiling, - dummy_static_lib): + dummy_static_lib, + version): """Link Haskell binary from static object files. Returns: @@ -132,7 +133,7 @@ def link_binary( # directly rather than doing multiple reversals with temporary # lists. - args.add(expose_packages(dep_info, lib_info = None, use_direct = False, use_my_pkg_id = None)) + args.add(expose_packages(dep_info, lib_info = None, use_direct = False, use_my_pkg_id = None, version = version)) _add_external_libraries(args, dep_info.external_libraries.values()) @@ -302,7 +303,13 @@ def link_library_dynamic(hs, cc, dep_info, extra_srcs, objects_dir, my_pkg_id): if hs.toolchain.is_darwin: args.add(["-optl-Wl,-dead_strip_dylibs"]) - args.add(expose_packages(dep_info, lib_info = None, use_direct = False, use_my_pkg_id = None)) + args.add(expose_packages( + dep_info, + lib_info = None, + use_direct = False, + use_my_pkg_id = None, + version = my_pkg_id.version if my_pkg_id else None, + )) _add_external_libraries(args, dep_info.external_libraries.values()) diff --git a/haskell/private/actions/repl.bzl b/haskell/private/actions/repl.bzl index dc5e6d20a3..2a4e49414d 100644 --- a/haskell/private/actions/repl.bzl +++ b/haskell/private/actions/repl.bzl @@ -33,6 +33,7 @@ def build_haskell_repl( build_info, output, package_caches, + version, lib_info = None, bin_info = None): """Build REPL script. @@ -52,7 +53,7 @@ def build_haskell_repl( None. """ - args = expose_packages(build_info, lib_info, use_direct = False, use_my_pkg_id = None) + args = expose_packages(build_info, lib_info, use_direct = False, use_my_pkg_id = None, version = version) if lib_info != None: for idir in set.to_list(lib_info.import_dirs): diff --git a/haskell/private/haskell_impl.bzl b/haskell/private/haskell_impl.bzl index 96ac8b81db..6f8b337048 100644 --- a/haskell/private/haskell_impl.bzl +++ b/haskell/private/haskell_impl.bzl @@ -77,6 +77,7 @@ use the 'haskell_import' rule instead. compiler_flags = ctx.attr.compiler_flags, with_profiling = False, main_function = ctx.attr.main_function, + version = ctx.attr.version, ) c_p = None @@ -100,6 +101,7 @@ use the 'haskell_import' rule instead. compiler_flags = ctx.attr.compiler_flags, with_profiling = True, main_function = ctx.attr.main_function, + version = ctx.attr.version, ) binary = link_binary( @@ -111,6 +113,7 @@ use the 'haskell_import' rule instead. c_p.objects_dir if with_profiling else c.objects_dir, with_profiling, ctx.file._dummy_static_lib, + version = ctx.attr.version, ) solibs = set.union( @@ -137,6 +140,7 @@ use the 'haskell_import' rule instead. repl_ghci_args = ctx.attr.repl_ghci_args, output = ctx.outputs.repl, package_caches = dep_info.package_caches, + version = ctx.attr.version, build_info = build_info, bin_info = bin_info, ) @@ -308,6 +312,7 @@ use the 'haskell_import' rule instead. compiler_flags = ctx.attr.compiler_flags, output = ctx.outputs.repl, package_caches = dep_info.package_caches, + version = ctx.attr.version, build_info = build_info, lib_info = lib_info, ) diff --git a/haskell/private/packages.bzl b/haskell/private/packages.bzl index 63d7e2b740..af992fa82f 100644 --- a/haskell/private/packages.bzl +++ b/haskell/private/packages.bzl @@ -2,12 +2,11 @@ load(":private/set.bzl", "set") -def expose_packages(build_info, lib_info, use_direct, use_my_pkg_id): +def expose_packages(build_info, lib_info, use_direct, use_my_pkg_id, version): """ Returns the list of command line argument which should be passed to GHC in order to enable haskell packages. """ - args = [ # In compile.bzl, we pass this just before all -package-id # arguments. Not doing so leads to bizarre compile-time failures. @@ -17,10 +16,20 @@ def expose_packages(build_info, lib_info, use_direct, use_my_pkg_id): "-hide-all-packages", ] - # Expose all prebuilt dependencies + has_version = version != None and version != "" + + if not has_version: + args.extend([ + # Macro version are disabled for all packages by default + # and enabled for package with version + # see https://github.com/tweag/rules_haskell/issues/414 + "-fno-version-macros", + ]) + + # Expose all prebuilt dependencies - # We have to remember to specify all (transitive) wired-in - # dependencies or we can't find objects for linking + # We have to remember to specify all (transitive) wired-in + # dependencies or we can't find objects for linking # XXX This should be really dep_info.direct_prebuilt_deps, but since we # cannot add prebuilt_dependencies to the "depends" field on package diff --git a/tests/package-name/BUILD b/tests/package-name/BUILD index d50a919c3d..6f92642322 100644 --- a/tests/package-name/BUILD +++ b/tests/package-name/BUILD @@ -20,6 +20,7 @@ haskell_test( name = "bin", size = "small", srcs = ["Main.hs"], + version = "0.0.0", # This flags triggers the `MIN_VERSION` macro generation deps = [ ":lib-a_Z", "//tests:base",