Skip to content

Commit

Permalink
Merge branch 'develop' into Add-New-Zone-Ideal-Loads-Output-Variables
Browse files Browse the repository at this point in the history
  • Loading branch information
jmythms committed Sep 29, 2020
2 parents 908ab51 + 30df506 commit 6b7b538
Show file tree
Hide file tree
Showing 1,189 changed files with 73,749 additions and 65,045 deletions.
8 changes: 2 additions & 6 deletions .github/workflows/mac_release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,9 @@ jobs:
mac_release:
runs-on: macos-10.15

strategy:
matrix:
osx_target: ["10.13", "10.15"]

steps:
- uses: actions/checkout@v2

#
- name: Set up Python 3.7
uses: actions/setup-python@v2
with:
Expand Down Expand Up @@ -48,7 +44,7 @@ jobs:
- name: Configure CMake
shell: bash
working-directory: ${{runner.workspace}}/EnergyPlus/build
run: cmake -DCMAKE_BUILD_TYPE=Release -DLINK_WITH_PYTHON=ON -DCMAKE_OSX_DEPLOYMENT_TARGET=${{ matrix.osx_target }} -DDOCUMENTATION_BUILD="BuildWithAll" -DTEX_INTERACTION="batchmode" -DBUILD_FORTRAN=ON -DBUILD_PACKAGE:BOOL=ON ..
run: cmake -DCMAKE_BUILD_TYPE=Release -DLINK_WITH_PYTHON=ON -DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 -DDOCUMENTATION_BUILD="BuildWithAll" -DTEX_INTERACTION="batchmode" -DBUILD_FORTRAN=ON -DBUILD_PACKAGE:BOOL=ON ..

- name: Build Package
working-directory: ${{runner.workspace}}/EnergyPlus/build
Expand Down
Binary file modified bin/EP-Launch/EP-Launch.exe
Binary file not shown.
7 changes: 6 additions & 1 deletion cmake/PythonCopyStandardLib.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,19 @@
# an easy way is to find the __init__ file for a known standard lib package and go two parents up
# should result in something like `/usr/lib/python3.7`

# this script must be called with a target directory to copy this into
# this script must be called with two args:
# 1 - the path to the EnergyPlus executable in the install tree, which is be used to determine where to copy the library
# since this is in the install tree, you'll need to use a cmake generator expression
# 2 - name of the folder to create to store the copied in python standard library, usually python_standard_library
import ctypes
from distutils.dir_util import copy_tree
import os
import platform
import shutil
import sys

print("PYTHON: Copying standard library files")

if len(sys.argv) == 3:
exe_path = sys.argv[1]
folder_name = sys.argv[2]
Expand Down
78 changes: 50 additions & 28 deletions cmake/PythonFixUpOnMac.cmake
Original file line number Diff line number Diff line change
@@ -1,53 +1,75 @@
# Only call this for APPLE
# set RESOLVED_PYTHON_LIB, and EXECUTABLE_PATH when calling
# set RESOLVED_PYTHON_LIB, EPLUS_DYNAMIC_LIB_NAME and EXECUTABLE_PATH when calling

# when the build first completes, prior to fixing anything up, the executables have dependencies that need to be fixed up
# when the build first completes, during packaging, the executables have dependencies that need to be fixed up
# energyplus, the core binary
# it has a dependency on the libenergyplusapi dynamic library, and it will be looking for it at: @rpath/libenergyplusapi.X.Y.Z.dylib
# it will need to be changed to look for the api lib at @executable_path/libenergyplusapi.X.Y.Z.dylib
# this is handled separately
# libenergyplusapi, the dynamic library
# now that we have detached the python dynamic lib into a lazy load, this won't have anything to change, w00t!
# libpythonwrapper, the python wrapper/interface
# this library was added to detach energyplus from a hard dependency on the python dylib, and e+ now instead lazy loads this interface
# this wrapper depends on the core python dll at /some/path/to/Python.framework/Versions/3.7/{SomePythonLibName}
# however it also has a dependency on the core python dll at /some/path/to/Python.framework/Versions/3.7/{SomePythonLibName}
# we are packing up the python lib with E+, so it just needs to look for it at @executable_path/{SomePythonLibName}
# we also change the -id from @rpath/libpythonwrapper to @executable_path/libpythonwrapper
# Python, the actual python library
# using @executable_path here works well because when you are running energyplus(.exe), it should definitely just be from the run directory
# libenergyplusapi, the dynamic library
# like the exe, this depends on the core python dll at /some/path/to/Python.framework/Versions/3.7/{SomePythonLibName}
# we are packing up the python lib with E+, so it will technically live at @executable_path/{SomePythonLibName}, HOWEVER
# with the API work, the client can now call this dynamic library from other locations, where the calling executable is not in the E+ dir
# because of this, we are not using @executable_path/, but instead @loader_path, which will allow the nested python dylib
# to be found relative to the file loading it, which is this libenergyplusapi dynamic library
# Python, or libpython3.7m.dylib, or whatever - the actual python library
# this is the main python dynamic library that we distribute with e+
# we just need to change the -id from /some/path/to/Python.framework/Versions/3.7/{SomePythonLibName} to @executable_path/{SomePythonLibName}
# we change the -id from /some/path/to/Python.framework/Versions/3.7/{SomePythonLibName} to @executable_path/{SomePythonLibName}
# there is also a dependency on libintl.8.dylib which we fix up using the @loader_path approach

