How to compile C extension for Python 3.7 in Windows - c

I am trying to compile a C file to use in Python. The file is a solver for differential algebric equations (DAE). My problem is that when I compile the setup.py file I receive the erro Cannot open source file: 'daesolver.c': No such file or directory. As the C file is quite complex I tried to do the same thing with a simpler example. I used the HelloWorld example provide by Elliot Forbes in (https://tutorialedge.net/python/python-c-extensions-tutorial/). Even in with this very simple function I receive the same error.
Here is the full output I receive from the build command.
C:\Users\Administrator>python c:\temp\teste_C2py\setup.py build
running build
running build_ext
building 'myModule' extension
C:\Program Files (x86)\Microsoft Visual
Studio\2017\Community\VC\Tools\MSVC\14.16.27023\bin\HostX86\x64\cl.exe /c
/nolog
o /Ox /W3 /GL /DNDEBUG /MD -IC:\ProgramData\Anaconda3\include -
IC:\ProgramData\Anaconda3\include "-IC:\Program Files (x8
6)\Microsoft Visual
Studio\2017\Community\VC\Tools\MSVC\14.16.27023\ATLMFC\include" "-
IC:\Program Files (x86)\Microsoft
Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023\include" "-
IC:\Program Files (x86)\Windows Kits\10\include\10.0.1
7763.0\ucrt" "-IC:\Program Files (x86)\Windows
Kits\10\include\10.0.17763.0\shared" "-IC:\Program Files (x86)\Windows Ki
ts\10\include\10.0.17763.0\um" "-IC:\Program Files (x86)\Windows
Kits\10\include\10.0.17763.0\winrt" "-IC:\Program Files
(x86)\Windows Kits\10\include\10.0.17763.0\cppwinrt" /Tctest.c
/Fobuild\temp.win-amd64-3.7\Release\test.obj
test.c
c1: fatal error C1083: Cannot open source file: 'test.c': No such file or
directory
error: command 'C:\\Program Files (x86)\\Microsoft Visual
Studio\\2017\\Community\\VC\\Tools\\MSVC\\14.16.27023\\bin\\Ho
stX86\\x64\\cl.exe' failed with exit status 2
Here is the test.c file
#include <Python.h>
// Function 1: A simple 'hello world' function
static PyObject* helloworld(PyObject* self, PyObject* args)
{
printf("Hello World\n");
return Py_None;
}
// Our Module's Function Definition struct
// We require this `NULL` to signal the end of our method
// definition
static PyMethodDef myMethods[] = {
{ "helloworld", helloworld, METH_NOARGS, "Prints Hello World" },
{ NULL, NULL, 0, NULL }
};
// Our Module Definition struct
static struct PyModuleDef myModule = {
PyModuleDef_HEAD_INIT,
"myModule",
"Test Module",
-1,
myMethods
};
// Initializes our module using our above struct
PyMODINIT_FUNC PyInit_myModule(void)
{
return PyModule_Create(&myModule);
}
and here is the setup.py
from distutils.core import setup, Extension
setup(name = 'myModule', version = '1.0', \
ext_modules = [Extension('myModule', ['test.c'])])
both files are located in the same folder c:\temp\teste_C2py.
I am using Python 3.7 in the Anaconda distribution 64 bits (I also want to do the same for x86).
I have installed in the same environment Visual Studio 2017 (community) with all the compiler for necessary (at least I think so).
The thing that is really strange is that I was made to do that when I installed just vs build tools 2017 in a VM but when I try to replicate the same in another machine it give me this error.
I also mess up the environment where I first made this work and now I am not able to do that again.
I also set up the environment variables VS150COMNTOOLS = C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\Tools
It seems that I am missing somenthing in the Visual Studio configuration because it does not make sense to no find a file that is the same folder.

I found the problem. As it used to be it was a very silly thing. I was trying do run the the setup script from the folder where the python.exe is located (because I have different versions of Python in my machine). But if instead of this I move to the folder where the setup.py file is located and run the coomand without any path befere the setup.py the build works! I don't have any idea why a relative path doesn't work here.
I hope this can help!

Related

Undefined reference to (Quickmail)

