Skip to content
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

Fortran fixes #108

Merged
merged 4 commits into from
Nov 16, 2017
Merged

Fortran fixes #108

merged 4 commits into from
Nov 16, 2017

Conversation

zbeekman
Copy link
Contributor

@zbeekman zbeekman commented Oct 29, 2017

  • Fixes BLT breaks simple Fortran w/ CMake 3.8 #105
    • CXX must be enabled earlier if ENABLE_GTEST is set, otherwise a CMake error occurs
  • Fixes Why are you adding -ffree-form (GFortran) #106
    • An option was added to allow users to specify FIXED, FREE or INFER for FORTRAN_FORMAT. Defaults to FREE: This is the old behavior for backwards compatibility. Setting FREE or FIXED cause CMAKE_Fortran_SOURCE to be set accordingly, setting INFER causes CMAKE_Fortran_SOURCE to NOT get set, so that the compiler handles detection of FREE vs FIXED source. Most compilers do this via the filename extension:
      • .f or .F: FIXED source formatting is assumed
      • .f90 or .F90: FREE source formatting is assumed
  • Allows user to not need to specify ENABLE_FORTRAN because this will default to TRUE IFF Fortran is detected already by CMake. (Query ENABLED_LANGUAGES global property.) Users will enable Fortran via project() command by default most of the time, and having to do this again for BLT is redundant and annoying, and unconventional/un-idiomatic.

@zbeekman
Copy link
Contributor Author

Let me know if you want me to cleanup the commits so that my "bug fix" commits are in the commits that introduced the issue. I'm happy to perform an interactive rebase to squash the commits so that each one is an atomic set of self-consistent changes (which they are save for removing IN_LIST (eef788c) and fixing set_property() (8fda969).

@zbeekman
Copy link
Contributor Author

I'm also thinking of stealing #99 and including the fix here and also setting up some dependent option logic (#107)

Copy link
Member

@kennyweiss kennyweiss left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the contribution @zbeekman

elseif(FORTRAN_FORMAT MATCHES INFER)
message(STATUS "Fortran source formatting not set---the compiler may infer this from each source file")
else()
message(ERROR
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think ERROR is a valid keyword here.
We typically use FATAL_ERROR for this kind of message.
See: https://cmake.org/cmake/help/v3.8/command/message.html

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're totally right, my apologies.

@@ -53,8 +53,14 @@ option(ENABLE_COVERAGE "Enables code coverage support" OFF)
################################
# Build Options
################################
get_property(_languages GLOBAL PROPERTY ENABLED_LANGUAGES)
if(_languages MATCHES "Fortran")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think ENABLED_LANGUAGES is a list -- https://cmake.org/cmake/help/v3.8/prop_gbl/ENABLED_LANGUAGES.html#prop_gbl:ENABLED_LANGUAGES

Does this only work if Fortran is the only enabled language?
What if multiple languages are enabled?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since one of our core macros already uses if( ... IN_LIST ...) (see the blt_setup_target macro), I think it is safe to say that blt already requires cmake 3.3 or higher.

We should probably note this in our documentation, add a check in SetupBLT and set policy CMP0057 appropriately.

See: https://stackoverflow.com/questions/23323147/best-way-to-check-with-cmake-whether-list-containts-a-specific-entry for some other options for checking if an item is in a list.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, ENABLED_LANGUAGES IS a list.

Fortunately MATCHES takes a regex so this check just looks for Fortran any where in the "list" (i.e. string with semicolons in it)

I noticed you were using IN_LIST, but I didn't see any calls to deal with CMP0057. I think it would be wise/safe to set CMP0057 to NEW.

I agree, IN_LIST is a much better solution.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To further elaborate, IN_LIST was causing CI failures because, AFAICT, CMP0057 was not set anywhere. My preference would be to set CMP0057 to NEW and switch back to IN_LIST (revert eef788c)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I created issue #109 about the required version of cmake and the CMP0057 issue.

SetupBLT.cmake Outdated
@@ -82,6 +82,13 @@ if (NOT BLT_LOADED)
endif()

################################
# Enable CXX required by GTEST
################################
if(ENABLE_GTEST)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure about this one.

I think we'd probably want the logic to go the other way.
I.e. rather than enabling CXX when GTEST is on, it should be a config error if GTEST is on when CXX is not available, and there should be an appropriate error message.
(Although, perhaps this could be valid for C projects that want to use gtest?)

Can others please weigh in here?

Copy link
Contributor Author

@zbeekman zbeekman Oct 30, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will note that testing C with GTest is perfectly valid/reasonable. I was tempted to implement it the way you are suggesting, but I didn't want to cause unexpected behavior (i.e. this will break backwards compatibility if people rely on GTest for C codes and haven't been explicitly enabling it)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was this brought on by an error you encountered?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it was this: #105

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@white238 yes #105. If you create a C or Fortran only minimal project CMake (at least the latest the latest stable version) throws an error. It’s possible it could be a CMake bug. I didn’t localize it beyond enabling gtest

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry coming in to this at the end due to a vacation (Disneyland was fun as always). This looks great.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like @kennyweiss -- I would prefer we add an error message if ENABLE_GTEST is on, but CXX isn't enabled.