# TODO: Look at whether we could do @loader_path across the board to make these things much easier, maybe even just put @loader_path inside fixup_executable...
# TODO: Look at whether we actually need to set any of these blob's IDs; I'm not sure

# the paths are dynamic, so we need to build out all these change commands somewhat dynamically
# the only thing we have to go on is that we know:
# EXECUTABLE_PATH points to the current energyplus executable, and
# EPLUS_DYNAMIC_LIB_NAME is the file _name_ of the E+ API dylib (libenergyplusapi.X.Y.Z.dylib)
# RESOLVED_PYTHON_LIB points to the Python dynamic library

message("Fixing up Python Dependencies on Mac")
# message("RESOLVED PYTHON LIB: ${RESOLVED_PYTHON_LIB}")
message("PYTHON: Fixing up Python Dependencies on Mac")

# get the python lib filename
get_filename_component(PYTHON_LIB_FILENAME ${RESOLVED_PYTHON_LIB} NAME)
set(WRAPPER_FILE_NAME "libpythonwrapper.dylib")

# derive a few paths from the args passed in
get_filename_component(BASE_PATH ${EXECUTABLE_PATH} DIRECTORY)
set(LOCAL_PYTHON_LIBRARY "${BASE_PATH}/${PYTHON_LIB_FILENAME}")
set(PYTHON_WRAPPER_PATH "${BASE_PATH}/${WRAPPER_FILE_NAME}")
include(GetPrerequisites)

# message("LOCAL PYTHON LIBRARY: ${LOCAL_PYTHON_LIBRARY}")
# message("PYTHON WRAPPER PATH: ${PYTHON_WRAPPER_PATH}")
# derive a few terms from the args passed in
get_filename_component(PYTHON_LIB_FILENAME ${RESOLVED_PYTHON_LIB} NAME) # Python dylib file name
get_filename_component(BASE_PATH ${EXECUTABLE_PATH} DIRECTORY) # Path to the staged install tree in the build directory
set(LOCAL_PYTHON_LIBRARY "${BASE_PATH}/${PYTHON_LIB_FILENAME}") # Path to the Python dylib once copied into the install tree
set(ENERGYPLUS_API_PATH "${BASE_PATH}/${EPLUS_DYNAMIC_LIB_NAME}") # Path to the EnergyPlus dylib once copied into the install tree

# now just fix up the pieces we need to fix up
# the Python dylib apparently needed chmod +x at one point; # TODO: Try without this...
execute_process(COMMAND "chmod" "+w" "${LOCAL_PYTHON_LIBRARY}")

# then we set the ID on the Python dylib; # TODO: Try without this...
execute_process(COMMAND "install_name_tool" -id "@executable_path/${PYTHON_LIB_FILENAME}" "${LOCAL_PYTHON_LIBRARY}")
execute_process(COMMAND "install_name_tool" -id "@executable_path/${WRAPPER_FILE_NAME}" "${PYTHON_WRAPPER_PATH}")

# changing the libpythonwrapper Python prereq is a bit funny - we should search to get the exact string original
include(GetPrerequisites)
get_prerequisites("${PYTHON_WRAPPER_PATH}" PREREQUISITES 1 1 "" "")
# for the energyplus executable, just find the python dynamic library right next to it for sure
get_prerequisites("${EXECUTABLE_PATH}" PREREQUISITES 1 1 "" "")
foreach(PREREQ IN LISTS PREREQUISITES)
string(FIND "${PREREQ}" "${PYTHON_LIB_FILENAME}" PYTHON_IN_PREREQ)
if (NOT PYTHON_IN_PREREQ EQUAL -1)
execute_process(COMMAND "install_name_tool" -change "${PREREQ}" "@executable_path/${PYTHON_LIB_FILENAME}" "${PYTHON_WRAPPER_PATH}")
execute_process(COMMAND "install_name_tool" -change "${PREREQ}" "@executable_path/${PYTHON_LIB_FILENAME}" "${EXECUTABLE_PATH}")
endif()
endforeach()

