# Copyright (c) 2017 CEF Python, see the Authors file.# All rights reserved. Licensed under BSD 3-clause license.# Project website: https://github.com/cztomczak/cefpython"""Called by build.py internally. Builds C++ projects usingdistutils/setuptools compilers. This tool is executed by build.pyon Windows only currently. Output directories are inbuild/build_cefpython/.Usage:build_cpp_projects.py [--force]TODO: Linux/Mac support, see makefiles, add include dirs usingcompiler.add_include_dir, compiler/linker flags,refactor macros."""# import setuptools so that distutils msvc compiler is patched# noinspection PyUnresolvedReferencesimport setuptoolsfrom distutils.ccompiler import new_compilerfrom common import *import shutilfrom pprint import pprint# MacrosMACROS = ["WIN32", "_WIN32", "_WINDOWS",# Windows 7+ minimum supported("NTDDI_VERSION", "0x06010000"),("WINVER", "0x0601"),("_WIN32_WINNT", "0x0601"),"NDEBUG", "_NDEBUG","_CRT_SECURE_NO_WARNINGS",]cefpython_app_MACROS = MACROS + ["BROWSER_PROCESS",]subprocess_MACROS = MACROS + ["RENDERER_PROCESS","UNICODE", "_UNICODE","NOMINMAX","WIN32_LEAN_AND_MEAN",("_HAS_EXCEPTIONS", "0"),]# Compiler argsCOMPILER_ARGS = ["/EHsc",]subprocess_COMPILER_ARGS = ["/MT",]# Linker argssubprocess_LINKER_ARGS = ["/MANIFEST:NO","/LARGEADDRESSAWARE",]# Command line argsFORCE_FLAG = Falsedef main():command_line_args()clean_build_directories_if_forced()print_compiler_options()build_cefpython_app_library()build_library(lib_name="client_handler",macros=MACROS,sources_dir=CLIENT_HANDLER_DIR,output_dir=BUILD_CLIENT_HANDLER)build_library(lib_name="cpp_utils",macros=MACROS,sources_dir=CPP_UTILS_DIR,output_dir=BUILD_CPP_UTILS)build_subprocess_executable()print("[build_cpp_projects.py] Done building C++ projects")def command_line_args():global FORCE_FLAGif "--force" in sys.argv:FORCE_FLAG = Truedef clean_build_directories_if_forced():build_dirs = [BUILD_CEFPYTHON_APP, BUILD_CLIENT_HANDLER, BUILD_CPP_UTILS,BUILD_SUBPROCESS]if FORCE_FLAG:print("[build_cpp_projects.py] Clean C++ projects build directories")for bdir in build_dirs:if os.path.isdir(bdir):shutil.rmtree(bdir)def print_compiler_options():compiler = get_compiler()print("build_cpp_projects.py] Shared macros:")pprint(MACROS, indent=3, width=160)print("[build_cpp_projects.py] cefpython_app library macros:")pprint(cefpython_app_MACROS, indent=3, width=160)print("[build_cpp_projects.py] subprocess executable macros:")pprint(subprocess_MACROS, indent=3, width=160)print("[build_cpp_projects.py] Compiler options:")pprint(vars(compiler), indent=3, width=160)def get_compiler(static=False):# NOTES:# - VS2008 and VS2010 are both using distutils/msvc9compiler.pycompiler = new_compiler()# Must initialize so that "compile_options" and others are availablecompiler.initialize()if static:compiler.compile_options.remove("/MD")# Overwrite function that adds /MANIFESTFILE, as for subprocess# manifest is disabled. Otherwise warning LNK4075 is generated.if hasattr(compiler, "manifest_setup_ldargs"):compiler.manifest_setup_ldargs = lambda *_: Nonereturn compilerdef build_library(lib_name, macros, output_dir,sources=None, sources_dir=None):assert bool(sources_dir) ^ bool(sources) # xorprint("[build_cpp_projects.py] Build library: {lib_name}".format(lib_name=lib_name))compiler = get_compiler()if not os.path.exists(output_dir):os.makedirs(output_dir)if sources_dir:assert not sourcessources = get_sources(sources_dir)(changed, objects) = smart_compile(compiler,macros=macros,extra_args=COMPILER_ARGS,sources=sources,output_dir=output_dir)lib_path = os.path.join(output_dir, lib_name + LIB_EXT)if changed or not os.path.exists(lib_path):compiler.create_static_lib(objects, lib_name,output_dir=output_dir)print("[build_cpp_projects.py] Created library: {lib_name}".format(lib_name=lib_name))else:print("[build_cpp_projects.py] Library is up-to-date: {lib_name}".format(lib_name=lib_name))def build_cefpython_app_library():sources = get_sources(SUBPROCESS_DIR, exclude_names=["main.cpp"])main_message_loop_dir = os.path.join(SUBPROCESS_DIR, "main_message_loop")sources.extend(get_sources(main_message_loop_dir))build_library(lib_name="cefpython_app",macros=cefpython_app_MACROS,sources=sources,output_dir=BUILD_CEFPYTHON_APP)def build_subprocess_executable():print("[buil_cpp_projects.py] Build executable: subprocess")compiler = get_compiler(static=True)sources = get_sources(SUBPROCESS_DIR,exclude_names=["print_handler_gtk.cpp"])(changed, objects) = smart_compile(compiler,macros=subprocess_MACROS,extra_args=subprocess_COMPILER_ARGS,sources=sources,output_dir=BUILD_SUBPROCESS)executable_path = os.path.join(BUILD_SUBPROCESS,"subprocess" + EXECUTABLE_EXT)if changed or not os.path.exists(executable_path):lib_dir = os.path.join(CEF_BINARIES_LIBRARIES, "lib")lib_dir_vs = os.path.join(lib_dir,get_msvs_for_python(vs_prefix=True))compiler.link_executable(objects,output_progname="subprocess",output_dir=BUILD_SUBPROCESS,libraries=["libcef","libcef_dll_wrapper_MT"],library_dirs=[lib_dir, lib_dir_vs],# TODO linker flags for Linux/Macextra_preargs=None,extra_postargs=subprocess_LINKER_ARGS)else:print("[build_cpp_projects.py] Executable is up-to-date: subprocess")def get_sources(sources_dir, exclude_names=None):if not exclude_names:exclude_names = list()sources = glob.glob(os.path.join(sources_dir, "*.cpp"))if MAC:sources.extend(glob.glob(os.path.join(sources_dir, "*.mm")))ret = list()for source_file in sources:filename = os.path.basename(source_file)if "_win.cpp" in filename and not WINDOWS:continueif "_linux.cpp" in filename and not LINUX:continueif "x11" in filename and not LINUX:continueif "gtk" in filename and not LINUX:continueif "_mac.cpp" in filename and not MAC:continueexclude = Falsefor name in exclude_names:if name in filename:exclude = Truebreakif not exclude:ret.append(source_file)return retdef smart_compile(compiler, macros, extra_args, sources, output_dir):"""Smart compile will only recompile files that need recompiling."""if not os.path.exists(output_dir):os.makedirs(output_dir)any_changed = Falseobjects = list()for source_file in sources:header_file = source_file.replace(".cpp", ".h")header_file = header_file.replace(".mm", ".h")assert header_file.endswith(".h")if not os.path.isfile(header_file):header_file = Noneobj_file = os.path.join(output_dir, os.path.basename(source_file))obj_file = obj_file.replace(".cpp", OBJ_EXT)obj_file = obj_file.replace(".mm", OBJ_EXT)assert obj_file.endswith(OBJ_EXT)if os.path.exists(obj_file):# Recompile source file if its time is newer than obj file,# Also check its header file time. Also check times of any# possible includes: cefpython_fixed.h, src/common/ files.obj_time = os.path.getmtime(obj_file)source_time = os.path.getmtime(source_file)header_time = os.path.getmtime(header_file) if header_file else 0cefpython_h_fixed_time = os.path.getmtime(CEFPYTHON_API_HFILE_FIXED)common_files_time = get_directory_mtime(os.path.join(SRC_DIR,"common"))changed = ((source_time > obj_time)or (header_time > obj_time)or (cefpython_h_fixed_time > obj_time)or (common_files_time > obj_time))else:changed = Trueif changed:any_changed = Trueelse:objects.append(obj_file)if any_changed:# If any has changed must recompile all given sources (for a library# or executable). This is because we don't know which sources include# which header files so must recompile everything.objects = list()# Compile each source file separately so that when compiling# source files from different directories, object files are# all put in the same output_directory. Otherwise distutils# will create lots of subdirs in output_directory.macros = macros_as_tuples(macros)common_dir = os.path.join(SRC_DIR, "common")original_dir = os.getcwd()for source_file in sources:source_dir = os.path.dirname(source_file)os.chdir(source_dir)source_basename = os.path.basename(source_file)oneobj = compiler.compile([source_basename],output_dir=output_dir,macros=macros,# TODO include dirs for Linux/Macinclude_dirs=[SRC_DIR,common_dir,get_python_include_path()],# TODO compiler flags for Linux/Macextra_preargs=None,extra_postargs=extra_args)assert len(oneobj) == 1objects.append(os.path.join(source_dir, oneobj[0]))os.chdir(original_dir)assert len(objects)return any_changed, objectsdef macros_as_tuples(macros):"""Return all macros as tuples. Required by distutils.ccompiler."""ret_macros = list()for macro in macros:if isinstance(macro, str):ret_macros.append((macro, ""))else:assert isinstance(macro, tuple)ret_macros.append(macro)return ret_macrosdef get_directory_mtime(directory):# For example check src/common/ directory for newest modification timeassert os.path.isdir(directory)files = glob.glob(os.path.join(directory, "*"))ret_mtime = 0for header_file in files:mtime = os.path.getmtime(header_file)if mtime > ret_mtime:ret_mtime = mtimeassert ret_mtimereturn ret_mtimeif __name__ == "__main__":main()
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。