(one that gives folks a chance to know whats wrong vs any cmake error they will encounter otherwise)

Even though you can use gtest for testing c, it's a c++ framework and folks are going to have to use a c++ compiler to compile tests.

@@ -93,6 +99,10 @@ if( NOT ( ( BLT_CXX_STD STREQUAL "c++98" )
Valid Options are ( c++98, c++11, c++14 )")
endif()

set(FORTRAN_FORMAT FREE CACHE STRING
"Fortran source formatting: FREE (default), FIXED, or INFER")
set_property(CACHE FORTRAN_FORMAT PROPERTY STRINGS FREE FIXED INFER)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How often do we expect users to want to explicitly set this option?
Should this be marked as an advanced cache variable?

Copy link
Contributor Author

@zbeekman zbeekman Oct 30, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was surprised and confused that you were setting FREE for everything, and others may have a similar experience. Marking as advanced may delay the resolution of peoples' issues... just food for thought. Personally I think INFER should be the default, but it's your project, so I'll defer to your preferences.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After an internal (offline) discussion, we're leaning towards making INFER the default, and projects that want to change this default can explicitly set the desired behavior.

This seems likely to lead to fewer surprises for fortran projects.

If the default is INFER, would it make sense for FORTRAN_FORMAT to be marked as advanced?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it could go either way.

I personally tend to reserve advanced CMake options for ones targeting the
project’s developers most of the time, or ones that are blatantly
experimental or dangerous (like in source builds). Basically anything where
a particular user requested some non standard functionality etc.

In this vein I’m inclined to default any options that a project provides to
non-advanced. In my mind, advanced says “you’re on your own if you mess with
this and we cannot envision a justifiable reason for doing so.” In
practice, however, I find most of the time users don’t even know about
ccmake or cmake-gui and therefore advanced vs normal is of very little
impact.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After reviewing -- I still feel we should simply remove all of the logic related to this and let folks using
BLT set CMAKE_Fortran_FORMAT (or the related source properties) as they see fit in their project.

Adding the option is another thing to explain and support vs standard CMake, which in this case is very straight forward.

Again, sorry for the extra effort, but not having it means we save on docs, maintenance, testing, etc in the long run.

@kennyweiss @white238, what do you think?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The benefit of keeping it is that the code is already written and it would make it easy for people setting up a fortran code to know about this distinction.

The downside is having to describe/maintain it, and the added complexity of additional configuration options.

I'm ok with removing this feature.

@zbeekman
Copy link
Contributor Author

@kennyweiss Since you're waiting on input from colleagues I won't do any major rebasing to cleanup the commits.

I'll fix the message(ERROR ... problem and wait for further direction.

@zbeekman
Copy link
Contributor Author

zbeekman commented Oct 30, 2017

I'm going to force push some cleaned up commits to my fork. This will update some of the diffs here and cause some of the commentary to go away. If you want me to undo that, just let me know, I've saved a local branch to restore it from.

EDIT: It seems Github has gotten smarter about inline comments/reviews since I last tried that.

@zbeekman
Copy link
Contributor Author

Please let me know if there's anything else I can do to help get this PR to a state where you would be willing to incorporate some or all of the proposed changes. If there are issues with a smaller set of the changes I can factor the PR into smaller one. Your wish is my command! (At least as far as this PR goes)

@zbeekman
Copy link
Contributor Author

zbeekman commented Oct 31, 2017 via email

@white238
Copy link
Member

This looks good, I'll admit I am not great with Fortran so any improvements from a person more knowledgeable than me is always welcome.

@zbeekman
Copy link
Contributor Author

zbeekman commented Oct 31, 2017

Here is a summary of issues that need to be decided on to merge this PR. If you are happy with the way things are you can check the checkbox, or edit the comment and add your GH name saying so for the purposes of internal discussions. If you check the checkbox I will make the appropriate change and push up to this PR

I'm happy to help out a little bit since resolving this will let me use BLT in a project that I am working on that requires porting from Makefiles/autotools. I can let it sit too, but I want to make sure that anything I can address gets addressed as quickly as it is feasible to do so.

@cyrush cyrush self-requested a review November 3, 2017 23:43
@@ -93,6 +99,10 @@ if( NOT ( ( BLT_CXX_STD STREQUAL "c++98" )
Valid Options are ( c++98, c++11, c++14 )")
endif()

set(FORTRAN_FORMAT FREE CACHE STRING
"Fortran source formatting: FREE (default), FIXED, or INFER")
set_property(CACHE FORTRAN_FORMAT PROPERTY STRINGS FREE FIXED INFER)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After reviewing -- I still feel we should simply remove all of the logic related to this and let folks using
BLT set CMAKE_Fortran_FORMAT (or the related source properties) as they see fit in their project.

Adding the option is another thing to explain and support vs standard CMake, which in this case is very straight forward.

Again, sorry for the extra effort, but not having it means we save on docs, maintenance, testing, etc in the long run.

@kennyweiss @white238, what do you think?

option(ENABLE_COPY_HEADERS "Copy headers to build directory" OFF)
option(ENABLE_FORTRAN "Enables Fortran compiler support" OFF)
option(ENABLE_FORTRAN "Enables Fortran compiler support" ${_fortran_already_enabled})
option(ENABLE_SHARED_LIBS "Enables shared libraries." OFF)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 for ENABLE_FORTRAN defaulting to on when folks already enabled fortran in the project stmt - Thanks for this change!

SetupBLT.cmake Outdated
@@ -82,6 +82,13 @@ if (NOT BLT_LOADED)
endif()

################################
# Enable CXX required by GTEST
################################
if(ENABLE_GTEST)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like @kennyweiss -- I would prefer we add an error message if ENABLE_GTEST is on, but CXX isn't enabled.

(one that gives folks a chance to know whats wrong vs any cmake error they will encounter otherwise)

Even though you can use gtest for testing c, it's a c++ framework and folks are going to have to use a c++ compiler to compile tests.

@white238
Copy link
Member

white238 commented Nov 4, 2017

I agree with @cyrush on the Fortran format... and with the gtest/CXX isssue. If we just turn on the CXX language it means they probably didn't define CMAKE_CXX_COMPILER.

@kennyweiss
Copy link
Member

Thanks @cyrush
Ok, so, to summarize:

  • It is a configuration error when ENABLE_GTEST = ON and CXX is not one of the project languages. We need a clear check / error message for this case.
  • Leave _languages MATCHES "Fortran". We will upgrade to if( ... IN_LIST ... ) when dealing with Minimum cmake version for blt #109
  • Remove FREE_FORM option from BLT. User codes that want this feature will have to explicity set this outside BLT

Does this work for everyone?

@cyrush
Copy link
Member

cyrush commented Nov 6, 2017

@kennyweiss , yes sounds good to me.

@zbeekman
Copy link
Contributor Author

zbeekman commented Nov 6, 2017 via email

@kennyweiss
Copy link
Member

@zbeekman -- are you planning to work on the requested changes, or would you like us to take care of it?

@zbeekman
Copy link
Contributor Author

zbeekman commented Nov 10, 2017 via email

@cyrush
Copy link
Member

cyrush commented Nov 10, 2017

@zbeekman, want to sync up at SC (I'll be there Sun - Wed)?

@zbeekman
Copy link
Contributor Author

zbeekman commented Nov 10, 2017 via email

@cyrush
Copy link
Member

cyrush commented Nov 10, 2017

@zbeekman sounds good, I'll ping you via email!

@kennyweiss
Copy link
Member

Thanks @zbeekman -- no rush at all, just wanted to follow up.

@zbeekman zbeekman force-pushed the Fortran-Fixes branch 3 times, most recently from 0c01317 to c8d2bde Compare November 15, 2017 22:49
@zbeekman
Copy link
Contributor Author

It looks like the FRUIT smoke tests fail w/ GFortran due to the .f file extension. I'll include a fix.

@zbeekman
Copy link
Contributor Author

Can I just rename blt_fruit_smoke.f to blt_fruit_smoke.f90?

I think that should work for 90% of compilers. This would be the more canonical Fortran convention, rather than explicitly setting free-form source properties in CMake.

@kennyweiss
Copy link
Member

@zbeekman -- I am fine with the file extension change for this test.

A different strategy would be to set the free-form flag for the fruit smoke test
(with a one-line comment in the cmake file about why you're doing that).

@zbeekman
Copy link
Contributor Author

@kennyweiss yes, I know, but IMO, there are a set of four file extensions allowable for Fortran files (other than include files...that's less clear):

  • .f: Fixed form, no preprocessing macros
  • .F: Fixed form, preprocessing required
  • .f90: Any free form Fortran source file, no preprocessing macros
  • .F90: Any free form Fortran, preprocessing required

@zbeekman
Copy link
Contributor Author

zbeekman commented Nov 15, 2017

gah, my gtest fix is broken, stand by...

EDIT: Issue found. I had a typo. I rebased to cleanup the commits and forced pushed to update.

Assuming all tests pass, then I think this is good to merge from my perspective.

 - If GTest is enabled without CXX we throw a `FATAL_ERROR` and explain to the
   user that enabling CXX is a hard requirement for using GTest.
 - Fixes LLNL#105
 - If user explicitly enables Fortran via `project()` or `enable_language()`
   they should not have to reenable it again.
 - Fixes LLNL#106
 - Users should explicitly set the `CMAKE_Fortran_FORMAT` vaiable for
   the project themselves, or set the target property as appropriate.
 - Move `blt_fruit_smoke.f` to `blt_fruit_smoke.f90`
@cyrush
Copy link
Member

cyrush commented Nov 16, 2017

@zbeekman renaming sounds like the best solution

Copy link
Member

@cyrush cyrush left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, thanks for the changes!

@cyrush cyrush merged commit a647ccd into LLNL:master Nov 16, 2017
@zbeekman zbeekman deleted the Fortran-Fixes branch November 28, 2017 20:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants