Conditions | 100 |
Total Lines | 446 |
Lines | 0 |
Ratio | 0 % |
Changes | 0 |
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
Complex classes like WriteTarget() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
1 | # Copyright (c) 2013 Google Inc. All rights reserved. |
||
610 | def WriteTarget(namer, qualified_target, target_dicts, build_dir, config_to_use, |
||
611 | options, generator_flags, all_qualified_targets, output): |
||
612 | |||
613 | # The make generator does this always. |
||
614 | # TODO: It would be nice to be able to tell CMake all dependencies. |
||
615 | circular_libs = generator_flags.get('circular', True) |
||
616 | |||
617 | if not generator_flags.get('standalone', False): |
||
618 | output.write('\n#') |
||
619 | output.write(qualified_target) |
||
620 | output.write('\n') |
||
621 | |||
622 | gyp_file, _, _ = gyp.common.ParseQualifiedTarget(qualified_target) |
||
623 | rel_gyp_file = gyp.common.RelativePath(gyp_file, options.toplevel_dir) |
||
624 | rel_gyp_dir = os.path.dirname(rel_gyp_file) |
||
625 | |||
626 | # Relative path from build dir to top dir. |
||
627 | build_to_top = gyp.common.InvertRelativePath(build_dir, options.toplevel_dir) |
||
628 | # Relative path from build dir to gyp dir. |
||
629 | build_to_gyp = os.path.join(build_to_top, rel_gyp_dir) |
||
630 | |||
631 | path_from_cmakelists_to_gyp = build_to_gyp |
||
632 | |||
633 | spec = target_dicts.get(qualified_target, {}) |
||
634 | config = spec.get('configurations', {}).get(config_to_use, {}) |
||
635 | |||
636 | target_name = spec.get('target_name', '<missing target name>') |
||
637 | target_type = spec.get('type', '<missing target type>') |
||
638 | target_toolset = spec.get('toolset') |
||
639 | |||
640 | cmake_target_type = cmake_target_type_from_gyp_target_type.get(target_type) |
||
641 | if cmake_target_type is None: |
||
642 | print ('Target %s has unknown target type %s, skipping.' % |
||
643 | ( target_name, target_type ) ) |
||
644 | return |
||
645 | |||
646 | SetVariable(output, 'TARGET', target_name) |
||
647 | SetVariable(output, 'TOOLSET', target_toolset) |
||
648 | |||
649 | cmake_target_name = namer.CreateCMakeTargetName(qualified_target) |
||
650 | |||
651 | extra_sources = [] |
||
652 | extra_deps = [] |
||
653 | |||
654 | # Actions must come first, since they can generate more OBJs for use below. |
||
655 | if 'actions' in spec: |
||
656 | WriteActions(cmake_target_name, spec['actions'], extra_sources, extra_deps, |
||
657 | path_from_cmakelists_to_gyp, output) |
||
658 | |||
659 | # Rules must be early like actions. |
||
660 | if 'rules' in spec: |
||
661 | WriteRules(cmake_target_name, spec['rules'], extra_sources, extra_deps, |
||
662 | path_from_cmakelists_to_gyp, output) |
||
663 | |||
664 | # Copies |
||
665 | if 'copies' in spec: |
||
666 | WriteCopies(cmake_target_name, spec['copies'], extra_deps, |
||
667 | path_from_cmakelists_to_gyp, output) |
||
668 | |||
669 | # Target and sources |
||
670 | srcs = spec.get('sources', []) |
||
671 | |||
672 | # Gyp separates the sheep from the goats based on file extensions. |
||
673 | # A full separation is done here because of flag handing (see below). |
||
674 | s_sources = [] |
||
675 | c_sources = [] |
||
676 | cxx_sources = [] |
||
677 | linkable_sources = [] |
||
678 | other_sources = [] |
||
679 | for src in srcs: |
||
680 | _, ext = os.path.splitext(src) |
||
681 | src_type = COMPILABLE_EXTENSIONS.get(ext, None) |
||
682 | src_norm_path = NormjoinPath(path_from_cmakelists_to_gyp, src); |
||
683 | |||
684 | if src_type == 's': |
||
685 | s_sources.append(src_norm_path) |
||
686 | elif src_type == 'cc': |
||
687 | c_sources.append(src_norm_path) |
||
688 | elif src_type == 'cxx': |
||
689 | cxx_sources.append(src_norm_path) |
||
690 | elif Linkable(ext): |
||
691 | linkable_sources.append(src_norm_path) |
||
692 | else: |
||
693 | other_sources.append(src_norm_path) |
||
694 | |||
695 | for extra_source in extra_sources: |
||
696 | src, real_source = extra_source |
||
697 | _, ext = os.path.splitext(real_source) |
||
698 | src_type = COMPILABLE_EXTENSIONS.get(ext, None) |
||
699 | |||
700 | if src_type == 's': |
||
701 | s_sources.append(src) |
||
702 | elif src_type == 'cc': |
||
703 | c_sources.append(src) |
||
704 | elif src_type == 'cxx': |
||
705 | cxx_sources.append(src) |
||
706 | elif Linkable(ext): |
||
707 | linkable_sources.append(src) |
||
708 | else: |
||
709 | other_sources.append(src) |
||
710 | |||
711 | s_sources_name = None |
||
712 | if s_sources: |
||
713 | s_sources_name = cmake_target_name + '__asm_srcs' |
||
714 | SetVariableList(output, s_sources_name, s_sources) |
||
715 | |||
716 | c_sources_name = None |
||
717 | if c_sources: |
||
718 | c_sources_name = cmake_target_name + '__c_srcs' |
||
719 | SetVariableList(output, c_sources_name, c_sources) |
||
720 | |||
721 | cxx_sources_name = None |
||
722 | if cxx_sources: |
||
723 | cxx_sources_name = cmake_target_name + '__cxx_srcs' |
||
724 | SetVariableList(output, cxx_sources_name, cxx_sources) |
||
725 | |||
726 | linkable_sources_name = None |
||
727 | if linkable_sources: |
||
728 | linkable_sources_name = cmake_target_name + '__linkable_srcs' |
||
729 | SetVariableList(output, linkable_sources_name, linkable_sources) |
||
730 | |||
731 | other_sources_name = None |
||
732 | if other_sources: |
||
733 | other_sources_name = cmake_target_name + '__other_srcs' |
||
734 | SetVariableList(output, other_sources_name, other_sources) |
||
735 | |||
736 | # CMake gets upset when executable targets provide no sources. |
||
737 | # http://www.cmake.org/pipermail/cmake/2010-July/038461.html |
||
738 | dummy_sources_name = None |
||
739 | has_sources = (s_sources_name or |
||
740 | c_sources_name or |
||
741 | cxx_sources_name or |
||
742 | linkable_sources_name or |
||
743 | other_sources_name) |
||
744 | if target_type == 'executable' and not has_sources: |
||
745 | dummy_sources_name = cmake_target_name + '__dummy_srcs' |
||
746 | SetVariable(output, dummy_sources_name, |
||
747 | "${obj}.${TOOLSET}/${TARGET}/genc/dummy.c") |
||
748 | output.write('if(NOT EXISTS "') |
||
749 | WriteVariable(output, dummy_sources_name) |
||
750 | output.write('")\n') |
||
751 | output.write(' file(WRITE "') |
||
752 | WriteVariable(output, dummy_sources_name) |
||
753 | output.write('" "")\n') |
||
754 | output.write("endif()\n") |
||
755 | |||
756 | |||
757 | # CMake is opposed to setting linker directories and considers the practice |
||
758 | # of setting linker directories dangerous. Instead, it favors the use of |
||
759 | # find_library and passing absolute paths to target_link_libraries. |
||
760 | # However, CMake does provide the command link_directories, which adds |
||
761 | # link directories to targets defined after it is called. |
||
762 | # As a result, link_directories must come before the target definition. |
||
763 | # CMake unfortunately has no means of removing entries from LINK_DIRECTORIES. |
||
764 | library_dirs = config.get('library_dirs') |
||
765 | if library_dirs is not None: |
||
766 | output.write('link_directories(') |
||
767 | for library_dir in library_dirs: |
||
768 | output.write(' ') |
||
769 | output.write(NormjoinPath(path_from_cmakelists_to_gyp, library_dir)) |
||
770 | output.write('\n') |
||
771 | output.write(')\n') |
||
772 | |||
773 | output.write(cmake_target_type.command) |
||
774 | output.write('(') |
||
775 | output.write(cmake_target_name) |
||
776 | |||
777 | if cmake_target_type.modifier is not None: |
||
778 | output.write(' ') |
||
779 | output.write(cmake_target_type.modifier) |
||
780 | |||
781 | if s_sources_name: |
||
782 | WriteVariable(output, s_sources_name, ' ') |
||
783 | if c_sources_name: |
||
784 | WriteVariable(output, c_sources_name, ' ') |
||
785 | if cxx_sources_name: |
||
786 | WriteVariable(output, cxx_sources_name, ' ') |
||
787 | if linkable_sources_name: |
||
788 | WriteVariable(output, linkable_sources_name, ' ') |
||
789 | if other_sources_name: |
||
790 | WriteVariable(output, other_sources_name, ' ') |
||
791 | if dummy_sources_name: |
||
792 | WriteVariable(output, dummy_sources_name, ' ') |
||
793 | |||
794 | output.write(')\n') |
||
795 | |||
796 | # Let CMake know if the 'all' target should depend on this target. |
||
797 | exclude_from_all = ('TRUE' if qualified_target not in all_qualified_targets |
||
798 | else 'FALSE') |
||
799 | SetTargetProperty(output, cmake_target_name, |
||
800 | 'EXCLUDE_FROM_ALL', exclude_from_all) |
||
801 | for extra_target_name in extra_deps: |
||
802 | SetTargetProperty(output, extra_target_name, |
||
803 | 'EXCLUDE_FROM_ALL', exclude_from_all) |
||
804 | |||
805 | # Output name and location. |
||
806 | if target_type != 'none': |
||
807 | # Link as 'C' if there are no other files |
||
808 | if not c_sources and not cxx_sources: |
||
809 | SetTargetProperty(output, cmake_target_name, 'LINKER_LANGUAGE', ['C']) |
||
810 | |||
811 | # Mark uncompiled sources as uncompiled. |
||
812 | if other_sources_name: |
||
813 | output.write('set_source_files_properties(') |
||
814 | WriteVariable(output, other_sources_name, '') |
||
815 | output.write(' PROPERTIES HEADER_FILE_ONLY "TRUE")\n') |
||
816 | |||
817 | # Mark object sources as linkable. |
||
818 | if linkable_sources_name: |
||
819 | output.write('set_source_files_properties(') |
||
820 | WriteVariable(output, other_sources_name, '') |
||
821 | output.write(' PROPERTIES EXTERNAL_OBJECT "TRUE")\n') |
||
822 | |||
823 | # Output directory |
||
824 | target_output_directory = spec.get('product_dir') |
||
825 | if target_output_directory is None: |
||
826 | if target_type in ('executable', 'loadable_module'): |
||
827 | target_output_directory = generator_default_variables['PRODUCT_DIR'] |
||
828 | elif target_type == 'shared_library': |
||
829 | target_output_directory = '${builddir}/lib.${TOOLSET}' |
||
830 | elif spec.get('standalone_static_library', False): |
||
831 | target_output_directory = generator_default_variables['PRODUCT_DIR'] |
||
832 | else: |
||
833 | base_path = gyp.common.RelativePath(os.path.dirname(gyp_file), |
||
834 | options.toplevel_dir) |
||
835 | target_output_directory = '${obj}.${TOOLSET}' |
||
836 | target_output_directory = ( |
||
837 | os.path.join(target_output_directory, base_path)) |
||
838 | |||
839 | cmake_target_output_directory = NormjoinPathForceCMakeSource( |
||
840 | path_from_cmakelists_to_gyp, |
||
841 | target_output_directory) |
||
842 | SetTargetProperty(output, |
||
843 | cmake_target_name, |
||
844 | cmake_target_type.property_modifier + '_OUTPUT_DIRECTORY', |
||
845 | cmake_target_output_directory) |
||
846 | |||
847 | # Output name |
||
848 | default_product_prefix = '' |
||
849 | default_product_name = target_name |
||
850 | default_product_ext = '' |
||
851 | if target_type == 'static_library': |
||
852 | static_library_prefix = generator_default_variables['STATIC_LIB_PREFIX'] |
||
853 | default_product_name = RemovePrefix(default_product_name, |
||
854 | static_library_prefix) |
||
855 | default_product_prefix = static_library_prefix |
||
856 | default_product_ext = generator_default_variables['STATIC_LIB_SUFFIX'] |
||
857 | |||
858 | elif target_type in ('loadable_module', 'shared_library'): |
||
859 | shared_library_prefix = generator_default_variables['SHARED_LIB_PREFIX'] |
||
860 | default_product_name = RemovePrefix(default_product_name, |
||
861 | shared_library_prefix) |
||
862 | default_product_prefix = shared_library_prefix |
||
863 | default_product_ext = generator_default_variables['SHARED_LIB_SUFFIX'] |
||
864 | |||
865 | elif target_type != 'executable': |
||
866 | print ('ERROR: What output file should be generated?', |
||
867 | 'type', target_type, 'target', target_name) |
||
868 | |||
869 | product_prefix = spec.get('product_prefix', default_product_prefix) |
||
870 | product_name = spec.get('product_name', default_product_name) |
||
871 | product_ext = spec.get('product_extension') |
||
872 | if product_ext: |
||
873 | product_ext = '.' + product_ext |
||
874 | else: |
||
875 | product_ext = default_product_ext |
||
876 | |||
877 | SetTargetProperty(output, cmake_target_name, 'PREFIX', product_prefix) |
||
878 | SetTargetProperty(output, cmake_target_name, |
||
879 | cmake_target_type.property_modifier + '_OUTPUT_NAME', |
||
880 | product_name) |
||
881 | SetTargetProperty(output, cmake_target_name, 'SUFFIX', product_ext) |
||
882 | |||
883 | # Make the output of this target referenceable as a source. |
||
884 | cmake_target_output_basename = product_prefix + product_name + product_ext |
||
885 | cmake_target_output = os.path.join(cmake_target_output_directory, |
||
886 | cmake_target_output_basename) |
||
887 | SetFileProperty(output, cmake_target_output, 'GENERATED', ['TRUE'], '') |
||
888 | |||
889 | # Includes |
||
890 | includes = config.get('include_dirs') |
||
891 | if includes: |
||
892 | # This (target include directories) is what requires CMake 2.8.8 |
||
893 | includes_name = cmake_target_name + '__include_dirs' |
||
894 | SetVariableList(output, includes_name, |
||
895 | [NormjoinPathForceCMakeSource(path_from_cmakelists_to_gyp, include) |
||
896 | for include in includes]) |
||
897 | output.write('set_property(TARGET ') |
||
898 | output.write(cmake_target_name) |
||
899 | output.write(' APPEND PROPERTY INCLUDE_DIRECTORIES ') |
||
900 | WriteVariable(output, includes_name, '') |
||
901 | output.write(')\n') |
||
902 | |||
903 | # Defines |
||
904 | defines = config.get('defines') |
||
905 | if defines is not None: |
||
906 | SetTargetProperty(output, |
||
907 | cmake_target_name, |
||
908 | 'COMPILE_DEFINITIONS', |
||
909 | defines, |
||
910 | ';') |
||
911 | |||
912 | # Compile Flags - http://www.cmake.org/Bug/view.php?id=6493 |
||
913 | # CMake currently does not have target C and CXX flags. |
||
914 | # So, instead of doing... |
||
915 | |||
916 | # cflags_c = config.get('cflags_c') |
||
917 | # if cflags_c is not None: |
||
918 | # SetTargetProperty(output, cmake_target_name, |
||
919 | # 'C_COMPILE_FLAGS', cflags_c, ' ') |
||
920 | |||
921 | # cflags_cc = config.get('cflags_cc') |
||
922 | # if cflags_cc is not None: |
||
923 | # SetTargetProperty(output, cmake_target_name, |
||
924 | # 'CXX_COMPILE_FLAGS', cflags_cc, ' ') |
||
925 | |||
926 | # Instead we must... |
||
927 | cflags = config.get('cflags', []) |
||
928 | cflags_c = config.get('cflags_c', []) |
||
929 | cflags_cxx = config.get('cflags_cc', []) |
||
930 | if (not cflags_c or not c_sources) and (not cflags_cxx or not cxx_sources): |
||
931 | SetTargetProperty(output, cmake_target_name, 'COMPILE_FLAGS', cflags, ' ') |
||
932 | |||
933 | elif c_sources and not (s_sources or cxx_sources): |
||
934 | flags = [] |
||
935 | flags.extend(cflags) |
||
936 | flags.extend(cflags_c) |
||
937 | SetTargetProperty(output, cmake_target_name, 'COMPILE_FLAGS', flags, ' ') |
||
938 | |||
939 | elif cxx_sources and not (s_sources or c_sources): |
||
940 | flags = [] |
||
941 | flags.extend(cflags) |
||
942 | flags.extend(cflags_cxx) |
||
943 | SetTargetProperty(output, cmake_target_name, 'COMPILE_FLAGS', flags, ' ') |
||
944 | |||
945 | else: |
||
946 | # TODO: This is broken, one cannot generally set properties on files, |
||
947 | # as other targets may require different properties on the same files. |
||
948 | if s_sources and cflags: |
||
949 | SetFilesProperty(output, s_sources_name, 'COMPILE_FLAGS', cflags, ' ') |
||
950 | |||
951 | if c_sources and (cflags or cflags_c): |
||
952 | flags = [] |
||
953 | flags.extend(cflags) |
||
954 | flags.extend(cflags_c) |
||
955 | SetFilesProperty(output, c_sources_name, 'COMPILE_FLAGS', flags, ' ') |
||
956 | |||
957 | if cxx_sources and (cflags or cflags_cxx): |
||
958 | flags = [] |
||
959 | flags.extend(cflags) |
||
960 | flags.extend(cflags_cxx) |
||
961 | SetFilesProperty(output, cxx_sources_name, 'COMPILE_FLAGS', flags, ' ') |
||
962 | |||
963 | # Linker flags |
||
964 | ldflags = config.get('ldflags') |
||
965 | if ldflags is not None: |
||
966 | SetTargetProperty(output, cmake_target_name, 'LINK_FLAGS', ldflags, ' ') |
||
967 | |||
968 | # Note on Dependencies and Libraries: |
||
969 | # CMake wants to handle link order, resolving the link line up front. |
||
970 | # Gyp does not retain or enforce specifying enough information to do so. |
||
971 | # So do as other gyp generators and use --start-group and --end-group. |
||
972 | # Give CMake as little information as possible so that it doesn't mess it up. |
||
973 | |||
974 | # Dependencies |
||
975 | rawDeps = spec.get('dependencies', []) |
||
976 | |||
977 | static_deps = [] |
||
978 | shared_deps = [] |
||
979 | other_deps = [] |
||
980 | for rawDep in rawDeps: |
||
981 | dep_cmake_name = namer.CreateCMakeTargetName(rawDep) |
||
982 | dep_spec = target_dicts.get(rawDep, {}) |
||
983 | dep_target_type = dep_spec.get('type', None) |
||
984 | |||
985 | if dep_target_type == 'static_library': |
||
986 | static_deps.append(dep_cmake_name) |
||
987 | elif dep_target_type == 'shared_library': |
||
988 | shared_deps.append(dep_cmake_name) |
||
989 | else: |
||
990 | other_deps.append(dep_cmake_name) |
||
991 | |||
992 | # ensure all external dependencies are complete before internal dependencies |
||
993 | # extra_deps currently only depend on their own deps, so otherwise run early |
||
994 | if static_deps or shared_deps or other_deps: |
||
995 | for extra_dep in extra_deps: |
||
996 | output.write('add_dependencies(') |
||
997 | output.write(extra_dep) |
||
998 | output.write('\n') |
||
999 | for deps in (static_deps, shared_deps, other_deps): |
||
1000 | for dep in gyp.common.uniquer(deps): |
||
1001 | output.write(' ') |
||
1002 | output.write(dep) |
||
1003 | output.write('\n') |
||
1004 | output.write(')\n') |
||
1005 | |||
1006 | linkable = target_type in ('executable', 'loadable_module', 'shared_library') |
||
1007 | other_deps.extend(extra_deps) |
||
1008 | if other_deps or (not linkable and (static_deps or shared_deps)): |
||
1009 | output.write('add_dependencies(') |
||
1010 | output.write(cmake_target_name) |
||
1011 | output.write('\n') |
||
1012 | for dep in gyp.common.uniquer(other_deps): |
||
1013 | output.write(' ') |
||
1014 | output.write(dep) |
||
1015 | output.write('\n') |
||
1016 | if not linkable: |
||
1017 | for deps in (static_deps, shared_deps): |
||
1018 | for lib_dep in gyp.common.uniquer(deps): |
||
1019 | output.write(' ') |
||
1020 | output.write(lib_dep) |
||
1021 | output.write('\n') |
||
1022 | output.write(')\n') |
||
1023 | |||
1024 | # Libraries |
||
1025 | if linkable: |
||
1026 | external_libs = [lib for lib in spec.get('libraries', []) if len(lib) > 0] |
||
1027 | if external_libs or static_deps or shared_deps: |
||
1028 | output.write('target_link_libraries(') |
||
1029 | output.write(cmake_target_name) |
||
1030 | output.write('\n') |
||
1031 | if static_deps: |
||
1032 | write_group = circular_libs and len(static_deps) > 1 |
||
1033 | if write_group: |
||
1034 | output.write('-Wl,--start-group\n') |
||
1035 | for dep in gyp.common.uniquer(static_deps): |
||
1036 | output.write(' ') |
||
1037 | output.write(dep) |
||
1038 | output.write('\n') |
||
1039 | if write_group: |
||
1040 | output.write('-Wl,--end-group\n') |
||
1041 | if shared_deps: |
||
1042 | for dep in gyp.common.uniquer(shared_deps): |
||
1043 | output.write(' ') |
||
1044 | output.write(dep) |
||
1045 | output.write('\n') |
||
1046 | if external_libs: |
||
1047 | for lib in gyp.common.uniquer(external_libs): |
||
1048 | output.write(' ') |
||
1049 | output.write(lib) |
||
1050 | output.write('\n') |
||
1051 | |||
1052 | output.write(')\n') |
||
1053 | |||
1054 | UnsetVariable(output, 'TOOLSET') |
||
1055 | UnsetVariable(output, 'TARGET') |
||
1056 | |||
1222 |