Commit Graph

354 Commits (e85ba9c77f680ab574b0836830554c2b4b74091a)

Author SHA1 Message Date
whitequark da56cf6dfd Rigorously handle -o and -c options in presence of multiple arguments.
This addresses PR#6475.

In 4.02 the behavior of ocamlc/ocamlopt with regards to these options
was as follows:
  * options and arguments are parsed left-to-right in the exact order
    in which they are passed, with compilation taking into account
    only the options leftwards from it;
  * "foo.c" is compiled to "foo.o" in current directory;
  * when "-c" is not specified:
    * "foo.ml" is compiled to "foo.cmo"/"foo.cmxo"
      in current directory;
    * after all files have been compiled, if any .ml files are passed,
      all provided files are linked as:
      * when "-o" is not specified: "a.out" in current directory;
      * when "-o out" is specified: "out".
  * when "-c" is specified:
    * "foo.ml" is compiled to:
      * when "-o" is not specified: "foo.cmo"/"foo.cmxo"
        in current directory;
      * when "-o out" is specified: "out.cmo"/"out.cmxo";
        and then compilation proceeds as if the last "-o" option
        has disappeared.
    * no final link is performed.

The behavior where the build product of the C sources always ended up
in the current directory was problematic: it required buildsystem
hacks to move the file in its proper place and ultimately was racy,
as multiple files with the same basename in different directories
may well end up overwriting each other with e.g. ocamlbuild.

On top of that, the behavior was quite confusing, since it is not
only stateful and dependent on argument order, but also the mere act
of compilation changed state.

The commit 1d8e590c has attempted to rectify that by looking at
the "-o" option when compiling C files, too. After that commit,
the behavior of ocamlc/ocamlopt was as follows (only the handling
of C files was changed, but the entire chart is provided for
posterity):
  * options and arguments are parsed left-to-right in the exact order
    in which they are passed, with compilation taking into account
    only the options leftwards from it;
  * "foo.c" is compiled to:
    * when "-o" is not specified: "foo.o" in current directory;
    * when "-o out" is specified: "out".
  * when "-c" is not specified:
    * "foo.ml" is compiled to "foo.cmo"/"foo.cmxo"
      in current directory;
    * after all files have been compiled, if any .ml files are passed,
      all provided files are linked as:
      * when "-o" is not specified: "a.out" in current directory;
      * when "-o out" is specified: "out".
  * when "-c" is specified:
    * "foo.ml" is compiled to:
      * when "-o" is not specified: "foo.cmo"/"foo.cmxo"
        in current directory;
      * when "-o out" is specified: "out.cmo"/"out.cmxo";
        and then compilation proceeds as if the last "-o" option
        has disappeared.
    * no final link is performed.

There is a non-obvious bug here. Specifically, what happens if more
than one C source file is passed together with a "-o" option? Also,
what happens if a C source file is passed together with a "-o" option
and then a final link is performed? The answer is that
the intermediate build product gets silently overwritten, with quite
opaque errors as a result.

There is some code (and even buildsystems) in the wild that is relying
on the fact that the -o option does not affect compilation of C source
files, e.g. by running commands such as (from ocamlnet):
  ocamlc -custom -o t tend.c t.ml

It might seem that the solution would be to make the behavior of
the compiler drivers for C files match that for the OCaml files;
specifically, pretend that the "-o" option has disappeared once
the C compiler has written a build product to the specified place.

However, this would still break the existing code, and moreover
does not address the underlying problem: that the option parsing
of the OCaml compiler driver is confusing and prone to creating
latent bugs.

Instead, this commit finishes (after 1d8e590c and 55d2d420) overhauls
the way option parsing in ocamlc/ocamlopt works to behave as follows:
  * options are parsed left-to-right in the order they are specified;
  * after all options are parsed, arguments are parsed left-to-right
    in the order they were specified;
  * when "-o out" and "-c" are specified:
    * when more than one file is passed, an error message
      is displayed.
    * when one file is passed:
      * "foo.c" is compiled to "out";
      * "foo.ml" is compiled to "out.cmo"/"out.cmxo".
  * when "-o out" is not specified or "-c" is not specified:
    * "foo.c" is compiled to "foo.o" in current directory;
    * "foo.ml" is compiled to "foo.cmo"/"foo.cmxo"
      in current directory;
  * when "-c" is not specified:
    * after all files have been compiled, if any .ml files are passed,
      all provided files are linked as:
      * when "-o" is not specified: "a.out" in current directory;
      * when "-o out" is specified: "out".

In short, the combination of "-o", "-c" and a single source file
compiles that one file to the corresponding intermediate
build product. Otherwise, passing "-o" will either set the name of
the final build product only or error out.

