visuald icon indicating copy to clipboard operation
visuald copied to clipboard

Struggling with ImportC

Open TurkeyMan opened this issue 4 months ago • 20 comments

So I added a .c file to my project

#pragma attribute(push, nothrow, nogc)

#if defined(_WIN32)
# include "pcap.h"
#endif

By default, Visual Studio treats it as a C/C++ file and hands it to cl.exe for compiling. So, I change the file's Item Type to "D Compile", which matches all the D source files: Image That kinda seemed to have some effect, now when I build, the file is included in the DMD command line:

1>Compiling appliance.d [...] variant.d zip.d os.c  # <-- NOTE THE os.c FILE HERE
1>COMPILED : error : C preprocess command C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.39.33519\bin\HostX64\x64\cl.exe failed for file third_party\urt\src\urt\internal\os.c, exit status 2
1>
1>third_party\urt\src\urt\internal\os.c(12): fatal error C1083: Cannot open include file: 'pcap.h': No such file or directory

But you can see from that build output, it invokes DMD (apparently correctly), and then it seems to try and build it with cl.exe as well??

Or, is that output coming from pipelink.exe (or whatever it's called) and it is delegating the .c file out to the C compiler before it reackes DMD?

Surprisingly, it complains because it can't find the include path, so it seems cl.exe is definitely invoked and trying to build the file; but the error is surprising, because the C/C++ compiler config actually DOES specify the correct include path. If I change that file back to "C/C++ compiler" and let the C compiler compile it, it does compile properly in that case.

So, I guess something is just askew when forcing a .c file to use the D Compiled item type...

TurkeyMan avatar Aug 25 '25 03:08 TurkeyMan

I just tried something else; instead of including it in the build, I thought if I import the .c file into .d source, then DMD would do the business through it's normal import logic:

import urt.internal.os; // <- this is os.c

I exclude the .c file from the build in the project settings to try and make sure MSBuild ignores it: Image Build:

1>Compiling appliance.d [...] variant.d zip.d  # <-- NO .c files on passed to the compiler
1>src\router\iface\package.d(27): error : C preprocess command C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.39.33519\bin\HostX64\x64\cl.exe failed for file third_party/urt/src/urt\internal\os.c, exit status 2
1>
1>third_party/urt/src/urt\internal\os.c(12): fatal error C1083: Cannot open include file: 'pcap.h': No such file or directory

Still trying to invoke cl.exe... strange?

Has anyone ever tried to use importC with VisualD?

TurkeyMan avatar Aug 25 '25 04:08 TurkeyMan

Also worth noting; when the .c file is set to D Compiler, making changes to the .c file does not seem to cause a project rebuild... it just thinks nothing changed :/

TurkeyMan avatar Aug 25 '25 04:08 TurkeyMan

Still trying to invoke cl.exe... strange?

is it not using cl for preprocessing? Does it do the same if you run cl with whatever the equivalent of -E is (to get a .i file)?

thewilsonator avatar Aug 25 '25 05:08 thewilsonator

Yes, dmd is invoking cl.exe to preprocess the C file, but the C/C++ options are not known to the D compiler, so you will have to add the necessary ones (defines and C only include paths) with -P.

I have only tried import C once (it failed too easily on system or SDK headers), but I would expect C files to best be compiled with msvc, and only import the C source or header files. dmd should handle this automatically (including the preprocessing), but might need additional include path options.

rainers avatar Aug 25 '25 05:08 rainers

Also worth noting; when the .c file is set to D Compiler, making changes to the .c file does not seem to cause a project rebuild... it just thinks nothing changed :/

It looks like the dependency tracker doesn't capture the activity of the cl.exe subprocess used for preprocessing. Not sure if it is easy to change that.

Edit: the tracker works and produces dmd-cl.read.tlog, but it isn't yet merged with the other dependencies.

rainers avatar Aug 25 '25 06:08 rainers

Oh? I thought Walter put the preprocessor he wrote some years back in DMD... does that mean DMD for windows depends on MSVC? It doesn't seem right that DMD depends on the VS C compiler to preprocess .c files :/

TurkeyMan avatar Aug 25 '25 06:08 TurkeyMan

IIRC Walter was worried about all the system specific extensions the compiler writers have added to the preprocessor and that are used in system headers.

rainers avatar Aug 25 '25 06:08 rainers

Oh? I thought Walter put the preprocessor he wrote some years back in DMD

No.

does that mean DMD for windows depends on MSVC?

It's either that or Clang or GCC (via MinGW). The flag -cpp= controls this choice, as does the environment variable CPPCMD.

thewilsonator avatar Aug 25 '25 06:08 thewilsonator

Is there anything VisualD can do to get the proper args through to the preprocessor?

TurkeyMan avatar Aug 25 '25 07:08 TurkeyMan

Is there anything VisualD can do to get the proper args through to the preprocessor?

I guess we could grab the VC project settings and forward them to dmd. That doesn't work for settings on specific files, though, as it is unknown upfront which files will be imported.

rainers avatar Aug 25 '25 07:08 rainers

I would expect the project settings applied to the current D compilation to cascade through to any imports... so I wouldn't grab it from the C++ settings, I'd probably grab the -I paths from the D settings?

TurkeyMan avatar Aug 25 '25 12:08 TurkeyMan

I'd probably grab the -I paths from the D settings?

I was expecting dmd to already do that (it searches c/h files there itself), but in fact that is not the case. Adding an option for the C include path is probably the simplest and setting its default to %(ImportPaths) makes it inherit the D import paths.

rainers avatar Aug 26 '25 06:08 rainers

That seems nice, I have argued on the forum that the C include paths should be separate to -I, but apparently Walter likes it the way it is. We'd be breaking from DMD's intent (although that seems fine 😉) Do you reckon it's a bug in DMD that it's not already passing the -I paths through, or is there some intention there?

TurkeyMan avatar Aug 26 '25 08:08 TurkeyMan

I have added an option to set the C include search path, but inheriting another setting turned out to be a nightmare wasting hours unsuccessfully trying to do a simple text replacement on a list in msbuild. So let's stick with dmds' behavior and not forward the import paths by default ;)

