-
Notifications
You must be signed in to change notification settings - Fork 70
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
MSVC/Windows support #214
MSVC/Windows support #214
Conversation
# Conflicts: # .gitignore
Hi, thank you for the contribution. It appears the travis and appveyor builds are failing - examining the output, "exit code 139" indicates a segfault. So there is likely a memory or double-free error somewhere. Look at the code, I think it's better to have a single logic path (where possible) for both Windows and non-Windows. So I'm OK using malloc() instead of variable-sized stack allocations everywhere in order to meet MSVC's requirements. I recommend removing the non- Going forward, we will need to ensure that future changes do not break the MSVC build. So I also recommend changing the Appveyor configuration to build with an MSVC toolset. I'm not overly versed in Appveyor, but I can try to provide assistance there if you need it. |
…/realloc for all archs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is looking better, thank you for making the changes. I have suggested a few more. The only mandatory one is fixing READSTAT_VERSION
.
Before approval, we will need to set up a build with MSVC on Appveyor (as mentioned previously).
src/bin/readstat.c
Outdated
#if !defined _MSC_VER | ||
# include <sys/time.h> | ||
#else | ||
# define READSTAT_VERSION "0.2.0" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The version should not be hard-coded. Currently we maintain version information in configure.ac.
src/bin/readstat.c
Outdated
unlink(output_filename); | ||
#else | ||
_unlink(output_filename); | ||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For platform differences like this, I would prefer to move the logic somewhere else so that it can be reused. For a simple case like this probably adding to the top of the file
#if defined _MSC_VER
#define unlink _unlink
#endif
Would be fine.
src/bin/readstat.c
Outdated
struct tm ltm; | ||
localtime_s(<m, ×tamp); | ||
strftime(buffer, sizeof(buffer), "%d %b %Y %H:%M", <m); | ||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For a more complicated platform difference like this, a separate function is probably warranted, e.g.
size_t readstat_strftime(char *s, size_t maxsize, const char *format, time_t timsetamp) {
#if !defined _MSC_VER
...
#else
...
#endif
}
That way we keep _MSC_VER out of the main application functions.
#include <unistd.h> | ||
#if !defined(_MSC_VER) | ||
# include <unistd.h> | ||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am guessing that most inclusions of unistd.h
are no longer needed even on Unix, but I can clean them up later.
src/sas/readstat_sas7bcat_read.c
Outdated
@@ -133,6 +134,9 @@ static readstat_error_t sas7bcat_parse_value_labels(const char *value_start, siz | |||
} | |||
|
|||
cleanup: | |||
if(label) | |||
free(label); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not important, but for future reference: free
will accept a NULL pointer, so it's not necessary to check it with if(label)
.
src/sas/readstat_sas7bdat_write.c
Outdated
char header[hinfo->page_header_size]; | ||
memset(header, 0, sizeof(header)); | ||
char *header = malloc(hinfo->page_header_size); | ||
memset(header, 0, hinfo->page_header_size); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
malloc
/memset
should use calloc(1, hinfo->page_header_size)
instead
Thank you for your feedback. |
@zebrys Thanks for making the requested changes. Go ahead and add READSTAT_VERSION to the MSVC file and I'll see if it looks manageable from my end. (Current version is 1.1.4.) |
ah! this looks great! i maintain a patch for MSVC support over here: https://github.com/jonathon-love/ReadStat but it looks like you've got it all covered anyway. let me see if i can simply use this as a drop-in replacement. |
hi, i'm having some failures, which i assume is to do with me using an earlier version of MSVC. https://ci.appveyor.com/project/jonathon-love/jamovi-readstat i'm using 14 (because we want python compatibility ... @ofajardo too). it looks like the earlier version doesn't support the jonathon-love@c77cbff#diff-34dc7b78affe90ca491a0d0492d933ee how would people feel about me making this compatible with MSVC 14? jonathon |
All versions are fine with me, as long as we get CI / Appveyor coverage in the end. The config file from the Boost::Math project may provide some guidance, as they cover both MSVC and GCC: https://github.com/boostorg/math/blob/develop/appveyor.yml |
The VS issue was due to a problem during a merge on our side. This last update is now tested with VS2017 and works well. It should also theoretically work with VS2019 and probably VS2014/VS2015 but the best would be to check. The restrict issue has been fixed as well (as a missing VLA use). @jonathon-love can you check the last update on VS2014? |
@evanmiller We never used Appveyor so far. We will try to do that. |
@zebrys Okay, that would be great! |
The iconv dependency is a problem for the CI on Windows: it does not seems to be already available on the image and is required for the MSVC project (we just need a directory with the header and the compiled lib files). What is the standard way to get dependencies like this in such CI ? |
Will this solve your problem? https://github.com/fastlane/fastlane/pull/13191/files We could also explore a native Win32 solution since almost all transcoding is routed through |
wrt iconv, you could consider my approach. i mount these projects as submodules: https://github.com/kiyolee/libiconv-win-build and here's my appveyor file: https://github.com/jamovi/jamovi-readstat/blob/master/appveyor.yml |
it all builds for me! |
Thank you for this link. I succeed to build a 32-bit version of ReadStat on Appveyor with some fix related to iconv. That being said, the package GNUWin32 is only for 32-bits machines and does not provide 64-bits libs (or static versions as well as debug ones). The unofficial repository https://github.com/pffang/libiconv-for-Windows.git does provides the required additional compiled versions for a proper x64 build. With this, the build succeed. |
This last version should be complete. The CI on MSVC/Windows seems to work correctly. The project has been tested successfully on multiple machine with MSVC 15 and 17! PS: @evanmiller Ok. |
oh, sorry evan, we assumed i'm sure you'll figure it out @zebrys, but it's just a simple substitution of here's the implementation jamovi-readstat and pyreadstat use: https://github.com/jamovi/jamovi-readstat/blob/master/jamovi/readstat.pyx#L26-L41 (in cython). cheers |
The CI seems to fail due to the MSVC configuration and not the branch as the same CI type work on the same branch content. Although I think MSVC 15 should be used regarding the documentation, the actual build version is 16.7 on our CI and 14.1 on your and it seems to prevent the build... |
The problem seems to come from the MSVC SDK compatibility. Our CI was using MSVC 2019 by default with the specified OS (despite the Appveyor documentation). The 4 last commits try to enforce MSVC 2015 (even with MSVC 2017/2019 using an older/legacy compiler). Although we try our best to fix the compatibility issue, but we did not succeed so far. Using explicitly MSVC 2017 or 2019 works well in the CI. What about using MSVC 2017 by default for the CI (at least temporary)? |
The last commits solve the SDK compatibility. However, this is far from being ideal as a very old SDK has to be used with the current available VS2015 (see the message before). |
Generally I prefer newer tooling, and as development goes forward with the new CI configuration, I'd rather not spend my time chasing down errors with old SDKs. Since the code base now builds with MSVC 14, I'm okay with using a newer compiler for CI and just waiting for user bug reports about MSVC 14 if it breaks in the future. Is that okay with you, @jonathon-love ? |
yeah, that's fine. (MSVC 14 is MSVC 2017 i think). cheers jonathon |
@zebrys Go ahead and configure it whichever way is most convenient for your team. When you give the word, I'll merge it in. |
08d4c2d
to
49cc0da
Compare
Tank you. You can now merge this PR! |
49cc0da
to
b590396
Compare
Thank you very much for all the work that went into this! |
This PR enable Microsoft Visual Studio (>=2017) to build the project and use it on Windows.