diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 330d723657..5ce6ff23b1 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -16,6 +16,30 @@ The license applies to all entries newer than 2009-04-28. */ +2010-08-14 20:23 UTC+0200 Viktor Szakats (harbour.01 syenar.hu) + * include/harbour.hbx + * include/hbapifs.h + * src/rtl/fslink.c + + Added hb_fsLinkRead() function. + + Added HB_FLINKREAD() function. + ; Please review/fix or remove. + + * utils/hbmk2/hbmk2.prg + + Added -ln= option to specify symlinks to targets. + + Added ${hb_dynprefix} macro. + + * contrib/hbpost.hbm + + Enabled creation of versionless and major-minor versioned + links to dynamic libs. + + Will now create versioned .dll names on win/wce. + + * include/hbapifs.h + * include/fileio.ch + + Moved some attr constants to .ch header. + + * contrib/make.hbs + ! Fixed to propage make control options to container projects. + 2010-08-13 18:34 UTC-0800 Pritpal Bedi (bedipritpal@hotmail.com) * contrib/hbide/ideobject.prg * contrib/hbide/idereportsmanager.prg @@ -383,7 +407,7 @@ ; Now HB_BUILD_CONTRIB_DYN works for all contribs also on Linux. ; TODO: Shouldn't harbour-2.1.0.so be called harbour.so.2.1.0 ? - ; TODO: Creating versionless links for contribs. + ; TODO: Creating versionless links for contribs. [DONE] 2010-08-07 15:55 UTC+0200 Viktor Szakats (harbour.01 syenar.hu) * utils/hbmk2/hbmk2.prg diff --git a/harbour/contrib/hbpost.hbm b/harbour/contrib/hbpost.hbm index c8f7a74232..3fcc4cafce 100644 --- a/harbour/contrib/hbpost.hbm +++ b/harbour/contrib/hbpost.hbm @@ -37,28 +37,38 @@ {(hbdyn|hbexe)&HB_BUILD_SHARED='yes'&!(HB_SYSLOC='yes')}-shared {(hbdyn|hbexe)&HB_BUILD_SHARED='yes'&HB_SYSLOC='yes'}-fullshared -# Experimental +# dynamic lib creation settings {_HB_BUILD_LIBDYN}-hbdyn {_HB_BUILD_LIBDYN}-shared {_HB_BUILD_LIBDYN}-implib=../lib/${hb_plat}/${hb_comp}${hb_build}/ {_HB_BUILD_LIBDYN&hb_dynsuffix}-implib=${hb_outputname}${hb_dynsuffix} {_HB_BUILD_LIBDYN&!hb_dynsuffix}-implib=${hb_outputname}_dll +{_HB_BUILD_LIBDYN&unix}-ln=${hb_dynprefix}${hb_outputname}${hb_dynext} +{_HB_BUILD_LIBDYN&unix&!darwin}-ln=${hb_dynprefix}${hb_outputname}${hb_dynext}.${hb_major}.${hb_minor} +{_HB_BUILD_LIBDYN&unix&darwin}-ln=${hb_dynprefix}${hb_outputname}.${hb_major}.${hb_minor}${hb_dynext} {_HB_BUILD_LIBDYN&allwin}-lhbmaindllp {_HB_BUILD_LIBDYN}-depimplib- +# output name tweaks for dynamic libs +# NOTE: We're altering previously set output name value here {hbdyn&unix&!darwin}-o${hb_outputname}${hb_dynext}.${hb_major}.${hb_minor}.${hb_release} {hbdyn&unix&darwin}-o${hb_outputname}.${hb_major}.${hb_minor}.${hb_release}${hb_dynext} -{hbdyn&!unix}-o${hb_outputname}${hb_dynsuffix} +{hbdyn&!unix&allwin}-o${hb_outputname}-${hb_major}${hb_minor}${hb_dynsuffix} +{hbdyn&!unix&!allwin}-o${hb_outputname}${hb_dynsuffix} + +# output dir (in sync with GNU Make) {hblib}-o../lib/${hb_plat}/${hb_comp}${hb_build}/ {hbexe}-o../bin/${hb_plat}/${hb_comp}${hb_build}/ {hbdyn&unix}-o../lib/${hb_plat}/${hb_comp}${hb_build}/ {hbdyn&!unix}-o../bin/${hb_plat}/${hb_comp}${hb_build}/ +# workdir (in sync with GNU Make) {hblib}-workdir=../lib/${hb_plat}/${hb_comp}${hb_build}/${hb_work}/${hb_outputname}${hb_workdynsub} {hbexe}-workdir=../bin/${hb_plat}/${hb_comp}${hb_build}/${hb_work}/${hb_outputname}${hb_workdynsub} {hbdyn&unix}-workdir=../lib/${hb_plat}/${hb_comp}${hb_build}/${hb_work}/${hb_outputname}${hb_workdynsub} {hbdyn&!unix}-workdir=../bin/${hb_plat}/${hb_comp}${hb_build}/${hb_work}/${hb_outputname}${hb_workdynsub} +# install {_HB_BUILD_INSTALL&_HB_INSTALL_LIB&hblib}-instpath=${_HB_INSTALL_LIB}/ {_HB_BUILD_INSTALL&_HB_INSTALL_BIN&hbexe}-instpath=${_HB_INSTALL_BIN}/ {_HB_BUILD_INSTALL&_HB_INSTALL_DYN&hbdyn}-instpath=${_HB_INSTALL_DYN}/ diff --git a/harbour/contrib/make.hbs b/harbour/contrib/make.hbs index 31947bb1a2..5be238631f 100755 --- a/harbour/contrib/make.hbs +++ b/harbour/contrib/make.hbs @@ -364,6 +364,7 @@ STATIC PROCEDURE build_projects( nAction, hProjectList, hProjectReqList, cOption LOCAL cProject LOCAL cProjectPath LOCAL lPrimary + LOCAL lContainer LOCAL cDynSuffix @@ -427,8 +428,9 @@ STATIC PROCEDURE build_projects( nAction, hProjectList, hProjectReqList, cOption cProjectPath := s_cBase + s_cHome + cProject lPrimary := cProject $ hProjectReqList + lContainer := "lFromContainer" $ hProjectList[ cProject ] - IF call_hbmk2( cProjectPath, iif( lPrimary, cOptions + cOptionsUser, " -inc" ), NIL ) + IF call_hbmk2( cProjectPath, iif( lPrimary .OR. lContainer, iif( lContainer, cOptions, cOptions + cOptionsUser ), " -inc" ), NIL ) /* Build dynamic lib */ IF GetEnv( "HB_BUILD_CONTRIB_DYN" ) == "yes" .AND. hProjectList[ cProject ][ "cType" ] == "hblib" @@ -442,10 +444,10 @@ STATIC PROCEDURE build_projects( nAction, hProjectList, hProjectReqList, cOption ELSE cDynSuffix := hb_libExt() ENDIF - call_hbmk2( cProjectPath, iif( lPrimary, cOptions + cOptionsUser, " -inc" ), cDynSuffix ) + call_hbmk2( cProjectPath, iif( lPrimary .OR. lContainer, iif( lContainer, cOptions, cOptions + cOptionsUser ), " -inc" ), cDynSuffix ) ENDIF - IF lPrimary .OR. "lFromContainer" $ hProjectList[ cProject ] + IF lPrimary .OR. lContainer /* Compile documentation */ IF lInstall diff --git a/harbour/include/fileio.ch b/harbour/include/fileio.ch index 195663aff5..e1c783d670 100644 --- a/harbour/include/fileio.ch +++ b/harbour/include/fileio.ch @@ -56,49 +56,83 @@ #define _FILEIO_CH /* File create flags */ -#define FC_NORMAL 0 /* No file attributes are set */ -#define FC_READONLY 1 /* Read-only file attribute is set */ -#define FC_HIDDEN 2 /* Hidden file attribute is set */ -#define FC_SYSTEM 4 /* System file attribute is set */ +#define FC_NORMAL 0 /* No file attributes are set */ +#define FC_READONLY 1 /* Read-only file attribute is set */ +#define FC_HIDDEN 2 /* Hidden file attribute is set */ +#define FC_SYSTEM 4 /* System file attribute is set */ + +/* File attributes flags */ +#define HB_FA_ALL 0x00000000 + +#define HB_FA_READONLY 0x00000001 /* R */ +#define HB_FA_HIDDEN 0x00000002 /* H */ +#define HB_FA_SYSTEM 0x00000004 /* S */ +#define HB_FA_LABEL 0x00000008 /* V */ +#define HB_FA_DIRECTORY 0x00000010 /* D | S_ISDIR() */ +#define HB_FA_ARCHIVE 0x00000020 /* A | S_ISREG() */ +#define HB_FA_DEVICE 0x00000040 /* I | S_ISBLK() */ +#define HB_FA_NORMAL 0x00000080 /* */ + +#define HB_FA_TEMPORARY 0x00000100 /* T | S_ISFIFO()??? */ +#define HB_FA_SPARSE 0x00000200 /* P | S_ISSOCK()??? */ +#define HB_FA_REPARSE 0x00000400 /* L | S_ISLNK() */ +#define HB_FA_COMPRESSED 0x00000800 /* C | S_ISCHR()??? */ +#define HB_FA_OFFLINE 0x00001000 /* O */ +#define HB_FA_NOTINDEXED 0x00002000 /* X */ +#define HB_FA_ENCRYPTED 0x00004000 /* E */ +#define HB_FA_VOLCOMP 0x00008000 /* M volume supports compression. */ + +/* POSIX file permission */ +#define HB_FA_SUID 0x08000000 /* 4000 set user ID on execution */ +#define HB_FA_SGID 0x04000000 /* 2000 set group ID on execution */ +#define HB_FA_SVTX 0x02000000 /* 1000 sticky bit */ +#define HB_FA_RUSR 0x01000000 /* 0400 read by owner */ +#define HB_FA_WUSR 0x00800000 /* 0200 write by owner */ +#define HB_FA_XUSR 0x00400000 /* 0100 execute/search by owner */ +#define HB_FA_RGRP 0x00200000 /* 0040 read by group */ +#define HB_FA_WGRP 0x00100000 /* 0020 write by group */ +#define HB_FA_XGRP 0x00080000 /* 0010 execute/search by group */ +#define HB_FA_ROTH 0x00040000 /* 0004 read by others */ +#define HB_FA_WOTH 0x00020000 /* 0002 write by others */ +#define HB_FA_XOTH 0x00010000 /* 0001 execute/search by others */ /* File access flags */ -#define FO_READ 0 /* File is opened for reading */ -#define FO_WRITE 1 /* File is opened for writing */ -#define FO_READWRITE 2 /* File is opened for reading and writing */ +#define FO_READ 0 /* File is opened for reading */ +#define FO_WRITE 1 /* File is opened for writing */ +#define FO_READWRITE 2 /* File is opened for reading and writing */ /* File open flags */ -#define FO_CREAT 0x0100 /* create and open file */ -#define FO_TRUNC 0x0200 /* open with truncation */ -#define FO_EXCL 0x0400 /* create and open only if file doesn't exist */ +#define FO_CREAT 0x0100 /* create and open file */ +#define FO_TRUNC 0x0200 /* open with truncation */ +#define FO_EXCL 0x0400 /* create and open only if file doesn't exist */ /* File sharing flags */ -#define FO_COMPAT 0 /* No sharing specified */ -#define FO_EXCLUSIVE 16 /* Deny further attempts to open the file */ -#define FO_DENYWRITE 32 /* Deny further attempts to open the file for writing */ -#define FO_DENYREAD 48 /* Deny further attempts to open the file for reading */ -#define FO_DENYNONE 64 /* Do not deny any further attempts to open the file */ -#define FO_SHARED FO_DENYNONE +#define FO_COMPAT 0 /* No sharing specified */ +#define FO_EXCLUSIVE 16 /* Deny further attempts to open the file */ +#define FO_DENYWRITE 32 /* Deny further attempts to open the file for writing */ +#define FO_DENYREAD 48 /* Deny further attempts to open the file for reading */ +#define FO_DENYNONE 64 /* Do not deny any further attempts to open the file */ +#define FO_SHARED FO_DENYNONE /* File seek mode flags */ -#define FS_SET 0 /* Seek from beginning of file */ -#define FS_RELATIVE 1 /* Seek from current file pointer */ -#define FS_END 2 /* Seek from end of file */ +#define FS_SET 0 /* Seek from beginning of file */ +#define FS_RELATIVE 1 /* Seek from current file pointer */ +#define FS_END 2 /* Seek from end of file */ /* File mode flags */ -#define FD_BINARY 1 /* Binary mode (raw) */ -#define FD_RAW FD_BINARY -#define FD_TEXT 2 /* Text mode (cooked) */ -#define FD_COOKED FD_TEXT -#define FD_ASCII FD_TEXT +#define FD_BINARY 1 /* Binary mode (raw) */ +#define FD_RAW FD_BINARY +#define FD_TEXT 2 /* Text mode (cooked) */ +#define FD_COOKED FD_TEXT +#define FD_ASCII FD_TEXT /* File system error codes */ -#define F_ERROR ( -1 ) /* Unspecified error */ +#define F_ERROR ( -1 ) /* Unspecified error */ /* HB_DISKSPACE() types */ -#define HB_DISK_AVAIL 0 -#define HB_DISK_FREE 1 -#define HB_DISK_USED 2 -#define HB_DISK_TOTAL 3 +#define HB_DISK_AVAIL 0 +#define HB_DISK_FREE 1 +#define HB_DISK_USED 2 +#define HB_DISK_TOTAL 3 #endif /* _FILEIO_CH */ - diff --git a/harbour/include/harbour.hbx b/harbour/include/harbour.hbx index 37076b53e2..337edc915c 100644 --- a/harbour/include/harbour.hbx +++ b/harbour/include/harbour.hbx @@ -415,6 +415,7 @@ DYNAMIC HB_FILEMATCH DYNAMIC HB_FISDEVICE DYNAMIC HB_FLINK DYNAMIC HB_FLINKSYM +DYNAMIC HB_FLINKREAD DYNAMIC HB_FLOCK DYNAMIC HB_FNAMEEXISTS DYNAMIC HB_FNAMEMERGE diff --git a/harbour/include/hbapifs.h b/harbour/include/hbapifs.h index 9652ce659d..6440f9c8a1 100644 --- a/harbour/include/hbapifs.h +++ b/harbour/include/hbapifs.h @@ -85,27 +85,6 @@ HB_EXTERN_BEGIN #define FXO_SHARELOCK 0x4000 /* emulate DOS SH_DENY* mode in POSIX OS */ #define FXO_COPYNAME 0x8000 /* copy final szPath into pFilename */ -/* File attributes flags */ -#define HB_FA_ALL 0x00000000 - -#define HB_FA_READONLY 0x00000001 /* R */ -#define HB_FA_HIDDEN 0x00000002 /* H */ -#define HB_FA_SYSTEM 0x00000004 /* S */ -#define HB_FA_LABEL 0x00000008 /* V */ -#define HB_FA_DIRECTORY 0x00000010 /* D | S_ISDIR() */ -#define HB_FA_ARCHIVE 0x00000020 /* A | S_ISREG() */ -#define HB_FA_DEVICE 0x00000040 /* I | S_ISBLK() */ -#define HB_FA_NORMAL 0x00000080 /* */ - -#define HB_FA_TEMPORARY 0x00000100 /* T | S_ISFIFO()??? */ -#define HB_FA_SPARSE 0x00000200 /* P | S_ISSOCK()??? */ -#define HB_FA_REPARSE 0x00000400 /* L | S_ISLNK() */ -#define HB_FA_COMPRESSED 0x00000800 /* C | S_ISCHR()??? */ -#define HB_FA_OFFLINE 0x00001000 /* O */ -#define HB_FA_NOTINDEXED 0x00002000 /* X */ -#define HB_FA_ENCRYPTED 0x00004000 /* E */ -#define HB_FA_VOLCOMP 0x00008000 /* M volume supports compression. */ - /* these definitions should be cleared, * now they only help to clean lower level code */ @@ -116,20 +95,6 @@ HB_EXTERN_BEGIN #define HB_FA_SOCKET HB_FA_SPARSE /* S_ISSOCK() */ #define HB_FA_LINK HB_FA_REPARSE /* S_ISLNK() */ -/* POSIX file permission */ -#define HB_FA_SUID 0x08000000 /* set user ID on execution */ -#define HB_FA_SGID 0x04000000 /* set group ID on execution */ -#define HB_FA_SVTX 0x02000000 /* sticky bit */ -#define HB_FA_RUSR 0x01000000 /* read by owner */ -#define HB_FA_WUSR 0x00800000 /* write by owner */ -#define HB_FA_XUSR 0x00400000 /* execute/search by owner */ -#define HB_FA_RGRP 0x00200000 /* read by group */ -#define HB_FA_WGRP 0x00100000 /* write by group */ -#define HB_FA_XGRP 0x00080000 /* execute/search by group */ -#define HB_FA_ROTH 0x00040000 /* read by others */ -#define HB_FA_WOTH 0x00020000 /* write by others */ -#define HB_FA_XOTH 0x00010000 /* execute/search by others */ - #define HB_FA_UGVS ( HB_FA_SUID | HB_FA_SGID | HB_FA_SVTX ) #define HB_FA_RWXU ( HB_FA_RUSR | HB_FA_WUSR | HB_FA_XUSR ) #define HB_FA_RWXG ( HB_FA_RGRP | HB_FA_WGRP | HB_FA_XGRP ) @@ -218,6 +183,7 @@ extern HB_EXPORT HB_BOOL hb_fsDirExists ( const char * pszDirName ); /* che extern HB_EXPORT HB_BOOL hb_fsCopy ( const char * pszSource, const char * pszDest ); /* copy file */ extern HB_EXPORT HB_BOOL hb_fsLink ( const char * pszExisting, const char * pszNewFile ); /* create hard link */ extern HB_EXPORT HB_BOOL hb_fsLinkSym ( const char * pszTarget, const char * pszNewFile ); /* create symbolic (soft) link */ +extern HB_EXPORT char * hb_fsLinkRead ( const char * pszFileName ); /* returns the link pointed to */ #define hb_fsFLock( h, s, l ) hb_fsLock( h, s, l, FL_LOCK ) #define hb_fsFUnlock( h, s, l ) hb_fsLock( h, s, l, FL_UNLOCK ) diff --git a/harbour/src/rtl/fslink.c b/harbour/src/rtl/fslink.c index 5e5247ea65..2b3f92c32e 100644 --- a/harbour/src/rtl/fslink.c +++ b/harbour/src/rtl/fslink.c @@ -4,7 +4,7 @@ /* * Harbour Project source code: - * hb_fsLink(), hb_fsLinkSym(), HB_FLINK, HB_FLINKSYM() functions + * hb_fsLink*(), HB_FLINK*() functions * * Copyright 2010 Viktor Szakats (harbour.01 syenar.hu) * www - http://harbour-project.org @@ -183,6 +183,108 @@ HB_BOOL hb_fsLinkSym( const char * pszTarget, const char * pszNewFile ) return fResult; } +/* NOTE: Caller must free the pointer, if not NULL */ +char * hb_fsLinkRead( const char * pszFile ) +{ + char * pszLink; + + if( pszFile ) + { +#if defined( HB_OS_WIN ) && ! defined( HB_OS_WIN_CE ) + { + typedef BOOL ( WINAPI * _HB_GETFINALPATHNAMEBYHANDLE )( HANDLE, LPTSTR, DWORD, DWORD ); + + static _HB_GETFINALPATHNAMEBYHANDLE s_pGetFinalPathNameByHandle = NULL; + + #ifndef VOLUME_NAME_DOS + #define VOLUME_NAME_DOS 0x0 + #endif + + if( ! s_pGetFinalPathNameByHandle ) + s_pGetFinalPathNameByHandle = ( _HB_GETFINALPATHNAMEBYHANDLE ) GetProcAddress( GetModuleHandle( TEXT( "kernel32.dll" ) ), +#if defined( UNICODE ) + "GetFinalPathNameByHandleW" ); +#else + "GetFinalPathNameByHandleA" ); +#endif + + if( s_pGetFinalPathNameByHandle ) + { + LPTSTR lpFileName = HB_TCHAR_CONVTO( pszFile ); + HANDLE hFile; + + hFile = CreateFile( lpFileName, + GENERIC_READ, + FILE_SHARE_READ, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL ); + + if( hFile == INVALID_HANDLE_VALUE ) + { + hb_fsSetIOError( HB_FALSE, 0 ); + hb_fsSetFError( hb_fsError() ); + pszLink = NULL; + } + else + { + DWORD size; + TCHAR lpLink[ HB_PATH_MAX ]; + size = s_pGetFinalPathNameByHandle( lpFileName, lpLink, HB_PATH_MAX, VOLUME_NAME_DOS ); + if( size < HB_PATH_MAX ) + { + pszLink = ( char * ) hb_xgrab( size ); + hb_wcntombcpy( pszLink, lpLink, ( HB_SIZE ) size ); + hb_fsSetIOError( HB_TRUE, 0 ); + hb_fsSetFError( hb_fsError() ); + } + else + { + hb_fsSetFError( 1 ); + pszLink = NULL; + } + } + + HB_TCHAR_FREE( lpFileName ); + } + else + { + hb_fsSetFError( 1 ); + pszLink = NULL; + } + } +#elif defined( HB_OS_UNIX ) + { + size_t size; + pszLink = ( char * ) hb_xgrab( HB_PATH_MAX + 1 ); + size = readlink( pszFile, pszLink, HB_PATH_MAX ); + hb_fsSetIOError( size != ( size_t ) -1, 0 ); + hb_fsSetFError( hb_fsError() ); + if( size == ( size_t ) -1 ) + { + hb_xfree( pszLink ); + pszLink = NULL; + } + else + pszLink[ size ] = '\0'; + } +#else + { + hb_fsSetFError( 1 ); + pszLink = NULL; + } +#endif + } + else + { + hb_fsSetFError( 2 ); + pszLink = NULL; + } + + return pszLink; +} + HB_FUNC( HB_FLINK ) { const char * pszExisting = hb_parc( 1 ), * pszNewFile = hb_parc( 2 ); @@ -208,3 +310,16 @@ HB_FUNC( HB_FLINKSYM ) hb_retni( F_ERROR ); } } + +HB_FUNC( HB_FLINKREAD ) +{ + const char * pszFile = hb_parc( 1 ); + + if( pszFile ) + hb_retc_buffer( hb_fsLinkRead( pszFile ) ); + else + { + hb_fsSetFError( 2 ); + hb_retc_null(); + } +} diff --git a/harbour/utils/hbmk2/hbmk2.prg b/harbour/utils/hbmk2/hbmk2.prg index b8a88e6c84..a78c8a88f9 100644 --- a/harbour/utils/hbmk2/hbmk2.prg +++ b/harbour/utils/hbmk2/hbmk2.prg @@ -262,8 +262,8 @@ REQUEST hbmk_KEYW #define LEFTEQUAL( l, r ) ( l = r ) /* NOTE: This requires Set( _SET_EXACT, .F. ) */ /* Logic (hack) to automatically add some libs to their - place in the liblist. In case of 'unicows' lib, this - should be after all app lib and before any Windows + right place in the liblist. In case of 'unicows' lib, + this should be after all app lib and before any Windows system libs. [vszakats] */ #define _IS_AUTOLIBSYSPRE( c ) ( hbmk[ _HBMK_cPLAT ] == "win" .AND. Lower( FNameNameGet( c ) ) == "unicows" ) @@ -416,14 +416,16 @@ REQUEST hbmk_KEYW #define _HBMK_lContainer 121 /* Target type: container */ #define _HBMK_lShowLevel 122 /* Show project nesting level in all output lines */ #define _HBMK_hFiles 123 /* Cache for the header parser (common for C and Harbour) */ -#define _HBMK_cDynLibExt 124 +#define _HBMK_cDynLibPrefix 124 /* Dynamic lib filename prefix */ +#define _HBMK_cDynLibExt 125 /* Dynamic lib filename extension */ +#define _HBMK_aLINK 126 /* Links to be created and pointing to the target */ -#define _HBMK_aArgs 125 -#define _HBMK_nArgTarget 126 -#define _HBMK_lPause 127 -#define _HBMK_nLevel 128 +#define _HBMK_aArgs 127 +#define _HBMK_nArgTarget 128 +#define _HBMK_lPause 129 +#define _HBMK_nLevel 130 -#define _HBMK_MAX_ 128 +#define _HBMK_MAX_ 130 #define _HBMK_DEP_CTRL_MARKER ".control." /* must be an invalid path */ @@ -766,7 +768,6 @@ FUNCTION hbmk2( aArgs, nArgTarget, /* @ */ lPause, nLevel ) LOCAL cDynDefPrefix := NIL LOCAL cLibPathPrefix LOCAL cLibPathSep - LOCAL cDynLibNamePrefix LOCAL cImpLibExt := "" LOCAL cResPrefix LOCAL cResExt @@ -942,6 +943,8 @@ FUNCTION hbmk2( aArgs, nArgTarget, /* @ */ lPause, nLevel ) hbmk[ _HBMK_lContainer ] := .F. hbmk[ _HBMK_lShowLevel ] := .F. + hbmk[ _HBMK_aLINK ] := {} + hbmk[ _HBMK_aArgs ] := aArgs hbmk[ _HBMK_nArgTarget ] := nArgTarget hbmk[ _HBMK_lPause ] := lPause @@ -1247,9 +1250,9 @@ FUNCTION hbmk2( aArgs, nArgTarget, /* @ */ lPause, nLevel ) aCOMPSUP := { "gcc" } ENDCASE IF hbmk[ _HBMK_cPLAT ] == "symbian" - cDynLibNamePrefix := "" + hbmk[ _HBMK_cDynLibPrefix ] := "" ELSE - cDynLibNamePrefix := "lib" + hbmk[ _HBMK_cDynLibPrefix ] := "lib" ENDIF DO CASE CASE hbmk[ _HBMK_cPLAT ] == "vxworks" @@ -1280,7 +1283,7 @@ FUNCTION hbmk2( aArgs, nArgTarget, /* @ */ lPause, nLevel ) aCOMPSUP := { "djgpp", "gcc", "watcom" } l_aLIBHBGT := { "gtdos" } hbmk[ _HBMK_cGTDEFAULT ] := "gtdos" - cDynLibNamePrefix := "" + hbmk[ _HBMK_cDynLibPrefix ] := "" hbmk[ _HBMK_cDynLibExt ] := "" /* NOTE: This will be reset later if djgpp is detected. */ cBinExt := ".exe" cOptPrefix := "-/" @@ -1292,7 +1295,7 @@ FUNCTION hbmk2( aArgs, nArgTarget, /* @ */ lPause, nLevel ) aCOMPSUP := { "gcc", "gccomf", "watcom" } l_aLIBHBGT := { "gtos2" } hbmk[ _HBMK_cGTDEFAULT ] := "gtos2" - cDynLibNamePrefix := "" + hbmk[ _HBMK_cDynLibPrefix ] := "" hbmk[ _HBMK_cDynLibExt ] := ".dll" cBinExt := ".exe" cOptPrefix := "-/" @@ -1327,7 +1330,7 @@ FUNCTION hbmk2( aArgs, nArgTarget, /* @ */ lPause, nLevel ) "mingw64", "msvc64", "msvcia64", "iccia64", "pocc64" } l_aLIBHBGT := { "gtwin", "gtwvt", "gtgui" } hbmk[ _HBMK_cGTDEFAULT ] := "gtwin" - cDynLibNamePrefix := "" + hbmk[ _HBMK_cDynLibPrefix ] := "" hbmk[ _HBMK_cDynLibExt ] := ".dll" cBinExt := ".exe" cOptPrefix := "-/" @@ -1347,7 +1350,7 @@ FUNCTION hbmk2( aArgs, nArgTarget, /* @ */ lPause, nLevel ) aCOMPSUP := { "mingwarm", "msvcarm", "poccarm" } l_aLIBHBGT := { "gtwvt", "gtgui" } hbmk[ _HBMK_cGTDEFAULT ] := "gtwvt" - cDynLibNamePrefix := "" + hbmk[ _HBMK_cDynLibPrefix ] := "" hbmk[ _HBMK_cDynLibExt ] := ".dll" cBinExt := ".exe" cOptPrefix := "-/" @@ -1840,15 +1843,19 @@ FUNCTION hbmk2( aArgs, nArgTarget, /* @ */ lPause, nLevel ) /* Process build-time configuration */ #if defined( HB_HAS_GPM ) - AAdd( hbmk[ _HBMK_aLIBUSERSYS ], "gpm" ) + IF hbmk[ _HBMK_cPLAT ] == "linux" + AAdd( hbmk[ _HBMK_aLIBUSERSYS ], "gpm" ) + ENDIF #endif #if defined( HB_HAS_WATT ) - SWITCH hbmk[ _HBMK_cCOMP ] - CASE "djgpp" ; AAdd( hbmk[ _HBMK_aLIBUSERSYS ], "watt" ) ; EXIT - CASE "watcom" ; AAdd( hbmk[ _HBMK_aLIBUSERSYS ], "wattcpwf" ) ; EXIT - ENDSWITCH - AAdd( hbmk[ _HBMK_aLIBPATH ], PathSepToSelf( GetEnv( "WATT_ROOT" ) ) + hb_ps() + "lib" ) + IF hbmk[ _HBMK_cPLAT ] == "dos" + SWITCH hbmk[ _HBMK_cCOMP ] + CASE "djgpp" ; AAdd( hbmk[ _HBMK_aLIBUSERSYS ], "watt" ) ; EXIT + CASE "watcom" ; AAdd( hbmk[ _HBMK_aLIBUSERSYS ], "wattcpwf" ) ; EXIT + ENDSWITCH + AAdd( hbmk[ _HBMK_aLIBPATH ], PathSepToSelf( GetEnv( "WATT_ROOT" ) ) + hb_ps() + "lib" ) + ENDIF #endif /* Process automatic make files in current dir. */ @@ -2233,6 +2240,13 @@ FUNCTION hbmk2( aArgs, nArgTarget, /* @ */ lPause, nLevel ) l_cIMPLIBNAME := NIL ENDIF + CASE Left( cParamL, Len( "-ln=" ) ) == "-ln=" + + cParam := MacroProc( hbmk, SubStr( cParam, Len( "-ln=" ) + 1 ), aParam[ _PAR_cFileName ] ) + IF ! Empty( cParam ) + AAddNewNotEmpty( hbmk[ _HBMK_aLINK ], PathSepToSelf( cParam ) ) + ENDIF + CASE Left( cParam, 2 ) == "-L" .AND. ; Len( cParam ) > 2 @@ -2859,12 +2873,12 @@ FUNCTION hbmk2( aArgs, nArgTarget, /* @ */ lPause, nLevel ) l_aLIBSHARED := { iif( hbmk[ _HBMK_lMT ], "harbourmt" + cPostfix,; "harbour" + cPostfix ) } ELSE - l_aLIBSHARED := { iif( hbmk[ _HBMK_lMT ], cPrefix + cDynLibNamePrefix + "harbourmt" + cPostfix + hbmk[ _HBMK_cDynLibExt ],; - cPrefix + cDynLibNamePrefix + "harbour" + cPostfix + hbmk[ _HBMK_cDynLibExt ] ) } + l_aLIBSHARED := { iif( hbmk[ _HBMK_lMT ], cPrefix + hbmk[ _HBMK_cDynLibPrefix ] + "harbourmt" + cPostfix + hbmk[ _HBMK_cDynLibExt ],; + cPrefix + hbmk[ _HBMK_cDynLibPrefix ] + "harbour" + cPostfix + hbmk[ _HBMK_cDynLibExt ] ) } ENDIF CASE hbmk[ _HBMK_cPLAT ] $ "os2|win|wce" - l_aLIBSHARED := { iif( hbmk[ _HBMK_lMT ], cDynLibNamePrefix + "harbourmt",; - cDynLibNamePrefix + "harbour" ) } + l_aLIBSHARED := { iif( hbmk[ _HBMK_lMT ], hbmk[ _HBMK_cDynLibPrefix ] + "harbourmt",; + hbmk[ _HBMK_cDynLibPrefix ] + "harbour" ) } OTHERWISE l_aLIBSHARED := NIL ENDCASE @@ -3735,8 +3749,8 @@ FUNCTION hbmk2( aArgs, nArgTarget, /* @ */ lPause, nLevel ) ENDIF CASE hbmk[ _HBMK_cPLAT ] == "linux" l_aLIBSYS := ArrayAJoin( { l_aLIBSYS, l_aLIBSYSCORE, l_aLIBSYSMISC } ) - l_aLIBSHARED := { iif( hbmk[ _HBMK_lMT ], cDynLibNamePrefix + "harbourmt" + cDL_Version + hbmk[ _HBMK_cDynLibExt ],; - cDynLibNamePrefix + "harbour" + cDL_Version + hbmk[ _HBMK_cDynLibExt ] ) } + l_aLIBSHARED := { iif( hbmk[ _HBMK_lMT ], hbmk[ _HBMK_cDynLibPrefix ] + "harbourmt" + cDL_Version + hbmk[ _HBMK_cDynLibExt ],; + hbmk[ _HBMK_cDynLibPrefix ] + "harbour" + cDL_Version + hbmk[ _HBMK_cDynLibExt ] ) } ENDCASE IF hbmk[ _HBMK_cPLAT ] $ "win|os2" cBin_Res := "wrc" + hbmk[ _HBMK_cCCEXT ] @@ -4393,6 +4407,7 @@ FUNCTION hbmk2( aArgs, nArgTarget, /* @ */ lPause, nLevel ) /* ; */ IF ! hbmk[ _HBMK_lStopAfterInit ] .AND. hbmk[ _HBMK_lCreateImpLib ] .AND. ! lDumpInfo + /* OBSOLETE functionality */ IF DoIMPLIB( hbmk, bBlk_ImpLib, cLibLibPrefix, cLibLibExt, hbmk[ _HBMK_aIMPLIBSRC ], hbmk[ _HBMK_cPROGNAME ], "" ) DoInstCopy( hbmk ) ENDIF @@ -4435,7 +4450,7 @@ FUNCTION hbmk2( aArgs, nArgTarget, /* @ */ lPause, nLevel ) ENDIF l_cIMPLIBNAME := hb_FNameMerge( l_cIMPLIBDIR, cLibLibPrefix + l_cIMPLIBNAME, cImpLibExt ) CASE lStopAfterCComp .AND. hbmk[ _HBMK_lCreateDyn ] - cName := cDynLibNamePrefix + cName + cName := hbmk[ _HBMK_cDynLibPrefix ] + cName IF Empty( cExt ) .AND. ! Empty( hbmk[ _HBMK_cDynLibExt ] ) cExt := hbmk[ _HBMK_cDynLibExt ] ENDIF @@ -4455,6 +4470,8 @@ FUNCTION hbmk2( aArgs, nArgTarget, /* @ */ lPause, nLevel ) ENDCASE ENDIF + DoLinkCalc( hbmk ) + /* Generate header with repository ID information */ IF ! lSkipBuild .AND. ! hbmk[ _HBMK_lStopAfterInit ] .AND. ! hbmk[ _HBMK_lStopAfterHarbour ] .AND. ! lDumpInfo @@ -5580,6 +5597,9 @@ FUNCTION hbmk2( aArgs, nArgTarget, /* @ */ lPause, nLevel ) IF hbmk[ _HBMK_nErrorLevel ] == _ERRLEV_OK .AND. ( Len( l_aOBJ ) + Len( hbmk[ _HBMK_aOBJUSER ] ) + Len( l_aOBJA ) ) > 0 .AND. ! hbmk[ _HBMK_lCLEAN ] + /* Must be called before target creation to avoid errors. */ + DoLinkDelete( hbmk ) + IF lTargetUpToDate hbmk_OutStd( hbmk, hb_StrFormat( I_( "Target up to date: %1$s" ), hbmk[ _HBMK_cPROGNAME ] ) ) @@ -5840,6 +5860,15 @@ FUNCTION hbmk2( aArgs, nArgTarget, /* @ */ lPause, nLevel ) ENDCASE ENDIF + IF lTargetUpToDate .OR. hbmk[ _HBMK_nErrorLevel ] == _ERRLEV_OK + DoLink( hbmk ) + IF ! lTargetUpToDate .OR. hbmk[ _HBMK_lInstForce ] + FOR EACH tmp IN hbmk[ _HBMK_aLINK ] + hb_AIns( hbmk[ _HBMK_aINSTFILE ], 1, { "", tmp }, .T. ) + NEXT + ENDIF + ENDIF + IF ! lTargetUpToDate .OR. hbmk[ _HBMK_lInstForce ] /* For win/bcc and os2/gcc the implib is not created at this point yet, so there will be a copy failure in case the implib generation @@ -5868,6 +5897,7 @@ FUNCTION hbmk2( aArgs, nArgTarget, /* @ */ lPause, nLevel ) /* bcc is known to create it for static libs */ FErase( FNameExtSet( hbmk[ _HBMK_cPROGNAME ], ".bak" ) ) ENDIF + DoLinkDelete( hbmk ) ENDIF IF ! Empty( l_cCSTUB ) FErase( l_cCSTUB ) @@ -6145,6 +6175,49 @@ STATIC PROCEDURE vxworks_env_init( hbmk ) RETURN +STATIC PROCEDURE DoLinkCalc( hbmk ) + LOCAL tmp + + FOR EACH tmp IN hbmk[ _HBMK_aLINK ] + tmp := PathNormalize( PathMakeAbsolute( tmp, hbmk[ _HBMK_cPROGNAME ] ) ) + NEXT + + RETURN + +STATIC FUNCTION DoLinkDelete( hbmk ) + LOCAL tmp + + FOR EACH tmp IN hbmk[ _HBMK_aLINK ] + FErase( tmp ) + NEXT + + RETURN .T. + +STATIC FUNCTION DoLink( hbmk ) + LOCAL cDir, cName, cExt + LOCAL tmp + LOCAL tmp1 + + FOR EACH tmp IN hbmk[ _HBMK_aLINK ] + tmp1 := DirAddPathSep( PathMakeRelative( FNameDirGet( tmp ), FNameDirGet( hbmk[ _HBMK_cPROGNAME ] ), .T. ) ) + FNameNameExtGet( hbmk[ _HBMK_cPROGNAME ] ) + + hb_FNameSplit( tmp1, @cDir, @cName, @cExt ) + /* Cheap hack */ + IF cDir == "." + hb_ps() .OR. ; + cDir == hb_ps() + cDir := "" + ENDIF + tmp1 := hb_FNameMerge( cDir, cName, cExt ) + + IF hb_FLinkSym( tmp1, tmp ) == F_ERROR + hbmk_OutErr( hbmk, hb_StrFormat( I_( "Error: Failed creating symbolic link %1$s to %2$s" ), tmp, tmp1 ) ) + ELSE + hbmk_OutStd( hbmk, hb_StrFormat( I_( "Created symbolic link %1$s to %2$s" ), tmp, tmp1 ) ) + ENDIF + NEXT + + RETURN .T. + STATIC FUNCTION DoIMPLIB( hbmk, bBlk_ImpLib, cLibLibPrefix, cLibLibExt, aIMPLIBSRC, cPROGNAME, cInstCat ) LOCAL cMakeImpLibDLL LOCAL tmp, tmp1 @@ -6216,6 +6289,8 @@ STATIC PROCEDURE DoInstCopy( hbmk ) LOCAL tSrc, tDst + LOCAL cLink + IF ! Empty( hbmk[ _HBMK_aINSTPATH ] ) FOR EACH aInstPath IN hbmk[ _HBMK_aINSTPATH ] @@ -6250,10 +6325,18 @@ STATIC PROCEDURE DoInstCopy( hbmk ) IF DirBuild( FNameDirGet( cDestFileName ) ) ++nCopied - IF hb_FCopy( cInstFile, cDestFileName ) == F_ERROR - hbmk_OutErr( hbmk, hb_StrFormat( I_( "Warning: Copying %1$s to %2$s failed with %3$s." ), cInstFile, cDestFileName, hb_ntos( FError() ) ) ) - ELSEIF hbmk[ _HBMK_lInfo ] - hbmk_OutStd( hbmk, hb_StrFormat( I_( "Copied %1$s to %2$s" ), cInstFile, cDestFileName ) ) + IF ! Empty( cLink := hb_FLinkRead( cInstFile ) ) + IF hb_FLinkSym( cLink, cDestFileName ) == F_ERROR + hbmk_OutErr( hbmk, hb_StrFormat( I_( "Warning: Copying symbolic link %1$s to %2$s failed with %3$s." ), cInstFile, cDestFileName, hb_ntos( FError() ) ) ) + ELSEIF hbmk[ _HBMK_lInfo ] + hbmk_OutStd( hbmk, hb_StrFormat( I_( "Copied symbolic link %1$s to %2$s" ), cInstFile, cDestFileName ) ) + ENDIF + ELSE + IF hb_FCopy( cInstFile, cDestFileName ) == F_ERROR + hbmk_OutErr( hbmk, hb_StrFormat( I_( "Warning: Copying %1$s to %2$s failed with %3$s." ), cInstFile, cDestFileName, hb_ntos( FError() ) ) ) + ELSEIF hbmk[ _HBMK_lInfo ] + hbmk_OutStd( hbmk, hb_StrFormat( I_( "Copied %1$s to %2$s" ), cInstFile, cDestFileName ) ) + ENDIF ENDIF ELSE hbmk_OutErr( hbmk, hb_StrFormat( I_( "Warning: Cannot create install directory for install target %1$s." ), cDestFileName ) ) @@ -9322,6 +9405,8 @@ STATIC FUNCTION MacroGet( hbmk, cMacro, cFileName ) cMacro := _WORKDIR_BASE_ ; EXIT CASE "HB_WORKDYNSUB" cMacro := hbmk[ _HBMK_cWorkDirDynSub ] ; EXIT + CASE "HB_DYNPREFIX" + cMacro := hbmk[ _HBMK_cDynLibPrefix ] ; EXIT CASE "HB_DYNSUFFIX" cMacro := hbmk_DYNSUFFIX( hbmk ) ; EXIT CASE "HB_DYNEXT" @@ -11211,6 +11296,7 @@ STATIC PROCEDURE ShowHelp( hbmk, lLong ) { "-[no]map" , I_( "create (or not) a map file" ) },; { "-[no]implib" , I_( "create (or not) an import library (in -hbdyn/-hbexe mode). The name will have a postfix added." ) },; { "-implib=" , I_( "create import library (in -hbdyn/-hbexe mode) name to (default: same as output)" ) },; + { "-ln=" , I_( "create symbolic link pointing to ( is considered relative to )" ) },; { "-[no]strip" , I_( "strip (no strip) binaries" ) },; { "-[no]trace" , I_( "show commands executed" ) },; { "-[no]beep" , I_( "enable (or disable) single beep on successful exit, double beep on failure" ) },;