3232load (
3333    ":private/cc_libraries.bzl" ,
3434    "deps_HaskellCcLibrariesInfo" ,
35+     "get_cc_libraries" ,
3536    "get_ghci_library_files" ,
37+     "get_library_files" ,
3638    "haskell_cc_libraries_aspect" ,
3739)
3840
@@ -110,6 +112,9 @@ def _cabal_tool_flag(tool):
110112def  _binary_paths (binaries ):
111113    return  [binary .dirname  for  binary  in  binaries .to_list ()]
112114
115+ def  _concat (sequences ):
116+     return  [item  for  sequence  in  sequences  for  item  in  sequence ]
117+ 
113118def  _prepare_cabal_inputs (
114119        hs ,
115120        cc ,
@@ -139,7 +144,26 @@ def _prepare_cabal_inputs(
139144    # to add libraries and headers for direct C library dependencies to the 
140145    # command line. 
141146    direct_libs  =  get_ghci_library_files (hs , cc .cc_libraries_info , cc .cc_libraries )
142-     transitive_libs  =  get_ghci_library_files (hs , cc .cc_libraries_info , cc .transitive_libraries )
147+ 
148+     # The regular Haskell rules perform mostly static linking, i.e. where 
149+     # possible all C library dependencies are linked statically. Cabal has no 
150+     # such mode, and since we have to provide dynamic C libraries for 
151+     # compilation, they will also be used for linking. Hence, we need to add 
152+     # RUNPATH flags for all dynamic C library dependencies. 
153+     (_ , dynamic_libs ) =  get_library_files (
154+         hs ,
155+         cc .cc_libraries_info ,
156+         get_cc_libraries (cc .cc_libraries_info , cc .transitive_libraries ),
157+         dynamic  =  True ,
158+     )
159+ 
160+     # The regular Haskell rules have separate actions for linking and 
161+     # compilation to which we pass different sets of libraries as inputs. The 
162+     # Cabal rules, in contrast, only have a single action for compilation and 
163+     # linking, so we must provide both sets of libraries as inputs to the same 
164+     # action. 
165+     transitive_compile_libs  =  get_ghci_library_files (hs , cc .cc_libraries_info , cc .transitive_libraries )
166+     transitive_link_libs  =  _concat (get_library_files (hs , cc .cc_libraries_info , cc .transitive_libraries ))
143167    env  =  dict (hs .env )
144168    env ["PATH" ] =  join_path_list (hs , _binary_paths (tool_inputs ) +  posix .paths )
145169    if  hs .toolchain .is_darwin :
@@ -169,7 +193,7 @@ def _prepare_cabal_inputs(
169193                    keep_filename  =  False ,
170194                    prefix  =  relative_rpath_prefix (hs .toolchain .is_darwin ),
171195                )
172-                 for  lib  in  direct_libs 
196+                 for  lib  in  dynamic_libs 
173197            ],
174198            uniquify  =  True ,
175199        )
@@ -190,7 +214,8 @@ def _prepare_cabal_inputs(
190214            depset (cc .files ),
191215            package_databases ,
192216            transitive_headers ,
193-             depset (transitive_libs ),
217+             depset (transitive_compile_libs ),
218+             depset (transitive_link_libs ),
194219            dep_info .interface_dirs ,
195220            dep_info .static_libraries ,
196221            dep_info .dynamic_libraries ,
@@ -205,6 +230,7 @@ def _prepare_cabal_inputs(
205230        inputs  =  inputs ,
206231        input_manifests  =  input_manifests ,
207232        env  =  env ,
233+         runfiles  =  depset (direct  =  dynamic_libs ),
208234    )
209235
210236def  _haskell_cabal_library_impl (ctx ):
@@ -572,6 +598,7 @@ def _haskell_cabal_binary_impl(ctx):
572598        executable  =  binary ,
573599        runfiles  =  ctx .runfiles (
574600            files  =  [data_dir ],
601+             transitive_files  =  c .runfiles ,
575602            collect_default  =  True ,
576603        ),
577604    )
0 commit comments