Skip to content

Add support for C sources and headers to dub#2522

Closed
cschlote wants to merge 23 commits intodlang:masterfrom
cschlote:add-importc-support-to-dub
Closed

Add support for C sources and headers to dub#2522
cschlote wants to merge 23 commits intodlang:masterfrom
cschlote:add-importc-support-to-dub

Conversation

@cschlote
Copy link
Contributor

@cschlote cschlote commented Oct 30, 2022

Add changes to support C source and header files with Dub

  • This is a work-in-project PR as basis for discussions on scope changes and impacts involved with adding C source and header file support to dub.
  • The goal is to be able to use C files (.c, .h and .i) in Dub projects the same way as usual D files (.d and .di). Dub shall be able to pick up these files automatically and pass them to the D compiler.
  • We need some switch to enable the support in JSON/SDL files (backward compatibility, test staging). For this 'cSourcePaths' and 'cImportPaths' were added. If specified, dub will pick up C source and pass extra paths to the compiler.
  • We need some way to detect existing ImportC support in D compilers (separate issue, WIP)
  • We must generalize some code by using isSourceFile(), isHeaderFile() and isImportCFile() instead of just checking for ".d" extension. (separate issue, WIP)

@rikkimax
Copy link
Contributor

This is going to need tests before going in.

However, I have no idea how that can happen without a build of at least one compiler with the preprocessor support working in the CI.

@cschlote
Copy link
Contributor Author

Yes for sure it needs testing in the CI. But nobody is hindering us to work out things in advance. In the meantime we can use and test the patched dub with our own projects.

I will continue with this patch stack, rebase it from time to time.

@rikkimax Is there already some code to determine the compiler version / D support level in dub? if we implement that first, we can test the patched dub in the CI - it should disable ImportC support in this case as some kind of negative test. And when the next DMD/LDC/GDC is released with ImportC support, it should switch to ImportC support.

@rikkimax
Copy link
Contributor

@rikkimax Is there already some code to determine the compiler version / D support level in dub?

Yes.

https://github.com/dlang/dub/blob/master/source/dub/compilers/compiler.d#L150

https://github.com/dlang/dub/blob/master/source/dub/platform.d#L252

(note ignore the determine platform stuff in that module, as that only applies to the dub executable).

There is code to compare compiler versions, however, you'll need to dig a bit into it I think.

package(dub) void checkPlatform(const scope ref ToolchainRequirements tr, BuildPlatform platform, string package_name)

auto buildsettings = targets[pack].buildSettings;
if (!buildsettings.sourceFiles.any!(f => f.endsWith(".d"))())
if (!buildsettings.sourceFiles.any!(f => f.endsWith(".d"))() &&
!buildsettings.sourceFiles.any!(f => f.endsWith(".c"))() )
Copy link
Contributor

@nordlow nordlow Nov 2, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replace with

if (!buildsettings.sourceFiles.any!(f => f.endsWith(".d", ".c")))

. startsWith and endsWith can take any (N >= 1) number of explicit needle parameters, where N is known at compile-time.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we move the list of hardcoded file endings somewhere else entirely? It's repeated many times in the code.

@cschlote cschlote force-pushed the add-importc-support-to-dub branch 2 times, most recently from c29ce22 to adae25d Compare November 8, 2022 09:31
@cschlote
Copy link
Contributor Author

I tested the current state of the PR with many of my projects and dub packages. I found other bugs, but nothing related to this PR.
I created some test code for ImportC here: https://gitlab.vahanus.net/dlang/examples/importc-tests.git

Although I agree, that there is much more potential to refactor the dub sources, I'm also a friend of agile development moving in small steps to a final goal. As this PR adds initial support for Import C with the next upcoming DMD release, we should focus on this current scope and proceed with other refactoring and improvements in other PRs. I would be nice to have working support for ImportC in dub before the next DMD release.

@cschlote cschlote force-pushed the add-importc-support-to-dub branch from adae25d to 3d73c2f Compare November 15, 2022 18:18
@ibuclaw
Copy link
Member

ibuclaw commented Nov 16, 2022

