-
Notifications
You must be signed in to change notification settings - Fork 711
Fix linking issue with cxx-options
and cxx-sources
fields in non-library components
#5315
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
Conversation
RE tests, could one go in cabal-testsuite? Seems like you have a suitable sketch of a test-case in the issue that can more or less be translated directly. |
Cabal/Distribution/Simple/GHC.hs
Outdated
ghcOptFPic = toFlag True, | ||
ghcOptDynLinkMode = toFlag GhcDynamicOnly, | ||
ghcOptObjSuffix = toFlag "dyn_o" | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this whitespace change noise be removed, please?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whitespace removed.
++ "flag." | ||
"'"++prefix++": -O[n]' is generally not needed. When building with " | ||
++ " optimisations Cabal automatically adds '-O2' for "++label++" code. " | ||
++ "Setting it yourself interferes with the --disable-optimization flag." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cabal/tests/ParserTests
has some tests for warnings from check
, which you might want to add to.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added the following test files to ensure that the check provides correct warnings:
regressions/cc-options-with-optimization
regressions/cxx-options-with-optimization
Cabal/Distribution/Simple/GHC.hs
Outdated
@@ -1088,15 +1088,15 @@ gbuildSources :: Verbosity | |||
-> Version -- ^ specVersion | |||
-> FilePath | |||
-> GBuildMode | |||
-> IO ([FilePath], [FilePath], [ModuleName]) | |||
-> IO ([FilePath], [FilePath], [FilePath], [ModuleName]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it worth defining a data type for these, rather than relying on 4-tuples and remembering which FilePath
is which?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a labeled "record" in place of the 4-tuple.
when needsRecomp $ | ||
runGhcProg opts | ||
| filename <- cxxSrcs ] | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This might be personal taste, but is this nicer than for_ cxxSrcs $ \ filename -> ...
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, never mind. I see it's patterned on the code below. Best to keep them obviously parallel.
@@ -449,7 +449,7 @@ allSourcesBuildInfo verbosity bi pps modules = do | |||
in findFileWithExtension fileExts (hsSourceDirs bi) file | |||
| module_ <- modules ++ otherModules bi ] | |||
|
|||
return $ sources ++ catMaybes bootFiles ++ cSources bi ++ jsSources bi | |||
return $ sources ++ catMaybes bootFiles ++ cSources bi ++ cxxSources bi ++ jsSources bi |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cabal-testsuite/PackageTests/SDlist
has a test for sdist
. Might be worth adding to?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see the test cases in cabal-testsuite
directory, but I'm unsure how to invoke these tests. Is there a script to run through these?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I figured out how to run the tests locally.
Cabal/ChangeLog.md
Outdated
separate compilation of C++ source files to correctly build and link | ||
non-library components (#5309). | ||
* Reduced warnings generated by hsc2hs and c2hs when `cxx-options` field | ||
is present in a omponent. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo: s/omponent/component/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice catch, I corrected this.
There seem to be some genuine failures on AppVeyor. |
@@ -657,14 +657,14 @@ buildOrReplLib forRepl verbosity numJobs pkg_descr lbi lib clbi = do | |||
info verbosity "Building C++ Sources..." | |||
sequence_ | |||
[ do let baseCxxOpts = Internal.componentCxxGhcOptions verbosity implInfo | |||
lbi libBi clbi libTargetDir filename | |||
lbi libBi clbi libTargetDir filename |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still a spurious whitespace change here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't we want the arguments to be vertically aligned the the function call above?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, sure. So long as it's deliberate and not just random reformatting noise.
} | ||
ghcOptProfilingMode = toFlag True, | ||
ghcOptObjSuffix = toFlag "p_o" | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And more whitespace changes here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same deliberate, vertical alignment with this whitespace.
I added this test case, Unfortunately, I'm getting this error when running the test suite:
I'm not sure how to correct this? Any pointers @quasicomputational @23Skidoo |
I ran into that issue before; I think that it's a bug in |
@quasicomputational I changed
I'm guessing |
Oh, run it (e: it = |
This seems to be happening on |
@23Skidoo I believe I corrected issues related to the IPIs test cases. |
@quasicomputational, could you help me diagnose this error message? I'm still trying to add a stripped down version of this repository as a test case for the The error message is a bit incomprehensible to me. It seems to me that it's trying to install
|
I fixed the For example, this Travis job failure doesn't look like something that needs to be fixed. It appears to be failing because files were added between two git commits. However, it kooks like most of the failures involve authentication failures via SSH keys. |
Travis is broken at the moment, yeah. Should be fixed soon and then you can rebase on master and try again. A couple of things:
|
@quasicomputational I'll try and cut down the test suite a bit, but it does need to do a lot of things to test that the functionality is correct:
Since all the I'll look into squashing some of the commits, but after I try and truncate the C & C++ code. |
Stubbing out the functionality is what I had in mind. Thanks a bunch! |
HEAD has the Travis stuff fixed now, so you probably want to rebase. Edit: Oh, it's been merged in. Carry on! |
The test suite has been pared down, however the run time didn't noticeably decrease. The All of the test suite tinkering commits have been squashed together. @quasicomputational, I believe that this is ready to be merged. Should we wait until Travis is fixed on |
Cabal/Distribution/Simple/GHC.hs
Outdated
filter (/= mainModName) (exeModules exe)) | ||
return BuildSources { | ||
cSourcesFiles = cSources bnfo, | ||
cxxSourceFiles = cxxSources bnfo, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code formatting here: equals aren't aligned.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
Cabal/Distribution/Simple/GHC.hs
Outdated
else return (main : cSources bnfo, [], exeModules exe) | ||
else return BuildSources { | ||
cSourcesFiles = cSources bnfo, | ||
cxxSourceFiles = cxxSources bnfo, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also not aligned here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
Cabal/Distribution/Simple/GHC.hs
Outdated
} | ||
else return BuildSources { | ||
cSourcesFiles = main : cSources bnfo, | ||
cxxSourceFiles = main : cxxSources bnfo, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These two lines don't look right. What if the main module is C++? (Are C++ main modules even supported?) What if it's in the C++-incompatible part of C? Don't we need to be able to tell between a C++ and a C module and then only add it to the appropriate list?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wasn't anticipating supporting a C++ main module, only linking to C++ though the C ABI.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK. So the main module shouldn't be added to cxxSourceFiles
at all? This is definitely worth having a test for, with a main module that uses some C++-breaking construct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried to address this by checking if main
is a C++ source. If it is neither a Haskell source nor a C++ source file, then we default to C. Defaulting to C (appeared) to have been the previous functionality.
Cabal/Distribution/Simple/GHC.hs
Outdated
opts | needProfiling = profCxxOpts | ||
| needDynamic = sharedCxxOpts | ||
| otherwise = vanillaCxxOpts | ||
odir = fromFlag (ghcOptObjDir opts) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Possibly stupid question: the C++ and C files are sharing an output directory here, so collisions are a possibility. Is that user error if it happens, or do we need to guard against it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would assume that collisions here is a user error. I also don't want the added complexity of a separate object directory for each (currently 2) FFI language.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK. Might be an idea to warn about it (either here or in cabal check
or both), but that can be done later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a TODO for this potential collision issue. Should I create a GitHub issue for this so that it is visibly tracked.
-- interface and wrapped in a C source file. | ||
-- Therefore we do not supply C++ flags | ||
-- because there will not be C++ sources | ||
{- ++ PD.cxxOptions bi -} ] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove the commented-out code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
@@ -525,7 +541,7 @@ getCppOptions bi lbi | |||
= platformDefines lbi | |||
++ cppOptions bi | |||
++ ["-I" ++ dir | dir <- PD.includeDirs bi] | |||
++ [opt | opt@('-':c:_) <- PD.ccOptions bi, c `elem` "DIU"] | |||
++ [opt | opt@('-':c:_) <- PD.ccOptions bi ++ PD.cxxOptions bi, c `elem` "DIU"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks a bit messy: what if the C and C++ files need different CPP options? But we're already muddling up C and CPPed Haskell, so I guess this isn't a huge problem.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have a vague recollection of something breaking without the cxx-options
being added here, but that was over a month ago so I don't recall exactly what it was.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It does look like it works at the moment for the common case, and without this change C++ CPP options won't be plumbed through at all. I think the ideal solution here would be to have separate getCppOptionsForHs
, getCppOptionsForCxx
, getCppOptionsForC
, etc functions, but, like I said, it's already a bit messy; I think it's sensible to leave that for later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that ideally this would be refactored out into separate functions.
However, I think leaving this for later would be best. I've already invested a lot of company time in this pull request and need to get back to implementing new features on our product.
I added a TODO above this function. Should I add a GitHub issue for this so that it is visibly tracked?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, that's fine. There's already a TODO about this, so let's open an issue and punt; it's evidently not causing anyone trouble today.
@@ -438,7 +445,8 @@ ppHsc2hs bi lbi clbi = | |||
++ [ "--cflag=" ++ opt | |||
| pkg <- pkgs | |||
, opt <- [ "-I" ++ opt | opt <- Installed.includeDirs pkg ] | |||
++ [ opt | opt <- Installed.ccOptions pkg ] ] | |||
++ [ opt | opt <- Installed.ccOptions pkg | |||
{- ++ Installed.cxxOptions pkg -} ] ] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Commented out code again.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
-- Therefore we do not supply C++ flags | ||
-- because there will not be C++ sources | ||
-- | ||
-- ++ Installed.cxxOptions pkg |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And another bit of commented out code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
Looks good to me. I've verified that the test case fails with cabal-install 2.2 and passes with this PR, and I don't see any potential show-stoppers. |
@quasicomputational, I merged upstream |
That test's flaky; I've seen it randomly fail before. I'm currently failing at getting it not to be skipped locally, but, if Travis comes back green-ish, it should be good to go. |
This is currently broken with: /usr/include/c++/5/bits/c++0x_warning.h:32:2: error: #error This file requires compiler and library support for the ISO C++ 2011 standard. This support must be enabled with the -std=c++11 or -std=gnu++11 compiler options. I thought this was fixed by haskell/cabal#4810 (which is in Cabal 2.2), but it might be broken because this: haskell/cabal#5315 (which is in is in Cabal 2.4, which isn't yet in LTS).
Using |
Standard checklist
[ci skip]
is used to avoid triggering the build bots.Changes
I have updated the
Cabal
library'scxx-options
andcxx-sources
fields to correctly link when building non-library components (benchmark
,executable
,test-suite
). This pull requests should resolve #5309 and complete the feature I (unknowingly) didn't fully implement in #4810 which partially resolved #3700.Specific fixes
The main culprit of the C++ object not being passed to the linker can be seen here.
I also removed the following warning when invoking
hsc2hs
while thecxx-options
field is present:Before we merge
I did not add any tests to the test suite. I looked through the
Cabal/test
and it wasn't immediately apparent where I would add tests for this functionality or what form the tests would take. However I think it would be prudent to add some tests for this functionality before we merge the pull request.Should the tests be added for
Cabal
the library orcabal-install
the executable?. I assumeCabal
, but I might be wrong.Should the tests be added in an existing module or a new module?
How do I add the new tests into the existing test suite for the Cabal.
I'd appreciate some direction on the testing front @23Skidoo, @amigalemming, @ezyang, @hvr, @quasicomputational.