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 |