Skip to content
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

can cxx_files support a .cc extension? #83

Closed
andrewray opened this issue May 20, 2017 · 30 comments · Fixed by #2195 or ocaml/opam-repository#14239
Closed

can cxx_files support a .cc extension? #83

andrewray opened this issue May 20, 2017 · 30 comments · Fixed by #2195 or ocaml/opam-repository#14239

Comments

@andrewray
Copy link

Currently assumes the file has a .cpp extension, though .cc is also pretty common.

@ghost
Copy link

ghost commented May 22, 2017

Sure, the fields c_names/cxx_names/... comes from our jenga rules. I'm assuming they take names rather than filenames to match (modules (...)) (/cc @sliquister). However, given that there are many more possible extensions for C/C++ files, it'd probably be simplier to replace them by c_files/cxx_files and take full filenames. I'll look at adding these in jbuilder.

@ghost ghost added the enhancement label Jun 2, 2017
@rauanmayemir
Copy link

Any progress on this? Having c_names take full filenames would be really helpful as there's currently no way of including .m/.mm stubs.

@rgrinberg
Copy link
Member

@rauanmayemir would you like to give this issue a try? It's not particularly difficult and I can give you a bit of info to get started.

@rauanmayemir
Copy link

@rgrinberg Hey, why not? I'd love to try!

@rgrinberg
Copy link
Member

rgrinberg commented Jul 1, 2018

Thinking about this a little more, I think that we could consider breaking compatibility here for dune 1.0. That is, we should reject c_names and cxx_names in dune files and only allow for c_files and cxx_files.

@rauanmayemir These details regarding compatibility are not so important and you can get started without worrying about it. We'll help you polish this part if it's required for 1.0. For now you can just use add c_files and cxx_files and ignore compat (it will be easy to add at the end).

The change consists of doing 3 things:

  • Renaming c_names and cxx_names. These fields (and all others) are defined in jbuild.ml. Changing this should be straight forward.

  • Change the rules (in gen_rules.ml) to stop appending the default extensions. Make sure to change variable and param names along the way.

  • Append the hard coded list of extensions here https://github.com/ocaml/dune/blob/master/src/action.ml#L816. I suppose it shouldn't be hard coded at all anymore given that we don't have a fixed set of extensions. But it's good enough for now. cc @dra27 for

  • Bonus: Add compatibility for c_names and cxx_names in jbuild files. In jbuild files, we'll need to read the c_names and cxx_names sexp fields and then convert them to c_files and cxx_files by appending the appropriate extensions. Familiarize yourself with the Syntax.renamed_in and Syntax.since functions by reading how they're used with fields such as source_tree.

  • Add tests for the feature. Have a look at c-stubs blackbox tests for inspiration. Familiarize yourself with our expect test workflow $ make test to run the tests and $ make accept-corrections to promote results. See run.t files for how to write test cases.

This is a very rough guide so don't hesitate to ask more questions.

Some open questions for our maintainers @diml @bobot @emillon @dra27 @avsm @Chris00 with c stubs experience:

  • Should we apply the same changes to header files? I know that header files don't really have the same variation in extension names. But it seems like this will make sense for consistency's sake.

  • Do we take this opportunity to change the meaning of :standard for c sources? I don't really like how we have the opposite default for C and OCaml sources. I think that :standard should include all C sources by default. This is more consistent and will reduce boilerplate.

@rauanmayemir
Copy link

I know that header files don't really have the same variation in extension names.

There could be .h, .hh, .hpp.

@rgrinberg
Copy link
Member

Okay. Even more of a reason to just specify extensions everywhere consistently.

@ghost
Copy link

ghost commented Jul 1, 2018

Replacing c_names by c_files is not compatible with changing the meaning of :standard. If we don't know the extensions for C files, we can't know what are the C files in the directory.

BTW, I'm not against adding support of c_files, but I don't think we should get rid of c_names yet.

@rgrinberg
Copy link
Member

rgrinberg commented Jul 2, 2018 via email

@ghost
Copy link

ghost commented Jul 2, 2018

What is the use case BTW? c_names and cxx_names are used only for C stubs for OCaml libraries. Why not simply rename the C files? It's better to use the same convention everywhere.

