diff --git a/CMakeLists.txt b/CMakeLists.txt index 2416ac69d..fa97269db 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,13 @@ # "More Modern" CMake version cmake_minimum_required(VERSION 3.12) -set(CMAKE_PREFIX_PATH "/prefix") +# Hint: This can be set to enable custom find_package +# search paths, probably best to set it when configuring +# on the command line to cmake instead of setting it +# here. +###set(CMAKE_PREFIX_PATH "/prefix") + +project(OpenEXRMetaProject) # An "official" way to make this a super-project # basically overrides the find_package to not find anything @@ -13,70 +19,48 @@ macro(find_package) endif() endmacro() -enable_testing() - -add_subdirectory(IlmBase) -# TODO: -#add_subdirectory(PyIlmBase) -add_subdirectory(OpenEXR) -# TODO: -#add_subdirectory(OpenEXR_Viewers) - -#[==[ - -# Packages - -if (OPENEXR_BUILD_PYTHON_LIBS) - find_package(PythonLibs ${OPENEXR_PYTHON_MAJOR}.${OPENEXR_PYTHON_MINOR}) - if(NOT PythonLibs_FOUND) - message(WARNING "Make Python ${OPENEXR_PYTHON_MAJOR}.${OPENEXR_PYTHON_MINOR} available to CMake's search path, and re-run configuration") - message(FATAL_ERROR "Python is a required dependency when OPENEXR_BUILD_PYTHON_LIBS is set") - endif() - find_package(Boost) - # Boost.Python use a new versioning scheme starting with Boost 1.67 - if(Boost_VERSION VERSION_GREATER_EQUAL 106700) - find_package(Boost COMPONENTS python${OPENEXR_PYTHON_MAJOR}${OPENEXR_PYTHON_MINOR}) - if(NOT Boost_PYTHON${OPENEXR_PYTHON_MAJOR}${OPENEXR_PYTHON_MINOR}_FOUND) - message(WARNING "user provided Boost Python${OPENEXR_PYTHON_MAJOR}${OPENEXR_PYTHON_MINOR} was not found. Trying default path...") - set(FIND_DEFAULT_PYTHON TRUE) - endif() +# If you want to use ctest to configure, build and +# upload the results, cmake has builtin support for +# submitting to CDash, or any server who speaks the +# same protocol +# +# These settings will need to be set for your environment, +# and then a script such as the example in +# +# cmake/SampleCTestScript.cmake +# +# edited and placed into the CI system, then run: +# +# cmake -S cmake/SampleCTestScript.cmake +# +# [or whatever you name the file you edit] +# +#set(CTEST_PROJECT_NAME "OpenEXR") +#set(CTEST_NIGHTLY_START_TIME "01:01:01 UTC") +#set(CTEST_DROP_METHOD "http") # there are others... +#set(CTEST_DROP_SITE "open.cdash.org") +#set(CTEST_DROP_LOCATION "/submit.php?project=MyProject") +#set(CTEST_DROP_SITE_CDASH TRUE) - else() - # older Boost versions < 1.67 - if(OPENEXR_PYTHON_MAJOR VERSION_GREATER_EQUAL 3) - find_package(Boost COMPONENTS python${OPENEXR_PYTHON_MAJOR}) - if(NOT Boost_PYTHON${OPENEXR_PYTHON_MAJOR}_FOUND) - message(WARNING "user provided Boost Python${OPENEXR_PYTHON_MAJOR} was not found. Trying default path...") - set(FIND_DEFAULT_PYTHON TRUE) - endif() - else() - set(FIND_DEFAULT_PYTHON TRUE) - endif() - endif() +include(CTest) +if(BUILD_TESTING) + enable_testing() +endif() - if(FIND_DEFAULT_PYTHON) - find_package(Boost COMPONENTS python) - if(NOT Boost_PYTHON_FOUND) - message(WARNING "Make boost Python available to CMake's search path, and re-run configuration") - message(FATAL_ERROR "boost Python is a required dependency when OPENEXR_BUILD_PYTHON_LIBS is set") - endif() - endif() +# Include these two modules without enable/disable options +add_subdirectory(IlmBase) +add_subdirectory(OpenEXR) - find_package(NumPy) +# should this just be always on and we conditionally compile what +# is found and warn otherwise? or error out? +option(PYILMBASE_ENABLE "Enables configuration of the PyIlmBase module" ON) +if(PYILMBASE_ENABLE) + add_subdirectory(PyIlmBase) endif() -if(OPENEXR_BUILD_VIEWERS) - message(WARNING "Viewers are currently out of order. Building anyway") - SET (FLTK_SKIP_FLUID 1) - find_package(FLTK) - if(NOT FLTK_FOUND) - message(WARNING "FLTK not found, exrdisplay will not be built") - endif() - find_package(OpenGL) - if(NOT OpenGL_FOUND) - message(WARNING "OpenGL not found, exrdisplay will not be built") - endif() +option(OPENEXRVIEWERS_ENABLE "Enables configuration of the viewers module" OFF) +if(OPENEXRVIEWERS_ENABLE) +# TODO: +# add_subdirectory(OpenEXR_Viewers) endif() - -#]==] diff --git a/INSTALL.md b/INSTALL.md index 86f249d81..8e244cb86 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -1,115 +1,228 @@ # Building and Installation -Download the latest release of OpenEXR from -http://www.openexr.com/downloads.html. +## TLDR; version -To build the OpenEXR binaries from source, compile and install the -individual sub-models (IlmBase, PyIlmBase, OpenEXR, OpenEXR_Viewers), -according to the instructions in the respective ``README`` -files. Build and install the IlmBase module first, then build and -install the OpenEXR module. Optionally, then build and install -PyIlmBase, OpenEXR_Viewers, and Contrib. +### For unix-ish systems (linux, mac, freebsd, etc.) -For cmake users, there is also a top-level cmake file that enables -building all the sub-modules in one pass. See the section about -cmake below. +1. Download the all-in-one OpenEXR package. +2. Unpack it, open a shell and cd to the source tree where you unpacked +3. make sure you have cmake 3.12 or newer. +4. Run something like (on mac / windos): -## Traditional autoconf configuration (unix platforms) +```console +$ mkdir build +$ cd build +$ cmake -DCMAKE_BUILD_TYPE=Release .. +$ make install +``` -For the basic installation: +*For those who prefer autoconf, a configure based system is provided. +See below for more information.* - cd /IlmBase - ./configure - make - make install +### For windows - cd /OpenEXR - ./configure - make - make install +Under windows, if you are using a command line-based setup, such as +cygwin, you can of course follow the above. For Visual Studio, cmake +generators are "multiple configuration", so you don't even have to +set the build type, although you will most likely need to specify +the install location. -See the module ``README`` files for options to ``configure``. +## General Setup -## Building from Git +Download the latest release of OpenEXR from github or +http://www.openexr.com/downloads.html. -Alternatively, you can download the latest release or the lastest -development branch directly from http://github.com/openexr. +To build OpenEXR, there are two methodologies that can be employed +when using the cmake-based build setup provided. The first, and +easiest, is as one big package. This means that you make your build +tree, point cmake at the source tree from the build tree, configure +as desired, and then compile / install away. + +The alternate method is as separate sub-folders. This allows one to +only use IlmBase, for example. However, you must always compile +IlmBase first, as all the other folders depend on that. Then OpenEXR +must be compile prior to building the viewers, if you choose to build +the provided viewers. Finally, there are other programs in Contrib +that may be of interest. + +This latter method is also the method followed by the traditional +autoconf / configure setup that is provided (see that section below). + +## CMake Configuration and installation + +The cmake configuration files (CMakeLists.txt and all that it adds) +represent current patterns and recommendations for "Modern CMake". +As such, we have set the minimum required version to **_3.12_**. +This is always an arbitrary line, but 3.12 is available on many +systems by default at this point, andhad some significant improvements +to the python discovery system for the PyIlmBase extension, and +so seemed like a good line to draw. + +As mentioned above, there are two ways of working with the OpenEXR +repository with cmake. If you are downloading the individual package +tarballs, this will be decided for you, as they are packaged as +separate projects. However, the configuration process will remain +mostly the same. + +When working with the "all-in-one" configuration, which would be the +default if you just grab the release from github, the top level +CMakeLists.txt just behaves as a "super project" in cmake parlance, +which basically makes sure cmake doesn't actually look for the +software being built in other places, but then just includes the +relevant directories. + +As such, each top level folder added is in itself a cmake project. +This unfortunately causes a small amount of duplication for some +options, with the benefit of greater flexibility. + +Once you have the software downloaded and are ready to build it, cmake +prefers to apply an out-of-tree configure and build process, and it +does so with one configuration (i.e. debug vs. release) per build +folder, all referencing the one source folder. The only concession to +this is that we offer the ability to build both static libraries and +shared libraries at once. + +cmake is easy to use with all the defaults from a command prompt: + +```console +$ mkdir build +$ cd build +$ cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF .. +$ env DESTDIR=/path/to/install make install +``` + +This only changes a couple of options, setting the build type and +enables static-only libraries. You will notice that in this scenario, +we are also able to use a delayed version of the install path, and a +variable name that is more standard for GNU-related build tools. +**NB:** If you are building using shared libraries, and installing +to a non-system library, you may have to set CMAKE_INSTALL_PREFIX, or +set CMAKE_INSTALL_RPATH, depending on what your system requires for +run path resolution. Again, it is best to see the rpath handling docs +from cmake to understand how that is controlled, and then double +confirm that our settings are in line with what your install needs. +This specific document is currently [here](https://gitlab.kitware.com/cmake/community/wikis/doc/cmake/RPATH-handling) + +A couple of tools are provided as part of cmake, **cmake-gui** +and **cmake**. The former is a windowed application, the latter a +console-based version of the same functionality. When starting from +scratch, these tools run an initial configuration step that determines +the setup / O.S. you have chosen based on the existing environment +(paths to compilers, etc). This step is required, as this set of tools +may change what options are provided (for example, the mac options for +creating a framework are only displayed on a mac). + +However, once cmake has performed an initial environment scan and +configuration, it can display a UI with all the options and important +variables we have defined. Once happy with the configuration, +you generate the build scripts and compile the software (or load a +project up in an IDE). If you are against all UI programs and would +like to see this list, you can also run the following + +```console +$ mkdir build +$ cd build +$ cmake .. +$ cmake -LAH +``` + +which will list all options and "advanced" variables (values that are +cached), at which point you could set those name on the command line +when re-configuring from scratch using the -DOPTION_NAME=VALUE +mechanism (NB: you may have to specify the type in special cases) + +### Configuration options + +For the OpenEXR sub projects, we are either +using the cmake accepted / generated names (i.e. BUILD_TESTING +from ctest), or have them centralized per sub project as much as +possible. Those files are: + +[Top Level Choices of Modules](CMakeLists.txt) +[IlmBase Settings](IlmBase/config/IlmBaseSetup.cmake) +[OpenEXR Settings](OpenEXR/config/OpenEXRSetup.cmake) +[PyIlmBase Settings](PyIlmBase/config/PyIlmBaseSetup.cmake) -After cloning the repo locally, use the cmake path outlined later, -or if you prefer the autoconf system, generate the configuration -scripts by first running the ``bootstrap`` script: +If you are interested in controlling custom namespace declarations +or similar options, you are encouraged to look at these files and +read the comments in addition to the tooltip string provided for +the gui application. +As per usual, these settings can also be +seen and/or edited using any of the various gui editors for working with +cmake such as **ccmake**, **cmake-gui**, as well as some of the IDEs in +common use. - cd /IlmBase - ./bootstrap - ./configure - make - make install +### Side note on continuous integration - cd /OpenExr - ./bootstrap - ./configure - make - make install +The command line cmake tool is the driver behind all of the above, +and has a rich set of integration capabilities with continuous +integration systems, including the ability to make cross-platform +scripts instead of a mish-mash of bash and cmd batch scripts. If you +are integrating OpenEXR into an internal continuous integration +system, please see [this file](cmake/SampleCTestScript.cmake) +as a sample script that uses ctest to build a configuration and +test it. -Building from git and ``bootstrap`` requires that **autoconf** is -installed. Download and install it from -https://www.gnu.org/software/autoconf/autoconf.html. +### A note on cross-compiling -## Building with CMake +Some limited attempts have been made to test cross compiling with +OpenEXR. For cmake, this is usually done using a toolchain file. +A sample file is provided in the cmake folder at the top level of +OpenEXR which demonstrates a toolchain file for using mingw under +linux to cross compile for windows. This toolchain file will +probably need to be customized for your particular O.S. +distribution and desired output platform. Additionally, you may +have extra steps to get the code compiling if you do not have +an emulator to run the binaries. -Alternatively, you can build with **cmake**, version 3.12 or newer. +[Sample Toolchain file](cmake/Toolchain-mingw.cmake) -There are two ways of working with the OpenEXR repository with cmake. -If you are downloading the individual package tarballs, this will be -working with the folders as separate projects. The other method is if -you download a tag, or just clone the repository from github, in which -case this is called "super project" mode in cmake parlance. This -involves a cmake setup at the top level above the individual folders -which aggregates the tree into one build system, which can be used to -build all the software as one set. - -Either way, the process of configuring and building is similar. You -can accept the configuration defaults we have chosen, or customize -the settings via normal cmake mechanisms. But in the case of individual -folders, you will apply the process once per folder, but in the case of -using the super project mode, you will configure and run from just the -one build folder. - -Cmake prefers to apply an out-of-tree configure and build process, where -there may be multiple build configurations (i.e. debug and release), one -per folder, all pointing at once source tree. OpenEXR assumes nothing -different, so for a unix-like system, the process might be: - - mkdir build - - cd build - - cmake .. - - make - - make test - - env DESTDIR=/path/to/install make install - -Of course, there are a number of generators and other options that can -be specified. This is beyond the scope of this document, however all of -the sub-projects within OpenEXR (IlmBase, OpenEXR, PyIlmBase, ...) -additionally have configuration options. - -The libraries in IlmBase and OpenEXR follow the standard cmake setting -of BUILD_SHARED_LIBS to control whether to build static or shared -libraries. However, they each have separate controls over whether to -build both shared AND static libraries as part of one configuration, -as well as other customization options. +## Traditional autoconf configuration (unix platforms) -If you are interested in controlling custom namespace declarations -or similar options, you are encouraged to look at the CMakeLists.txt -infrastructure. In particular, there has been an attempt to centralize -the settings into a common place to more easily see all of them in a -text editor. For IlmBase, this is config/IlmBaseSetup.cmake inside the -IlmBase tree. For OpenEXR, the settings will similarly be found in -config/OpenEXRSetup.cmake. As per usual, these settings can also be -seen and/or edited using any of the various gui editors for working with -cmake such as **ccmake**, **cmake-gui**, as well as some of the IDEs in -common use. +The autoconf configuration assumes that each sub-element of +OpenEXR is it's own project. As such, it needs to be compiled +in stages, as was described as the second method to install +OpenEXR in the general setup above. + +Like most autoconf / configure based setups, there is a set of +options that can be set via various flags to the ```configure``` +script. ```configure --help``` will show you these prior to +configuring anything. + +Unlike the very basic directions below, you can also do the +out-of-tree builds using the configure mechanism - just pre-make +and cd to that build folder, and add the path to the configure +script. If you are using the git repo, you will have to have +pre-run the bootstrap command to prepare the configure script. + +**Important:** If you are checking out the git repository and +attempting to build and install, you need to insert a call to +```bootstrap``` in the steps below. This requires you to have +autoconf and all the autotools installed. A distribution +package does not have this requirement. + +1. Compile IlmBase: + +```console +$ cd /IlmBase +$ ./configure +$ make +$ make install +``` + +2. Compile OpenEXR (if desired) + +```console +$ cd /OpenEXR +$ ./configure +$ make +$ make install +``` + +From here, you are free to compile and install the extra modules +included as desired - PyIlmBase and OpenEXR_Viewers using the +same pattern as above. + +## Building with CMake -For cross-compiling for additional platforms, there is also and included -sample script in cmake/Toolchain-mingw.cmake which may work for you by -following the comments at the top of that file, although some editing -is likely to be needed to point cmake at the correct cross-compiler -binaries for your platform. +Alternatively, you can build with **cmake**, version 3.12 or newer. diff --git a/IlmBase/CMakeLists.txt b/IlmBase/CMakeLists.txt index 9a8f8285f..06cb9563d 100644 --- a/IlmBase/CMakeLists.txt +++ b/IlmBase/CMakeLists.txt @@ -38,36 +38,9 @@ add_subdirectory( IlmThread ) # Can't seem to do EXCLUDE_FROM_ALL on the test executables # since you can't then create a dependency on the internal # "test" target such that it is auto built -enable_testing() include(CTest) if(BUILD_TESTING) - # TODO: - #include(CTest) - #set(CTEST_PROJECT_NAME "OpenEXR - IlmBase") - #set(CTEST_NIGHTLY_START_TIME "01:01:01 UTC") - #set(CTEST_DROP_METHOD "http") # there are others... - #set(CTEST_DROP_SITE "open.cdash.org") - #set(CTEST_DROP_LOCATION "/submit.php?project=MyProject") - #set(CTEST_DROP_SITE_CDASH TRUE) - # - # Then can make a ctest script that has something like the following - # in it: - # set(CTEST_SOURCE_DIRECTORY "/source") - # set(CTEST_BINARY_DIRECTORY "/binary") - # - # set(ENV{CXXFLAGS} "--coverage") - # set(CTEST_CMAKE_GENERATOR "Ninja") - # set(CTEST_USE_LAUNCHERS 1) - # set(CTEST_COVERAGE_COMMAND "gcov") - # set(CTEST_MEMORYCHECK_COMMAND "valgrind") - # #set(CTEST_MEMORYCHECK_TYPE "ThreadSanitizer") - # ctest_start("Continuous") - # ctest_configure() - # ctest_build() - # ctest_test() - # ctest_coverage() - # ctest_memcheck() - # ctest_submit() + enable_testing() add_subdirectory( HalfTest ) add_subdirectory( IexTest ) diff --git a/OpenEXR/CMakeLists.txt b/OpenEXR/CMakeLists.txt index 224eb4c17..6aeca88ab 100644 --- a/OpenEXR/CMakeLists.txt +++ b/OpenEXR/CMakeLists.txt @@ -8,11 +8,7 @@ cmake_policy(SET CMP0076 NEW) # numbers include(config/ParseConfigure.cmake) -project(OpenEXR VERSION ${OPENEXR_VERSION}) - -# Everyone depends on IlmBase, and we currently rely on -# the version matched with our release -find_package(IlmBase ${OPENEXR_VERSION} EXACT REQUIRED CONFIG) +project(OpenEXR VERSION ${OPENEXR_VERSION} LANGUAGES C CXX) ####################################### ####################################### @@ -25,6 +21,10 @@ find_package(IlmBase ${OPENEXR_VERSION} EXACT REQUIRED CONFIG) ####################################### include(config/OpenEXRSetup.cmake) +# Everyone depends on IlmBase, and we currently rely on +# the version matched with our release +find_package(IlmBase ${OPENEXR_VERSION} EXACT REQUIRED CONFIG) + # generates config headers, package config files add_subdirectory(config) @@ -32,16 +32,21 @@ add_subdirectory(config) # the libraries include(config/LibraryDefine.cmake) +########################## + add_subdirectory( IlmImf ) add_subdirectory( IlmImfUtil ) add_subdirectory( IlmImfExamples ) +########################## +# Tests +########################## # Can't seem to do EXCLUDE_FROM_ALL on the test executables # since you can't then create a dependency on the internal # "test" target such that it is auto built -enable_testing() include(CTest) if(BUILD_TESTING) + enable_testing() add_subdirectory( IlmImfTest ) add_subdirectory( IlmImfUtilTest ) add_subdirectory( IlmImfFuzzTest ) diff --git a/cmake/SampleCTestScript.cmake b/cmake/SampleCTestScript.cmake new file mode 100644 index 000000000..d18d110fb --- /dev/null +++ b/cmake/SampleCTestScript.cmake @@ -0,0 +1,59 @@ +# This is a sample cmake test script that can be used to integrate into +# a larger CI setup if you are building your own versions of OpenEXR +# and also use a cdash (or cdash compliant) results server. +# +# There are also settings in the CMakeLists.txt you may wish to +# just set in there, or replicate here. + +# Running ctest -S thisscript.cmake will build into the binary directory +# and run a few different tests based on what commands are specified +# (and the steps below). It is best to read the ctest docs to +# understand all these settings, and how to control it, this is merely +# provided as a sample + +# An edited version (or multiple) are intended to be placed in the CI +# system, and putting O.S. / configuration specific control to this file +# instead of having to put it into the make CMakeLists.txt tree +# somehow. + +# this contains the path to the source tree. This may come in as an +# environment variable from the CI system, but you are free to have +# any path in here +set(CTEST_SOURCE_DIRECTORY "$ENV{PATH_TO_OPENEXR_TREE}") +# Similarly, this is scratch space used to configure, build +# and run the various tests. +# For CI builds, it is recommended to make sure this is a +# unique tree for each build +set(CTEST_BINARY_DIRECTORY "/tmp/ctest") + +# set an override for any compile flags to enable coverage +# NB: This can make some of the auxiliary binaries such as the +# dwa lookup table generator quite slow +#set(ENV{CXXFLAGS} "--coverage") + +# If you have alternate build systems, you can control that here +#set(CTEST_CMAKE_GENERATOR "Ninja") +set(CTEST_USE_LAUNCHERS 1) + +# The various paths to programs to run coverage and memory checks +set(CTEST_COVERAGE_COMMAND "gcov") +set(CTEST_MEMORYCHECK_COMMAND "valgrind") +#set(CTEST_MEMORYCHECK_TYPE "ThreadSanitizer") +# + +# any of the usual configurations (Debug, Release, etc). +# We do not attempt to create any alternate configurations +set(CTEST_CONFIGURATION_TYPE "RelWithDebInfo") + +# can be Continuous, Nightly, or Experimental (see the cmake docs) +ctest_start("Continuous") + +# applies the various ctest steps +ctest_configure() +ctest_build() +ctest_test() +ctest_coverage() +ctest_memcheck() + +# This uploads the results to the server you configured +ctest_submit()