Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Fix #8778 - FindPython in modern cmake and handle issue when LINK_WITH_PYTHON on windows with both Release/debug libraries #8832

Merged
merged 8 commits into from
Jul 1, 2021

Conversation

jmarrec
Copy link
Contributor

@jmarrec jmarrec commented Jun 18, 2021

Pull request overview

(This is the third version of this branch).

  • Fix LINK_WITH_PYTHON issue on windows #8778 -handle issue when LINK_WITH_PYTHON on windows with both Release/debug libraries
  • Use the modern cmake FindPython instead of the deprecated FindPythonInterp+FindPythonLibs
    • Previously the deprecated FindPythonInterp and FindPythonLibs where called at different points (toplevel CMakeLists.txt and src/EnergyPlus/CMakeLists.txt respectively), which in my case often resulted in different versions being picked up (I have a 3.6 system python on Ubuntu, and 4 different pyenv versions and several virtualenvs on top of these).
    • FindPythonInterp/FindPythonLibs were deprecated in favor of FindPython in CMake 3.12: https://cmake.org/cmake/help/latest/module/FindPythonInterp.html

This requires bumping the cmake_minimum_version to at least 3.12. Because of we're bumping, we're actually bumping to 3.16 here which adds PCH (precompiled headers) which is an option enabled by default now

option(ENABLE_PCH "Enable Precompiled Headers" ON)

target_precompile_headers was added in version 3.16: https://cmake.org/cmake/help/git-stage/command/target_precompile_headers.html

Pull Request Author

Add to this list or remove from it as applicable. This is a simple templated set of guidelines.

  • Title of PR should be user-synopsis style (clearly understandable in a standalone changelog context)
  • Label the PR with at least one of: Defect, Refactoring, NewFeature, Performance, and/or DoNoPublish
  • Pull requests that impact EnergyPlus code must also include unit tests to cover enhancement or defect repair
  • Author should provide a "walkthrough" of relevant code changes using a GitHub code review comment process
  • If any diffs are expected, author must demonstrate they are justified using plots and descriptions
  • If changes fix a defect, the fix should be demonstrated in plots and descriptions
  • If any defect files are updated to a more recent version, upload new versions here or on DevSupport
  • If IDD requires transition, transition source, rules, ExpandObjects, and IDFs must be updated, and add IDDChange label
  • If structural output changes, add to output rules file and add OutputChange label
  • If adding/removing any LaTeX docs or figures, update that document's CMakeLists file dependencies

Reviewer

This will not be exhaustively relevant to every PR.

  • Perform a Code Review on GitHub
  • If branch is behind develop, merge develop and build locally to check for side effects of the merge
  • If defect, verify by running develop branch and reproducing defect, then running PR and reproducing fix
  • If feature, test running new feature, try creative ways to break it
  • CI status: all green or justified
  • Check that performance is not impacted (CI Linux results include performance check)
  • Run Unit Test(s) locally
  • Check any new function arguments for performance impacts
  • Verify IDF naming conventions and styles, memos and notes and defaults
  • If new idf included, locally check the err file and other outputs

jmarrec added 4 commits June 18, 2021 11:13
A conversation with @Myoldmopar lead to this. I'm already bumping to 3.12, but 3.16 added Precompiled Headers (PCH) which is a significant speedup.
3.13 added target_link_options which is also handy.
@jmarrec jmarrec added the Defect Includes code to repair a defect in EnergyPlus label Jun 18, 2021
@jmarrec jmarrec requested a review from Myoldmopar June 18, 2021 09:19
@jmarrec jmarrec self-assigned this Jun 18, 2021
CMakeLists.txt Outdated
@@ -9,7 +9,7 @@ cmake_policy(SET CMP0048 NEW) # handling project_version_* variables

project(EnergyPlus)

cmake_minimum_required(VERSION 3.10)
cmake_minimum_required(VERSION 3.16)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

New Minimum version here to 3.16 for precompiled header support.

Comment on lines +157 to +162
# If LINK_WITH_PYTHON, also request the Development (libs) at the same time, to ensure consistent version between interpreter and Development
if(LINK_WITH_PYTHON)
find_package(Python 3.6 COMPONENTS Interpreter Development REQUIRED)
else()
find_package(Python 3.6 COMPONENTS Interpreter REQUIRED)
endif()
Copy link
Contributor Author

Choose a reason for hiding this comment

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

New way, find both components at the same time to ensure consistent versions

Copy link
Member

Choose a reason for hiding this comment

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

Love it!

@@ -270,7 +275,7 @@ endif()
add_subdirectory(idd)

