Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(468)

Side by Side Diff: pylib/gyp/generator/cmake.py

Issue 1657823003: Add limited support for Mac to CMake generator. (Closed) Base URL: https://chromium.googlesource.com/external/gyp.git@master
Patch Set: Correctly merge global xcode settings. Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright (c) 2013 Google Inc. All rights reserved. 1 # Copyright (c) 2013 Google Inc. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 """cmake output module 5 """cmake output module
6 6
7 This module is under development and should be considered experimental. 7 This module is under development and should be considered experimental.
8 8
9 This module produces cmake (2.8.8+) input as its output. One CMakeLists.txt is 9 This module produces cmake (2.8.8+) input as its output. One CMakeLists.txt is
10 created for each configuration. 10 created for each configuration.
(...skipping 16 matching lines...) Expand all
27 not be able to find the header file directories described in the generated 27 not be able to find the header file directories described in the generated
28 CMakeLists.txt file. 28 CMakeLists.txt file.
29 """ 29 """
30 30
31 import multiprocessing 31 import multiprocessing
32 import os 32 import os
33 import signal 33 import signal
34 import string 34 import string
35 import subprocess 35 import subprocess
36 import gyp.common 36 import gyp.common
37 import gyp.xcode_emulation
37 38
38 generator_default_variables = { 39 generator_default_variables = {
39 'EXECUTABLE_PREFIX': '', 40 'EXECUTABLE_PREFIX': '',
40 'EXECUTABLE_SUFFIX': '', 41 'EXECUTABLE_SUFFIX': '',
41 'STATIC_LIB_PREFIX': 'lib', 42 'STATIC_LIB_PREFIX': 'lib',
42 'STATIC_LIB_SUFFIX': '.a', 43 'STATIC_LIB_SUFFIX': '.a',
43 'SHARED_LIB_PREFIX': 'lib', 44 'SHARED_LIB_PREFIX': 'lib',
44 'SHARED_LIB_SUFFIX': '.so', 45 'SHARED_LIB_SUFFIX': '.so',
45 'SHARED_LIB_DIR': '${builddir}/lib.${TOOLSET}', 46 'SHARED_LIB_DIR': '${builddir}/lib.${TOOLSET}',
46 'LIB_DIR': '${obj}.${TOOLSET}', 47 'LIB_DIR': '${obj}.${TOOLSET}',
(...skipping 554 matching lines...) Expand 10 before | Expand all | Expand 10 after
601 self.cmake_target_base_names_conficting.add(cmake_target_base_name) 602 self.cmake_target_base_names_conficting.add(cmake_target_base_name)
602 603
603 def CreateCMakeTargetName(self, qualified_target): 604 def CreateCMakeTargetName(self, qualified_target):
604 base_name = CreateCMakeTargetBaseName(qualified_target) 605 base_name = CreateCMakeTargetBaseName(qualified_target)
605 if base_name in self.cmake_target_base_names_conficting: 606 if base_name in self.cmake_target_base_names_conficting:
606 return CreateCMakeTargetFullName(qualified_target) 607 return CreateCMakeTargetFullName(qualified_target)
607 return base_name 608 return base_name
608 609
609 610
610 def WriteTarget(namer, qualified_target, target_dicts, build_dir, config_to_use, 611 def WriteTarget(namer, qualified_target, target_dicts, build_dir, config_to_use,
611 options, generator_flags, all_qualified_targets, output): 612 options, generator_flags, all_qualified_targets, flavor,
612 613 output):
613 # The make generator does this always. 614 # The make generator does this always.
614 # TODO: It would be nice to be able to tell CMake all dependencies. 615 # TODO: It would be nice to be able to tell CMake all dependencies.
615 circular_libs = generator_flags.get('circular', True) 616 circular_libs = generator_flags.get('circular', True)
616 617
617 if not generator_flags.get('standalone', False): 618 if not generator_flags.get('standalone', False):
618 output.write('\n#') 619 output.write('\n#')
619 output.write(qualified_target) 620 output.write(qualified_target)
620 output.write('\n') 621 output.write('\n')
621 622
622 gyp_file, _, _ = gyp.common.ParseQualifiedTarget(qualified_target) 623 gyp_file, _, _ = gyp.common.ParseQualifiedTarget(qualified_target)
623 rel_gyp_file = gyp.common.RelativePath(gyp_file, options.toplevel_dir) 624 rel_gyp_file = gyp.common.RelativePath(gyp_file, options.toplevel_dir)
624 rel_gyp_dir = os.path.dirname(rel_gyp_file) 625 rel_gyp_dir = os.path.dirname(rel_gyp_file)
625 626
626 # Relative path from build dir to top dir. 627 # Relative path from build dir to top dir.
627 build_to_top = gyp.common.InvertRelativePath(build_dir, options.toplevel_dir) 628 build_to_top = gyp.common.InvertRelativePath(build_dir, options.toplevel_dir)
628 # Relative path from build dir to gyp dir. 629 # Relative path from build dir to gyp dir.
629 build_to_gyp = os.path.join(build_to_top, rel_gyp_dir) 630 build_to_gyp = os.path.join(build_to_top, rel_gyp_dir)
630 631
631 path_from_cmakelists_to_gyp = build_to_gyp 632 path_from_cmakelists_to_gyp = build_to_gyp
632 633
633 spec = target_dicts.get(qualified_target, {}) 634 spec = target_dicts.get(qualified_target, {})
634 config = spec.get('configurations', {}).get(config_to_use, {}) 635 config = spec.get('configurations', {}).get(config_to_use, {})
635 636
637 xcode_settings = None
638 if flavor == 'mac':
639 xcode_settings = gyp.xcode_emulation.XcodeSettings(spec)
640
636 target_name = spec.get('target_name', '<missing target name>') 641 target_name = spec.get('target_name', '<missing target name>')
637 target_type = spec.get('type', '<missing target type>') 642 target_type = spec.get('type', '<missing target type>')
638 target_toolset = spec.get('toolset') 643 target_toolset = spec.get('toolset')
639 644
640 cmake_target_type = cmake_target_type_from_gyp_target_type.get(target_type) 645 cmake_target_type = cmake_target_type_from_gyp_target_type.get(target_type)
641 if cmake_target_type is None: 646 if cmake_target_type is None:
642 print ('Target %s has unknown target type %s, skipping.' % 647 print ('Target %s has unknown target type %s, skipping.' %
643 ( target_name, target_type ) ) 648 ( target_name, target_type ) )
644 return 649 return
645 650
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
897 output.write('set_property(TARGET ') 902 output.write('set_property(TARGET ')
898 output.write(cmake_target_name) 903 output.write(cmake_target_name)
899 output.write(' APPEND PROPERTY INCLUDE_DIRECTORIES ') 904 output.write(' APPEND PROPERTY INCLUDE_DIRECTORIES ')
900 WriteVariable(output, includes_name, '') 905 WriteVariable(output, includes_name, '')
901 output.write(')\n') 906 output.write(')\n')
902 907
903 # Defines 908 # Defines
904 defines = config.get('defines') 909 defines = config.get('defines')
905 if defines is not None: 910 if defines is not None:
906 SetTargetProperty(output, 911 SetTargetProperty(output,
907 cmake_target_name, 912 cmake_target_name,
908 'COMPILE_DEFINITIONS', 913 'COMPILE_DEFINITIONS',
909 defines, 914 defines,
910 ';') 915 ';')
911 916
912 # Compile Flags - http://www.cmake.org/Bug/view.php?id=6493 917 # Compile Flags - http://www.cmake.org/Bug/view.php?id=6493
913 # CMake currently does not have target C and CXX flags. 918 # CMake currently does not have target C and CXX flags.
914 # So, instead of doing... 919 # So, instead of doing...
915 920
916 # cflags_c = config.get('cflags_c') 921 # cflags_c = config.get('cflags_c')
917 # if cflags_c is not None: 922 # if cflags_c is not None:
918 # SetTargetProperty(output, cmake_target_name, 923 # SetTargetProperty(output, cmake_target_name,
919 # 'C_COMPILE_FLAGS', cflags_c, ' ') 924 # 'C_COMPILE_FLAGS', cflags_c, ' ')
920 925
921 # cflags_cc = config.get('cflags_cc') 926 # cflags_cc = config.get('cflags_cc')
922 # if cflags_cc is not None: 927 # if cflags_cc is not None:
923 # SetTargetProperty(output, cmake_target_name, 928 # SetTargetProperty(output, cmake_target_name,
924 # 'CXX_COMPILE_FLAGS', cflags_cc, ' ') 929 # 'CXX_COMPILE_FLAGS', cflags_cc, ' ')
925 930
926 # Instead we must... 931 # Instead we must...
927 cflags = config.get('cflags', []) 932 cflags = config.get('cflags', [])
928 cflags_c = config.get('cflags_c', []) 933 cflags_c = config.get('cflags_c', [])
929 cflags_cxx = config.get('cflags_cc', []) 934 cflags_cxx = config.get('cflags_cc', [])
935 if xcode_settings:
936 cflags = xcode_settings.GetCflags(config_to_use)
937 cflags_c = xcode_settings.GetCflagsC(config_to_use)
938 cflags_cxx = xcode_settings.GetCflagsCC(config_to_use)
939 #cflags_objc = xcode_settings.GetCflagsObjC(config_to_use)
940 #cflags_objcc = xcode_settings.GetCflagsObjCC(config_to_use)
941
930 if (not cflags_c or not c_sources) and (not cflags_cxx or not cxx_sources): 942 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, ' ') 943 SetTargetProperty(output, cmake_target_name, 'COMPILE_FLAGS', cflags, ' ')
932 944
933 elif c_sources and not (s_sources or cxx_sources): 945 elif c_sources and not (s_sources or cxx_sources):
934 flags = [] 946 flags = []
935 flags.extend(cflags) 947 flags.extend(cflags)
936 flags.extend(cflags_c) 948 flags.extend(cflags_c)
937 SetTargetProperty(output, cmake_target_name, 'COMPILE_FLAGS', flags, ' ') 949 SetTargetProperty(output, cmake_target_name, 'COMPILE_FLAGS', flags, ' ')
938 950
939 elif cxx_sources and not (s_sources or c_sources): 951 elif cxx_sources and not (s_sources or c_sources):
(...skipping 18 matching lines...) Expand all
958 flags = [] 970 flags = []
959 flags.extend(cflags) 971 flags.extend(cflags)
960 flags.extend(cflags_cxx) 972 flags.extend(cflags_cxx)
961 SetFilesProperty(output, cxx_sources_name, 'COMPILE_FLAGS', flags, ' ') 973 SetFilesProperty(output, cxx_sources_name, 'COMPILE_FLAGS', flags, ' ')
962 974
963 # Linker flags 975 # Linker flags
964 ldflags = config.get('ldflags') 976 ldflags = config.get('ldflags')
965 if ldflags is not None: 977 if ldflags is not None:
966 SetTargetProperty(output, cmake_target_name, 'LINK_FLAGS', ldflags, ' ') 978 SetTargetProperty(output, cmake_target_name, 'LINK_FLAGS', ldflags, ' ')
967 979
980 # XCode settings
981 xcode_settings = config.get('xcode_settings', {})
982 for xcode_setting, xcode_value in xcode_settings.viewitems():
983 SetTargetProperty(output, cmake_target_name,
984 "XCODE_ATTRIBUTE_%s" % xcode_setting, xcode_value,
985 '' if isinstance(xcode_value, str) else ' ')
986
968 # Note on Dependencies and Libraries: 987 # Note on Dependencies and Libraries:
969 # CMake wants to handle link order, resolving the link line up front. 988 # 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. 989 # 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. 990 # 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. 991 # Give CMake as little information as possible so that it doesn't mess it up.
973 992
974 # Dependencies 993 # Dependencies
975 rawDeps = spec.get('dependencies', []) 994 rawDeps = spec.get('dependencies', [])
976 995
977 static_deps = [] 996 static_deps = []
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1022 output.write(')\n') 1041 output.write(')\n')
1023 1042
1024 # Libraries 1043 # Libraries
1025 if linkable: 1044 if linkable:
1026 external_libs = [lib for lib in spec.get('libraries', []) if len(lib) > 0] 1045 external_libs = [lib for lib in spec.get('libraries', []) if len(lib) > 0]
1027 if external_libs or static_deps or shared_deps: 1046 if external_libs or static_deps or shared_deps:
1028 output.write('target_link_libraries(') 1047 output.write('target_link_libraries(')
1029 output.write(cmake_target_name) 1048 output.write(cmake_target_name)
1030 output.write('\n') 1049 output.write('\n')
1031 if static_deps: 1050 if static_deps:
1032 write_group = circular_libs and len(static_deps) > 1 1051 write_group = circular_libs and len(static_deps) > 1 and flavor != 'mac'
1033 if write_group: 1052 if write_group:
1034 output.write('-Wl,--start-group\n') 1053 output.write('-Wl,--start-group\n')
1035 for dep in gyp.common.uniquer(static_deps): 1054 for dep in gyp.common.uniquer(static_deps):
1036 output.write(' ') 1055 output.write(' ')
1037 output.write(dep) 1056 output.write(dep)
1038 output.write('\n') 1057 output.write('\n')
1039 if write_group: 1058 if write_group:
1040 output.write('-Wl,--end-group\n') 1059 output.write('-Wl,--end-group\n')
1041 if shared_deps: 1060 if shared_deps:
1042 for dep in gyp.common.uniquer(shared_deps): 1061 for dep in gyp.common.uniquer(shared_deps):
1043 output.write(' ') 1062 output.write(' ')
1044 output.write(dep) 1063 output.write(dep)
1045 output.write('\n') 1064 output.write('\n')
1046 if external_libs: 1065 if external_libs:
1047 for lib in gyp.common.uniquer(external_libs): 1066 for lib in gyp.common.uniquer(external_libs):
1048 output.write(' ') 1067 output.write(' "')
1049 output.write(lib) 1068 output.write(RemovePrefix(lib, "$(SDKROOT)"))
1050 output.write('\n') 1069 output.write('"\n')
1051 1070
1052 output.write(')\n') 1071 output.write(')\n')
1053 1072
1054 UnsetVariable(output, 'TOOLSET') 1073 UnsetVariable(output, 'TOOLSET')
1055 UnsetVariable(output, 'TARGET') 1074 UnsetVariable(output, 'TARGET')
1056 1075
1057 1076
1058 def GenerateOutputForConfig(target_list, target_dicts, data, 1077 def GenerateOutputForConfig(target_list, target_dicts, data,
1059 params, config_to_use): 1078 params, config_to_use):
1060 options = params['options'] 1079 options = params['options']
1061 generator_flags = params['generator_flags'] 1080 generator_flags = params['generator_flags']
1081 flavor = gyp.common.GetFlavor(params)
1062 1082
1063 # generator_dir: relative path from pwd to where make puts build files. 1083 # generator_dir: relative path from pwd to where make puts build files.
1064 # Makes migrating from make to cmake easier, cmake doesn't put anything here. 1084 # Makes migrating from make to cmake easier, cmake doesn't put anything here.
1065 # Each Gyp configuration creates a different CMakeLists.txt file 1085 # Each Gyp configuration creates a different CMakeLists.txt file
1066 # to avoid incompatibilities between Gyp and CMake configurations. 1086 # to avoid incompatibilities between Gyp and CMake configurations.
1067 generator_dir = os.path.relpath(options.generator_output or '.') 1087 generator_dir = os.path.relpath(options.generator_output or '.')
1068 1088
1069 # output_dir: relative path from generator_dir to the build directory. 1089 # output_dir: relative path from generator_dir to the build directory.
1070 output_dir = generator_flags.get('output_dir', 'out') 1090 output_dir = generator_flags.get('output_dir', 'out')
1071 1091
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1134 # CMake by default names the object resulting from foo.c to be foo.c.o. 1154 # CMake by default names the object resulting from foo.c to be foo.c.o.
1135 # Gyp traditionally names the object resulting from foo.c foo.o. 1155 # Gyp traditionally names the object resulting from foo.c foo.o.
1136 # This should be irrelevant, but some targets extract .o files from .a 1156 # This should be irrelevant, but some targets extract .o files from .a
1137 # and depend on the name of the extracted .o files. 1157 # and depend on the name of the extracted .o files.
1138 output.write('set(CMAKE_C_OUTPUT_EXTENSION_REPLACE 1)\n') 1158 output.write('set(CMAKE_C_OUTPUT_EXTENSION_REPLACE 1)\n')
1139 output.write('set(CMAKE_CXX_OUTPUT_EXTENSION_REPLACE 1)\n') 1159 output.write('set(CMAKE_CXX_OUTPUT_EXTENSION_REPLACE 1)\n')
1140 output.write('\n') 1160 output.write('\n')
1141 1161
1142 # Force ninja to use rsp files. Otherwise link and ar lines can get too long, 1162 # Force ninja to use rsp files. Otherwise link and ar lines can get too long,
1143 # resulting in 'Argument list too long' errors. 1163 # resulting in 'Argument list too long' errors.
1144 output.write('set(CMAKE_NINJA_FORCE_RESPONSE_FILE 1)\n') 1164 # However, rsp files don't work correctly on Mac.
1165 if flavor != 'mac':
1166 output.write('set(CMAKE_NINJA_FORCE_RESPONSE_FILE 1)\n')
1145 output.write('\n') 1167 output.write('\n')
1146 1168
1147 namer = CMakeNamer(target_list) 1169 namer = CMakeNamer(target_list)
1148 1170
1149 # The list of targets upon which the 'all' target should depend. 1171 # The list of targets upon which the 'all' target should depend.
1150 # CMake has it's own implicit 'all' target, one is not created explicitly. 1172 # CMake has it's own implicit 'all' target, one is not created explicitly.
1151 all_qualified_targets = set() 1173 all_qualified_targets = set()
1152 for build_file in params['build_files']: 1174 for build_file in params['build_files']:
1153 for qualified_target in gyp.common.AllTargets(target_list, 1175 for qualified_target in gyp.common.AllTargets(target_list,
1154 target_dicts, 1176 target_dicts,
1155 os.path.normpath(build_file)): 1177 os.path.normpath(build_file)):
1156 all_qualified_targets.add(qualified_target) 1178 all_qualified_targets.add(qualified_target)
1157 1179
1158 for qualified_target in target_list: 1180 for qualified_target in target_list:
1181 if flavor == 'mac':
1182 gyp_file, _, _ = gyp.common.ParseQualifiedTarget(qualified_target)
1183 spec = target_dicts[qualified_target]
1184 gyp.xcode_emulation.MergeGlobalXcodeSettingsToSpec(data[gyp_file], spec)
1185
1159 WriteTarget(namer, qualified_target, target_dicts, build_dir, config_to_use, 1186 WriteTarget(namer, qualified_target, target_dicts, build_dir, config_to_use,
1160 options, generator_flags, all_qualified_targets, output) 1187 options, generator_flags, all_qualified_targets, flavor, output)
1161 1188
1162 output.close() 1189 output.close()
1163 1190
1164 1191
1165 def PerformBuild(data, configurations, params): 1192 def PerformBuild(data, configurations, params):
1166 options = params['options'] 1193 options = params['options']
1167 generator_flags = params['generator_flags'] 1194 generator_flags = params['generator_flags']
1168 1195
1169 # generator_dir: relative path from pwd to where make puts build files. 1196 # generator_dir: relative path from pwd to where make puts build files.
1170 # Makes migrating from make to cmake easier, cmake doesn't put anything here. 1197 # Makes migrating from make to cmake easier, cmake doesn't put anything here.
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1212 arglists.append((target_list, target_dicts, data, 1239 arglists.append((target_list, target_dicts, data,
1213 params, config_name)) 1240 params, config_name))
1214 pool.map(CallGenerateOutputForConfig, arglists) 1241 pool.map(CallGenerateOutputForConfig, arglists)
1215 except KeyboardInterrupt, e: 1242 except KeyboardInterrupt, e:
1216 pool.terminate() 1243 pool.terminate()
1217 raise e 1244 raise e
1218 else: 1245 else:
1219 for config_name in config_names: 1246 for config_name in config_names:
1220 GenerateOutputForConfig(target_list, target_dicts, data, 1247 GenerateOutputForConfig(target_list, target_dicts, data,
1221 params, config_name) 1248 params, config_name)
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698