# for the energyplus dylib, search for the python dylib prereq and change it to use @loader_path
get_prerequisites("${ENERGYPLUS_API_PATH}" PREREQUISITES 1 1 "" "")
foreach(PREREQ IN LISTS PREREQUISITES)
string(FIND "${PREREQ}" "${PYTHON_LIB_FILENAME}" PYTHON_IN_PREREQ)
if (NOT PYTHON_IN_PREREQ EQUAL -1)
execute_process(COMMAND "install_name_tool" -change "${PREREQ}" "@loader_path/${PYTHON_LIB_FILENAME}" "${ENERGYPLUS_API_PATH}")
endif()
endforeach()

# and the python library itself depends on a gettext lib (on our github actions builds anyway)
get_prerequisites("${LOCAL_PYTHON_LIBRARY}" PREREQUISITES 1 1 "" "")
foreach(PREREQ IN LISTS PREREQUISITES)
string(FIND "${PREREQ}" "libint" LIBINT_IN_PREREQ)
if (NOT LIBINT_IN_PREREQ EQUAL -1)
get_filename_component(LIB_INT_FILENAME ${PREREQ} NAME)
execute_process(COMMAND "${CMAKE_COMMAND}" -E copy "${PREREQ}" "${BASE_PATH}")
execute_process(COMMAND "install_name_tool" -change "${PREREQ}" "@loader_path/${LIB_INT_FILENAME}" "${LOCAL_PYTHON_LIBRARY}")
endif()
endforeach()
29 changes: 7 additions & 22 deletions cmake/PythonGetLibAndLinkUp.cmake
Original file line number Diff line number Diff line change
@@ -1,29 +1,14 @@
# Linking up to Python is not necessarily complex, but it is tricky to get right.
# Our goal here is to provide a fully packaged embedded Python interpreter and Python 3.5+ standard library
# This file's job is to copy over the required Python DLL and fixup the EnergyPlus binary on Mac to find on it locally
# To accomplish this, we need to know which EnergyPlus binary to fixup, and some info about the Python library
# The steps we follow are:
# Use finder to get Python library and include paths
# Add Python include path to include_directories
# Link E+ against Python library
# At install time find the Python library and copy it into the install tree
# At install time find the Python site-packages folder and copy it into the install tree
# In E+ need to setPath before calling PyInitialize so we can get all the site_packages
# Now we should also consider whether we want to try to build *without* Python
# I can imagine doing this on the 32 bit Windows, for example.
# And this would *not* exclude calling E+ as a library from C or Python -- it would just disable Python Plugins
# If we don't do this then we'll need to install both 32 and 64 bit Python on Windows and get the right one
# During build time, the built EnergyPlus executable tree stays linked against the Python wherever it is installed on the system.
# During install time, this file is used to copy over the Python dynamic library into the install tree
# In addition, on Windows, the proper Python filename is fixed up prior to copying.

# We need to connect up to python for a couple reasons.
# 1. We use Python in our testing scripts
# 2. We link EnergyPlus up against the Python lib for Python Plugin work
# 3. We use Python for our Python API runs
# We are going to create a local virtual environment that is portable so we can package it and install it
# Users will not need to have Python installed, and it will come with a Python.exe and a Pip.exe for installing libraries
# Prior to calling, set:
# RESOLVED_PYTHON_LIB to the Python library file found through CMake's usual finder
# EXECUTABLE_PATH which will be the executable directory in the INSTALL TREE, thus you need to use a generator expression

# set RESOLVED_PYTHON_LIB, and EXECUTABLE_PATH when calling

message("Collecting Python dynamic library")
message("PYTHON: Collecting Python dynamic library")

# get some path info things
get_filename_component(BASE_PATH ${EXECUTABLE_PATH} DIRECTORY)
Expand Down
Loading

3 comments on commit 6b7b538

@nrel-bot-2c
Copy link

Choose a reason for hiding this comment

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

Add-New-Zone-Ideal-Loads-Output-Variables (jmythms) - x86_64-Linux-Ubuntu-18.04-gcc-7.5: OK (2948 of 3024 tests passed, 0 test warnings)

Messages:\n

  • 76 tests had: AUD diffs.
  • 73 tests had: RDD diffs.

Failures:\n

regression Test Summary

  • Passed: 661
  • Failed: 76

Build Badge Test Badge

@nrel-bot-2c
Copy link

Choose a reason for hiding this comment

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

Add-New-Zone-Ideal-Loads-Output-Variables (jmythms) - x86_64-Linux-Ubuntu-18.04-gcc-7.5-UnitTestsCoverage-Debug: OK (1548 of 1548 tests passed, 0 test warnings)

Build Badge Test Badge Coverage Badge

@nrel-bot-2c
Copy link

Choose a reason for hiding this comment

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

Add-New-Zone-Ideal-Loads-Output-Variables (jmythms) - x86_64-Linux-Ubuntu-18.04-gcc-7.5-IntegrationCoverage-Debug: OK (721 of 722 tests passed, 0 test warnings)

Failures:\n

integration Test Summary

  • Passed: 721
  • Timeout: 1

Build Badge Test Badge Coverage Badge

Please sign in to comment.