@rauanmayemir
Copy link

After looking into relevant code and working on this for a bit, I've come to realise that simply adding c_files might not work unless we choose one of c/cxx approaches to handle those files. (C outputs its files in the same place, Cxx follows '-o dest', MSVS specifies '-llib' flags differently, install_c_headers only accepts '.h', etc)

If we'd specify all commonly used extensions (which, I'm guessing, there are not that much of) and split the c_files behaviour to use Gen.build_c_file/build_cxx_file, then it would be simpler to add those extension options to each appropriate c_names/cxx_names stanza (i.e automatically choose extension based on what we found in the directory).

Personally, I solved my problem by just renaming stubs.m to stubs.c and adding -x objective-c to c_flags. 😅
I'd argue that anything more complicated would be better solved with a custom rule.

Unless I'm missing something here?

@rgrinberg
Copy link
Member

rgrinberg commented Jul 2, 2018

We can also add an objc_names field if it's a common enough use case. -x objective-c is clang only I assume?

My thinking is that renaming here is quite pesky, because now your editor won't know it's objective C anymore for example.

@emillon
Copy link
Collaborator

emillon commented Jul 5, 2018

As a suggestion, would it make sense to make these extensions configurable in the dune file ? There's some variety, especially in the C++ world, and I don't think we want to ask users to rename their files. This gives a nice escape hatch for "the C compiler will know how to handle this".

@rauanmayemir
Copy link

rauanmayemir commented Jul 5, 2018

@emillon I like this much better than adding a separate field per lang/'dialect'.

@diml How do you like c_extension and cxx_extension fields? With .c and .cpp defaults changes will be minimal.

It will also be sort of consistent with c_name being file's name and c_extension - its extension. (It could be named differently to clearly indicate it's a file extension, not a 'plugin')

@rauanmayemir
Copy link

rauanmayemir commented Jul 5, 2018

I'm not very familiar with sexpr's, but would this fly?

(c_names (myc_stubs (mym_stubs m)))

@ghost
Copy link

ghost commented Jul 6, 2018

Yes, that makes sense. To make this more future proof, let's call these c_extensions and cxx_extensions. Additionally, we should allow these to be set once and for all for a given project via the env stanza, so that one may write in their dune-project file:

(env
 (_ (cxx_extensions .m .c++ .cpp)))

@emillon
Copy link
Collaborator

emillon commented Jul 6, 2018

I'm surprised that dune knows about the differences between C and C++ (I'd expect it to just pass these to the system compiler). What kind of handling does it do? (because there might be something to do to support Objective-C).

@rgrinberg
Copy link
Member

I'm fine with either feature, but IMO it's a bit weird to make the default extension customizable rather than simply let users put full filenames. This seems to me like adding more code to fix a problem that we've created ourselves in the first place.

@ghost
Copy link

ghost commented Jul 6, 2018

Make the extensions customizable would allow to make :standard for c_names be all the C files for instance. Although, I don't know how important that is.

@emillon the flags are a bit different between the two. See build_cxx_file in gen_rules.ml for instance of cxx_flags in super_context.ml. But, yh maybe we need a more generic system allowing arbitrary foreign code and where C and C++ are just two particular instances.

@rgrinberg
Copy link
Member

Make the extensions customizable would allow to make :standard for c_names be all the C files for instance. Although, I don't know how important that is.

I think this can also be done by making :standard be a glob: *.c and allowing globs in the osl for these fields.

@ghost
Copy link

ghost commented Jul 6, 2018

The question is more what happens when there is no c_names field at all. If the default is all c files, then you don't even need a c_names field.

@rgrinberg
Copy link
Member

Yeah, the default would be all files with a .c extension.

@ghost
Copy link

ghost commented Jul 6, 2018

yes, but then we have the same question for C++ files. There are many different questions in this PR, I think at this point someone should write a concrete proposal that we can reason about. For instance even if we allow more extensions, it doesn't solve the problem regarding objective-C files that might require specific treatment.

@rauanmayemir
Copy link

The question is more what happens when there is no c_names field at all. If the default is all c files, then you don't even need a c_names field.

