-
Notifications
You must be signed in to change notification settings - Fork 49
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Track included files via TH's addDependentFile #153
base: master
Are you sure you want to change the base?
Conversation
Yeah, that's a red flag. IIRC we're already using a GHC api that's specifically about C/C++, so perhaps GHC itself is a better place to implement this. That way it works for all TH that generates such code. Having access to the flags, it could leverage the compiler flags that makefiles use for this purpose. That way it works for all compiler flags, as well as for transitive includes. I'd be ok with merging a workaround like this, if it has a comment referencing a GHC issue that describes the problem. |
@MathiasSven Thank you for creating this PR. |
It would still be a problem, this PR only addresses includes that are relative to the current file, so if you had a About the GHC issue, are you suggesting I open a GHC issue or is there one already on this topic? I am likely wrong on this, I didn't take much time to understand this library's internals, but doesn't it work by constructing an intermediate module that then contains all the foreign import calls? I don't think it is using any GHC API, (GHC is also a hidden module, and it doesn't look to be in the |
Build dependencies are generally an issue that build tools should look at. |
So, is it better to use this function only when users want to use it? |
I agree that this is beyond GHC's role, for that matter, I also think it might be beyond what one would expect from Cabal. Both Cabal and GHC don't do much with C/C++ files, they mostly relay information to the respective compilers. However, I think there could be some middle ground. Projects with more complex build steps may opt for more granular build systems, but given this library (as I see it) aims to simplify the process of FFI for the Haskell programmer, I think it would be fine to place some build responsibilities on it. If GHC exposed to TH more information about how it is being called, and specifically, how it calls the C/C++ compiler, we could both check all included directories, and also call
I could add a section to the documentation as part of the PR to clarify when a file would be tracked or not.
Unless you were working on both a shared library and Haskell simultaneously this issue should not really manifest itself, the main issue I think is if you are using |
So IIUC Cabal never tracks header dependencies? My use of
If some of the interactions are not supported, that's indicative of an architectural problem, and/or a bug that should be fixed. Nonetheless, I am ok with taking a pragmatic approach in this library, as Mathias suggests. |
I don't believe so, it will track the files you explicitly put in Going back to what can be done to fully fix this issue (at least without waiting on GHC/Cabal to implement a standardized of way of dealing with this), as I mentioned before there already is a "hack" that would give us all the information we needed: {-# LANGUAGE TemplateHaskell #-}
module Main where
import Language.Haskell.TH.Syntax
import GHC.Tc.Types
import GHC.Driver.Flags
import GHC.Settings
import GHC.Driver.Session
import Unsafe.Coerce
info = $( let runTcM :: TcM a -> Q a
runTcM action = Q (unsafeCoerce action)
in
do
dflags <- runTcM getDynFlags
root <- getPackageRoot
let ts = toolSettings dflags
lift
[ show $ includePaths dflags
, root
, toolSettings_pgm_cxx ts
, toolSettings_pgm_c ts
, fst $ toolSettings_pgm_P ts
]
)
main :: IO ()
main = putStrLn $ unlines info
@roberth Would your suggestion be to raise an issue on GHC about giving a non edit: |
Closes #152
Previously, files included via
C.include
would not be tracked by GHC, so changes made to saytest.h
would not recompile aFoo.hs
withC.include "test.h"
. If working with cabal, tracked files must be placed in cabal's top levelextra-source-files
stanza in order for this to be useful, more context given in the relevant issue.Possible outstanding issues:
The solution in this PR only applies to files that are referenced relative to the current file. That is, if one were to have this setup:
With a cabal file containing:
ghc-options: -threaded -I./cbits
While the usage of
C.include "test.h"
would still work, it would no longer be tracked. I can't think of any solution to this other than trying to access the GHC flags from within TH, which I have seen done, but seemed very hacky, usingunsafeCoerce
to get aTcM
from aQ
.Perhaps there is another principle approach that would make use of how the C preprocessor itself looks for files. As it stands, this PR also only applies to includes of the form
"..."
ignoring<...>
.