This preserves compatibility with old code, makes the handling of
C and OCaml sources consistent, and overall makes the behavior
of the option parser more straightforward. However, this may break
code that relies on the fact that options are parsed in-order, e.g.
  ocamlc -o t a.ml -g b.ml
where debug info would be built only for "b.ml".

Some alternative implementation paths I have considered:
  * Collect the C sources and process them after OCaml sources,
    while paying attention to any "-o" or "-c" that may have
    been set. This doesn't work because compilation of C sources
    is also affected by many flags, e.g. "-I", and so this would
    have the same drawbacks but none of the benefits;
  * Compile C and OCaml sources in-order as usual, but error out
    when an improper combination of flags is encountered in
    the middle of a compilation. This is technically feasible,
    and is the option that maximally preserves compatibility, but
    it is very complex: it doubles the amount of implicitly mutated
    global state, and there's no guarantee I will get all edge
    cases right. Moreover, the option parsing remains confusing,
    and I strongly believe that the current behavior should not
    remain in place.

On top of that it is hard to imagine cases where setting new options
in the middle of compilation would actually be desirable, because
this mechanism is very inexpressive: it can only add new options and
option values, since there is no way to negate or clear most of
the driver's state. Most likely is that any code that does so,
does it in error and remains operational by pure chance.
2016-06-14 11:36:35 -04:00
whitequark 4dc3efe3b0 Interpret all command-line options before compiling any files.
The behavior of ocamlc and ocamlopt drivers before this commit is
that the command-line options and arguments are processed exactly
sequentially; encountered options (e.g. "-o") modify the state of
the driver, and encountered arguments (e.g. "t.ml") compile
the corresponding file with whatever state the driver had at the time.

This can be quite confusing, because compiler drivers (e.g. gcc/g++,
clang/clang++, rustc, javac, go, ...) either parse the entire command
line before going on to compile files or reject options after
the first argument (only in the case of go). Thus the behavior
of ocamlc and ocamlopt is unexpected.

The following commit provides another reason for this change.
2016-06-14 11:36:35 -04:00
Sébastien Hinderer 3bbf34319e Add the -no-version option to the toplevel.
This option requests the toplevel not to print its version number
at startup.
2016-05-09 17:22:29 +02:00
Sébastien Hinderer eef6cc5eae Option sharing between byetcode and native toplevels. 2016-05-02 15:44:46 +02:00
Demi Obenour fe05f8fc29 Add `-alias-deps` and `-app-funct`
This was meant for GPR #514, but I forgot to include it.
2016-04-19 12:21:09 -04:00
Demi Obenour 795a4d532d Add explicit command-line flags for currently-default settings
-no-keep-docs
    -no-keep-locs
    -no-principal
    -no-rectypes
    -no-strict-formats
2016-04-18 10:53:51 -04:00
Mark Shinwell ee367399a2 Attend to final Flambda CR comments for 4.03 release 2016-03-30 11:29:34 +02:00
alainfrisch 502e4f9336 More warnings when compiling the compiler. 2016-03-15 22:46:35 +01:00
Mark Shinwell 5dced42768 Merge pull request #480 from mshinwell/flambda_unbox-closures
GPR#480: Flambda fix: try to make Unbox_closures behave more reasonably
2016-02-26 16:18:04 +00:00
Damien Doligez 5401ce8473 Update headers for the new license.
Remains to be done: remove all headers in testsuite/tests.
2016-02-18 16:59:16 +01:00
Leo White 4253ed1530 Tidy up new command-line parameters 2016-02-11 16:02:02 +00:00
Mark Shinwell 4137939cd7 Make warning 59 less unhelpful (includes work by Runhang Li) 2016-02-11 14:35:18 +00:00
Leo White d79380ff63 Enable opaque option in ocamlc 2016-02-11 11:39:14 +00:00
Mark Shinwell bde2bdd206 Reformatting only (to the standards of tools/check-typo) 2016-02-10 18:28:38 +01:00
Damien Doligez 1c28b231ef Revert "PR#6475: accept -o in ocamlc when compiling C files"
This reverts commit 1d8e590c54.

Conflicts:
	Changes
	bytecomp/bytelink.ml
	driver/optcompile.ml
	ocamlbuild/ocaml_specific.ml
	ocamlbuild/testsuite/internal.ml
	utils/ccomp.ml
2016-02-10 10:34:02 +01:00
Mark Shinwell f95fb8bbb0 Bug fixes etc for Flambda 2016-02-09 18:38:16 +01:00
Mark Shinwell a397511031 Import latest Flambda changes 2016-02-09 09:59:26 +01:00
Mark Shinwell 05f1746cb5 Rename to max_arguments_for_tailcalls; revise numbers assuming no unboxed floats using the OCaml calling conventions 2016-02-08 15:02:40 +01:00
Mark Shinwell b5618e8642 max_arguments_without_passing_on-stack 2016-01-29 15:57:36 +00:00
Pierre Chambart b0b0f6609c Enable flambda 2016-01-28 15:04:47 +01:00
Jeremie Dimino d8704f6ba8 Add module Ast_invariants
This module checks all the AST invariants. This is to ensure that all
invariants are written down in one place and are consistently checked
between the various clients of the AST (typer, pprintast, ...).