While testing I noticed that the semantic analysis also errors on C imports, that also needs to be adjusted.

BTW: It think Iain has also changed the search slightly for dmd 2.112 and it might also find .h files when importing.

rainers avatar Aug 29 '25 11:08 rainers

Hmmm, yeah okay let's wait until the next DMD release to see where this stuff lands.

TurkeyMan avatar Sep 03 '25 02:09 TurkeyMan

The added import C support can be found in https://github.com/dlang/visuald/releases/tag/v1.4.2-beta1.

The semantic engine now also runs the preprocessor, but an edited .c/.h file must be saved, though, as it is controlled by Visual C, not Visual D.

rainers avatar Sep 03 '25 07:09 rainers

I used those new options, made propgress. I couldn't see anywhere to pass flags to the preprocessor though. I wanted to silence preprocessor warnings. For some reason #pragma warning(disable:4005) in the code doesn't actually affect the preprocessor's behaviour as I'd expect :/

TurkeyMan avatar Sep 05 '25 08:09 TurkeyMan

For some reason #pragma warning(disable:4005) in the code.

In importc.h or in your own files?

thewilsonator avatar Sep 05 '25 08:09 thewilsonator

You can pass options to the preprocessor with -P as additional command line option, e.g. -P/wd4005

rainers avatar Sep 05 '25 08:09 rainers

For some reason #pragma warning(disable:4005) in the code.

In importc.h or in your own files?

At the top of the .c file that I'm compiling, before the #include that emits the warnings. I'll try the -P strategy Rainer suggested (thanks!).

TurkeyMan avatar Sep 05 '25 13:09 TurkeyMan