execute_process(
COMMAND ${PYTHON_EXECUTABLE} "${PROJECT_SOURCE_DIR}/scripts/dev/generate_epJSON_schema/generate_epJSON_schema.py" "${PROJECT_SOURCE_DIR}"
COMMAND ${Python_EXECUTABLE} "${PROJECT_SOURCE_DIR}/scripts/dev/generate_epJSON_schema/generate_epJSON_schema.py" "${PROJECT_SOURCE_DIR}"
Copy link
Contributor Author

Choose a reason for hiding this comment

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

PYTHON_XXXX variables were retained for backward compatibility, but the official casing is Programname_XXX so Python_XXX to be consitent with the rest of cmake.

Copy link
Member

Choose a reason for hiding this comment

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

OK, makes sense. I'm pretty sure if anyone ever adds another call from Python they'll end up just copying whatever we have in place anyway.

@@ -1,12 +1,12 @@
project(EnergyPlusDocs LANGUAGES NONE)

cmake_minimum_required(VERSION 3.5.1)
cmake_minimum_required(VERSION 3.12)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

In docs, we only need to bump to 3.12 for FindPython because PCH isn't in the mix... So I did 3.12 instead of 3.16, up for debate.

Copy link
Member

Choose a reason for hiding this comment

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

Hmmm...I'm not sure. I guess it's best to keep the minimum required to the minimum required for that specific project scope. So 3.12 makes sense for the new FindPython.

Comment on lines 885 to 902
# In case you have both release and debug Python libraries on your system, Python_LIBRARIES might be "optimized;C:/.../python38.lib;debug;C:/.../python38_d.lib"
# so it can't be used directly, we could use a generator expression to find the $<TARGET_FILE:Python::Python> library used and that'd point directly
# to the DLL. But it won't work nicely for the install(code ...) command below... so we do a hack, get the optimized one always...
list(LENGTH Python_LIBRARIES _LEN)
if (_LEN GREATER 1)
set (_Python_DOING_RELEASE FALSE)
foreach(_currentArg ${Python_LIBRARIES})
message("_currentArg=${_currentArg}")
if ("x${_currentArg}" STREQUAL "xoptimized")
set(_Python_DOING_RELEASE TRUE)
elseif(_Python_DOING_RELEASE)
get_filename_component(RESOLVED_PYTHON_LIBRARY "${_currentArg}" REALPATH)
break()
endif()
endforeach()
# else()
# No-op, already done above
endif()
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Actual fix for #8778 when you have both Release and Debug python libs on your system.

@Myoldmopar
Copy link
Member

Well would you look at that!? Happy on all 3 platforms! This is good stuff.

Copy link
Member

@Myoldmopar Myoldmopar left a comment

Choose a reason for hiding this comment

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

I feel confident with all of this but I do want some clarification on the loop for finding the right version of Python. If we can get this resolved I believe this is good to go.

@@ -9,7 +9,7 @@ cmake_policy(SET CMP0048 NEW) # handling project_version_* variables

project(EnergyPlus)

cmake_minimum_required(VERSION 3.10)
cmake_minimum_required(VERSION 3.17)
Copy link
Member

Choose a reason for hiding this comment

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

Great! This makes the whole PCH thing feel much better too.

Comment on lines +157 to +162
# If LINK_WITH_PYTHON, also request the Development (libs) at the same time, to ensure consistent version between interpreter and Development
if(LINK_WITH_PYTHON)
find_package(Python 3.6 COMPONENTS Interpreter Development REQUIRED)
else()
find_package(Python 3.6 COMPONENTS Interpreter REQUIRED)
endif()
Copy link
Member

Choose a reason for hiding this comment

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

Love it!

@@ -270,7 +275,7 @@ endif()
add_subdirectory(idd)

execute_process(
COMMAND ${PYTHON_EXECUTABLE} "${PROJECT_SOURCE_DIR}/scripts/dev/generate_epJSON_schema/generate_epJSON_schema.py" "${PROJECT_SOURCE_DIR}"
COMMAND ${Python_EXECUTABLE} "${PROJECT_SOURCE_DIR}/scripts/dev/generate_epJSON_schema/generate_epJSON_schema.py" "${PROJECT_SOURCE_DIR}"
Copy link
Member

Choose a reason for hiding this comment

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

OK, makes sense. I'm pretty sure if anyone ever adds another call from Python they'll end up just copying whatever we have in place anyway.

@@ -1,12 +1,12 @@
project(EnergyPlusDocs LANGUAGES NONE)

cmake_minimum_required(VERSION 3.5.1)
cmake_minimum_required(VERSION 3.12)
Copy link
Member

Choose a reason for hiding this comment

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

Hmmm...I'm not sure. I guess it's best to keep the minimum required to the minimum required for that specific project scope. So 3.12 makes sense for the new FindPython.

elseif(_Python_DOING_RELEASE)
get_filename_component(RESOLVED_PYTHON_LIBRARY "${_currentArg}" REALPATH)
break()
endif()
Copy link
Member

Choose a reason for hiding this comment

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

Is there a code path here missing in case you don't find the optimized keyword? I know it would be random but just trying to make it as robust as possible. Maybe if the finder finds multiple debug build versions on one system?? Would it be debug;C:/Something.lib;debug;C:/SomethingElse.lib?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@Myoldmopar AFAIK you cannot install only debug libraries, and optimized are always installed. Either you have both and it's guaranteed you'll have optimized, or you have only one item. See source code here: https://gitlab.kitware.com/cmake/cmake/blob/fc762735196dbbc983dfac2145cd7afd7892bf54/Modules/FindPython/Support.cmake#L63-91

Copy link
Member

Choose a reason for hiding this comment

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

OK thanks.

@Myoldmopar
Copy link
Member

No point waiting on this to go in. This is a great set of changes. Much more reliable finding! Thanks @jmarrec !

@Myoldmopar Myoldmopar merged commit 4708fe7 into develop Jul 1, 2021
@Myoldmopar Myoldmopar deleted the FindPython branch July 1, 2021 02:57
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
Defect Includes code to repair a defect in EnergyPlus
Projects
None yet
Development

Successfully merging this pull request may close these issues.

LINK_WITH_PYTHON issue on windows
6 participants