#!/usr/bin/env python import sys import importlib import os import shutil import platform # Nuclex SCons libraries sys.path.append('../../References/scripts/scons') nuclex = importlib.import_module('nuclex') archive = importlib.import_module('archive') # ----------------------------------------------------------------------------------------------- # universal_openexr_target_name = 'openexr' environment = nuclex.create_cplusplus_environment() # ----------------------------------------------------------------------------------------------- # # Step 0: preparatory work # Fetch the list of headers used when compiling openexr_headers_file = environment.File('openexr-headers') openexr_header_files = archive.split_lines(openexr_headers_file.get_text_contents()) # Fetch the list of sources to compile openexr openexr_sources_file = environment.File('openexr-sources') openexr_source_files = archive.split_lines(openexr_sources_file.get_text_contents()) # ----------------------------------------------------------------------------------------------- # # Step 1: Download the current release # Fetch the available download URLs from a file download_url_file = environment.File('openexr-download-urls') download_urls = archive.split_lines(download_url_file.get_text_contents()) # Determine the target filename for the download (below 'downloads' folder) archive_filename = os.path.basename(download_urls[0]) archive_file = environment.File(os.path.join('downloads', archive_filename)) # Tell SCons how to "produce" the downloaded archive (by calling wget) if not archive_file.exists(): download_archive = environment.Command( source = download_url_file, #action = 'wget ' + download_urls[0] + ' --output-document=$TARGET', action = archive.download_url_in_urlfile, target = archive_file ) # ----------------------------------------------------------------------------------------------- # # Step 2: Extract the release into the build directory def extract_compressed_tarball(target, source, env): """Extracts the distribution .tar.gz archive and applies a patch that ensures the same headers will work on Windows and average Linux distributions. @param target Output files, not used by the function but passed along so SCons can look at them and knows its dependency tree @param source Source files, expected to be an array containing the .tar.gz path and the unified diff path @param env SCons build environment""" archive.extract_compressed_tarball(str(source[0]), 'build', 1) # SCons is too stupid to be told to copy the frigging file AFTER # extraction, so we'll work around the sucker: shutil.copyfile( 'OpenEXRConfig.h', 'build/config/OpenEXRConfig.h' ) openexr_header_files.append('build/config/OpenEXRConfig.h') #if platform.system() == 'Windows': # openexr_source_files.append('build/IlmThread/IlmThreadMutexWin32.cpp') # openexr_source_files.append('build/IlmThread/IlmThreadSemaphoreWin32.cpp') # openexr_source_files.append('build/IlmThread/IlmThreadWin32.cpp') #else: # openexr_source_files.append('build/IlmThread/IlmThreadMutexPosix.cpp') # openexr_source_files.append('build/IlmThread/IlmThreadSemaphorePosix.cpp') # openexr_source_files.append('build/IlmThread/IlmThreadPosix.cpp') # Tell SCons how to "produce" the sources & headers (by calling tar) extract_archive = environment.Command( source = archive_file, #action = 'tar --extract --gzip --strip-components=1 --file=$SOURCE --directory=build', action = extract_compressed_tarball, target = ( openexr_source_files + openexr_header_files + [ 'build/IlmImf/b44ExpLogTable.cpp', 'build/IlmImf/dwaLookups.cpp' ] ) ) # Note: b44ExpLogTable.cpp and dwaLookups.cpp are part of the archive, but # shouldn't be compiled to openexr.lib / libopenexr.a. That's why they're not # in openexr_source_files. # ----------------------------------------------------------------------------------------------- # # Step 3: Compile and run the b44explog look-up-table generator b44explog_environment = environment.Clone() del b44explog_environment['SOURCE_DIRECTORY'] # We define the sources ourselves del b44explog_environment['HEADER_DIRECTORY'] # The generator has no internal header dependencies # Add b44explog.cpp as the single source file we're going to compile b44explog_environment.add_source_directory( 'build/IlmImf', [ 'build/IlmImf/b44ExpLogTable.cpp' ], scons_issue_2908_workaround_needed = True ) b44explog_environment.add_project('../ilmbase') b44explog_environment.add_include_directory('../ilmbase/Include/Half') # Build the b44explog executable compile_b44explog = b44explog_environment.build_executable( 'b44explog', console = True ) # Run the code generator to generate the b44explog.h header b44explog_header = b44explog_environment.Command( source = compile_b44explog, action = '$SOURCE > $TARGET', target = 'build/IlmImf/b44ExpLogTable.h' ) # Add the generated header to openexr_header_files so it gets copied into # the 'Include' directory with the other headers openexr_header_files.append('build/IlmImf/b44ExpLogTable.h') # ERROR: These make SCons invent a circular dependency from b44explog.cpp to b44explog.h ?! #b44explog_environment.Depends('build/Half/half.cpp', 'build/Half/b44explog.h') #b44explog_environment.Depends('build/Half/half.cpp', b44explog_header) # ----------------------------------------------------------------------------------------------- # # Step 4: Compile and run the dwa look-up-table generator dwa_environment = environment.Clone() del dwa_environment['SOURCE_DIRECTORY'] # We define the sources ourselves dwa_environment['HEADER_DIRECTORY'] = 'build/config' # Add dwa.cpp as the single source file we're going to compile dwa_environment.add_source_directory( 'build/IlmImf', [ 'build/IlmImf/dwaLookups.cpp' ], scons_issue_2908_workaround_needed = True ) dwa_environment.add_include_directory('build/IlmImf') dwa_environment.add_project('../ilmbase') dwa_environment.add_include_directory('../ilmbase/Include/config') dwa_environment.add_include_directory('../ilmbase/Include/Half') dwa_environment.add_include_directory('../ilmbase/Include/IlmThread') dwa_environment.add_include_directory('../ilmbase/Include/Imath') dwa_environment.add_include_directory('../ilmbase/Include/IexMath') dwa_environment.add_include_directory('../ilmbase/Include/Iex') dwa_environment.add_library('pthread') # Build the dwa executable compile_dwa = dwa_environment.build_executable( 'dwalookups', console = True ) # Run the code generator to generate the dwa.h header dwa_header = dwa_environment.Command( source = compile_dwa, action = '$SOURCE > $TARGET', target = 'build/IlmImf/dwaLookups.h' ) # Add the generated header to openexr_header_files so it gets copied into # the 'Include' directory with the other headers openexr_header_files.append('build/IlmImf/dwaLookups.h') # ERROR: These make SCons invent a circular dependency from dwa.cpp to dwa.h ?! #dwa_environment.Depends('build/Half/half.cpp', 'build/Half/dwa.h') #dwa_environment.Depends('build/Half/half.cpp', dwa_header) # ----------------------------------------------------------------------------------------------- # # Step 5: Compile the openexr library openexr_environment = environment.Clone() del openexr_environment['SOURCE_DIRECTORY'] # We define the sources ourselves openexr_environment['HEADER_DIRECTORY'] = 'build/config' # Main include directory # Set up additional include directories for the openexr modules openexr_environment.add_include_directory('../zlib/Include') openexr_environment.add_include_directory('../ilmbase/Include/config') openexr_environment.add_include_directory('../ilmbase/Include/Half') openexr_environment.add_include_directory('../ilmbase/Include/IlmThread') openexr_environment.add_include_directory('../ilmbase/Include/Imath') #openexr_environment.add_include_directory('../ilmbase/Include/IexMath') openexr_environment.add_include_directory('../ilmbase/Include/Iex') openexr_environment.add_include_directory('build/IlmImf') #openexr_environment.add_include_directory('build/IexMath') #openexr_environment.add_include_directory('build/Half') # Add all sources from the sources list to this build openexr_environment.add_source_directory( 'build', openexr_source_files, scons_issue_2908_workaround_needed = True ) # And finally, compile the openexr.lib / libopenexr.a library compile_openexr_library = openexr_environment.build_library( universal_openexr_target_name, static = True ) # ----------------------------------------------------------------------------------------------- # # Step 6: Create an 'Include' directory containing only the headers for header in openexr_header_files: if header.startswith('build/'): install_path = os.path.join('Include', header[6:]) environment.InstallAs(install_path, header) # ----------------------------------------------------------------------------------------------- #