configure: improve cross-compilation detection#524
Conversation
|
I just realised that the whole commit message should be written imperatively, not just the commit title or first sentence of commit comment. |
No, background information may follow. Your message here really isn't too bad and it's an improvement on previous commit messages. However, it could be improved:
(This is nothing to do with commit messages per se - it's just better writing).
This is basically saying the same thing, a third time - I don't think it's necessary.
This is background info and in general the style used in commit messages is to start a new paragraph for the background information. You should read through the existing commit messages to get a sense for this. Here are some recent examples: And See the general structure?
This is explaining what the change does at the code level. It doesn't make sense at the abstract level of the commit message (why should we unset the variable? we could also just flag "not a cross-build" internally in some other way).
If the point is that the new behaviour is consistent with autotools, then it's better to say that directly rather than force the reader to make that connection themselves (even if it's fairly simple, there's no reason not to state your point explicitly). |
|
Sorry for delay, I got sick. I'm better now.
I added the first sentence after my comment. It wasn't there and I added it without thinking twice because I wanted to rewrite it after I set the PR to draft. Thanks for the suggestion. Yes, It's better.
Yes. I need to get better in breaking down text to sections to understand them better.
Yes. That's better to explicitly state that point. |
I think you're misinterpreting what I said. I'm not saying the solution is wrong.
That's ok as a solution, but, I think the comment doesn't explain that very well. It doesn't say where the change is, it doesn't really explain how the solution works; you have to look at the code to make sense of it. |
|
To explain more:
We don't need to unset the variable. That's the solution you have chosen. And, it didn't explain how that fixes the issue. What was written was:
it doesn't say how we "use" $CXX_FOR_BUILD for detecting a cross build, and it doesn't say how/why unsetting the variable alters the result of that detection. For example it doesn't explain the variable is unset just before the check for whether the $CXX_FOR_BUILD is set or not (which is used to detect a cross build). That's so easy to say and makes it so much clearer. |
|
I'm still alive and I will fix the mentioned things once the situation gets better. |
No worries, Mobin. I'm aware of the situation. Stay safe. |
bfa8560 to
27cfb8d
Compare
|
I cleaned up both commit message and code comments explaining the change, to be more clear and to respect the context of each other. The commit message doesn't mention variables anymore because it doesn't make sense to talk about it in the context of commit message. In the other hand, code comments now focus on variables which make sense in the context of the code. Also the commit message is separated into three sections to be consistent with style of other commits. |
27cfb8d to
65340b0
Compare
|
Hey Mobin, welcome back! The commit message is better, thanks. I do still have a few minor concerns about this PR:
|
Thanks! I missed the project so much.
OK.
I didn't account for that. I think the problem here is that it should also check for *_FOR_BUILD variables because they affect the build environment and make a difference between host and build machine. I think this addresses your concern about the new behaviour. I try to think about all scenarios that make this check fail to correctly identify a native-build if there are any except the case you mentioned.
I will rewrite it to improve it. |
|
Hi @mobin-2008 , I'd really like you to finish this before opening any other pull requests please. I've already invested review time into it, I don't want that wasted, and this has taken too long for a small change (I know you've had a lot going on, but still, this should be finished before moving on to other things). The grammar in comments doesn't have to be perfect but you should make sure comments are accurate, clear, and contain appropriate details. You should also switch to comparing each of the *_FOR_BUILD variables as you suggested in your last comment. That's not much to do, there's no reason not to just finish this off. Thanks. |
Ok. I'm on it. |
65340b0 to
f8fbd82
Compare
|
I tested it with cports building and it correctly assumes the build is native because of equal environment for both specified compilers. Also I think configure should always write |
davmac314
left a comment
There was a problem hiding this comment.
Other than the specific comments, I think this also needs documentation to be updated.
| ## Assume the build is native if both $CXX and $CXX_FOR_BUILD and their respective flags have the | ||
| ## same value and unset CXX_FOR_BUILD if that is the case |
There was a problem hiding this comment.
The comment isn't very clear; it doesn't explain the connection between assuming the build is native and unsetting CXX_FOR_BUILD. I already made a very similar comment about this in the previous iteration:
it doesn't say how we "use" $CXX_FOR_BUILD for detecting a cross build, and it doesn't say how/why unsetting the variable alters the result of that detection. For example it doesn't explain the variable is unset just before the check for whether the $CXX_FOR_BUILD is set or not (which is used to detect a cross build). That's so easy to say and makes it so much clearer.
The text "their respective flags" is also vague (who is the "they" corresponding to "their"?), it would be better to be more specific.
| FULL_CXXFLAGS="${CXXFLAGS:-}" | ||
| FULL_LDFLAGS="${LDFLAGS:-}" | ||
| if [ -n "${CXXFLAGS_EXTRA:-}" ]; then | ||
| if [ -n "${CXXFLAGS:-}" ]; then | ||
| FULL_CXXFLAGS="$CXXFLAGS $CXXFLAGS_EXTRA" | ||
| else | ||
| FULL_CXXFLAGS="$CXXFLAGS_EXTRA" | ||
| fi | ||
| fi | ||
| if [ -n "${LDFLAGS_EXTRA:-}" ]; then | ||
| if [ -n "${LDFLAGS:-}" ]; then | ||
| FULL_LDFLAGS="$LDFLAGS $LDFLAGS_EXTRA" | ||
| else | ||
| FULL_LDFLAGS="$LDFLAGS_EXTRA" | ||
| fi | ||
| fi | ||
| if [ "$FULL_CXXFLAGS" = "${CXXFLAGS_FOR_BUILD:-}" ] && \ | ||
| [ "$FULL_LDFLAGS" = "${LDFLAGS_FOR_BUILD:-}" ]; then | ||
| unset CXX_FOR_BUILD | ||
| fi | ||
| unset FULL_CXXFLAGS | ||
| unset FULL_LDFLAGS |
There was a problem hiding this comment.
I have a few thoughts about the approach here. I guess you try to derive the full set of flags that will be used for regular compilation (i.e. both from CXXCFLAGS and CXXFLAGS_EXTRA) and compare with the flags for build (CXXFLAGS_FOR_BUILD ) to check whether the compiler flags that will ultimately be used for building application code and host code are the same (a brief comment to explain this would have been good, but that might be moot, as per following).
Mainly, I think this is too complex. We are anyway taking a heuristic approach (if flags differ we don't know for sure if it is or isn't a cross-build) and having overcomplicated heuristics isn't worth it. Some ideas for simplifying it:
First, the point of setting CXXFLAGS_EXTRA is to use the automatically-derived (default) flags for building application code (and add some additional, i.e. EXTRA, flags). Someone using this functionality is unlikely to go to the trouble of then specifying the exact same set of flags in CXXFLAGS_FOR_BUILD. So, it doesn't make a lot of sense to me to even consider CXXFLAGS_EXTRA in this equation, or if you do it should be more along the lines of "if CXXFLAGS_EXTRA is set, assume it might be setting compilation target and so it may be a cross-build".
Second, building for a different target can't be done by changing only the link stage. So I don't think there's much point doing the LDFLAGS comparison.
There was a problem hiding this comment.
So, it doesn't make a lot of sense to me to even consider CXXFLAGS_EXTRA
In a similar vein, it doesn't make much sense to compare a configure-determined CXXFLAGS value with the CXXFLAGS_FOR_BUILD value. If the user didn't set CXXFLAGS and didn't set CXXFLAGS_FOR_BUILD, should they really be considered different?
There was a problem hiding this comment.
First, the point of setting CXXFLAGS_EXTRA is to use the automatically-derived (default) flags for building application code (and add some additional, i.e. EXTRA, flags). Someone using this functionality is unlikely to go to the trouble of then specifying the exact same set of flags in CXXFLAGS_FOR_BUILD.
And I'm not assuming that. My case for such logic is this:
./configure CXX="clang++" CXX_FOR_BUILD="clang++" CXXFLAGS_EXTRA="--target=aarch64-linux-gnu"This logic is there to detect any difference between host compiler and build compiler and CXXFLAGS_EXTRA would make a difference.
So, it doesn't make a lot of sense to me to even consider CXXFLAGS_EXTRA in this equation, or if you do it should be more along the lines of "if CXXFLAGS_EXTRA is set, assume it might be setting compilation target and so it may be a cross-build".
Now I'm thinking, yeah, that make sense to change it to "if CXXFLAGS_EXTRA is set, assume it might be setting compilation target and so it may be a cross-build".
In a similar vein, it doesn't make much sense to compare a configure-determined CXXFLAGS value with the CXXFLAGS_FOR_BUILD value. If the user didn't set CXXFLAGS and didn't set CXXFLAGS_FOR_BUILD, should they really be considered different?
No. They are not different and current logic just assume the build is native in that case because the CXXFLAGS is not utilized by configure at that point and the script never sets any *_FOR_BUILD variable so the check would be [ "" = "" ] && unset CXX_FOR_BUILD.
There was a problem hiding this comment.
Second, building for a different target can't be done by changing only the link stage. So I don't think there's much point doing the LDFLAGS comparison.
You're right, checking for compiler flags is enough.
There was a problem hiding this comment.
No. They are not different and current logic just assume the build is native in that case because the CXXFLAGS is not utilized by configure at that point
You are right, I thought this new logic was added after setting CXXFLAGS with default flags, but it is not.
Ok, but what other configurations did you test? Seems to me like: ... is going to be detected as a cross-build. In general it feels to me like you are now rushing this PR. Please don't; take the time to get it right.
I don't know what you mean. What issues will this avoid? |
No. ./configure CXX=gcc CXX_FOR_BUILD=gcc
Checking whether "gcc" is a working C++ compiler...
... Yes.
Checking whether "-std=c++11" is accepted by the compiler...
... Yes.
Checking whether "-Wall" is accepted by the compiler...
... Yes.
Checking whether "-Os" is accepted by the compiler...
... Yes.
Checking whether "-fno-plt" is accepted by the compiler...
... Yes.
Checking whether "-fno-rtti" is accepted by the compiler...
... Yes.
Checking whether "-fno-rtti" breaks exceptions...
... Yes. Disabling -fno-rtti
Checking whether "-flto" is accepted as an option for both compiling and linking...
... Yes.
Looking for "libcap" via pkg-config...
... Found.
Checking whether header "linux/ioprio.h" is available...
... Yes.
Checking whether "-fsanitize=address,undefined" is accepted as an option for both compiling and linking...
... Yes.
Creating mconfig...
... done.
Done!Because the check if [ "$FULL_CXXFLAGS" = "${CXXFLAGS_FOR_BUILD:-}" ]; then
unset CXX_FOR_BUILD
fiin this case will be if [ "" = "" ]; then
unset CXX_FOR_BUILD
fiwhich is true.
I'm trying to balance the correctness with time to avoid taking too much time for a simple PR.
The problem is that if I generate mconfig with: ./configure CXX=clang++ CXX_FOR_BUILD=clang++ CXXFLAGS="-std=c++11 --target=aarch64-linux-gnu"and then try to build the app, it will use |
Where? configure help message? |
Ok.
In this project correctness should be considered paramount. Not considering things properly is what leads to taking too much time for the PR. You also ignored one of my earlier review comments (which I pointed out again this review); this is not making things faster, it is making it slower, and is using up my time as well as yours.
I think they should be written to mconfig if they are set (even if set to empty string), not always. |
|
I'm happy for you to go ahead with changes to address the review. I think you may need to rebase onto main in order to pull the documentation (BUILD) changes so that you can updated them accordingly - please also go ahead and do that. |
BUILD. |
|
Ok. I will apply changes tomorrow (It's 2 AM in here) and also make sure to don't rush the process to avoid missing any review points and ensuring correctness. |
Thanks. It doesn't have to be done by tomorrow - get it right rather than do it quickly, please. |
b3e0f3c to
a091a33
Compare
|
I tested it with cports and other cases (
|
| ## Assume the build is native if both $CXX and $CXX_FOR_BUILD and their respective compiler flags | ||
| ## ($CXXFLAGS and $CXXFLAGS_FOR_BUILD) have the same value. | ||
| # The $CXX_FOR_BUILD is a variable set by the user to the compiler for the build machine. The | ||
| # configure script assume the build is cross when the $CXX_FOR_BUILD is set. The following check | ||
| # ensures that the host compiler and the build compiler are actually different and if they're not, | ||
| # unsets the $CXX_FOR_BUILD before all the checks for cross-compile along the script. |
There was a problem hiding this comment.
The textual content is now a lot better.
However:
The following check ensures that the host compiler and the build compiler are actually different and if they're not, unsets the $CXX_FOR_BUILD before all the checks for cross-compile along the script
This is not accurate. The check ensures that either the host compiler and the build compiler are different or that CXX_FOR_BUILD is unset.
Also, why is this mixing single and double hashes (# vs ##) at the beginning of the comment lines?
There was a problem hiding this comment.
Also, why is this mixing single and double hashes (
#vs##) at the beginning of the comment lines?
The idea I had for ## and # were that ## was the subject and # was the additional description.
There was a problem hiding this comment.
I see in other places ## seems to be used for a kind of brief heading describing what the following section of code does at a high level, but never with this much detail and never with # lines immediately underneath.
If you want to have a ## line similar to the others that's fine but it needs to be concise (like the others) and probably more of a general description than specifics about variable names and so on.
Here's an example of another ##-style heading already in the code:
## Verify PLATFORM value
It's true that this does mention a specific variable, but in a very general way. It doesn't go into detail about what "verify" means or how it is done; compare that to what is written (with ##) above.
Then, at least have a blank line or something between that heading and further description (with single '#'s), so that everything isn't jammed together. Paragraphs are supposed to be separated from any previous paragraph or heading (in all writing). Put the additional detail here in this part since that seems to be what it's intended for.
|
|
||
| If cross-compiling (i.e. specifying the CXX_FOR_BUILD variable), there are some additional | ||
| considerations regarding use of the "configure" script. | ||
| By specifying CXX_FOR_BUILD variable, the "configure" script will assume the build is cross, unless |
There was a problem hiding this comment.
"By specifying CXX_FOR_BUILD variable" -> "If the CXX_FOR_BUILD variable is specified"
"build is cross" -> "build is a cross-build".
| If cross-compiling, there are some additional considerations regarding use of the "configure" | ||
| script. |
There was a problem hiding this comment.
This paragraph can probably just go. It was introductory, but it's been moved past the point where it can serve as introduction.
| If all of these conditions are met, the "configure" script will instead assume that the build is | ||
| native in this case. |
There was a problem hiding this comment.
"in this case" is redundant, you have already specified the case for which this applicable (via "If all of these conditions are met").
|
Please go ahead and make changes to address the recent review comments (unless you need more discussion). |
a091a33 to
c758ecd
Compare
davmac314
left a comment
There was a problem hiding this comment.
Please make the changes requested.
| If the CXX_FOR_BUILD variable is specified, the "configure" script will assume the build is | ||
| cross-build, unless all of the following conditions are met: |
There was a problem hiding this comment.
"build is cross-build" -> "build is a cross-build"
You left out "a".
| esac | ||
| done | ||
|
|
||
| ## Verify the build is cross-build when CXX_FOR_BUILD is specificed |
| ## Verify the build is cross-build when CXX_FOR_BUILD is specificed | ||
| if [ -n "${CXX_FOR_BUILD:-}" ]; then | ||
| # The $CXX_FOR_BUILD is a variable set by the user to the compiler for the build machine. | ||
| # The configure script assume the build is cross-build when the $CXX_FOR_BUILD is set. The |
There was a problem hiding this comment.
You can't say "the configure script assume the build is cross-build when the $CXX_FOR_BUILD is set." and then specifically say how the following check (which is within the configure script!) doesn't assume that at all. This comment contradicts itself. Qualify the first sentence so that it's accurate and is not being contradicted: "Later parts of this script assume that ...".
It's also clearer if you don't talk about "the configure script" in comments within the configure script, as if it is referring to something else. You can say "this script" instead of "the configure script".
c758ecd to
0d7728e
Compare
davmac314
left a comment
There was a problem hiding this comment.
I'll approve this shortly, but please see the notes I've added and make those changes before merging.
| # The point of setting $CXXFLAGS_EXTRA is to use the automatically-derived (default) flags | ||
| # for building application code (and add some additional, i.e. EXTRA, flags). Someone using | ||
| # this functionality is unlikely to go to the trouble of then specifying the exact same set | ||
| # of flags in $CXXFLAGS_FOR_BUILD, therefor when $CXXFLAGS_EXTRA is set, assume it's always | ||
| # different from $CXXFLAGS_FOR_BUILD. |
There was a problem hiding this comment.
Could you remove this, actually? It was never meant to be a code comment when I wrote it (as a review comment), the tone is all wrong and it's not really all that clear without the rest of the review context.
| If cross-compiling (i.e. specifying the CXX_FOR_BUILD variable), there are some additional | ||
| considerations regarding use of the "configure" script. | ||
| If the CXX_FOR_BUILD variable is specified, the "configure" script will assume the build is | ||
| a cross-build, unless all of the following conditions are met: |
There was a problem hiding this comment.
Lines should extend as close to 100 columns as possible so "a" should be on the previous line.
davmac314
left a comment
There was a problem hiding this comment.
Please make fixes as per comments before merging.
The issue here I think is that, the moment I push these new changes into my branch, GitHub will invalidate your approval on this PR. |
Assume the build is native if the compiler for the host and the build machine are the same and both use the same flags. It is fairly common to set both variables to the same compiler with same flags in a native build. For example, cbuild (Chimera Linux package builder) defines both the host and the build compiler and their respective compiler flags, regardless of native or cross build. Also, that assumption in this case is consistent with GNU autotools behaviour.
0d7728e to
d2c9a7a
Compare
Assume the build as native if both $CXX and $CXX_FOR_BUILD have the same value. If the compiler for the host and the build machine are the same, it's a native build. There is a chance that the user may set both $CXX and $CXX_FOR_BUILD to the same compiler. For example, cbuild (Chimera Linux package builder) sets both variables regardless of native or cross build and because we use $CXX_FOR_BUILD for detecting cross build, we should unset that variable in this case.
Also, GNU autotools detects this case and assumes the build as native.