Skip to content

Commit

Permalink
Account for filename collisions on systems with case-insensitive file…
Browse files Browse the repository at this point in the history
… systems
  • Loading branch information
ratzlaff committed Sep 12, 2019
1 parent a9f04f3 commit f7259c7
Show file tree
Hide file tree
Showing 3 changed files with 170 additions and 12 deletions.
65 changes: 65 additions & 0 deletions modules/gmake2/tests/test_gmake2_objects.lua
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,71 @@ OBJECTS += $(OBJDIR)/hello111.o
else ifeq ($(config),release)
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
$(error "invalid configuration $(config)")
endif
Expand Down
76 changes: 76 additions & 0 deletions modules/vstudio/tests/vc2010/test_files.lua
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,82 @@
]]
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.
Expand Down
41 changes: 29 additions & 12 deletions src/base/oven.lua
Original file line number Diff line number Diff line change
Expand Up @@ -695,23 +695,40 @@
-- conflicting object file names - hello1.o

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
seq[cfg] = f.sequence + 1

if seq[cfg] == 1 then
if f.sequence == 0 then
-- first time seeing this objname
break
end

if not bases[f.objname] then
bases[f.objname] = {}
-- getting here has changed our sequence number, but this new "basename"
-- 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

if not bases[f.objname][cfg] then
bases[f.objname][cfg] = 1
break
if not bases[lowerobj][cfg] then
-- not a collision
-- 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
until good_sequence
end


Expand All @@ -732,12 +749,12 @@
-- For each base file name encountered, keep a count of the number of
-- collisions that have occurred for each project configuration. Use
-- this collision count to generate the unique object file names.

if not bases[file.basename] then
bases[file.basename] = {}
local lowerbase = file.basename:lower()
if not bases[lowerbase] then
bases[lowerbase] = {}
end

local sequences = bases[file.basename]
local sequences = bases[lowerbase]

for cfg in p.project.eachconfig(prj) do
local fcfg = p.fileconfig.getconfig(file, cfg)
Expand Down

0 comments on commit f7259c7

Please sign in to comment.