Merge pull request #1332 from ratzlaff/fix_case_insensitive_collisions
Account for filename collisions on systems with case-insensitive file…
This commit is contained in:
commit
53e4f81312
@ -156,6 +156,71 @@ OBJECTS += $(OBJDIR)/hello111.o
|
|||||||
else ifeq ($(config),release)
|
else ifeq ($(config),release)
|
||||||
OBJECTS += $(OBJDIR)/hello1.o
|
OBJECTS += $(OBJDIR)/hello1.o
|
||||||
|
|
||||||
|
else
|
||||||
|
$(error "invalid configuration $(config)")
|
||||||
|
endif
|
||||||
|
|
||||||
|
]]
|
||||||
|
end
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Test that changes in case are treated as if multiple files of the same name are being built
|
||||||
|
--
|
||||||
|
|
||||||
|
function suite.uniqueObjNames_ignoreCase1()
|
||||||
|
files { "a/hello.cpp", "b/Hello.cpp" }
|
||||||
|
prepare()
|
||||||
|
test.capture [[
|
||||||
|
# File sets
|
||||||
|
# #############################################
|
||||||
|
|
||||||
|
OBJECTS :=
|
||||||
|
|
||||||
|
OBJECTS += $(OBJDIR)/Hello1.o
|
||||||
|
OBJECTS += $(OBJDIR)/hello.o
|
||||||
|
|
||||||
|
]]
|
||||||
|
end
|
||||||
|
|
||||||
|
function suite.uniqueObjNames_ignoreCase2()
|
||||||
|
files { "a/hello.cpp", "b/hello.cpp", "c/Hello1.cpp" }
|
||||||
|
prepare()
|
||||||
|
test.capture [[
|
||||||
|
# File sets
|
||||||
|
# #############################################
|
||||||
|
|
||||||
|
OBJECTS :=
|
||||||
|
|
||||||
|
OBJECTS += $(OBJDIR)/Hello11.o
|
||||||
|
OBJECTS += $(OBJDIR)/hello.o
|
||||||
|
OBJECTS += $(OBJDIR)/hello1.o
|
||||||
|
|
||||||
|
]]
|
||||||
|
end
|
||||||
|
|
||||||
|
function suite.uniqueObjectNames_ignoreCase_Release()
|
||||||
|
files { "a/hello.cpp", "b/hello.cpp", "c/Hello1.cpp", "d/Hello11.cpp" }
|
||||||
|
filter "configurations:Debug"
|
||||||
|
excludes {"b/hello.cpp"}
|
||||||
|
filter "configurations:Release"
|
||||||
|
excludes {"d/Hello11.cpp"}
|
||||||
|
|
||||||
|
prepare()
|
||||||
|
test.capture [[
|
||||||
|
# File sets
|
||||||
|
# #############################################
|
||||||
|
|
||||||
|
OBJECTS :=
|
||||||
|
|
||||||
|
OBJECTS += $(OBJDIR)/Hello11.o
|
||||||
|
OBJECTS += $(OBJDIR)/hello.o
|
||||||
|
|
||||||
|
ifeq ($(config),debug)
|
||||||
|
OBJECTS += $(OBJDIR)/Hello111.o
|
||||||
|
|
||||||
|
else ifeq ($(config),release)
|
||||||
|
OBJECTS += $(OBJDIR)/hello1.o
|
||||||
|
|
||||||
else
|
else
|
||||||
$(error "invalid configuration $(config)")
|
$(error "invalid configuration $(config)")
|
||||||
endif
|
endif
|
||||||
|
@ -479,6 +479,82 @@
|
|||||||
]]
|
]]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Test that changes in case are treated as if multiple files of the same name are being built
|
||||||
|
--
|
||||||
|
|
||||||
|
function suite.uniqueObjectNames_onSourceNameCollision_ignoreCase()
|
||||||
|
files { "hello.cpp", "greetings/Hello.cpp" }
|
||||||
|
prepare()
|
||||||
|
test.capture [[
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="greetings\Hello.cpp" />
|
||||||
|
<ClCompile Include="hello.cpp">
|
||||||
|
<ObjectFileName>$(IntDir)\hello1.obj</ObjectFileName>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
]]
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function suite.uniqueObjectNames_onBaseNameCollision_ignoreCase1()
|
||||||
|
files { "a/hello.cpp", "b/Hello.cpp", "c/hello1.cpp" }
|
||||||
|
prepare()
|
||||||
|
test.capture [[
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="a\hello.cpp" />
|
||||||
|
<ClCompile Include="b\Hello.cpp">
|
||||||
|
<ObjectFileName>$(IntDir)\Hello1.obj</ObjectFileName>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="c\hello1.cpp">
|
||||||
|
<ObjectFileName>$(IntDir)\hello11.obj</ObjectFileName>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
]]
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function suite.uniqueObjectNames_onBaseNameCollision_ignoreCase2()
|
||||||
|
files { "a/hello1.cpp", "b/Hello.cpp", "c/hello.cpp" }
|
||||||
|
prepare()
|
||||||
|
test.capture [[
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="a\hello1.cpp" />
|
||||||
|
<ClCompile Include="b\Hello.cpp" />
|
||||||
|
<ClCompile Include="c\hello.cpp">
|
||||||
|
<ObjectFileName>$(IntDir)\hello2.obj</ObjectFileName>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
]]
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function suite.uniqueObjectNames_onBaseNameCollision_Release_ignoreCase()
|
||||||
|
files { "a/Hello.cpp", "b/hello.cpp", "c/hello1.cpp", "d/hello11.cpp" }
|
||||||
|
filter "configurations:Debug"
|
||||||
|
excludes {"b/hello.cpp"}
|
||||||
|
filter "configurations:Release"
|
||||||
|
excludes {"d/hello11.cpp"}
|
||||||
|
|
||||||
|
prepare()
|
||||||
|
test.capture [[
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="a\Hello.cpp" />
|
||||||
|
<ClCompile Include="b\hello.cpp">
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||||
|
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)\hello1.obj</ObjectFileName>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="c\hello1.cpp">
|
||||||
|
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)\hello11.obj</ObjectFileName>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="d\hello11.cpp">
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
]]
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Check handling of per-file forced includes.
|
-- Check handling of per-file forced includes.
|
||||||
|
@ -695,23 +695,40 @@
|
|||||||
-- conflicting object file names - hello1.o
|
-- conflicting object file names - hello1.o
|
||||||
|
|
||||||
function oven.uniqueSequence(f, cfg, seq, bases)
|
function oven.uniqueSequence(f, cfg, seq, bases)
|
||||||
while true do
|
local good_sequence = true
|
||||||
|
repeat
|
||||||
|
-- be optimistic
|
||||||
|
good_sequence = true
|
||||||
f.sequence = seq[cfg] or 0
|
f.sequence = seq[cfg] or 0
|
||||||
seq[cfg] = f.sequence + 1
|
seq[cfg] = f.sequence + 1
|
||||||
|
|
||||||
if seq[cfg] == 1 then
|
if f.sequence == 0 then
|
||||||
|
-- first time seeing this objname
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
|
|
||||||
if not bases[f.objname] then
|
-- getting here has changed our sequence number, but this new "basename"
|
||||||
bases[f.objname] = {}
|
-- may still collide with files that actually end with this "sequence number"
|
||||||
|
-- so we have to check the bases table now
|
||||||
|
|
||||||
|
-- objname changes with the sequence number on every loop
|
||||||
|
local lowerobj = f.objname:lower()
|
||||||
|
if not bases[lowerobj] then
|
||||||
|
-- this is the first appearance of a file that produces this objname
|
||||||
|
-- intialize the table for any future basename that matches our objname
|
||||||
|
bases[lowerobj] = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
if not bases[f.objname][cfg] then
|
if not bases[lowerobj][cfg] then
|
||||||
bases[f.objname][cfg] = 1
|
-- not a collision
|
||||||
break
|
-- start a sequence for a future basename that matches our objname for this cfg
|
||||||
|
bases[lowerobj][cfg] = 1
|
||||||
|
good_sequence = true
|
||||||
|
else
|
||||||
|
-- is truly a collision, try the next sequence number
|
||||||
|
good_sequence = false
|
||||||
end
|
end
|
||||||
end
|
until good_sequence
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -733,11 +750,12 @@
|
|||||||
-- collisions that have occurred for each project configuration. Use
|
-- collisions that have occurred for each project configuration. Use
|
||||||
-- this collision count to generate the unique object file names.
|
-- this collision count to generate the unique object file names.
|
||||||
|
|
||||||
if not bases[file.basename] then
|
local lowerbase = file.basename:lower()
|
||||||
bases[file.basename] = {}
|
if not bases[lowerbase] then
|
||||||
|
bases[lowerbase] = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
local sequences = bases[file.basename]
|
local sequences = bases[lowerbase]
|
||||||
|
|
||||||
for cfg in p.project.eachconfig(prj) do
|
for cfg in p.project.eachconfig(prj) do
|
||||||
local fcfg = p.fileconfig.getconfig(file, cfg)
|
local fcfg = p.fileconfig.getconfig(file, cfg)
|
||||||
|
Loading…
Reference in New Issue
Block a user