The invariants are checked in Pparsee, after applying the ppx
rewriters.
2016-01-27 18:41:12 +00:00
Pierre Chambart ab2e736358 Rename compiler_configuration file
Renamed to ocaml_compiler_internal_params.
2016-01-25 18:50:29 +01:00
Pierre Chambart 2555c4e773 Update main and ocamldep 2016-01-25 18:50:29 +01:00
Pierre Chambart 5b2d1e7d5d Reindent compenv 2016-01-25 18:50:29 +01:00
Pierre Chambart d6ea706a02 Add handling of OCAMLPARAM as a file 2016-01-25 18:45:04 +01:00
alainfrisch 87de6a160d Useless bindings, unit patterns, whitespace. 2016-01-19 23:40:55 +01:00
Mark Shinwell d3a8745b84 Merge remote-tracking branch 'ocaml/trunk' into flambda_prereq-clflags 2016-01-15 13:22:04 +00:00
Mark Shinwell 10e5dcfc37 Support 'opaque' in OCAMLPARAM 2016-01-15 11:38:37 +00:00
Mark Shinwell 7d1d8814c0 code review 2016-01-14 17:13:43 +00:00
Mark Shinwell fb4d06a3aa Clflags stuff and Arg_helper 2016-01-14 11:27:30 +00:00
Thomas Refis cae2a7e53c use Timings.source_provenance in more places 2015-12-31 11:00:39 +00:00
Pierre Chambart fc5acece95 Rename type build_kind and sourcefile arguments to source_provenance 2015-12-18 13:54:47 +00:00
Pierre Chambart 99fa546753 Clean up and time separately parsing and preprocessing 2015-12-18 13:35:44 +00:00
Pierre Chambart 0443e425e4 Record the source file name being built in Compilenv 2015-12-18 13:35:44 +00:00
Pierre Chambart b05b5f71f5 Remove last use of Timining.start/stop in {opt,}compile.ml 2015-12-18 13:35:44 +00:00
Pierre Chambart 828e78d4a4 Avoid using Timings.start/stop 2015-12-18 13:35:44 +00:00
Pierre Chambart 233e1b1791 Record compiler runtime 2015-12-18 13:33:10 +00:00
alainfrisch 7ad212045f Add module to deal with 'front-end' built-in attributes. 2015-12-02 14:46:14 +01:00
alainfrisch 945d0c7d7a Keep deprecation flag on compilation unit, extracted from a floating attribute in the .mli file. 2015-11-27 19:13:56 +01:00
Damien Doligez be79451d83 PR#7008: Fatal error in ocamlc with empty compilation unit name
git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@16523 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
2015-10-19 13:01:28 +00:00
Damien Doligez b860d63145 whitespace cleanup, cut long lines, add some missing headers
git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@16415 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
2015-09-11 11:58:31 +00:00
Gabriel Scherer cb3bb152ab add option handling for colors in compiler, OCAMLPARAM and ocamlbuild
(Simon Cruanes and Gabriel Scherer)

Use one of
  -color auto
  -color always
  -color never

git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@16348 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
2015-08-15 15:57:51 +00:00
Alain Frisch 4e9bf58e90 Typo.
git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@16242 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
2015-07-24 11:34:51 +00:00
Damien Doligez 860c670848 merge branch 4.02 from 4.02.1 (rev 15540) to a few fixes after 4.02.2 (rev 16205)
git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@16214 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
2015-07-17 14:31:05 +00:00
Leo White 5c55e4cc08 Attach documentation comments to Parsetree
git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@16189 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
2015-06-28 13:11:50 +00:00
Gabriel Scherer d19a8bd2f1 PR#6636: add a --version option (Peter Zotov)
git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@16141 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
2015-05-24 14:52:57 +00:00
Alain Frisch 63945879c1 Cleanup + better interaction between -intf and -pack (the .cmi file was not added to the list of objects in that case).
git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@16100 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
2015-05-07 12:44:22 +00:00
Alain Frisch 6610c56462 Cleanup.
git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@16099 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
2015-05-07 12:41:39 +00:00
Alain Frisch 918f584b64 #6845: -no-check-prims to tell ocamlc not to check primitives in runtime.
git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@16031 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
2015-04-22 10:53:47 +00:00
Gabriel Scherer eca0967403 PR#6167: OCAMLPARAM support for disabling PIC generation ('pic=0')
(Gabor Pali)

git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@15793 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
2015-01-24 16:35:26 +00:00