Hi David,
The short answer is I've figured out what needs to be changed to get the plugin to compile with oscog-eem.2257.
FileAttributesPlugin-AlistairGrant.13 compiles and all the automated tests with 'file' in the package name pass (except for truncate, which has always failed).
If you're interested in what I had to do, please see below my signature.
Thanks again, Alistair
On Wed, Jul 26, 2017 at 07:46:31PM -0400, David T. Lewis wrote:
Hi Alistair,
I cannot really look into this much for the next few days, but I suspect that you are looking at a mismatch between your VMMaker and platforms sources.
VMMaker-dtl.392.mcz is the most up to date version of the traditional interpreter VM. It is intended to be compiled with the platform sources that come from the original Subversion repository at squeakvm.org.
I've never checked out the code using subversion, it seems to work fine if the platform source is the latest Cog branch (don't forget I'm not generating an entire VM, just the C code for one plugin).
VMMaker.oscog-eem.2257 is the most up to date version of the oscog branch of VMMaker that is the basis of the latest Cog and Spur VMs for Squeak and Pharo. It is intended to be compiled with the platform sources from the GitHub repository. In the the VMMaker repository, the "oscog" suffix distinguishes the Cog/Spur development (suitable for Pharo) from the traditional branch.
Your plugin will probably work fine with either combination of VMMaker and platforms sources, but you cannot mix the two without problems such as what you are seeing now.
I personally use the traditional interpreter VM platform for plugin development, then validate the resulting plugin on Cog/Spur (which usually just works without issues). But either combination of VMMaker and platforms sources should be fine as long as you do not mix the two.
Given that your goal is a plugin to support Pharo images, you will want test with VMMaker.oscog-eem.2257 and the latest platforms sources from the GitHub repository.
Yep, that's what I'm trying to do - and what was failing.
That will verify that the plugin can be generated from a VMMaker.oscog image, and that the resulting C code works with the overall Cog/Spur code base that is maintained on GitHub.
OK, thanks for the explanation.
I've started stepping in to the code generation and it looks like TMethod has changed significantly between dtl.392 and oscog-eem.2257.
One example of a change is, given:
<var: 'statBuf' type: 'struct stat'> <var: 'statBufPointer' declareC: 'struct stat *statBufPointer= &statBuf'>
dtl.392 isn't as aggressive when removing variables that it considers unreferenced, so the above works. oscog-eem.2257 doesn't recognise the reference to statBuf in the declareC:, so removes it, leading to the lack of variable declaration.
Changing the source to:
<var: 'statBuf' type: 'struct stat'> <var: 'statBufPointer' type: 'struct stat *'>
statBufPointer := self cCode: '&statBuf'.
appears to generate the correct C (based on visual inspection, I haven't built and tested it yet).
Also #isDefinedTrueExpression:isSmalltalk:comment:ifTrue:ifFalse: used to allow arbitrary expressions in the ifTrue: block. That appears to be no longer the case. I've changed all these to use #cPreprocessorDirective:.
HTH, Dave
On Wed, Jul 26, 2017 at 09:02:41PM +0000, Alistair Grant wrote:
Hi All,
I've realised that I have been doing all my development using an old version of VMMaker: dtl.392.
Before submitting my plugin I thought I should check that it builds correctly with the latest VMMaker.
However taking a clean squeak image (Squeak5.1-16549-32bit-201608171728-Linux) and loading what I believe is the latest VMMaker: oscog-eem.2257 causes the plugin to fail to compile with numerous errors (on Ubuntu 16.04, gcc 4.8.5).
Could someone please let me know which version of VMMaker I should be using?
If you're interested in the sorts of problems I'm facing:
The full code is available from:
MCHttpRepository location: 'http://smalltalkhub.com/mc/Alistair/FileAttributesPlugin/main' user: '' password: ''
An example of one of the failures is a method that begins:
fileToAttributeArray: cPathName mask: attributeMask array: attributeArray "Answer a file attribute array from pathNameOop."
| getStats useLstat getAccess statArray accessArray combinedArray status fileNameOop statBuf statBufPointer | <returnTypeC: 'int'> <var: 'cPathName' type: 'char *'> <var: 'attributeArray' type: 'sqInt *'> <var: 'statBuf' type: 'struct stat'> <var: 'statBufPointer' declareC: 'struct stat *statBufPointer= &statBuf'>
dtl.392 correctly creates C definitions for statBuf and statBufPointer, i.e.:
static int fileToAttributeArraymaskarray(char *cPathName, sqInt attributeMask, sqInt *attributeArray) { sqInt accessArray; sqInt combinedArray; sqInt fileNameOop; sqInt getAccess; sqInt getStats; sqInt statArray; struct stat statBuf; struct stat *statBufPointer= &statBuf; sqInt status; sqInt useLstat;
oscog-eem.2257 produces:
static int fileToAttributeArraymaskarray(char *cPathName, sqInt attributeMask, sqInt *attributeArray) { sqInt accessArray; sqInt combinedArray; sqInt fileNameOop; int getAccess; int getStats; sqInt statArray; struct stat *statBufPointer= &statBuf; sqInt status; int useLstat;
As can be seen, the statBuf declaration is missing.
Further along:
isSymlink: cPathName boolean: resultOop "Set resultOop to a boolean indicating whether cPathName is a symbolic link. Answer status (0 = success)"
| status statBuf | <var: 'cPathName' type: 'char *'> <var: 'resultOop' type: 'sqInt *'> <var: 'statBuf' type: 'struct stat'> self isDefinedTrueExpression: 'HAVE_LSTAT == 1' inSmalltalk: [] comment: '' ifTrue: [ status := self cCode: 'lstat(cPathName, &statBuf)'. (status ~= 0) ifTrue: [^self cantStatPath]. ((self cCode: 'S_ISLNK(statBuf.st_mode)') = 0) ifFalse: [self cCode: '*resultOop = interpreterProxy->trueObject()'] ifTrue: [self cCode: '*resultOop = interpreterProxy->falseObject()']. ] ifFalse: []. ^0
dtl.392 produces:
static sqInt isSymlinkboolean(char *cPathName, sqInt *resultOop) { struct stat statBuf; sqInt status;
# if (HAVE_LSTAT == 1) // status = lstat(cPathName, &statBuf); if (status != 0) { return -3; } if ((S_ISLNK(statBuf.st_mode)) == 0) { *resultOop = interpreterProxy->falseObject(); } else { *resultOop = interpreterProxy->trueObject(); } # endif // HAVE_LSTAT == 1
return 0;
}
oscog-eem.2257 produces:
static sqInt isSymlinkboolean(char *cPathName, sqInt *resultOop) { struct stat statBuf; sqInt status;
isDefinedTrueExpressioninSmalltalkcommentifTrueifFalse("HAVE_LSTAT == 1", null, "", ((status =
lstat(cPathName, &statBuf)), (status != 0 ? (/* begin cantStatPath */ return -3) : 0), ((S_ISLNK(statBuf.st_mode)) == 0 ? *resultOop = interpreterProxy->falseObject() : *resultOop = interpreterProxy->trueObject())), null); return 0; }
Any help appreciated.
Thanks very much, Alistair
# vim: tw=72