I don't quite understand this part. Does dune automatically scan the directory and compile whatever C files it finds in current directory? Or you want it to be that way?

@rgrinberg
Copy link
Member

I don't quite understand this part. Does dune automatically scan the directory and compile whatever C files it finds in current directory? Or you want it to be that way?

The current situation is that dune requires the stubs to be listed. What we'd like is a situation that is symmetric with the modules field. Specifying no sources would mean dune automatically discover them using some default extensions.

@rauanmayemir
Copy link

Sounds great. I'll start with basic c_extensions/cxx_extensions fields and ask for guidance from there.

@rgrinberg
Copy link
Member

I think I agree with @diml that we need a concrete proposal before committing to anything. You could help us by clarifying what kind of special treatment objective C needs here. I'm not really convinced that adding fields for default extensions is a good approach (see my previous comments).

Further more, we should perhaps think about other languages as well here. I recall @Chris00 wanting some basic fortran support. Are there are other languages that are useful for adding fast support like this?

Finally, what about jsoo? If we have auto discovery then it should be consistently be applied for jsoo stubs as well.

@rauanmayemir
Copy link

My use case for Objective-C involves writing bindings for Cocoa to draw UI on OCaml side. It's a library that gets linked into a complete 'exe.o' and embedded as a dependency(along with libasmrun.a) into an xcode project target. (in main.m I'm calling caml_main and caml_callback to call a function from my 'exe.o')

If I were to run it outside of xcodebuild flow, all I'd need to do is to add -framework Cocoa to a linking step (or -framework Foundation if it didn't involve UI). Since I'm not doing that, I don't need any 'special treatment'.

So, practically, there are no problems except for dune not being able to understand '.m' extension out of the box.

@rgrinberg
Copy link
Member

@rauanmayemir Why can't you write a main.c file? It has to be a C source, or does CC understand objective C on OSX?

Anyway, I've went ahead and just fixed the original issue in #2195. I'm thinking that having all this generality for file extensions is a bit of overkill and we have bigger fish to fry. However, if you have an idea of how to better support this, feel free to come up with a proposal.

@rauanmayemir
Copy link

I have to specify clang option to choose objc for .c files, plus there’s an extra hassle making an editor treat .c files as ObjC.

It’s not a big deal and I agree that at the moment dune has other important things to deal with.

We can circle back to this at some point in future.

rgrinberg added a commit to rgrinberg/opam-repository that referenced this issue May 30, 2019
CHANGES:

