| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. 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 #include "tools/gn/filesystem_utils.h" | 5 #include "tools/gn/filesystem_utils.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/files/file_util.h" | 9 #include "base/files/file_util.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 156 // null-terminated strings with -1 passed for the length, so we do that here. | 156 // null-terminated strings with -1 passed for the length, so we do that here. |
| 157 // There should not be embedded nulls in filesystem strings. | 157 // There should not be embedded nulls in filesystem strings. |
| 158 return ::CompareString(LOCALE_USER_DEFAULT, LINGUISTIC_IGNORECASE, | 158 return ::CompareString(LOCALE_USER_DEFAULT, LINGUISTIC_IGNORECASE, |
| 159 a.c_str(), -1, b.c_str(), -1) == CSTR_EQUAL; | 159 a.c_str(), -1, b.c_str(), -1) == CSTR_EQUAL; |
| 160 #else | 160 #else |
| 161 // Assume case-sensitive filesystems on non-Windows. | 161 // Assume case-sensitive filesystems on non-Windows. |
| 162 return a == b; | 162 return a == b; |
| 163 #endif | 163 #endif |
| 164 } | 164 } |
| 165 | 165 |
| 166 // Helper function for computing subdirectories in the build directory |
| 167 // corresponding to absolute paths. This will try to resolve the absolute |
| 168 // path as a source-relative path first, and otherwise it creates a |
| 169 // special subdirectory for absolute paths to keep them from colliding with |
| 170 // other generated sources and outputs. |
| 171 void AppendFixedAbsolutePathSuffix(const BuildSettings* build_settings, |
| 172 const SourceDir& source_dir, |
| 173 OutputFile* result) { |
| 174 const std::string& build_dir = build_settings->build_dir().value(); |
| 175 |
| 176 if (base::StartsWith(source_dir.value(), build_dir, |
| 177 base::CompareCase::SENSITIVE)) { |
| 178 size_t build_dir_size = build_dir.size(); |
| 179 result->value().append(&source_dir.value()[build_dir_size], |
| 180 source_dir.value().size() - build_dir_size); |
| 181 } else { |
| 182 result->value().append("ABS_PATH"); |
| 183 #if defined(OS_WIN) |
| 184 // Windows absolute path contains ':' after drive letter. Remove it to |
| 185 // avoid inserting ':' in the middle of path (eg. "ABS_PATH/C:/"). |
| 186 std::string src_dir_value = source_dir.value(); |
| 187 const auto colon_pos = src_dir_value.find(':'); |
| 188 if (colon_pos != std::string::npos) |
| 189 src_dir_value.erase(src_dir_value.begin() + colon_pos); |
| 190 #else |
| 191 const std::string& src_dir_value = source_dir.value(); |
| 192 #endif |
| 193 result->value().append(src_dir_value); |
| 194 } |
| 195 } |
| 196 |
| 166 } // namespace | 197 } // namespace |
| 167 | 198 |
| 168 std::string FilePathToUTF8(const base::FilePath::StringType& str) { | 199 std::string FilePathToUTF8(const base::FilePath::StringType& str) { |
| 169 #if defined(OS_WIN) | 200 #if defined(OS_WIN) |
| 170 return base::WideToUTF8(str); | 201 return base::WideToUTF8(str); |
| 171 #else | 202 #else |
| 172 return str; | 203 return str; |
| 173 #endif | 204 #endif |
| 174 } | 205 } |
| 175 | 206 |
| (...skipping 597 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 773 #endif | 804 #endif |
| 774 | 805 |
| 775 if (!write_success && err) { | 806 if (!write_success && err) { |
| 776 *err = Err(Location(), "Unable to write file.", | 807 *err = Err(Location(), "Unable to write file.", |
| 777 "I was writing \"" + FilePathToUTF8(file_path) + "\"."); | 808 "I was writing \"" + FilePathToUTF8(file_path) + "\"."); |
| 778 } | 809 } |
| 779 | 810 |
| 780 return write_success; | 811 return write_success; |
| 781 } | 812 } |
| 782 | 813 |
| 783 SourceDir GetToolchainOutputDir(const Settings* settings) { | 814 BuildDirContext::BuildDirContext(const Target* target) |
| 784 return settings->toolchain_output_subdir().AsSourceDir( | 815 : BuildDirContext(target->settings()) { |
| 785 settings->build_settings()); | |
| 786 } | 816 } |
| 787 | 817 |
| 788 SourceDir GetToolchainOutputDir(const BuildSettings* build_settings, | 818 BuildDirContext::BuildDirContext(const Settings* settings) |
| 789 const Label& toolchain_label, bool is_default) { | 819 : BuildDirContext(settings->build_settings(), |
| 790 std::string result = build_settings->build_dir().value(); | 820 settings->toolchain_label(), |
| 791 result.append(GetOutputSubdirName(toolchain_label, is_default)); | 821 settings->is_default()) { |
| 792 return SourceDir(SourceDir::SWAP_IN, &result); | |
| 793 } | 822 } |
| 794 | 823 |
| 795 SourceDir GetToolchainGenDir(const Settings* settings) { | 824 BuildDirContext::BuildDirContext(const Scope* execution_scope) |
| 796 return GetToolchainGenDirAsOutputFile(settings).AsSourceDir( | 825 : BuildDirContext(execution_scope->settings()) { |
| 797 settings->build_settings()); | |
| 798 } | 826 } |
| 799 | 827 |
| 800 OutputFile GetToolchainGenDirAsOutputFile(const Settings* settings) { | 828 BuildDirContext::BuildDirContext(const Scope* execution_scope, |
| 801 OutputFile result(settings->toolchain_output_subdir()); | 829 const Label& toolchain_label) |
| 802 result.value().append("gen/"); | 830 : BuildDirContext(execution_scope->settings()->build_settings(), |
| 831 toolchain_label, |
| 832 execution_scope->settings()->default_toolchain_label() == |
| 833 toolchain_label) { |
| 834 } |
| 835 |
| 836 BuildDirContext::BuildDirContext(const BuildSettings* in_build_settings, |
| 837 const Label& in_toolchain_label, |
| 838 bool in_is_default_toolchain) |
| 839 : build_settings(in_build_settings), |
| 840 toolchain_label(in_toolchain_label), |
| 841 is_default_toolchain(in_is_default_toolchain) { |
| 842 } |
| 843 |
| 844 SourceDir GetBuildDirAsSourceDir(const BuildDirContext& context, |
| 845 BuildDirType type) { |
| 846 return GetBuildDirAsOutputFile(context, type).AsSourceDir( |
| 847 context.build_settings); |
| 848 } |
| 849 |
| 850 OutputFile GetBuildDirAsOutputFile(const BuildDirContext& context, |
| 851 BuildDirType type) { |
| 852 OutputFile result(GetOutputSubdirName(context.toolchain_label, |
| 853 context.is_default_toolchain)); |
| 854 DCHECK(result.value().empty() || result.value().back() == '/'); |
| 855 |
| 856 if (type == BuildDirType::GEN) |
| 857 result.value().append("gen/"); |
| 858 else if (type == BuildDirType::OBJ) |
| 859 result.value().append("obj/"); |
| 803 return result; | 860 return result; |
| 804 } | 861 } |
| 805 | 862 |
| 806 SourceDir GetToolchainGenDir(const BuildSettings* build_settings, | 863 SourceDir GetSubBuildDirAsSourceDir(const BuildDirContext& context, |
| 807 const Label& toolchain_label, bool is_default) { | 864 const SourceDir& source_dir, |
| 808 std::string result = GetToolchainOutputDir( | 865 BuildDirType type) { |
| 809 build_settings, toolchain_label, is_default).value(); | 866 return GetSubBuildDirAsOutputFile(context, source_dir, type) |
| 810 result.append("gen/"); | 867 .AsSourceDir(context.build_settings); |
| 811 return SourceDir(SourceDir::SWAP_IN, &result); | |
| 812 } | 868 } |
| 813 | 869 |
| 814 SourceDir GetOutputDirForSourceDir(const Settings* settings, | 870 OutputFile GetSubBuildDirAsOutputFile(const BuildDirContext& context, |
| 815 const SourceDir& source_dir) { | 871 const SourceDir& source_dir, |
| 816 return GetOutputDirForSourceDir( | 872 BuildDirType type) { |
| 817 settings->build_settings(), source_dir, | 873 DCHECK(type != BuildDirType::TOOLCHAIN_ROOT); |
| 818 settings->toolchain_label(), settings->is_default()); | 874 OutputFile result = GetBuildDirAsOutputFile(context, type); |
| 819 } | |
| 820 | |
| 821 void AppendFixedAbsolutePathSuffix(const BuildSettings* build_settings, | |
| 822 const SourceDir& source_dir, | |
| 823 OutputFile* result) { | |
| 824 const std::string& build_dir = build_settings->build_dir().value(); | |
| 825 | |
| 826 if (base::StartsWith(source_dir.value(), build_dir, | |
| 827 base::CompareCase::SENSITIVE)) { | |
| 828 size_t build_dir_size = build_dir.size(); | |
| 829 result->value().append(&source_dir.value()[build_dir_size], | |
| 830 source_dir.value().size() - build_dir_size); | |
| 831 } else { | |
| 832 result->value().append("ABS_PATH"); | |
| 833 #if defined(OS_WIN) | |
| 834 // Windows absolute path contains ':' after drive letter. Remove it to | |
| 835 // avoid inserting ':' in the middle of path (eg. "ABS_PATH/C:/"). | |
| 836 std::string src_dir_value = source_dir.value(); | |
| 837 const auto colon_pos = src_dir_value.find(':'); | |
| 838 if (colon_pos != std::string::npos) | |
| 839 src_dir_value.erase(src_dir_value.begin() + colon_pos); | |
| 840 #else | |
| 841 const std::string& src_dir_value = source_dir.value(); | |
| 842 #endif | |
| 843 result->value().append(src_dir_value); | |
| 844 } | |
| 845 } | |
| 846 | |
| 847 SourceDir GetOutputDirForSourceDir( | |
| 848 const BuildSettings* build_settings, | |
| 849 const SourceDir& source_dir, | |
| 850 const Label& toolchain_label, | |
| 851 bool is_default_toolchain) { | |
| 852 return GetOutputDirForSourceDirAsOutputFile( | |
| 853 build_settings, source_dir, toolchain_label, is_default_toolchain) | |
| 854 .AsSourceDir(build_settings); | |
| 855 } | |
| 856 | |
| 857 OutputFile GetOutputDirForSourceDirAsOutputFile( | |
| 858 const BuildSettings* build_settings, | |
| 859 const SourceDir& source_dir, | |
| 860 const Label& toolchain_label, | |
| 861 bool is_default_toolchain) { | |
| 862 OutputFile result(GetOutputSubdirName(toolchain_label, is_default_toolchain)); | |
| 863 result.value().append("obj/"); | |
| 864 | 875 |
| 865 if (source_dir.is_source_absolute()) { | 876 if (source_dir.is_source_absolute()) { |
| 866 // The source dir is source-absolute, so we trim off the two leading | 877 // The source dir is source-absolute, so we trim off the two leading |
| 867 // slashes to append to the toolchain object directory. | 878 // slashes to append to the toolchain object directory. |
| 868 result.value().append(&source_dir.value()[2], | 879 result.value().append(&source_dir.value()[2], |
| 869 source_dir.value().size() - 2); | 880 source_dir.value().size() - 2); |
| 870 } else { | 881 } else { |
| 871 // System-absolute. | 882 // System-absolute. |
| 872 AppendFixedAbsolutePathSuffix(build_settings, source_dir, &result); | 883 AppendFixedAbsolutePathSuffix(context.build_settings, source_dir, &result); |
| 873 } | 884 } |
| 874 return result; | 885 return result; |
| 875 } | 886 } |
| 876 | 887 |
| 877 OutputFile GetOutputDirForSourceDirAsOutputFile(const Settings* settings, | 888 SourceDir GetBuildDirForTargetAsSourceDir(const Target* target, |
| 878 const SourceDir& source_dir) { | 889 BuildDirType type) { |
| 879 return GetOutputDirForSourceDirAsOutputFile( | 890 return GetSubBuildDirAsSourceDir( |
| 880 settings->build_settings(), source_dir, | 891 BuildDirContext(target), target->label().dir(), type); |
| 881 settings->toolchain_label(), settings->is_default()); | |
| 882 } | 892 } |
| 883 | 893 |
| 884 SourceDir GetGenDirForSourceDir(const Settings* settings, | 894 OutputFile GetBuildDirForTargetAsOutputFile(const Target* target, |
| 885 const SourceDir& source_dir) { | 895 BuildDirType type) { |
| 886 return GetGenDirForSourceDirAsOutputFile(settings, source_dir).AsSourceDir( | 896 return GetSubBuildDirAsOutputFile( |
| 887 settings->build_settings()); | 897 BuildDirContext(target), target->label().dir(), type); |
| 888 } | 898 } |
| 889 | 899 |
| 890 OutputFile GetGenDirForSourceDirAsOutputFile(const Settings* settings, | 900 SourceDir GetScopeCurrentBuildDirAsSourceDir(const Scope* scope, |
| 891 const SourceDir& source_dir) { | 901 BuildDirType type) { |
| 892 OutputFile result = GetToolchainGenDirAsOutputFile(settings); | 902 if (type == BuildDirType::TOOLCHAIN_ROOT) |
| 893 | 903 return GetBuildDirAsSourceDir(BuildDirContext(scope), type); |
| 894 if (source_dir.is_source_absolute()) { | 904 return GetSubBuildDirAsSourceDir( |
| 895 // The source dir should be source-absolute, so we trim off the two leading | 905 BuildDirContext(scope), scope->GetSourceDir(), type); |
| 896 // slashes to append to the toolchain object directory. | |
| 897 DCHECK(source_dir.is_source_absolute()); | |
| 898 result.value().append(&source_dir.value()[2], | |
| 899 source_dir.value().size() - 2); | |
| 900 } else { | |
| 901 // System-absolute. | |
| 902 AppendFixedAbsolutePathSuffix(settings->build_settings(), source_dir, | |
| 903 &result); | |
| 904 } | |
| 905 return result; | |
| 906 } | 906 } |
| 907 | |
| 908 SourceDir GetTargetOutputDir(const Target* target) { | |
| 909 return GetOutputDirForSourceDirAsOutputFile( | |
| 910 target->settings(), target->label().dir()).AsSourceDir( | |
| 911 target->settings()->build_settings()); | |
| 912 } | |
| 913 | |
| 914 OutputFile GetTargetOutputDirAsOutputFile(const Target* target) { | |
| 915 return GetOutputDirForSourceDirAsOutputFile( | |
| 916 target->settings(), target->label().dir()); | |
| 917 } | |
| 918 | |
| 919 SourceDir GetTargetGenDir(const Target* target) { | |
| 920 return GetTargetGenDirAsOutputFile(target).AsSourceDir( | |
| 921 target->settings()->build_settings()); | |
| 922 } | |
| 923 | |
| 924 OutputFile GetTargetGenDirAsOutputFile(const Target* target) { | |
| 925 return GetGenDirForSourceDirAsOutputFile( | |
| 926 target->settings(), target->label().dir()); | |
| 927 } | |
| 928 | |
| 929 SourceDir GetCurrentOutputDir(const Scope* scope) { | |
| 930 return GetOutputDirForSourceDirAsOutputFile( | |
| 931 scope->settings(), scope->GetSourceDir()).AsSourceDir( | |
| 932 scope->settings()->build_settings()); | |
| 933 } | |
| 934 | |
| 935 SourceDir GetCurrentGenDir(const Scope* scope) { | |
| 936 return GetGenDirForSourceDir(scope->settings(), scope->GetSourceDir()); | |
| 937 } | |
| OLD | NEW |