The goal is to be able to use C file (.c, .h and .i) in Dub projects the same way as usual D files (.d and .di). Dub shall be able to pick up these files automatically and pass them to the D compiler.

FYI the GDC compiler has been able to compile C/C++/Go/Fortran/Rust... sources since 2004. It's all delegated by the D compiler driver when you invoke it normally: gdc file1.d file2.cpp file3.go file4.rs -o combined.exe.

Calling the gate haveImportCSupport is could be misleading, as don't really need importC in order for the D compiler to compile foreign language sources.

@redthing1
Copy link

I tried the PR and seems to work quite well! Hope to see merge soon.

@cschlote cschlote force-pushed the add-importc-support-to-dub branch from 3d73c2f to a8744b4 Compare November 18, 2022 18:52
@cschlote
Copy link
Contributor Author

The goal is to be able to use C file (.c, .h and .i) in Dub projects the same way as usual D files (.d and .di). Dub shall be able to pick up these files automatically and pass them to the D compiler.

FYI the GDC compiler has been able to compile C/C++/Go/Fortran/Rust... sources since 2004. It's all delegated by the D compiler driver when you invoke it normally: gdc file1.d file2.cpp file3.go file4.rs -o combined.exe.

Calling the gate haveImportCSupport is could be misleading, as don't really need importC in order for the D compiler to compile foreign language sources.

Interesting. I have never tried to feed other language sources to GDC, yet.

But the goal of this PR is to teach 'dub' to pass C files to the DMD, LDC2 and GDC compilers. Otherwise no code is generated and the linker will emit errors on the missing stuff. So although GDC might be able to compile these files without any addition effort, without this PR the 'dub' project won't build as expected.

@cschlote cschlote marked this pull request as ready for review November 22, 2022 13:57
@WebFreak001
Copy link
Member

WebFreak001 commented Nov 23, 2022

maybe instead of trying to apply this to sourcePaths/sourceFiles, should we add a new key to the dub.json/sdl like "cPaths" or "sourceCPaths" or "cSourcePaths"?

Or a more generic "foreignSourcePaths"?

For C paths we could maybe also consider implementing ctod or similar in DUB, so compilers without importC will work as well, or if you want to manually enable it because of importC restrictions.

Advantages: we don't suddenly start compiling C source files inside D projects, which might have been there incrementally while porting to D. (a case Walter brings up often)

Additionally tooling can recognize when people want to explicitly enable ImportC.

@cschlote
Copy link
Contributor Author

cschlote commented Nov 24, 2022

maybe instead of trying to apply this to sourcePaths/sourceFiles, should we add a new key to the dub.json/sdl like "cPaths" or "sourceCPaths" or "cSourcePaths"?
Or a more generic "foreignSourcePaths"?

I kept my C/foreign in separate directories and used pre-build/gen Hooks to convert them to object files. The object ist then added to the linker flags.

Starting with ImportC I tend to add my C sources inside of the usuall D directories. Simply because C is then no longer foreign. For more complex C projects, which can't be compiled with ImportC, I would use external hooks and linklibs as before.

For C paths we could maybe also consider implementing ctod or similar in DUB, so compilers without importC will work as well, or if you want to manually enable it because of importC restrictions.

I wouldn't mix up things here. We have pre Hooks to handle the complicated stuff, or Import for the simpler code. CtoD never worked for me, because most old C code uses the PrePro for funny things.

Advantages: we don't suddenly start compiling C source files inside D projects, which might have been there incrementally while porting to D. (a case Walter brings up often)

Ok, that would be a point. A switch like 'enable-importc' in the dub file would be a good workaround. if enabled, dub would pass C files to the compiler silently. Otherwise I will gibe a warning instead that C files are found, but not yet sent to the compiler until the 'enable-importc' property ist set. Later this could be removed when most Dub projects are adapted.

Additionally tooling can recognize when people want to explicitly enable ImportC.

How?

@cschlote cschlote force-pushed the add-importc-support-to-dub branch from a8744b4 to 397bbad Compare November 26, 2022 16:12
@cschlote
Copy link
Contributor Author

