# This file contains the default configuration to compile for Windows # platforms. It contains sensitive enviroment configuration that # shouldn't be modified unless you now what you are doing. # PLEASE, DO NOT EDIT THIS FILE from cerbero.config import Architecture, Platform, FatalError from cerbero.utils import EnvValue, EnvValueArg, EnvValueCmd, EnvValuePath # We don't want anything from mingw or msys detected in configure and # used later. allow_system_libs = False # Environment variables are terrible. We use them for several purposes at once: # 1. To pass configuration to build tools (WINEPREFIX, WINEDEBUG, etc) # 2. To pass configuration to build system (ac_cv_*, CC, LD, CFLAGS, PERL, etc) # 3. To pass configuration to the toolchain (LIBRARY_PATH, INCLUDE, LIB, etc) # 4. To set PATH # # If we use a single `env` scratch space for storing all the above env, we hit # two problems: # * Some recipes use the MinGW toolchain while others use the MSVC toolchain # * Autotools must be configured via env vars, but Meson wants native/cross files # # So we divide the env vars into five sections: # 1. For build tools that are used regardless of toolchain: `env` # 2. For the build system when using MinGW: `mingw_env_for_build_system` # 3. For the build system when using MSVC: `msvc_env_for_build_system` # 4. For the MinGW toolchain: `mingw_env_for_toolchain` # 5. For the MSVC toolchain: `msvc_env_for_toolchain` # Meson-specific configuration goes into `meson_properties` # mingw_env_for_toolchain = dict() mingw_env_for_build_system = dict() msvc_env_for_toolchain = dict() msvc_env_for_build_system = dict() if platform == Platform.WINDOWS: separator = ';' if target_arch == Architecture.X86: build = 'i686-w64-mingw32' if target_arch == Architecture.X86_64: build = 'x86_64-w64-mingw32' else: env['WIX'] = os.path.join(build_tools_prefix, 'lib', 'wix') # NOTE: Ensure that whatever directory this goes into is ignored by the # .cerbero deps CI job otherwise we will tar up ~1GB of generated data. env['WINEPREFIX'] = os.path.join(build_tools_prefix, 'var', 'tmp', 'wine') env['WINEDEBUG'] = 'fixme-all' separator = ':' if target_arch == Architecture.X86: buildname = 'windows_x86' arch_flags = ['-m32'] arch_rcflags = ['-F', 'pe-i386'] dlltool_flags = ['--as-flags=--32', '-m', 'i386'] host = 'i386-w64-mingw32' _path = 'multilib' else: buildname = 'windows_x86_64' arch_flags = [] arch_rcflags = [] dlltool_flags = [] host = 'x86_64-w64-mingw32' _path = 'multilib' target = host if not toolchain_prefix: toolchain_prefix = os.path.join(home_dir, 'mingw', _path) if not mingw_perl_prefix: mingw_perl_prefix = os.path.join(home_dir, 'mingw', 'perl') if not tools_prefix: tools_prefix = 'x86_64-w64-mingw32-' def cmd(command, args=None, wrapper=None): if not args: args = [] if not wrapper: wrapper = [] return EnvValueCmd(wrapper + ['%s%s' % (tools_prefix, command)] + args) # 'universal' is set by cerbero itself when building under a universal regime # so that we can construct different paths to include/lib directories to where # they actually are. Without this we don't know where the headers/libs will # actually end up if universal_archs: incl_dir = os.path.join(prefix, target_arch, 'include') lib_dir = os.path.join(prefix, target_arch, 'lib') else: incl_dir = os.path.join(prefix, 'include') lib_dir = os.path.join(prefix, 'lib') if target_arch != Architecture.UNIVERSAL and not os.path.exists(incl_dir): os.makedirs(incl_dir) if target_arch != Architecture.UNIVERSAL and not os.path.exists(lib_dir): os.makedirs(lib_dir) # Default GCC compiler flags mingw_env_for_build_system['CPPFLAGS'] = EnvValueArg(arch_flags) mingw_env_for_build_system['CFLAGS'] = EnvValueArg(arch_flags) mingw_env_for_build_system['CXXFLAGS'] = EnvValueArg(arch_flags) mingw_env_for_build_system['LDFLAGS'] = EnvValueArg(arch_flags) # Default MSVC compiler flags # # If no BOM is found from source file, msvc assumes the file is encoded # using the current user code page unless '/utf-8' option was specified. # Auto detected (by msvc) code page might cause compile error depending on locale # https://docs.microsoft.com/en-us/cpp/build/reference/utf-8-set-source-and-executable-character-sets-to-utf-8 msvc_env_for_build_system['CPPFLAGS'] = EnvValueArg('/utf-8') msvc_env_for_build_system['CFLAGS'] = EnvValueArg('/utf-8') msvc_env_for_build_system['CXXFLAGS'] = EnvValueArg('/utf-8') msvc_env_for_build_system['LDFLAGS'] = EnvValueArg() if variants.uwp: # Setting WINAPI_FAMILY to APP allows us to get link-time errors for # many forbidden APIs instead of having to run a packaged app through # the Windows App Certification Kit # -APPCONTAINER is required for compliance: # https://docs.microsoft.com/en-us/previous-versions/windows/hh920280(v=win.10)#appcontainercheck msvc_env_for_build_system['CFLAGS'] += ['-DWINAPI_FAMILY=WINAPI_FAMILY_APP'] msvc_env_for_build_system['CXXFLAGS'] += ['-DWINAPI_FAMILY=WINAPI_FAMILY_APP'] msvc_env_for_build_system['LDFLAGS'] += ['-APPCONTAINER', 'WindowsApp.lib'] # When not cross-compiling, this is set using C{,PLUS}_INCLUDE_PATH in cerbero/config.py if cross: mingw_env_for_build_system['CPPFLAGS'] += ['-I' + incl_dir] mingw_env_for_build_system['CFLAGS'] += ['-I' + incl_dir] mingw_env_for_build_system['CXXFLAGS'] += ['-I' + incl_dir] ccache = use_ccache and ['ccache'] or [] # By default the target Windows 7, but for UWP it's Windows 10 target_winver = '0x0A00' if variants.uwp else '0x0601' winver_flags = ['-DWINVER=' + target_winver, '-D_WIN32_WINNT=' + target_winver] # MinGW and MSVC build system config env for config_env in (mingw_env_for_build_system, msvc_env_for_build_system): config_env['CPPFLAGS'] += winver_flags config_env['CFLAGS'] += winver_flags config_env['CXXFLAGS'] += winver_flags # MinGW build system config env mingw_env_for_build_system['CC'] = cmd('gcc', arch_flags, ccache) mingw_env_for_build_system['CXX'] = cmd('g++', arch_flags, ccache) mingw_env_for_build_system['LD'] = cmd('ld') mingw_env_for_build_system['CPP'] = cmd('cpp') mingw_env_for_build_system['RANLIB'] = cmd('ranlib') mingw_env_for_build_system['AR'] = cmd('ar') mingw_env_for_build_system['AS'] = cmd('as') mingw_env_for_build_system['STRIP'] = cmd('strip') mingw_env_for_build_system['WINDRES'] = cmd('windres', arch_rcflags) mingw_env_for_build_system['RC'] = cmd('windres', arch_rcflags) mingw_env_for_build_system['NM'] = cmd('nm') # MSVC build system config env msvc_env_for_build_system['CC'] = EnvValueCmd('cl') msvc_env_for_build_system['CXX'] = EnvValueCmd('cl') msvc_env_for_build_system['AR'] = EnvValueCmd('lib') # MinGW toolchain config env mingw_env_for_toolchain['LIBRARY_PATH'] = EnvValuePath([lib_dir]) # General env vars that should always be set env['PERL'] = 'perl' env['GENDEF'] = 'gendef' env['DLLTOOL'] = cmd('dlltool', dlltool_flags).get() # MinGW Perl PATH, only needed when building on Windows with MSYS if platform == Platform.WINDOWS: perlbin = os.path.join(mingw_perl_prefix, 'bin') env['PATH'] = '%s%s%s' % (perlbin, separator, env['PATH']) # MinGW toolchain PATH toolchainbin = os.path.join(toolchain_prefix, 'bin') if toolchainbin not in env['PATH']: env['PATH'] = '%s%s%s' % (toolchainbin, separator, env['PATH']) libexecdir = os.path.join(toolchain_prefix, "libexec/gcc/x86_64-w64-mingw32/8.2.0/") env['PATH'] = '%s%s%s' % (libexecdir, separator, env['PATH']) # These only have meaning for autotools, so let's just leave it in the general env env['ne_cv_libsfor_socket'] = '-lws2_32' env['ne_cv_libsfor_gethostbyname'] = '-lws2_32' env['ac_cv_func_malloc_0_nonnull'] = 'yes' env['ac_cv_func_realloc_0_nonnull'] = 'yes' env['lt_cv_deplibs_check_method'] = 'pass_all' env['ac_cv_lib_bz2_BZ2_bzlibVersion'] = 'yes' env['ac_cv_c_attribute_aligned'] = '64' if platform == Platform.WINDOWS and target_arch != Architecture.UNIVERSAL: # Make's job server is buggy and broken on Windows, which causes it to # either hang or print server errors like: # 2068442963 [sig] make 18324 sig_dispatch_pending: Win32 error 298 releasing sigcatch_nosync(0x150) # Only use one process to make the build more reliable. allow_parallel_build = False from cerbero.ide.vs.env import get_msvc_env, append_path # Always try to fetch msvc env vars on Windows, since we optionally use it # for finding `lib.exe` have_visualstudio = False try: # Contains only the env vars that MSVC needs, including any existing vars # that were appended/prepended and have new values msvc_env, msvc_version = get_msvc_env(arch, target_arch, variants.uwp, vs_install_version, vs_install_path) have_visualstudio = True except FatalError as e: if variants.visualstudio: raise e print('Could not find Visual Studio; will only use MinGW') if have_visualstudio: for key, value in msvc_env.items(): msvc_env_for_toolchain[key] = EnvValue.from_key(key, value) # We want the MSVC compiler and linker to find the headers and libraries # provided by recipes built by us, so append to INCLUDE and LIB. # NOTE: We do not want to add the MinGW toolchain paths here msvc_env_for_toolchain['INCLUDE'] += [incl_dir] msvc_env_for_toolchain['LIB'] += [lib_dir] msvc_env_for_toolchain['WINDRES'] = EnvValueCmd('rc') if variants.uwp: meson_properties['needs_exe_wrapper'] = 'true' # Export the env for a shell if for_shell: from itertools import chain if variants.visualstudio: env_dicts = chain(msvc_env_for_toolchain.items(), msvc_env_for_build_system.items()) else: env_dicts = chain(mingw_env_for_toolchain.items(), mingw_env_for_build_system.items()) for var, val in env_dicts: if var in env: # Don't set it twice if val.get() in env[var]: continue env[var] = '{}{}{}'.format(val.get(), val.sep, env[var]) else: env[var] = val.get()