- Restricted the set of variables available for expansion in the destination
  filename of `install` stanza to simplify implementation and avoid dependency
  cycles. (ocaml/dune#2073, @aalekseyev, @diml)

- [menhir] call menhir from context root build_dir (ocaml/dune#2067, @ejgallego,
  review by @diml, @rgrinberg)

- [coq] Add `coq.pp` stanza to help with pre-processing of grammar
  files (ocaml/dune#2054, @ejgallego, review by @rgrinberg)

- Add a new more generic form for the *promote* mode: `(promote
  (until-clean) (into <dir>))` (ocaml/dune#2068, @diml)

- Allow to promote only a subset of the targets via `(promote (only
  <pred>))`. For instance: `(promote (only *.mli))` (ocaml/dune#2068, @diml)

- Improve the behavior when a strict subset of the targets of a rule is already
  in the source tree for projects using the dune language < 1.10 (ocaml/dune#2068, fixes
  ocaml/dune#2061, @diml)

- With lang dune >= 1.10, rules in standard mode are no longer allowed to
  produce targets that are present in the source tree. This has been a warning
  for long enough (ocaml/dune#2068, @diml)

- Allow %{...} variables in pps flags (ocaml/dune#2076, @mlasson review by @diml and
  @aalekseyev).

- Add a 'cookies' option to ppx_rewriter/deriver flags in library stanzas. This
  allow to specify cookie requests from variables expanded at each invocation of
  the preprocessor. (ocaml/dune#2106, @mlasson @diml)

- Add more opam metadata and use it to generate `.opam` files. In particular, a
  `package` field has been added to specify package specific information.
  (ocaml/dune#2017, ocaml/dune#2091, @avsm, @jonludlam, @rgrinberg)

- Clean up the special support for `findlib.dynload`. Before, Dune would simply
  match on the library name. Now, we only match on the findlib package name when
  the library doesn't come from Dune. Someone writing a library called
  `findlib.dynload` with Dune would have to add `(special_builtin_support
  findlib_dynload)` to trigger the special behavior. (ocaml/dune#2115, @diml)

- Install the `future_syntax` preprocessor as `ocaml-syntax-shims.exe` (ocaml/dune#2125,
  @rgrinberg)

- Hide full command on errors and warnings in development and show them in CI.
  (detected using the `CI` environment variable). Commands for which the
  invocation might be omitted must output an error prefixed with `File `. Add an
  `--always-show-command-line` option to disable this behavior and always show
  the full command. (ocaml/dune#2120, fixes ocaml/dune#1733, @rgrinberg)

- In `dune-workspace` files, add the ability to choose the host context and to
  create duplicates of the default context with different settings. (ocaml/dune#2098,
  @TheLortex, review by @diml, @rgrinberg and @aalekseyev)

- Add support for hg in `dune subst` (ocaml/dune#2135, @diml)

- Don't build documentation for implementations of virtual libraries (ocaml/dune#2141,
  fixes ocaml/dune#2138, @jonludlam)

- Fix generation of the `-pp` flag in .merlin (ocaml/dune#2142, @rgrinberg)

- Make `dune subst` add a `(version ...)` field to the `dune-project`
  file (ocaml/dune#2148, @diml)

- Add the `%{os_type}` variable, which is a short-hand for
  `%{ocaml-config:os_type}` (ocaml/dune#1764, @diml)

- Allow `enabled_if` fields in `library` stanzas, restricted to the
  `%{os_type}`, `%{model}`, `%{architecture}`, `%{system}` variables (ocaml/dune#1764,
  ocaml/dune#2164 @diml, @rgrinberg)

- Fix `chdir` on external and source paths. Dune will also fail gracefully if
  the external or source path does not exist (ocaml/dune#2165, fixes ocaml/dune#2158, @rgrinberg)

- Support the `.cc` extension fro C++ sources (ocaml/dune#2195, fixes ocaml/dune#83, @rgrinberg)

- Run `ocamlformat` relative to the context root. This improves the locations of
  errors. (ocaml/dune#2196, fixes ocaml/dune#1370, @rgrinberg)

- Fix detection of `README`, `LICENSE`, `CHANGE`, and `HISTORY` files. These
  would be undetected whenever the project was nested in another workspace.
  (ocaml/dune#2194, @rgrinberg)

- Fix generation of `.merlin` whenever there's more than one stanza with the
  same ppx preprocessing specification (ocaml/dune#2209 ,fixes ocaml/dune#2206, @rgrinberg)

- Fix generation of `.meriln` in the presence of the `copy_files` stanza and
  preprocessing specifications of other stanazs. (ocaml/dune#2211, fixes ocaml/dune#2206,
  @rgrinberg)
rgrinberg added a commit to rgrinberg/opam-repository that referenced this issue Jun 4, 2019
CHANGES:

- Restricted the set of variables available for expansion in the destination
  filename of `install` stanza to simplify implementation and avoid dependency
  cycles. (ocaml/dune#2073, @aalekseyev, @diml)

- [menhir] call menhir from context root build_dir (ocaml/dune#2067, @ejgallego,
  review by @diml, @rgrinberg)

- [coq] Add `coq.pp` stanza to help with pre-processing of grammar
  files (ocaml/dune#2054, @ejgallego, review by @rgrinberg)

- Add a new more generic form for the *promote* mode: `(promote
  (until-clean) (into <dir>))` (ocaml/dune#2068, @diml)

- Allow to promote only a subset of the targets via `(promote (only
  <pred>))`. For instance: `(promote (only *.mli))` (ocaml/dune#2068, @diml)

- Improve the behavior when a strict subset of the targets of a rule is already
  in the source tree for projects using the dune language < 1.10 (ocaml/dune#2068, fixes
  ocaml/dune#2061, @diml)

- With lang dune >= 1.10, rules in standard mode are no longer allowed to
  produce targets that are present in the source tree. This has been a warning
  for long enough (ocaml/dune#2068, @diml)

- Allow %{...} variables in pps flags (ocaml/dune#2076, @mlasson review by @diml and
  @aalekseyev).

- Add a 'cookies' option to ppx_rewriter/deriver flags in library stanzas. This
  allow to specify cookie requests from variables expanded at each invocation of
  the preprocessor. (ocaml/dune#2106, @mlasson @diml)

- Add more opam metadata and use it to generate `.opam` files. In particular, a
  `package` field has been added to specify package specific information.
  (ocaml/dune#2017, ocaml/dune#2091, @avsm, @jonludlam, @rgrinberg)

- Clean up the special support for `findlib.dynload`. Before, Dune would simply
  match on the library name. Now, we only match on the findlib package name when
  the library doesn't come from Dune. Someone writing a library called
  `findlib.dynload` with Dune would have to add `(special_builtin_support
  findlib_dynload)` to trigger the special behavior. (ocaml/dune#2115, @diml)

- Install the `future_syntax` preprocessor as `ocaml-syntax-shims.exe` (ocaml/dune#2125,
  @rgrinberg)

- Hide full command on errors and warnings in development and show them in CI.
  (detected using the `CI` environment variable). Commands for which the
  invocation might be omitted must output an error prefixed with `File `. Add an
  `--always-show-command-line` option to disable this behavior and always show
  the full command. (ocaml/dune#2120, fixes ocaml/dune#1733, @rgrinberg)

- In `dune-workspace` files, add the ability to choose the host context and to
  create duplicates of the default context with different settings. (ocaml/dune#2098,
  @TheLortex, review by @diml, @rgrinberg and @aalekseyev)

- Add support for hg in `dune subst` (ocaml/dune#2135, @diml)

- Don't build documentation for implementations of virtual libraries (ocaml/dune#2141,
  fixes ocaml/dune#2138, @jonludlam)

- Fix generation of the `-pp` flag in .merlin (ocaml/dune#2142, @rgrinberg)

- Make `dune subst` add a `(version ...)` field to the `dune-project`
  file (ocaml/dune#2148, @diml)

- Add the `%{os_type}` variable, which is a short-hand for
  `%{ocaml-config:os_type}` (ocaml/dune#1764, @diml)

- Allow `enabled_if` fields in `library` stanzas, restricted to the
  `%{os_type}`, `%{model}`, `%{architecture}`, `%{system}` variables (ocaml/dune#1764,
  ocaml/dune#2164 @diml, @rgrinberg)

- Fix `chdir` on external and source paths. Dune will also fail gracefully if
  the external or source path does not exist (ocaml/dune#2165, fixes ocaml/dune#2158, @rgrinberg)

- Support the `.cc` extension fro C++ sources (ocaml/dune#2195, fixes ocaml/dune#83, @rgrinberg)

- Run `ocamlformat` relative to the context root. This improves the locations of
  errors. (ocaml/dune#2196, fixes ocaml/dune#1370, @rgrinberg)

- Fix detection of `README`, `LICENSE`, `CHANGE`, and `HISTORY` files. These
  would be undetected whenever the project was nested in another workspace.
  (ocaml/dune#2194, @rgrinberg)

- Fix generation of `.merlin` whenever there's more than one stanza with the
  same ppx preprocessing specification (ocaml/dune#2209 ,fixes ocaml/dune#2206, @rgrinberg)

- Fix generation of `.merlin` in the presence of the `copy_files` stanza and
  preprocessing specifications of other stanazs. (ocaml/dune#2211, fixes ocaml/dune#2206,
  @rgrinberg)

- Run `refmt` from the context's root directory. This improves error messages in
  case of syntax errors. (ocaml/dune#2223, @rgrinberg)

- In .merlin files, don't pass `-dump-ast` to the `future_syntax` preprocessor.
  Merlin doesn't seem to like it when binary AST is generated by a `-pp`
  preprocessor. (ocaml/dune#2236, @aalekseyev)

- `dune install` will verify that all files mentioned in all .install files
  exist before trying to install anything. This prevents partial installation of
  packages (ocaml/dune#2230, @rgrinberg)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants