Merge pull request #809 from Blizzard/os-touch

Added os touchfile and a workaround for vs2010 reloading
This commit is contained in:
Tom van Dijck 2017-06-20 10:54:00 -07:00 committed by GitHub
commit 411a808070
5 changed files with 151 additions and 4 deletions

View File

@ -59,7 +59,7 @@
end
elseif p.project.isc(prj) or p.project.iscpp(prj) then
p.generate(prj, ".vcxproj", vstudio.vc2010.generate)
local projFileModified = p.generate(prj, ".vcxproj", vstudio.vc2010.generate)
-- Skip generation of empty user files
local user = p.capture(function() vstudio.vc2010.generateUser(prj) end)
@ -69,7 +69,10 @@
-- Only generate a filters file if the source tree actually has subfolders
if tree.hasbranches(project.getsourcetree(prj)) then
p.generate(prj, ".vcxproj.filters", vstudio.vc2010.generateFilters)
if p.generate(prj, ".vcxproj.filters", vstudio.vc2010.generateFilters) == true and projFileModified == false then
-- vs workaround for issue where if only the .filters file is modified, VS doesn't automaticly trigger a reload
p.touch(prj, ".vcxproj")
end
end
end

View File

@ -137,6 +137,7 @@
--
-- Returns a boolean if the file was modified
-- Open a file for output, and call a function to actually do the writing.
-- Used by the actions to generate workspace and project files.
--
@ -160,22 +161,56 @@
-- make sure output folder exists.
local dir = path.getdirectory(fn)
ok, err = os.mkdir(dir)
local ok, err = os.mkdir(dir)
if not ok then
error(err, 0)
end
local f, err = os.writefile_ifnotequal(output, fn);
if (f < 0) then
if (f == 0) then
return false -- file not modified
elseif (f < 0) then
error(err, 0)
elseif (f > 0) then
printf("Generated %s...", path.getrelative(os.getcwd(), fn))
return true -- file modified
end
end
--
-- Marks a file as modified without changing its contents
--
-- @param obj
-- A workspace or project object; will be passed to the callback function.
-- @param ext
-- An optional extension for the generated file, with the leading dot.
--
function premake.touch(obj, ext)
local fn = premake.filename(obj, ext)
-- make sure output folder exists.
local dir = path.getdirectory(fn)
local ok, err = os.mkdir(dir)
if not ok then
error(err, 0)
end
local f, err = os.touchfile(fn);
if (f == 0) then
return false -- file marked as modified
elseif (f < 0) then
error(err, 0)
elseif (f > 0) then
return true -- file created
end
end
---
-- Returns the full path a file generated from any of the project
-- objects (project, workspace, rule).

107
src/host/os_touchfile.c Normal file
View File

@ -0,0 +1,107 @@
/**
* \file os_touchfile.c
* \brief markes a file as modified without changing its contents.
* \author Blizzard Entertainment (contact tvandijck@blizzard.com)
* \author Copyright (c) 2015 Jason Perkins and the Premake project
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "premake.h"
#if PLATFORM_WINDOWS
#include <io.h>
#else
#include <unistd.h>
#include <sys/types.h>
#endif
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
static int truncate_file(const char* fn)
{
FILE* file = fopen(fn, "rb");
size_t size;
file = fopen(fn, "ab");
if (file == NULL)
{
return FALSE;
}
fseek(file, 0, SEEK_END);
size = ftell(file);
// append a dummy space. There are better ways to do
// a touch, however this is a rather simple
// multiplatform method
if (fwrite(" ", 1, 1, file) != 1)
{
fclose(file);
return FALSE;
}
#if PLATFORM_WINDOWS
if (_chsize(_fileno(file), (long)size) != 0)
{
fclose(file);
return FALSE;
}
#endif
fclose(file);
#if !PLATFORM_WINDOWS
if (truncate(fn, (off_t)size) != 0)
{
return FALSE;
}
#endif
return TRUE;
}
int os_touchfile(lua_State* L)
{
FILE* file;
const char* dst = luaL_checkstring(L, 1);
// if destination exist, mark the file as modified
if (do_isfile(L, dst))
{
if (truncate_file(dst))
{
lua_pushinteger(L, 0);
return 1;
} else {
lua_pushinteger(L, -1);
lua_pushfstring(L, "unable to touch file '%s'", dst);
return 2;
}
}
#if PLATFORM_WINDOWS
wchar_t wide_path[PATH_MAX];
if (MultiByteToWideChar(CP_UTF8, 0, dst, -1, wide_path, PATH_MAX) == 0)
{
lua_pushinteger(L, -1);
lua_pushstring(L, "unable to encode path");
return 2;
}
file = _wfopen(wide_path, L"wb");
#else
file = fopen(dst, "wb");
#endif
if (file != NULL)
{
fclose(file);
lua_pushinteger(L, 1);
return 1;
}
lua_pushinteger(L, -1);
lua_pushfstring(L, "unable to open file to '%s'", dst);
return 2;
}

View File

@ -86,6 +86,7 @@ static const luaL_Reg os_functions[] = {
{ "stat", os_stat },
{ "uuid", os_uuid },
{ "writefile_ifnotequal", os_writefile_ifnotequal },
{ "touchfile", os_touchfile },
{ "compile", os_compile },
{ NULL, NULL }
};

View File

@ -140,6 +140,7 @@ int os_rmdir(lua_State* L);
int os_stat(lua_State* L);
int os_uuid(lua_State* L);
int os_writefile_ifnotequal(lua_State* L);
int os_touchfile(lua_State* L);
int os_compile(lua_State* L);
int string_endswith(lua_State* L);
int string_hash(lua_State* L);