I am looking for how to install quickmail.
I put quickmail.h here: C:\Program Files\CodeBlocks\MinGW\include, the .a and .la here: C:\Program Files\CodeBlocks\MinGW\lib.
I linked these .a files by adding them in the linker settings. I also did include the library like this: #include <quickmail.h>, but the functions are not recognized.
What should I do ?
The 4 files in the bin folder are in the project folder and I downloaded files from here : quickmail - Sourceforge.
EDIT : I get \main.c|9|undefined reference to '__imp_quickmail_initialize'| \main.c|10|undefined reference to '__imp_quickmail_create'| \main.c|11|undefined reference to '__imp_quickmail_set_body' and I put C:\Program Files\CodeBlocks\MinGW\include in search directories.
This is the code :
#include <stdio.h>
#include <stdlib.h>
#include <quickmail.h>
int main()
{
const char* error;
quickmail_initialize();
quickmail mailobj = quickmail_create("aaa#gmail.com", "libquickmail test e-mail");
quickmail_set_body(mailobj, "This is a test e-mail.\nThis mail was sent using libquickmail.");
quickmail_add_attachment_file(mailobj, "words.txt", NULL);
if ((error = quickmail_send(mailobj, "smtp.gmail.com", 587, "aaa#gmail.com", "MAGA2020")) != NULL)
fprintf(stderr, "Error sending e-mail: %s\n", error);
quickmail_destroy(mailobj);
return 0;
}
Sorry, the site gave me the wrong version.
To use a library you need to include the header in the code (in this case #include <quickmail.h>) and if needed tell the compiler where to find this file (the full path to the lib folder) with the -I compiler flag.
Next you need to tell the linker to link with the library (in this case -lquickmail or -lquickmaillight) and if needed where to find this file (the full path to the lib folder) with the -L linker flag.
Your errors are linker errors, so it seems the second step wasn't properly done.
In Code::Blocks it looks like this (though unlike the screenshots you should set it at the top-level instead of just for Debug builds):

Is it possible to make Gyp generate a pre (or post) build step?

I'm using gyp to generate Visual Studio projects, make files, and Xcode projects.
I would like to have a pre-build step that calls a command line tool which generates some code that I later compile in, is this possible?
Incidentally, in cmake I do it using a post build step on a project that I depend on as a kind of workaround for there being no pre build there, so a post build step would also be fine.
I can see that I can call arbitrary commands at generation time using <!() syntax but I'd really prefer to generate the projects once and then on compile have the code generation step occur.
I got somewhere using actions...
I have this little application:
main.c
#include <stdio.h>
int main() {
#include "some_output"
return 0;
}
And this input file
some_input
printf("Hello World!\n");
And so I can fake up some, albeit Windows specific, code generation in my .gyp file like so (i.e. printing the file to standard out and redirecting back into a file, yes, silly but it illustrates the point hopefully):
gypping.gyp
{
'targets': [
{
'target_name': 'gypping',
'type': 'executable',
'sources': [
'main.c',
'<(INTERMEDIATE_DIR)/some_output',
],
'actions': [{
'action_name': 'create_something_generated',
'inputs': [
'some_input'
],
'outputs': [
'<(INTERMEDIATE_DIR)/some_output',
],
'action': ['type', '<#(_inputs)', '>', '<#(_outputs)'],
},
],
},
],
}
This seems to nearly work in so much as when I build in Visual Studio (having run gyp --depth=.) I get the following error:
1>------ Build started: Project: gypping, Configuration: Default Win32 ------
1> create_something_generated
1> '"C:\dev\code\Sandpit\gypping\.\setup_env.bat"' is not recognized as an internal or external command,
1> operable program or batch file.
1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V140\Microsoft.CppCommon.targets(171,5): error MSB6006: "cmd.exe" exited with code 1.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
I can't find setup_env.bat in my path.
I created an empty setup_env.bat file and I simplified the action by removing the > (I guess the escaping goes wrong with this). Now I get this:
'bash' is not recognized as an internal or external command,
I do not have bash as I'm on Windows.
I think Gyp is finished for me then, I guess I'll stick to cmake.
actions are exactly what you want. They are run pre-compile and the Git docs show them being used to generate files to be used during the compile step.
I have Git for Windows installed and use that, not cygwin, for running the generated actions via Visual Studio. Here is my setenv.bat:
REM Set up to use Git Bash for running "cygwin" actions.
REM CD to where this file lives to avoid path relativization problems.
cd %~dp0
set PATH=%PATH%;C:\Program Files\Git\bin
I have also seen Git for Windows installed in
%USERPROFILE%\AppData\Local\Programs\Git. I have no idea what causes the differing locations. Change the above PATH as necessary.
I am looking for the answer to how to generate a post build step

PC-Lint error : Error 307: Can't open indirect file 'gcc-include-path.lnt'

I am trying to use PC-Lint on windows for exercising static code analysis on C files. I installed the software and ran the configuration setup for gcc compiler where I got the following files in the config directory:
co-gcc.h, co-gcc.lnt, env-ecl-console.lnt, filea.cpp, fileb.cpp, LIN.BAT,
lset.bat, options.lnt, std.lnt, std_a.lnt
However when I try to run the test sample by typing >lin filea fileb from the config directory, I get the following error:
co-gcc.lnt 37 Error 307: Can't open indirect file 'gcc-include-path.lnt'
How do we get the gcc-include-path.lnt file?
Error got solved by creating lint_cmac.h, lint_cppmac.h, gcc-include-path.lnt, and size-options.lnt files using the makefile co-gcc.mak located in PC-lint9.00h\lnt folder.

I cannot include config.h in gimp

I am new to gimp programming. I have installed the gimp and using it in Visual Studio 2010. The configuration is ok.
I was trying to compile the code from here:
http://git.gnome.org/browse/gimp/tree/plug-ins/common/blur.c
The problem is that when including config.h, I am getting this:
fatal error C1189: #error : "config.h must be included prior to stdplugins-intl.h"
where is this config.h file located?
Also, I have problem with this code:
GimpRunMode run_mode; run_mode = param[0].data.d_int32;
it says a value of type gint32 cannot be assigned to an entity of type GimpRunMode.
config.h is generated when you run ./configure in the root of the gimp directory. If you have run configure it should have ended up in the root of the gimp directory.
As to your other problem, try casting the value before assigning it:
GimpRunMode run_mode;
run_mode = (GimpRunMode)param[0].data.d_int32;

how to write unicode hello world in C on windows

im tyring to get this to work:
#define UNICODE
#define _UNICODE
#include <wchar.h>
int main()
{
wprintf(L"Hello World!\n");
wprintf(L"£안, 蠀, ☃!\n");
return 0;
}
using visual studio 2008 express (on windows xp, if it matters).
when i run this from the command prompt (started as cmd /u which is supposed to enable unicode ?) i get this:
C:\dev\unicodevs\unicodevs\Debug>unicodevs.exe
Hello World!
┬ú∞
C:\dev\unicodevs\unicodevs\Debug>
which i suppose was to be expected given that the terminal does not have the font to render those.
but what gets me is that even if i try this:
C:\dev\unicodevs\unicodevs\Debug>cmd /u /c "unicodevs.exe > output.txt"
the file produced (even though its UTF-8 encoded) looks like:
Hello World!
壓
the source file itself is defined as unicode (encoded in UTF-8 without BOM).
the compiler output when building:
1>------ Rebuild All started: Project: unicodevs, Configuration: Debug Win32 ------
1>Deleting intermediate and output files for project 'unicodevs', configuration 'Debug|Win32'
1>Compiling...
1>main.c
1>.\main.c(1) : warning C4005: 'UNICODE' : macro redefinition
1> command-line arguments : see previous definition of 'UNICODE'
1>.\main.c(2) : warning C4005: '_UNICODE' : macro redefinition
1> command-line arguments : see previous definition of '_UNICODE'
1>Note: including file: C:\Program Files\Microsoft Visual Studio 9.0\VC\include\wchar.h
1>Note: including file: C:\Program Files\Microsoft Visual Studio 9.0\VC\include\crtdefs.h
1>Note: including file: C:\Program Files\Microsoft Visual Studio 9.0\VC\include\sal.h
1>C:\Program Files\Microsoft Visual Studio 9.0\VC\include\sal.h(108) : warning C4001: nonstandard extension 'single line comment' was used
1>Note: including file: C:\Program Files\Microsoft Visual Studio 9.0\VC\include\crtassem.h
1>Note: including file: C:\Program Files\Microsoft Visual Studio 9.0\VC\include\vadefs.h
1>Note: including file: C:\Program Files\Microsoft Visual Studio 9.0\VC\include\swprintf.inl
1>Note: including file: C:\Program Files\Microsoft Visual Studio 9.0\VC\include\wtime.inl
1>Linking...
1>Embedding manifest...
1>Creating browse information file...
1>Microsoft Browse Information Maintenance Utility Version 9.00.30729
1>Copyright (C) Microsoft Corporation. All rights reserved.
1>Build log was saved at "file://c:\dev\unicodevs\unicodevs\unicodevs\Debug\BuildLog.htm"
1>unicodevs - 0 error(s), 3 warning(s)
========== Rebuild All: 1 succeeded, 0 failed, 0 skipped ==========
any ideas on what am i doing wrong ?
similar questions on ST (like this one: unicode hello world for C?) seem to refer to *nix builds - as far as i understand setlocale() is not available for windows.
i also tried building this using code::blocks/mingw gcc, but got the same results.
It's not the writing (wprintf) that's the problem, it's the cmd redirection of output that's causing the problem. You can try testing by writing directly to file instead. In that case, you might then run into notepad (or rather Windows API function) not guessing correctly and interpreting your text as ASCII incorrectly if you're just writing a couple of words. In which case, you'll need to write the BOM characters into the file first as well.
#include <stdio.h>
#include <wchar.h>
int main()
{
FILE *out;
char bom[] = "\xFF\xFE";
wchar_t s[] = L"中文!";
size_t c;
out = fopen ("out.txt", "w");
if(out == NULL)
{
perror("out.txt");
return 1;
}
c = fwrite(bom, 1, 2, out);
if(c != 2)
{
perror ("Fatal write error.");
fclose(out);
return 2;
}
c = fwrite(s, sizeof(wchar_t), wcslen(s), out);
if(c != wcslen(s))
{
perror ("Fatal write error.");
fclose(out);
return 2;
}
fclose(out);
return 0;
}

Resources