One of my own old dub projects from 2019 uses C files, which are compiled to object files. This PR passes the C file now directly to the D compiler. Unfortunatelly this doesn't work. So we need a configuration switch/option as proposed by @WebFreak001 .

@cschlote cschlote force-pushed the add-importc-support-to-dub branch from 397bbad to f6ea2e0 Compare November 29, 2022 11:56
@cschlote cschlote changed the title Add ImportC support to dub Add support for C sources and headers to dub Dec 1, 2022
@cschlote cschlote changed the title Add support for C sources and headers to dub Draft: Add support for C sources and headers to dub Dec 1, 2022
@cschlote
Copy link
Contributor Author

cschlote commented Dec 1, 2022

I added new keyword to dub.json/sdl: 'cSourcePaths' and 'cImportPaths'
They allow to pickup C sources and headers in the given paths.
Tested with https://gitlab.vahanus.net/dlang/examples/importc-tests.git (for 'cSourcePaths').
For 'cImportPaths' more testing and likely some changes are needed.
Please review and comment.

@cschlote cschlote force-pushed the add-importc-support-to-dub branch from 9c4e449 to f535e9d Compare December 1, 2022 08:13
@cschlote cschlote requested a review from WebFreak001 December 1, 2022 08:17
Copy link
Member

@WebFreak001 WebFreak001 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also add your test project to the tests folder

@cschlote cschlote force-pushed the add-importc-support-to-dub branch from f535e9d to 0142f43 Compare December 1, 2022 20:59
@WebFreak001
Copy link
Member

WebFreak001 commented Dec 2, 2022

please don't force push while still reviewing, it makes it hard to understand what has changed, especially on a change with this many changed lines of code.

I think for this we will need to squash it all at the end anyway, so we can do this after the reviews pass I think.

@cschlote cschlote force-pushed the add-importc-support-to-dub branch from 0142f43 to a48af9e Compare December 2, 2022 08:26
@cschlote
Copy link
Contributor Author

cschlote commented Dec 2, 2022

please don't force push while still reviewing, it makes it hard to understand what has changed, especially on a change with this many changed lines of code.

I think for this we will need to squash it all at the end anyway, so we can do this after the reviews pass I think.

Ok, I tend to rebase my changes to the latest master, especially when other changes happen on master, which conflict with the PR. So I can resolve them now. I added the requested changes as commits to the current patch stack.

And yes, I will rework the patch stack at the end and split up the changes into reasonable commits. Some functions in utils are currently unused - probably we want them in a separate PR and with active use in the source.

@cschlote cschlote force-pushed the add-importc-support-to-dub branch from 115463a to 20bb284 Compare December 2, 2022 10:04
@cschlote cschlote marked this pull request as draft December 2, 2022 10:37
@cschlote cschlote changed the title Draft: Add support for C sources and headers to dub Add support for C sources and headers to dub Dec 2, 2022
cschlote and others added 23 commits December 2, 2022 20:06
…ortc)

Added functions to determine the type of a file. It can be either a
source or a header file. It might also be a C source, intermediate or
header file to be used with ImportC.
Starting with the next DMD version 2.101 the compiler also processes
C files. Add some code to pickup the C files in the source directories
as well.
We might need also some helper functions/enums for these file patterns.
Seems to compiler related, so placed stub here for discussion.
Using suggested way to add a new JSON/SDL keyword 'cSourcePaths'. These
paths will be searched for .c files. This avoids the problem with
unexpected behaviour of dub for old dub projects with C source in the
existing source directories.

I was told that Walter Bright keeps C sources in the same directory while
porting them to D. Also I found such things in my own old dub projects.
Co-authored-by: Jan Jurzitza <gh@webfreak.org>
@cschlote cschlote force-pushed the add-importc-support-to-dub branch from 20bb284 to 3b7308f Compare December 2, 2022 19:08
@cschlote cschlote marked this pull request as ready for review December 3, 2022 12:20
@cschlote
Copy link
Contributor Author

cschlote commented Dec 3, 2022

Cleanup up the patch stack. I re-submitted the PR as #2544.

@cschlote cschlote closed this Dec 3, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

Comments