Fixed #163 : Installed version.xml now contains relative paths for installed files, so installed folder can me moved as needed under Windows, like when building a binary setup with CPack

git-svn-id: https://svn.code.sf.net/p/speed-dreams/code/trunk@2810 30fe4595-0a0c-4342-8851-515496e4dcbd

Former-commit-id: 5fd9f606bde20a3b1ede882a3f47f4c2a105b7dd
Former-commit-id: 5b445f0db8342984cf3457be1a5dc45d3a14d754
This commit is contained in:
pouillot 2010-09-27 21:06:35 +00:00
parent 5f5593b5c4
commit 25ae2a25c4
5 changed files with 122 additions and 64 deletions

View file

@ -1053,7 +1053,8 @@ MACRO(SD_INSTALL_FILES)
# Get the filename
GET_FILENAME_COMPONENT(XMLFILENAME ${XML_FILE} NAME)
#Execute xmlversion to get the file in the users home directory
# Execute xmlversion to register the file as to be installed / updated at run-time
# in the user settings folder.
IF(WIN32)
GET_TARGET_PROPERTY(TXML_LIB txml LOCATION)
GET_TARGET_PROPERTY(TGF_LIB tgf LOCATION)
@ -1070,7 +1071,7 @@ MACRO(SD_INSTALL_FILES)
IF(NOT IS_ABSOLUTE \${SD_DATADIR_ABS})
GET_FILENAME_COMPONENT(SD_DATADIR_ABS \"\${CMAKE_INSTALL_PREFIX}/\${SD_DATADIR_ABS}\" ABSOLUTE)
ENDIF()
EXECUTE_PROCESS(COMMAND \"\${XMLVERSION_EXE}\" \"\${SD_DATADIR_ABS}/version.xml\" \"\${CMAKE_INSTALL_PREFIX}/${DEST_ALL}/${XMLFILENAME}\" \"${USER_PATH}/${XMLFILENAME}\" RESULT_VARIABLE XMLVERSTATUS)
EXECUTE_PROCESS(COMMAND \"\${XMLVERSION_EXE}\" \"\${SD_DATADIR_ABS}/version.xml\" \"${DATA_PATH}/${XMLFILENAME}\" \"${USER_PATH}/${XMLFILENAME}\" \"\${SD_DATADIR_ABS}\" RESULT_VARIABLE XMLVERSTATUS)
IF(XMLVERSTATUS)
MESSAGE(FATAL_ERROR \"ERROR: xmlversion failed\")
ENDIF(XMLVERSTATUS)")
@ -1088,7 +1089,7 @@ MACRO(SD_INSTALL_FILES)
ELSE(CUR_DESTDIR MATCHES \"[^/]\")
SET(CUR_DESTDIR_CORR \"\")
ENDIF(CUR_DESTDIR MATCHES \"[^/]\")
EXECUTE_PROCESS(COMMAND \${XMLVERSION_EXE} \"\${CUR_DESTDIR_CORR}\${SD_DATADIR_ABS}/version.xml\" \"\${CUR_DESTDIR_CORR}\${CMAKE_INSTALL_PREFIX}/${DEST_ALL}/${XMLFILENAME}\" \"${USER_PATH}/${XMLFILENAME}\" RESULT_VARIABLE XMLVERSTATUS)
EXECUTE_PROCESS(COMMAND \"\${XMLVERSION_EXE}\" \"\${CUR_DESTDIR_CORR}\${SD_DATADIR_ABS}/version.xml\" \"${DATA_PATH}/${XMLFILENAME}\" \"${USER_PATH}/${XMLFILENAME}\" \"\${CUR_DESTDIR_CORR}\${SD_DATADIR_ABS}\" RESULT_VARIABLE XMLVERSTATUS)
IF(XMLVERSTATUS)
MESSAGE(FATAL_ERROR \"ERROR: xmlversion failed\")
ENDIF(XMLVERSTATUS)")

View file

@ -27,13 +27,6 @@
#include "tgf.h"
#include "portability.h"
#ifndef TRUE
#define TRUE 1
#endif //TRUE
#ifndef FALSE
#define FALSE 0
#endif //FALSE
static int GfFileSetupCopyFile( const char* dataLocation, const char* localLocation )
{
@ -126,14 +119,16 @@ void GfFileSetup()
char *dataLocation;
char *localLocation;
char *absLocalLocation;
char *count;
char *absDataLocation;
bool *count;
int countLength;
int index;
int found;
bool found;
int major;
int minor;
struct stat st;
// Open data (installation) version.xml.
filenameLength = strlen(GetDataDir()) + 12 + 40;
filename = (char*)malloc( sizeof(char) * filenameLength );
sprintf( filename, "%sversion.xml", GetDataDir() );
@ -144,6 +139,18 @@ void GfFileSetup()
return;
}
// Exit if nothing inside.
if( GfParmListSeekFirst( dataVersionHandle, "versions" ) != 0 )
{
free( filename );
GfParmReleaseHandle( dataVersionHandle );
return;
}
// Create LocalDir (user settings root) if not already done.
GfDirCreate( GetLocalDir() );
// Open local (user settings) version.xml (create it if not there).
if( filenameLength < strlen(GetLocalDir()) + 12 )
{
free( filename );
@ -151,12 +158,11 @@ void GfFileSetup()
filename = (char*)malloc( sizeof(char) * filenameLength );
}
GfDirCreate( GetLocalDir() );
sprintf( filename, "%sversion.xml", GetLocalDir() );
localVersionHandle = GfParmReadFile( filename, GFPARM_RMODE_CREAT );
GfParmWriteFile( NULL, localVersionHandle, "versions" );
// Exit if open/creation failed.
if( !localVersionHandle )
{
free( filename );
@ -164,31 +170,26 @@ void GfFileSetup()
return;
}
if( GfParmListSeekFirst( dataVersionHandle, "versions" ) != 0 )
{
free( filename );
GfParmReleaseHandle( dataVersionHandle );
GfParmReleaseHandle( localVersionHandle );
return;
}
countLength = GfParmGetEltNb( localVersionHandle, "versions" ) + GfParmGetEltNb( dataVersionHandle, "versions" ) + 2;
count = (char*)malloc( sizeof(char) * countLength );
memset( count, 0, sizeof(char) * countLength );
// Setup the index of the XML files referenced in the local version.xml.
countLength = GfParmGetEltNb( localVersionHandle, "versions" )
+ GfParmGetEltNb( dataVersionHandle, "versions" ) + 2;
count = (bool*)malloc( sizeof(bool) * countLength );
for( index = 0; index < countLength; index++ )
count[index] = false;
if( GfParmListSeekFirst( localVersionHandle, "versions" ) == 0 )
{
do
{
index = atoi( GfParmListGetCurEltName( localVersionHandle, "versions" ) );
if( 0 <= index && index < countLength )
count[index] = TRUE;
count[index] = true;
} while( GfParmListSeekNext( localVersionHandle, "versions" ) == 0 );
}
// For each file referenced in the installation version.xml
do
{
found = FALSE;
found = false;
// Get its installation path (data), user settings path (local),
// and new major and minor version numbers
@ -200,6 +201,9 @@ void GfFileSetup()
absLocalLocation = (char*)malloc( sizeof(char)*(strlen(GetLocalDir())+strlen(localLocation)+3) );
sprintf( absLocalLocation, "%s%s", GetLocalDir(), localLocation );
absDataLocation = (char*)malloc( sizeof(char)*(strlen(GetDataDir())+strlen(dataLocation)+3) );
sprintf( absDataLocation, "%s%s", GetDataDir(), dataLocation );
GfLogTrace("Checking %s : user settings version ", localLocation);
// Search for its old major and minor version numbers in the user settings.
@ -209,7 +213,7 @@ void GfFileSetup()
{
if( strcmp( absLocalLocation, GfParmGetCurStr( localVersionHandle, "versions", "Local location", "" ) ) == 0 )
{
found = TRUE;
found = true;
const int locMinor = (int)GfParmGetCurNum( localVersionHandle, "versions", "Minor version", NULL, 0 );
const int locMajor = (int)GfParmGetCurNum( localVersionHandle, "versions", "Major version", NULL, 0 );
@ -219,7 +223,7 @@ void GfFileSetup()
{
GfLogTrace("obsolete (installed one is %d.%d) => updating ...\n",
major, minor);
GfFileSetupCopy( dataLocation, absLocalLocation, major, minor, localVersionHandle, -1 );
GfFileSetupCopy( absDataLocation, absLocalLocation, major, minor, localVersionHandle, -1 );
}
else
{
@ -227,7 +231,7 @@ void GfFileSetup()
if (stat(absLocalLocation, &st))
{
GfLogTrace(", but the file is not there => installing ...\n");
GfFileSetupCopy( dataLocation, absLocalLocation, major, minor, localVersionHandle, -1 );
GfFileSetupCopy( absDataLocation, absLocalLocation, major, minor, localVersionHandle, -1 );
}
else
GfLogTrace(".\n");
@ -244,12 +248,13 @@ void GfFileSetup()
while( count[index] )
++index;
GfLogTrace("not found => installing ...\n");
GfFileSetupCopy( dataLocation, absLocalLocation, major, minor, localVersionHandle, index );
count[index] = TRUE;
GfFileSetupCopy( absDataLocation, absLocalLocation, major, minor, localVersionHandle, index );
count[index] = true;
}
free( dataLocation );
free( localLocation );
free( absDataLocation );
free( absLocalLocation );
GfParmWriteFile( NULL, localVersionHandle, "versions" );

View file

@ -521,8 +521,22 @@ char* GfTime2Str(tdble sec, int sgn)
return strdup(buf);
}
// Determine if a dir or file path is absolute or not.
bool GfPathIsAbsolute(const char *pszPath)
{
return pszPath != 0 && strlen(pszPath) > 0
#ifdef WIN32
&& (pszPath[0] == '/' // Leading '/'
|| pszPath[0] == '\\' // Leading '\'
|| (strlen(pszPath) > 2 && pszPath[1] == ':'
&& (pszPath[2] == '/' || pszPath[2] == '\\'))); // Leading 'x:/' or 'x:\'
#else
&& pszPath[0] == '/' ; // Leading '/'
#endif
}
// Normalize a directory path in-place : \ to / conversion + mandatory unique trailing /.
static char* normalizeDirPath(char* pszPath, size_t nMaxPathSize)
char* GfPathNormalizeDir(char* pszPath, size_t nMaxPathLen)
{
#ifdef WIN32
// Replace '\' by '/'
@ -534,7 +548,7 @@ static char* normalizeDirPath(char* pszPath, size_t nMaxPathSize)
// Add a trailing '/' if not present.
if (pszPath[strlen(pszPath)-1] != '/')
if (strlen(pszPath) < nMaxPathSize - 1)
if (strlen(pszPath) < nMaxPathLen - 1)
strcat(pszPath, "/");
else
GfLogFatal("Path '%s' too long ; could not normalize\n", pszPath);
@ -627,7 +641,7 @@ static char* makeRunTimeDirPath(const char* srcPath)
// Fix \ and add a trailing / is needed.
if (tgtPath)
normalizeDirPath(tgtPath, bufSize);
GfPathNormalizeDir(tgtPath, bufSize - 1);
if (!tgtPath)
GfLogFatal("Path '%s' too long ; could not make as a run-time path\n", srcPath);

View file

@ -256,6 +256,13 @@ typedef void (*tfDirfreeUserData)(void*); /**< Function to call for releasing th
TGF_API void GfDirFreeList(tFList *list, tfDirfreeUserData freeUserData, bool freeName = false, bool freeDispName = false);
/**************************************
* Directory and file path management *
**************************************/
TGF_API bool GfPathIsAbsolute(const char *path);
TGF_API char* GfPathNormalizeDir(char* pszPath, size_t nMaxPathLen);
/**********************************
* Interface For Parameter Files *
**********************************/

View file

@ -15,27 +15,31 @@
* *
***************************************************************************/
/* TODO : Clarify the use of DESTDIR environment variable
and see if the added "dataDir" command line arg can replace it
*/
#include <tgf.h>
#include <portability.h>
static const char* strip_destdir(const char *filename, const char *destdir )
static const char* strip_destdir(const char *filename, const char *destDir )
{
int xx;
int destdir_length;
int destDir_length;
if( !destdir )
if( !destDir )
return filename;
if( !filename )
return NULL;
destdir_length = strlen( destdir );
destDir_length = strlen( destDir );
for( xx = 0; xx < destdir_length; ++xx )
if( destdir[ xx ] != filename[ xx ] )
for( xx = 0; xx < destDir_length; ++xx )
if( destDir[ xx ] != filename[ xx ] )
return filename;
return &filename[ destdir_length ];
return &filename[ destDir_length ];
}
static int findIndex( void *versionHandle, const char* dataLocation,
@ -82,19 +86,40 @@ static int findIndex( void *versionHandle, const char* dataLocation,
}
static int process( const char* versionFile, const char* dataLocation,
const char* userLocation, const char * destdir )
const char* userLocation, const char* destDir, const char* dataDir )
{
void *versionHandle;
void *xmlHandle;
int index;
char *path;
const char* actualDataLoc;
char *absDataLocation;
int majorVer, minorVer;
xmlHandle = GfParmReadFile( dataLocation, GFPARM_RMODE_STD );
// If dataLocation is not absolute, use dataDir to make it such.
if (!GfPathIsAbsolute(dataLocation))
{
if (dataDir && strlen(dataDir) > 0)
{
const char cLastChar = dataDir[strlen(dataDir) - 1];
absDataLocation = (char*)malloc( sizeof(char) * (strlen(dataDir) + strlen(dataLocation) + 2));
sprintf(absDataLocation, "%s%s%s", dataDir,
(cLastChar == '/' || cLastChar == '\\') ? "" : "/", dataLocation);
}
else
{
fprintf( stderr, "xmlversion: No dataDir specified, whereas a relative file pathname \"%s\".\n",
dataLocation );
return 1;
}
}
else
absDataLocation = strdup(dataLocation);
xmlHandle = GfParmReadFile( absDataLocation, GFPARM_RMODE_STD );
if( !xmlHandle )
{
fprintf( stderr, "xmlversion: Can't open \"%s\".\n", dataLocation );
fprintf( stderr, "xmlversion: Can't open \"%s\".\n", absDataLocation );
return 1;
}
@ -106,19 +131,21 @@ static int process( const char* versionFile, const char* dataLocation,
}
index = findIndex( versionHandle, dataLocation, userLocation, "versions", false );
actualDataLoc = strip_destdir( dataLocation, destdir );
actualDataLoc = strip_destdir( dataLocation, destDir ); // TODO: Is is really usefull ? Comment needed.
majorVer = GfParmGetMajorVersion( xmlHandle );
minorVer = GfParmGetMinorVersion( xmlHandle );
path = (char*)malloc( sizeof(char) * 31 );
snprintf( path, 30, "versions/%d", index );
// Note : Data location is set to a relative path is specified such, absolute otherwise.
GfParmSetStr( versionHandle, path, "Data location", actualDataLoc);
GfParmSetStr( versionHandle, path, "Local location", userLocation );
GfParmSetNum( versionHandle, path, "Major version", NULL, (tdble)majorVer);
GfParmSetNum( versionHandle, path, "Minor version", NULL, (tdble)minorVer);
free( path );
free(absDataLocation);
GfParmWriteFile( NULL, versionHandle, "versions" );
@ -131,12 +158,12 @@ static int process( const char* versionFile, const char* dataLocation,
return 0;
}
static int add_directory( const char* versionFile, const char* directoryName, const char *destdir )
static int add_directory( const char* versionFile, const char* directoryName, const char *destDir )
{
void *versionHandle;
char *path;
int index;
const char* actualDataLoc;
const char* actualDirName;
versionHandle = GfParmReadFile( versionFile, GFPARM_RMODE_STD );
if( !versionHandle )
@ -147,12 +174,12 @@ static int add_directory( const char* versionFile, const char* directoryName, co
}
index = findIndex( versionHandle, directoryName, "", "directories", true );
actualDataLoc = strip_destdir( directoryName, destdir );
actualDirName = strip_destdir( directoryName, destDir );
path = (char*)malloc( sizeof(char) * 31 );
snprintf( path, 30, "directories/%d", index );
GfParmSetStr( versionHandle, path, "Data location", actualDataLoc);
GfParmSetStr( versionHandle, path, "Data location", actualDirName);
free( path );
@ -160,7 +187,7 @@ static int add_directory( const char* versionFile, const char* directoryName, co
GfParmReleaseHandle( versionHandle );
fprintf(stderr, "xmlversion: Updated %s (directory %s).\n", versionFile, actualDataLoc);
fprintf(stderr, "xmlversion: Updated %s (directory %s).\n", versionFile, actualDirName);
return 0;
}
@ -170,14 +197,16 @@ int main( int argc, char **argv )
const char *versionfile;
const char *dataLocation;
const char *userLocation;
const char *destdir;
const char *dataDir;
const char *destDir;
int ret;
if( argc <= 3 )
{
fprintf( stderr, "Usage: xmlversion version-file data-location local-location\n\n" );
fprintf( stderr, "Usage: xmlversion version-file data-location local-location [datadir]\n\n" );
fprintf( stderr, " version-file: The location of the version.xml file\n" );
fprintf( stderr, " data-location: Full path and filename to the location of installed xml-file\n" );
fprintf( stderr, " data-location: Path and filename to the location of installed xml-file\n" );
fprintf( stderr, " (relative to datadir if specified, otherwise absolute)\n\n" );
fprintf( stderr, " local-location: path and filename to the location of the local xml-file\n" );
fprintf( stderr, " (relative to the users local directory)\n\n" );
fprintf( stderr, "Usage: xmlversion -d version-file local-location\n\n" );
@ -192,26 +221,28 @@ int main( int argc, char **argv )
// Uncomment to get debug traces.
//GfInit();
if( argc > 4 )
fprintf( stderr, "Warning: Too many arguments (should be 3). Ignoring extra ones.\n" );
if( argc > 5 )
fprintf( stderr, "Warning: Too many arguments (should be 3 or 4). Ignoring extra ones.\n" );
versionfile = argv[1];
dataLocation = argv[2];
userLocation = argv[3];
destdir = getenv( "DESTDIR" );
GfLogDebug("xmlversion: DESTDIR='%s'\n", destdir ? destdir : "<undefined>");
dataDir = argc > 4 ? argv[4] : 0;
destDir = getenv( "DESTDIR" );
GfLogDebug("xmlversion: DESTDIR='%s'\n", destDir ? destDir : "<undefined>");
GfLogDebug("xmlversion: versionfile='%s'\n", versionfile);
GfLogDebug("xmlversion: dataLocation='%s'\n", dataLocation);
GfLogDebug("xmlversion: userLocation='%s'\n", userLocation);
GfLogDebug("xmlversion: dataDir='%s'\n", dataDir ? dataDir : "<not specified>");
if( strcmp( versionfile, "-d" ) == 0 )
ret = add_directory( dataLocation, userLocation, destdir );
ret = add_directory( dataLocation, userLocation, destDir );
else if( strcmp( dataLocation, "-d" ) == 0 )
ret = add_directory( versionfile, userLocation, destdir );
ret = add_directory( versionfile, userLocation, destDir );
else if( strcmp( userLocation, "-d" ) == 0 )
ret = add_directory( versionfile, dataLocation, destdir );
ret = add_directory( versionfile, dataLocation, destDir );
else
ret = process( versionfile, dataLocation, userLocation, destdir );
ret = process( versionfile, dataLocation, userLocation, destDir, dataDir );
exit( ret );
}