summaryrefslogtreecommitdiff
path: root/gcc/ada/make.adb
diff options
context:
space:
mode:
authorcharlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4>2003-10-21 13:42:24 +0000
committercharlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4>2003-10-21 13:42:24 +0000
commit9dfe12ae5b94d03c997ea2903022a5d2d5c5f266 (patch)
treebdfc70477b60f1220cb05dd233a4570dd9c6bb5c /gcc/ada/make.adb
parent1c662558a1113238a624245a45382d3df90ccf13 (diff)
downloadgcc-9dfe12ae5b94d03c997ea2903022a5d2d5c5f266.tar.gz
2003-10-21 Arnaud Charlet <charlet@act-europe.fr>
* 3psoccon.ads, 3veacodu.adb, 3vexpect.adb, 3vsoccon.ads, 3vsocthi.adb, 3vsocthi.ads, 3vtrasym.adb, 3zsoccon.ads, 3zsocthi.adb, 3zsocthi.ads, 50system.ads, 51system.ads, 55system.ads, 56osinte.adb, 56osinte.ads, 56taprop.adb, 56taspri.ads, 56tpopsp.adb, 57system.ads, 58system.ads, 59system.ads, 5aml-tgt.adb, 5bml-tgt.adb, 5csystem.ads, 5dsystem.ads, 5fosinte.adb, 5gml-tgt.adb, 5hml-tgt.adb, 5isystem.ads, 5lparame.adb, 5msystem.ads, 5psystem.ads, 5sml-tgt.adb, 5sosprim.adb, 5stpopsp.adb, 5tsystem.ads, 5usystem.ads, 5vml-tgt.adb, 5vsymbol.adb, 5vtraent.adb, 5vtraent.ads, 5wml-tgt.adb, 5xparame.ads, 5xsystem.ads, 5xvxwork.ads, 5yparame.ads, 5ytiitho.adb, 5zinit.adb, 5zml-tgt.adb, 5zparame.ads, 5ztaspri.ads, 5ztfsetr.adb, 5zthrini.adb, 5ztiitho.adb, 5ztpopsp.adb, 7stfsetr.adb, 7straces.adb, 7strafor.adb, 7strafor.ads, 7stratas.adb, a-excach.adb, a-exexda.adb, a-exexpr.adb, a-exextr.adb, a-exstat.adb, a-strsup.adb, a-strsup.ads, a-stwisu.adb, a-stwisu.ads, bld.adb, bld.ads, bld-io.adb, bld-io.ads, clean.adb, clean.ads, ctrl_c.c, erroutc.adb, erroutc.ads, errutil.adb, errutil.ads, err_vars.ads, final.c, g-arrspl.adb, g-arrspl.ads, g-boubuf.adb, g-boubuf.ads, g-boumai.ads, g-bubsor.adb, g-bubsor.ads, g-comver.adb, g-comver.ads, g-ctrl_c.ads, g-dynhta.adb, g-dynhta.ads, g-eacodu.adb, g-excact.adb, g-excact.ads, g-heasor.adb, g-heasor.ads, g-memdum.adb, g-memdum.ads, gnatclean.adb, gnatsym.adb, g-pehage.adb, g-pehage.ads, g-perhas.ads, gpr2make.adb, gpr2make.ads, gprcmd.adb, gprep.adb, gprep.ads, g-semaph.adb, g-semaph.ads, g-string.adb, g-string.ads, g-strspl.ads, g-wistsp.ads, i-vthrea.adb, i-vthrea.ads, i-vxwoio.adb, i-vxwoio.ads, Makefile.generic, Makefile.prolog, Makefile.rtl, prep.adb, prep.ads, prepcomp.adb, prepcomp.ads, prj-err.adb, prj-err.ads, s-boarop.ads, s-carsi8.adb, s-carsi8.ads, s-carun8.adb, s-carun8.ads, s-casi16.adb, s-casi16.ads, s-casi32.adb, s-casi32.ads, s-casi64.adb, s-casi64.ads, s-casuti.adb, s-casuti.ads, s-caun16.adb, s-caun16.ads, s-caun32.adb, s-caun32.ads, s-caun64.adb, s-caun64.ads, scng.adb, scng.ads, s-exnint.adb, s-exnllf.adb, s-exnlli.adb, s-expint.adb, s-explli.adb, s-geveop.adb, s-geveop.ads, s-hibaen.ads, s-htable.adb, s-htable.ads, sinput-c.adb, sinput-c.ads, s-memcop.ads, socket.c, s-purexc.ads, s-scaval.adb, s-stopoo.adb, s-strcom.adb, s-strcom.ads, s-strxdr.adb, s-rident.ads, s-thread.adb, s-thread.ads, s-tpae65.adb, s-tpae65.ads, s-tporft.adb, s-traent.adb, s-traent.ads, styleg.adb, styleg.ads, styleg-c.adb, styleg-c.ads, s-veboop.adb, s-veboop.ads, s-vector.ads, symbols.adb, symbols.ads, tb-alvms.c, tb-alvxw.c, tempdir.adb, tempdir.ads, vms_conv.ads, vms_conv.adb, vms_data.ads, vxaddr2line.adb: Files added. Merge with ACT tree. * 4dintnam.ads, 4mintnam.ads, 4uintnam.ads, 52system.ads, 5dosinte.ads, 5etpopse.adb, 5mosinte.ads, 5qosinte.adb, 5qosinte.ads, 5qstache.adb, 5qtaprop.adb, 5qtaspri.ads, 5stpopse.adb, 5uintman.adb, 5uosinte.ads, adafinal.c, g-enblsp.adb, io-aux.c, scn-nlit.adb, scn-slit.adb, s-exnflt.ads, s-exngen.adb, s-exngen.ads, s-exnlfl.ads, s-exnlin.ads, s-exnsfl.ads, s-exnsin.ads, s-exnssi.ads, s-expflt.ads, s-expgen.adb, s-expgen.ads, s-explfl.ads, s-explin.ads, s-expllf.ads, s-expsfl.ads, s-expsin.ads, s-expssi.ads, style.adb: Files removed. Merge with ACT tree. * 1ic.ads, 31soccon.ads, 31soliop.ads, 3asoccon.ads, 3bsoccon.ads, 3gsoccon.ads, 3hsoccon.ads, 3ssoccon.ads, 3ssoliop.ads, 3wsoccon.ads, 3wsocthi.adb, 3wsocthi.ads, 3wsoliop.ads, 41intnam.ads, 42intnam.ads, 4aintnam.ads, 4cintnam.ads, 4gintnam.ads, 4hexcpol.adb, 4hintnam.ads, 4lintnam.ads, 4nintnam.ads, 4ointnam.ads, 4onumaux.ads, 4pintnam.ads, 4sintnam.ads, 4vcaldel.adb, 4vcalend.adb, 4vintnam.ads, 4wexcpol.adb, 4wintnam.ads, 4zintnam.ads, 51osinte.adb, 51osinte.ads, 52osinte.adb, 52osinte.ads, 53osinte.ads, 54osinte.ads, 5aosinte.adb, 5aosinte.ads, 5asystem.ads, 5ataprop.adb, 5atasinf.ads, 5ataspri.ads, 5atpopsp.adb, 5avxwork.ads, 5bosinte.adb, 5bosinte.ads, 5bsystem.ads, 5cosinte.ads, 5esystem.ads, 5fintman.adb, 5fosinte.ads, 5fsystem.ads, 5ftaprop.adb, 5ftasinf.ads, 5ginterr.adb, 5gintman.adb, 5gmastop.adb, 5gosinte.ads, 5gproinf.ads, 5gsystem.ads, 5gtaprop.adb, 5gtasinf.ads, 5gtpgetc.adb, 5hosinte.adb, 5hosinte.ads, 5hsystem.ads, 5htaprop.adb, 5htaspri.ads, 5htraceb.adb, 5iosinte.adb, 5itaprop.adb, 5itaspri.ads, 5ksystem.ads, 5kvxwork.ads, 5lintman.adb, 5lml-tgt.adb, 5losinte.ads, 5lsystem.ads, 5mvxwork.ads, 5ninmaop.adb, 5nintman.adb, 5nosinte.ads, 5ntaprop.adb, 5ntaspri.ads, 5ointerr.adb, 5omastop.adb, 5oosinte.adb, 5oosinte.ads, 5oosprim.adb, 5oparame.adb, 5osystem.ads, 5otaprop.adb, 5otaspri.ads, 5posinte.ads, 5posprim.adb, 5pvxwork.ads, 5sintman.adb, 5sosinte.adb, 5sosinte.ads, 5ssystem.ads, 5staprop.adb, 5stasinf.ads, 5staspri.ads, 5svxwork.ads, 5tosinte.ads, 5vasthan.adb, 5vinmaop.adb, 5vinterr.adb, 5vintman.adb, 5vintman.ads, 5vmastop.adb, 5vosinte.adb, 5vosinte.ads, 5vosprim.adb, 5vsystem.ads, 5vtaprop.adb, 5vtaspri.ads, 5vtpopde.adb, 5vtpopde.ads, 5wgloloc.adb, 5wintman.adb, 5wmemory.adb, 5wosprim.adb, 5wsystem.ads, 5wtaprop.adb, 5wtaspri.ads, 5ysystem.ads, 5zinterr.adb, 5zintman.adb, 5zosinte.adb, 5zosinte.ads, 5zosprim.adb, 5zsystem.ads, 5ztaprop.adb, 6vcpp.adb, 6vcstrea.adb, 6vinterf.ads, 7sinmaop.adb, 7sintman.adb, 7sosinte.adb, 7sosprim.adb, 7staprop.adb, 7staspri.ads, 7stpopsp.adb, 7straceb.adb, 9drpc.adb, a-caldel.adb, a-caldel.ads, a-charac.ads, a-colien.ads, a-comlin.adb, adaint.c, adaint.h, ada-tree.def, a-diocst.adb, a-diocst.ads, a-direio.adb, a-except.adb, a-except.ads, a-excpol.adb, a-exctra.adb, a-exctra.ads, a-filico.adb, a-interr.adb, a-intsig.adb, a-intsig.ads, ali.adb, ali.ads, ali-util.adb, ali-util.ads, a-ngcefu.adb, a-ngcoty.adb, a-ngelfu.adb, a-nudira.adb, a-nudira.ads, a-nuflra.adb, a-nuflra.ads, a-reatim.adb, a-reatim.ads, a-retide.ads, a-sequio.adb, a-siocst.adb, a-siocst.ads, a-ssicst.adb, a-ssicst.ads, a-strbou.adb, a-strbou.ads, a-strfix.adb, a-strmap.adb, a-strsea.ads, a-strunb.adb, a-strunb.ads, a-ststio.adb, a-stunau.adb, a-stunau.ads, a-stwibo.adb, a-stwibo.ads, a-stwifi.adb, a-stwima.adb, a-stwiun.adb, a-stwiun.ads, a-tags.adb, a-tags.ads, a-tasatt.adb, a-taside.adb, a-teioed.adb, a-textio.adb, a-textio.ads, a-tienau.adb, a-tifiio.adb, a-tiflau.adb, a-tiflio.adb, a-tigeau.adb, a-tigeau.ads, a-tiinau.adb, a-timoau.adb, a-tiocst.adb, a-tiocst.ads, atree.adb, atree.ads, a-witeio.adb, a-witeio.ads, a-wtcstr.adb, a-wtcstr.ads, a-wtdeio.adb, a-wtedit.adb, a-wtenau.adb, a-wtflau.adb, a-wtinau.adb, a-wtmoau.adb, bcheck.adb, binde.adb, bindgen.adb, bindusg.adb, checks.adb, checks.ads, cio.c, comperr.adb, comperr.ads, csets.adb, cstand.adb, cstreams.c, debug_a.adb, debug_a.ads, debug.adb, decl.c, einfo.adb, einfo.ads, errout.adb, errout.ads, eval_fat.adb, eval_fat.ads, exp_aggr.adb, expander.adb, expander.ads, exp_attr.adb, exp_ch11.adb, exp_ch13.adb, exp_ch2.adb, exp_ch3.adb, exp_ch3.ads, exp_ch4.adb, exp_ch5.adb, exp_ch6.adb, exp_ch7.adb, exp_ch7.ads, exp_ch8.adb, exp_ch9.adb, exp_code.adb, exp_dbug.adb, exp_dbug.ads, exp_disp.adb, exp_dist.adb, expect.c, exp_fixd.adb, exp_imgv.adb, exp_intr.adb, exp_pakd.adb, exp_prag.adb, exp_strm.adb, exp_strm.ads, exp_tss.adb, exp_tss.ads, exp_util.adb, exp_util.ads, exp_vfpt.adb, fe.h, fmap.adb, fmap.ads, fname.adb, fname.ads, fname-uf.adb, fname-uf.ads, freeze.adb, freeze.ads, frontend.adb, g-awk.adb, g-awk.ads, g-busora.adb, g-busora.ads, g-busorg.adb, g-busorg.ads, g-casuti.adb, g-casuti.ads, g-catiio.adb, g-catiio.ads, g-cgi.adb, g-cgi.ads, g-cgicoo.adb, g-cgicoo.ads, g-cgideb.adb, g-cgideb.ads, g-comlin.adb, g-comlin.ads, g-crc32.adb, g-crc32.ads, g-debpoo.adb, g-debpoo.ads, g-debuti.adb, g-debuti.ads, g-diopit.adb, g-diopit.ads, g-dirope.adb, g-dirope.ads, g-dyntab.adb, g-dyntab.ads, g-except.ads, g-exctra.adb, g-exctra.ads, g-expect.adb, g-expect.ads, g-hesora.adb, g-hesora.ads, g-hesorg.adb, g-hesorg.ads, g-htable.adb, g-htable.ads, gigi.h, g-io.adb, g-io.ads, g-io_aux.adb, g-io_aux.ads, g-locfil.adb, g-locfil.ads, g-md5.adb, g-md5.ads, gmem.c, gnat1drv.adb, gnatbind.adb, gnatchop.adb, gnatcmd.adb, gnatfind.adb, gnatkr.adb, gnatlbr.adb, gnatlink.adb, gnatls.adb, gnatmake.adb, gnatmem.adb, gnatname.adb, gnatprep.adb, gnatprep.ads, gnatpsta.adb, gnatxref.adb, g-os_lib.adb, g-os_lib.ads, g-regexp.adb, g-regexp.ads, g-regist.adb, g-regist.ads, g-regpat.adb, g-regpat.ads, g-soccon.ads, g-socket.adb, g-socket.ads, g-socthi.adb, g-socthi.ads, g-soliop.ads, g-souinf.ads, g-speche.adb, g-speche.ads, g-spipat.adb, g-spipat.ads, g-spitbo.adb, g-spitbo.ads, g-sptabo.ads, g-sptain.ads, g-sptavs.ads, g-table.adb, g-table.ads, g-tasloc.adb, g-tasloc.ads, g-thread.adb, g-thread.ads, g-traceb.adb, g-traceb.ads, g-trasym.adb, g-trasym.ads, hostparm.ads, i-c.ads, i-cobol.adb, i-cpp.adb, i-cstrea.ads, i-cstrin.adb, i-cstrin.ads, impunit.adb, init.c, inline.adb, interfac.ads, i-pacdec.ads, itypes.adb, itypes.ads, i-vxwork.ads, lang.opt, lang-specs.h, layout.adb, lib.adb, lib.ads, lib-list.adb, lib-load.adb, lib-load.ads, lib-sort.adb, lib-util.adb, lib-writ.adb, lib-writ.ads, lib-xref.adb, lib-xref.ads, link.c, live.adb, make.adb, make.ads, Makefile.adalib, Makefile.in, Make-lang.in, makeusg.adb, mdll.adb, mdll-fil.adb, mdll-fil.ads, mdll-utl.adb, mdll-utl.ads, memroot.adb, memroot.ads, memtrack.adb, misc.c, mkdir.c, mlib.adb, mlib.ads, mlib-fil.adb, mlib-fil.ads, mlib-prj.adb, mlib-prj.ads, mlib-tgt.adb, mlib-tgt.ads, mlib-utl.adb, mlib-utl.ads, namet.adb, namet.ads, namet.h, nlists.ads, nlists.h, nmake.adt, opt.adb, opt.ads, osint.adb, osint.ads, osint-b.adb, osint-c.adb, par.adb, par-ch10.adb, par-ch11.adb, par-ch2.adb, par-ch3.adb, par-ch4.adb, par-ch5.adb, par-ch6.adb, par-ch9.adb, par-endh.adb, par-labl.adb, par-load.adb, par-prag.adb, par-sync.adb, par-tchk.adb, par-util.adb, prj.adb, prj.ads, prj-attr.adb, prj-attr.ads, prj-com.adb, prj-com.ads, prj-dect.adb, prj-dect.ads, prj-env.adb, prj-env.ads, prj-ext.adb, prj-ext.ads, prj-makr.adb, prj-makr.ads, prj-nmsc.adb, prj-nmsc.ads, prj-pars.adb, prj-pars.ads, prj-part.adb, prj-part.ads, prj-pp.adb, prj-pp.ads, prj-proc.adb, prj-proc.ads, prj-strt.adb, prj-strt.ads, prj-tree.adb, prj-tree.ads, prj-util.adb, prj-util.ads, raise.c, raise.h, repinfo.adb, repinfo.h, restrict.adb, restrict.ads, rident.ads, rtsfind.adb, rtsfind.ads, s-addima.ads, s-arit64.adb, s-assert.adb, s-assert.ads, s-atacco.adb, s-atacco.ads, s-auxdec.adb, s-auxdec.ads, s-bitops.adb, scans.ads, scn.adb, scn.ads, s-crc32.adb, s-crc32.ads, s-direio.adb, sem.adb, sem.ads, sem_aggr.adb, sem_attr.adb, sem_attr.ads, sem_case.adb, sem_case.ads, sem_cat.adb, sem_cat.ads, sem_ch10.adb, sem_ch11.adb, sem_ch12.adb, sem_ch12.ads, sem_ch13.adb, sem_ch13.ads, sem_ch3.adb, sem_ch3.ads, sem_ch4.adb, sem_ch5.adb, sem_ch5.ads, sem_ch6.adb, sem_ch6.ads, sem_ch7.adb, sem_ch7.ads, sem_ch8.adb, sem_ch8.ads, sem_ch9.adb, sem_disp.adb, sem_disp.ads, sem_dist.adb, sem_elab.adb, sem_eval.adb, sem_eval.ads, sem_intr.adb, sem_maps.adb, sem_mech.adb, sem_prag.adb, sem_prag.ads, sem_res.adb, sem_res.ads, sem_type.adb, sem_type.ads, sem_util.adb, sem_util.ads, sem_warn.adb, s-errrep.adb, s-errrep.ads, s-exctab.adb, s-exctab.ads, s-exnint.ads, s-exnllf.ads, s-exnlli.ads, s-expint.ads, s-explli.ads, s-expuns.ads, s-fatflt.ads, s-fatgen.adb, s-fatgen.ads, s-fatlfl.ads, s-fatllf.ads, s-fatsfl.ads, s-fileio.adb, s-fileio.ads, s-finimp.adb, s-finimp.ads, s-finroo.adb, s-finroo.ads, sfn_scan.adb, s-gloloc.adb, s-gloloc.ads, s-imgdec.adb, s-imgenu.adb, s-imgrea.adb, s-imgwch.adb, sinfo.adb, sinfo.ads, s-inmaop.ads, sinput.adb, sinput.ads, sinput-d.adb, sinput-l.adb, sinput-l.ads, sinput-p.adb, sinput-p.ads, s-interr.adb, s-interr.ads, s-intman.ads, s-maccod.ads, s-mastop.adb, s-mastop.ads, s-memory.adb, s-memory.ads, snames.adb, snames.ads, snames.h, s-osprim.ads, s-parame.ads, s-parint.ads, s-pooloc.adb, s-pooloc.ads, s-poosiz.adb, sprint.adb, s-proinf.ads, s-scaval.ads, s-secsta.adb, s-secsta.ads, s-sequio.adb, s-shasto.adb, s-shasto.ads, s-soflin.ads, s-stache.adb, s-stache.ads, s-stalib.adb, s-stalib.ads, s-stoele.ads, s-stopoo.ads, s-stratt.adb, s-stratt.ads, s-strops.adb, s-strops.ads, s-taasde.adb, s-taasde.ads, s-tadeca.adb, s-tadeca.ads, s-tadert.adb, s-tadert.ads, s-taenca.adb, s-taenca.ads, s-taprob.adb, s-taprob.ads, s-taprop.ads, s-tarest.adb, s-tarest.ads, s-tasdeb.adb, s-tasdeb.ads, s-tasinf.adb, s-tasinf.ads, s-tasini.adb, s-tasini.ads, s-taskin.adb, s-taskin.ads, s-tasque.adb, s-tasque.ads, s-tasren.adb, s-tasren.ads, s-tasres.ads, s-tassta.adb, s-tassta.ads, s-tasuti.adb, s-tasuti.ads, s-tataat.adb, s-tataat.ads, s-tpinop.adb, s-tpinop.ads, s-tpoben.adb, s-tpoben.ads, s-tpobop.adb, s-tpobop.ads, s-tposen.adb, s-tposen.ads, s-traceb.adb, s-traceb.ads, stringt.adb, stringt.ads, stringt.h, style.ads, stylesw.adb, stylesw.ads, s-unstyp.ads, s-vaflop.ads, s-valrea.adb, s-valuti.adb, s-vercon.adb, s-vmexta.adb, s-wchcnv.ads, s-wchcon.ads, s-widcha.adb, switch.adb, switch.ads, switch-b.adb, switch-c.adb, switch-m.adb, s-wwdcha.adb, s-wwdwch.adb, sysdep.c, system.ads, table.adb, table.ads, targparm.adb, targparm.ads, targtyps.c, tbuild.adb, tbuild.ads, tracebak.c, trans.c, tree_io.adb, treepr.adb, treeprs.adt, ttypes.ads, types.ads, types.h, uintp.adb, uintp.ads, uintp.h, uname.adb, urealp.adb, urealp.ads, urealp.h, usage.adb, utils2.c, utils.c, validsw.adb, validsw.ads, widechar.adb, xeinfo.adb, xnmake.adb, xref_lib.adb, xref_lib.ads, xr_tabls.adb, xr_tabls.ads, xtreeprs.adb, xsnames.adb, einfo.h, sinfo.h, treeprs.ads, nmake.ads, nmake.adb, gnatvsn.ads: Merge with ACT tree. * gnatvsn.adb: Rewritten in a simpler and more efficient way. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@72751 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ada/make.adb')
-rw-r--r--gcc/ada/make.adb4145
1 files changed, 2929 insertions, 1216 deletions
diff --git a/gcc/ada/make.adb b/gcc/ada/make.adb
index 2408a879012..240f872d934 100644
--- a/gcc/ada/make.adb
+++ b/gcc/ada/make.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2002 Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2003 Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -33,6 +33,7 @@ with ALI; use ALI;
with ALI.Util; use ALI.Util;
with Csets;
with Debug;
+with Fmap;
with Fname; use Fname;
with Fname.SF; use Fname.SF;
with Fname.UF; use Fname.UF;
@@ -40,7 +41,7 @@ with Gnatvsn; use Gnatvsn;
with Hostparm; use Hostparm;
with Makeusg;
with MLib.Prj;
-with MLib.Tgt;
+with MLib.Tgt; use MLib.Tgt;
with MLib.Utl;
with Namet; use Namet;
with Opt; use Opt;
@@ -55,14 +56,13 @@ with Prj.Ext;
with Prj.Pars;
with Prj.Util;
with SFN_Scan;
-with Sinput.L;
+with Sinput.P;
with Snames; use Snames;
-with Stringt; use Stringt;
with Switch; use Switch;
with Switch.M; use Switch.M;
+with System.HTable;
with Targparm;
-
-with System.WCh_Con; use System.WCh_Con;
+with Tempdir;
package body Make is
@@ -73,6 +73,16 @@ package body Make is
-- Every program depends on this package, that must then be checked,
-- especially when -f and -a are used.
+ type Sigint_Handler is access procedure;
+
+ procedure Install_Int_Handler (Handler : Sigint_Handler);
+ pragma Import (C, Install_Int_Handler, "__gnat_install_int_handler");
+ -- Called by Gnatmake to install the SIGINT handler below
+
+ procedure Sigint_Intercepted;
+ -- Called when the program is interrupted by Ctrl-C to delete the
+ -- temporary mapping files and configuration pragmas files.
+
-------------------------
-- Note on terminology --
-------------------------
@@ -125,11 +135,16 @@ package body Make is
-- Extracts the first element from the Q.
procedure Insert_Project_Sources
- (The_Project : Project_Id;
- Into_Q : Boolean);
- -- If Into_Q is True, insert all sources of the project file that are not
- -- already marked into the Q. If Into_Q is False, call Osint.Add_File for
- -- all sources of the project file.
+ (The_Project : Project_Id;
+ All_Projects : Boolean;
+ Into_Q : Boolean);
+ -- If Into_Q is True, insert all sources of the project file(s) that are
+ -- not already marked into the Q. If Into_Q is False, call Osint.Add_File
+ -- for the first source, then insert all other sources that are not already
+ -- marked into the Q. If All_Projects is True, all sources of all projects
+ -- are concerned; otherwise, only sources of The_Project are concerned,
+ -- including, if The_Project is an extending project, sources inherited
+ -- from projects being extended.
First_Q_Initialization : Boolean := True;
-- Will be set to false after Init_Q has been called once.
@@ -138,6 +153,13 @@ package body Make is
-- Points to the first valid element in the Q.
Unique_Compile : Boolean := False;
+ -- Set to True if -u or -U or a project file with no main is used
+
+ Unique_Compile_All_Projects : Boolean := False;
+ -- Set to True if -U is used
+
+ RTS_Specified : String_Access := null;
+ -- Used to detect multiple --RTS= switches
type Q_Record is record
File : File_Name_Type;
@@ -183,14 +205,6 @@ package body Make is
Table_Increment => 100,
Table_Name => "Make.Saved_Linker_Switches");
- package Saved_Make_Switches is new Table.Table
- (Table_Component_Type => String_Access,
- Table_Index_Type => Integer,
- Table_Low_Bound => 1,
- Table_Initial => 20,
- Table_Increment => 100,
- Table_Name => "Make.Saved_Make_Switches");
-
package Switches_To_Check is new Table.Table (
Table_Component_Type => String_Access,
Table_Index_Type => Integer,
@@ -199,19 +213,96 @@ package body Make is
Table_Increment => 100,
Table_Name => "Make.Switches_To_Check");
+ package Library_Paths is new Table.Table (
+ Table_Component_Type => String_Access,
+ Table_Index_Type => Integer,
+ Table_Low_Bound => 1,
+ Table_Initial => 20,
+ Table_Increment => 100,
+ Table_Name => "Make.Library_Paths");
+
+ package Failed_Links is new Table.Table (
+ Table_Component_Type => File_Name_Type,
+ Table_Index_Type => Integer,
+ Table_Low_Bound => 1,
+ Table_Initial => 10,
+ Table_Increment => 100,
+ Table_Name => "Make.Failed_Links");
+
+ package Successful_Links is new Table.Table (
+ Table_Component_Type => File_Name_Type,
+ Table_Index_Type => Integer,
+ Table_Low_Bound => 1,
+ Table_Initial => 10,
+ Table_Increment => 100,
+ Table_Name => "Make.Successful_Links");
+
+ package Library_Projs is new Table.Table (
+ Table_Component_Type => Project_Id,
+ Table_Index_Type => Integer,
+ Table_Low_Bound => 1,
+ Table_Initial => 10,
+ Table_Increment => 100,
+ Table_Name => "Make.Library_Projs");
+
+ type Linker_Options_Data is record
+ Project : Project_Id;
+ Options : String_List_Id;
+ end record;
+
+ package Linker_Opts is new Table.Table (
+ Table_Component_Type => Linker_Options_Data,
+ Table_Index_Type => Integer,
+ Table_Low_Bound => 1,
+ Table_Initial => 10,
+ Table_Increment => 100,
+ Table_Name => "Make.Linker_Opts");
+
+ -- Two variables to keep the last binder and linker switch index
+ -- in tables Binder_Switches and Linker_Switches, before adding
+ -- switches from the project file (if any) and switches from the
+ -- command line (if any).
+
+ Last_Binder_Switch : Integer := 0;
+ Last_Linker_Switch : Integer := 0;
+
Normalized_Switches : Argument_List_Access := new Argument_List (1 .. 10);
Last_Norm_Switch : Natural := 0;
Saved_Maximum_Processes : Natural := 0;
- Saved_WC_Encoding_Method : WC_Encoding_Method := WC_Encoding_Method'First;
- Saved_WC_Encoding_Method_Set : Boolean := False;
type Arg_List_Ref is access Argument_List;
The_Saved_Gcc_Switches : Arg_List_Ref;
Project_File_Name : String_Access := null;
+ -- The path name of the main project file, if any
+
+ Project_File_Name_Present : Boolean := False;
+ -- True when -P is used with a space between -P and the project file name
+
Current_Verbosity : Prj.Verbosity := Prj.Default;
- Main_Project : Prj.Project_Id := No_Project;
+ -- Verbosity to parse the project files
+
+ Main_Project : Prj.Project_Id := No_Project;
+ -- The project id of the main project file, if any
+
+ -- Packages of project files where unknown attributes are errors.
+
+ Naming_String : aliased String := "naming";
+ Builder_String : aliased String := "builder";
+ Compiler_String : aliased String := "compiler";
+ Binder_String : aliased String := "binder";
+ Linker_String : aliased String := "linker";
+
+ Gnatmake_Packages : aliased String_List :=
+ (Naming_String 'Access,
+ Builder_String 'Access,
+ Compiler_String 'Access,
+ Binder_String 'Access,
+ Linker_String 'Access);
+
+ Packages_To_Check_By_Gnatmake : constant String_List_Access :=
+ Gnatmake_Packages'Access;
procedure Add_Source_Dir (N : String);
-- Call Add_Src_Search_Dir.
@@ -247,16 +338,6 @@ package body Make is
Table_Name => "Make.Bad_Compilation");
-- Full name of all the source files for which compilation fails.
- Original_Ada_Include_Path : constant String_Access :=
- Getenv ("ADA_INCLUDE_PATH");
- Original_Ada_Objects_Path : constant String_Access :=
- Getenv ("ADA_OBJECTS_PATH");
- Current_Ada_Include_Path : String_Access := null;
- Current_Ada_Objects_Path : String_Access := null;
-
- Max_Line_Length : constant := 127;
- -- Maximum number of characters per line, when displaying a path
-
Do_Compile_Step : Boolean := True;
Do_Bind_Step : Boolean := True;
Do_Link_Step : Boolean := True;
@@ -264,6 +345,111 @@ package body Make is
-- Can be set to False with the switches -c, -b and -l.
-- These flags are reset to True for each invokation of procedure Gnatmake.
+ Shared_String : aliased String := "-shared";
+
+ No_Shared_Switch : aliased Argument_List := (1 .. 0 => null);
+ Shared_Switch : aliased Argument_List := (1 => Shared_String'Access);
+ Bind_Shared : Argument_List_Access := No_Shared_Switch'Access;
+ -- Switch to added in front of gnatbind switches. By default no switch is
+ -- added. Switch "-shared" is added if there is a non-static Library
+ -- Project File.
+
+ Bind_Shared_Known : Boolean := False;
+ -- Set to True after the first time Bind_Shared is computed
+
+ procedure Make_Failed (S1 : String; S2 : String := ""; S3 : String := "");
+ -- Delete all temp files created by Gnatmake and call Osint.Fail,
+ -- with the parameter S1, S2 and S3 (see osint.ads).
+ -- This is called from the Prj hierarchy and the MLib hierarchy.
+
+ --------------------------
+ -- Obsolete Executables --
+ --------------------------
+
+ Executable_Obsolete : Boolean := False;
+ -- Executable_Obsolete is initially set to False for each executable,
+ -- and is set to True whenever one of the source of the executable is
+ -- compiled, or has already been compiled for another executable.
+
+ Max_Header : constant := 200; -- Arbitrary
+
+ type Header_Num is range 1 .. Max_Header;
+ -- Header_Num for the hash table Obsoleted below
+
+ function Hash (F : Name_Id) return Header_Num;
+ -- Hash function for the hash table Obsoleted below
+
+ package Obsoleted is new System.HTable.Simple_HTable
+ (Header_Num => Header_Num,
+ Element => Boolean,
+ No_Element => False,
+ Key => Name_Id,
+ Hash => Hash,
+ Equal => "=");
+ -- A hash table to keep all files that have been compiled, to detect
+ -- if an executable is up to date or not.
+
+ procedure Enter_Into_Obsoleted (F : Name_Id);
+ -- Enter a file name, without directory information, into the has table
+ -- Obsoleted.
+
+ function Is_In_Obsoleted (F : Name_Id) return Boolean;
+ -- Check if a file name, without directory information, has already been
+ -- entered into the hash table Obsoleted.
+
+ type Dependency is record
+ This : Name_Id;
+ Depends_On : Name_Id;
+ end record;
+ -- Components of table Dependencies below.
+
+ package Dependencies is new Table.Table (
+ Table_Component_Type => Dependency,
+ Table_Index_Type => Integer,
+ Table_Low_Bound => 1,
+ Table_Initial => 20,
+ Table_Increment => 100,
+ Table_Name => "Make.Dependencies");
+ -- A table to keep dependencies, to be able to decide if an executable
+ -- is obsolete.
+
+ procedure Add_Dependency (S : Name_Id; On : Name_Id);
+ -- Add one entry in table Dependencies
+
+ ----------------------------
+ -- Arguments and Switches --
+ ----------------------------
+
+ Arguments : Argument_List_Access;
+ -- Used to gather the arguments for invocation of the compiler
+
+ Last_Argument : Natural := 0;
+ -- Last index of arguments in Arguments above
+
+ Arguments_Collected : Boolean := False;
+ -- Set to True when the arguments for the next invocation of the compiler
+ -- have been collected.
+
+ Arguments_Project : Project_Id;
+ -- Project id, if any, of the source to be compiled
+
+ Arguments_Path_Name : File_Name_Type;
+ -- Full path of the source to be compiled, when Arguments_Project is not
+ -- No_Project.
+
+ Dummy_Switch : constant String_Access := new String'("- ");
+ -- Used to initialized Prev_Switch in procedure Check
+
+ procedure Add_Arguments (Args : Argument_List);
+ -- Add arguments to global variable Arguments, increasing its size
+ -- if necessary and adjusting Last_Argument.
+
+ function Configuration_Pragmas_Switch
+ (For_Project : Project_Id) return Argument_List;
+ -- Return an argument list of one element, if there is a configuration
+ -- pragmas file to be specified for For_Project,
+ -- otherwise return an empty argument list.
+
----------------------
-- Marking Routines --
----------------------
@@ -311,15 +497,32 @@ package body Make is
-- Call Makeusg, if Usage_Needed is True.
-- Set Usage_Needed to False.
+ procedure Debug_Msg (S : String; N : Name_Id);
+ -- If Debug.Debug_Flag_W is set outputs string S followed by name N.
+
+ type Project_Array is array (Positive range <>) of Project_Id;
+ No_Projects : constant Project_Array := (1 .. 0 => No_Project);
+
+ procedure Recursive_Compute_Depth
+ (Project : Project_Id;
+ Visited : Project_Array;
+ Depth : Natural);
+ -- Compute depth of Project and of the projects it depends on
+
-----------------------
-- Gnatmake Routines --
-----------------------
+ Gnatmake_Called : Boolean := False;
+ -- Set to True when procedure Gnatmake is called.
+ -- Attempt to delete temporary files is made only when Gnatmake_Called
+ -- is True.
+
subtype Lib_Mark_Type is Byte;
- -- ??? this needs a comment
+ -- Used in Mark_Directory
Ada_Lib_Dir : constant Lib_Mark_Type := 1;
- -- ??? this needs a comment
+ -- Used to mark a directory as a GNAT lib dir
-- Note that the notion of GNAT lib dir is no longer used. The code
-- related to it has not been removed to give an idea on how to use
@@ -335,6 +538,10 @@ package body Make is
-- The directory lookup penalty is incurred every single time this
-- routine is called.
+ procedure Check_Steps;
+ -- Check what steps (Compile, Bind, Link) must be executed.
+ -- Set the step flags accordingly.
+
function Is_External_Assignment (Argv : String) return Boolean;
-- Verify that an external assignment switch is syntactically correct.
-- Correct forms are
@@ -355,28 +562,19 @@ package body Make is
-- Store Dir in name table and set lib mark as name info to identify
-- Ada libraries.
- function Object_File_Name (Source : String) return String;
- -- Returns the object file name suitable for switch -o.
+ Output_Is_Object : Boolean := True;
+ -- Set to False when using a switch -S for the compiler
- procedure Set_Ada_Paths
- (For_Project : Prj.Project_Id;
- Including_Libraries : Boolean);
- -- Set, if necessary, env. variables ADA_INCLUDE_PATH and
- -- ADA_OBJECTS_PATH.
- --
- -- Note: this will modify these environment variables only
- -- for the current gnatmake process and all of its children
- -- (invocations of the compiler, the binder and the linker).
- -- The caller process ADA_INCLUDE_PATH and ADA_OBJECTS_PATH are
- -- not affected.
+ procedure Check_For_S_Switch;
+ -- Set Output_Is_Object to False when the -S switch is used for the
+ -- compiler.
function Switches_Of
(Source_File : Name_Id;
Source_File_Name : String;
Naming : Naming_Data;
In_Package : Package_Id;
- Allow_ALI : Boolean)
- return Variable_Value;
+ Allow_ALI : Boolean) return Variable_Value;
-- Return the switches for the source file in the specified package
-- of a project file. If the Source_File ends with a standard GNAT
-- extension (".ads" or ".adb"), try first the full name, then the
@@ -385,22 +583,21 @@ package body Make is
-- default switches for Ada. If all failed, return No_Variable_Value.
procedure Test_If_Relative_Path
- (Switch : in out String_Access;
- Parent : String_Access);
+ (Switch : in out String_Access;
+ Parent : String_Access;
+ Including_L_Switch : Boolean := True);
-- Test if Switch is a relative search path switch.
-- If it is, fail if Parent is null, otherwise prepend the path with
-- Parent. This subprogram is only called when using project files.
+ -- For gnatbind switches, Including_L_Switch is False, because the
+ -- argument of the -L switch is not a path.
- procedure Set_Library_For
- (Project : Project_Id;
- There_Are_Libraries : in out Boolean);
- -- If Project is a library project, add the correct
- -- -L and -l switches to the linker invocation.
-
- procedure Set_Libraries is
- new For_Every_Project_Imported (Boolean, Set_Library_For);
- -- Add the -L and -l switches to the linker for all
- -- of the library projects.
+ function Is_In_Object_Directory
+ (Source_File : File_Name_Type;
+ Full_Lib_File : File_Name_Type) return Boolean;
+ -- Check if, when using a project file, the ALI file is in the project
+ -- directory of the ultimate extending project. If it is not, we ignore
+ -- the fact that this ALI file is read-only.
----------------------------------------------------
-- Compiler, Binder & Linker Data and Subprograms --
@@ -446,6 +643,13 @@ package body Make is
-- Set to True after having scanned the file_name for
-- switch "-o file_name"
+ Object_Directory_Seen : Boolean := False;
+ -- Set to True after having scanned the object directory for
+ -- switch "-D obj_dir".
+
+ Object_Directory_Path : String_Access := null;
+ -- The path name of the object directory, set with switch -D.
+
type Make_Program_Type is (None, Compiler, Binder, Linker);
Program_Args : Make_Program_Type := None;
@@ -453,6 +657,10 @@ package body Make is
-- options within the gnatmake command line.
-- Used in Scan_Make_Arg only, but must be a global variable.
+ Temporary_Config_File : Boolean := False;
+ -- Set to True when there is a temporary config file used for a project
+ -- file, to avoid displaying the -gnatec switch for a temporary file.
+
procedure Add_Switches
(The_Package : Package_Id;
File_Name : String;
@@ -476,10 +684,13 @@ package body Make is
-- added at the beginning of the command line.
procedure Check
- (Lib_File : File_Name_Type;
- ALI : out ALI_Id;
- O_File : out File_Name_Type;
- O_Stamp : out Time_Stamp_Type);
+ (Source_File : File_Name_Type;
+ The_Args : Argument_List;
+ Lib_File : File_Name_Type;
+ Read_Only : Boolean;
+ ALI : out ALI_Id;
+ O_File : out File_Name_Type;
+ O_Stamp : out Time_Stamp_Type);
-- Determines whether the library file Lib_File is up-to-date or not. The
-- full name (with path information) of the object file corresponding to
-- Lib_File is returned in O_File. Its time stamp is saved in O_Stamp.
@@ -499,23 +710,102 @@ package body Make is
-- linker file is returned in O_File and O_Stamp is empty.
-- Otherwise O_File is No_File.
+ procedure Collect_Arguments
+ (Source_File : File_Name_Type;
+ Args : Argument_List);
+ -- Collect all arguments for a source to be compiled, including those
+ -- that come from a project file.
+
procedure Display (Program : String; Args : Argument_List);
-- Displays Program followed by the arguments in Args if variable
-- Display_Executed_Programs is set. The lower bound of Args must be 1.
- type Temp_File_Names is array (Positive range <>) of Temp_File_Name;
+ -----------------
+ -- Mapping files
+ -----------------
+
+ type Temp_File_Names is
+ array (Project_Id range <>, Positive range <>) of Name_Id;
type Temp_Files_Ptr is access Temp_File_Names;
+ type Indices is array (Project_Id range <>) of Natural;
+
+ type Indices_Ptr is access Indices;
+
+ type Free_File_Indices is array
+ (Project_Id range <>, Positive range <>) of Positive;
+
+ type Free_Indices_Ptr is access Free_File_Indices;
+
The_Mapping_File_Names : Temp_Files_Ptr;
- Last_Mapping_File_Name : Natural := 0;
+ -- For each project, the name ids of the temporary mapping files used
+
+ Last_Mapping_File_Names : Indices_Ptr;
+ -- For each project, the index of the last mapping file created
+
+ The_Free_Mapping_File_Indices : Free_Indices_Ptr;
+ -- For each project, the indices in The_Mapping_File_Names of the mapping
+ -- file names that can be reused for subsequent compilations.
+
+ Last_Free_Indices : Indices_Ptr;
+ -- For each project, the number of mapping files that can be reused
+
+ Gnatmake_Mapping_File : String_Access := null;
+ -- The path name of a mapping file specified by switch -C=
procedure Delete_Mapping_Files;
-- Delete all temporary mapping files
- procedure Init_Mapping_File (File_Name : in out Temp_File_Name);
+ procedure Init_Mapping_File
+ (Project : Project_Id;
+ File_Index : in out Natural);
-- Create a new temporary mapping file, and fill it with the project file
- -- mappings, when using project file(s)
+ -- mappings, when using project file(s). The out parameter File_Index is
+ -- the index to the name of the file in the array The_Mapping_File_Names.
+
+ procedure Delete_Temp_Config_Files;
+ -- Delete all temporary config files
+
+ procedure Delete_All_Temp_Files;
+ -- Delete all temp files (config files, mapping files, path files)
+
+ -------------------
+ -- Add_Arguments --
+ -------------------
+
+ procedure Add_Arguments (Args : Argument_List) is
+ begin
+ if Arguments = null then
+ Arguments := new Argument_List (1 .. Args'Length + 10);
+
+ else
+ while Last_Argument + Args'Length > Arguments'Last loop
+ declare
+ New_Arguments : Argument_List_Access :=
+ new Argument_List (1 .. Arguments'Last * 2);
+
+ begin
+ New_Arguments (1 .. Last_Argument) :=
+ Arguments (1 .. Last_Argument);
+ Arguments := New_Arguments;
+ end;
+ end loop;
+ end if;
+
+ Arguments (Last_Argument + 1 .. Last_Argument + Args'Length) := Args;
+ Last_Argument := Last_Argument + Args'Length;
+ end Add_Arguments;
+
+ --------------------
+ -- Add_Dependency --
+ --------------------
+
+ procedure Add_Dependency (S : Name_Id; On : Name_Id) is
+ begin
+ Dependencies.Increment_Last;
+ Dependencies.Table (Dependencies.Last) := (S, On);
+ end Add_Dependency;
--------------------
-- Add_Object_Dir --
@@ -564,7 +854,7 @@ package body Make is
procedure Generic_Position (New_Position : out Integer);
-- Generic procedure that chooses a position for S in T at the
-- beginning or the end, depending on the boolean Append_Switch.
-
+ -- Calling this procedure may expand the table.
----------------------
-- Generic_Position --
@@ -691,17 +981,22 @@ package body Make is
while Switch_List /= Nil_String loop
Element := String_Elements.Table (Switch_List);
- String_To_Name_Buffer (Element.Value);
+ Get_Name_String (Element.Value);
if Name_Len > 0 then
- if Opt.Verbose_Mode then
- Write_Str (" Adding ");
- Write_Line (Name_Buffer (1 .. Name_Len));
- end if;
+ declare
+ Argv : constant String := Name_Buffer (1 .. Name_Len);
+ -- We need a copy, because Name_Buffer may be
+ -- modified.
- Scan_Make_Arg
- (Name_Buffer (1 .. Name_Len),
- And_Save => False);
+ begin
+ if Opt.Verbose_Mode then
+ Write_Str (" Adding ");
+ Write_Line (Argv);
+ end if;
+
+ Scan_Make_Arg (Argv, And_Save => False);
+ end;
end if;
Switch_List := Element.Next;
@@ -709,16 +1004,21 @@ package body Make is
when Single =>
Program_Args := Program;
- String_To_Name_Buffer (Switches.Value);
+ Get_Name_String (Switches.Value);
if Name_Len > 0 then
- if Opt.Verbose_Mode then
- Write_Str (" Adding ");
- Write_Line (Name_Buffer (1 .. Name_Len));
- end if;
+ declare
+ Argv : constant String := Name_Buffer (1 .. Name_Len);
+ -- We need a copy, because Name_Buffer may be modified
+
+ begin
+ if Opt.Verbose_Mode then
+ Write_Str (" Adding ");
+ Write_Line (Argv);
+ end if;
- Scan_Make_Arg
- (Name_Buffer (1 .. Name_Len), And_Save => False);
+ Scan_Make_Arg (Argv, And_Save => False);
+ end;
end if;
end case;
end if;
@@ -767,7 +1067,7 @@ package body Make is
Display (Gnatbind.all, Bind_Args (Args'First .. Bind_Last));
if Gnatbind_Path = null then
- Osint.Fail ("error, unable to locate " & Gnatbind.all);
+ Make_Failed ("error, unable to locate ", Gnatbind.all);
end if;
GNAT.OS_Lib.Spawn
@@ -783,10 +1083,13 @@ package body Make is
-----------
procedure Check
- (Lib_File : File_Name_Type;
- ALI : out ALI_Id;
- O_File : out File_Name_Type;
- O_Stamp : out Time_Stamp_Type)
+ (Source_File : File_Name_Type;
+ The_Args : Argument_List;
+ Lib_File : File_Name_Type;
+ Read_Only : Boolean;
+ ALI : out ALI_Id;
+ O_File : out File_Name_Type;
+ O_Stamp : out Time_Stamp_Type)
is
function First_New_Spec (A : ALI_Id) return File_Name_Type;
-- Looks in the with table entries of A and returns the spec file name
@@ -916,8 +1219,8 @@ package body Make is
Source_Name : Name_Id;
Text : Text_Buffer_Ptr;
- Prev_Switch : Character;
- -- First character of previous switch processed
+ Prev_Switch : String_Access;
+ -- Previous switch processed
Arg : Arg_Id := Arg_Id'First;
-- Current index in Args.Table for a given unit (init to stop warning)
@@ -925,15 +1228,29 @@ package body Make is
Switch_Found : Boolean;
-- True if a given switch has been found
- Num_Args : Integer;
- -- Number of compiler arguments processed
-
-- Start of processing for Check
begin
pragma Assert (Lib_File /= No_File);
- Text := Read_Library_Info (Lib_File);
+ -- If the ALI file is read-only, set temporarily
+ -- Check_Object_Consistency to False: we don't care if the object file
+ -- is not there; presumably, a library will be used for linking.
+
+ if Read_Only then
+ declare
+ Saved_Check_Object_Consistency : constant Boolean :=
+ Opt.Check_Object_Consistency;
+ begin
+ Opt.Check_Object_Consistency := False;
+ Text := Read_Library_Info (Lib_File);
+ Opt.Check_Object_Consistency := Saved_Check_Object_Consistency;
+ end;
+
+ else
+ Text := Read_Library_Info (Lib_File);
+ end if;
+
Full_Lib_File := Full_Library_Info_Name;
Full_Obj_File := Full_Object_File_Name;
Lib_Stamp := Current_Library_File_Stamp;
@@ -978,6 +1295,15 @@ package body Make is
return;
end if;
+ -- Don't take Ali file into account if it was generated with
+ -- errors.
+
+ if ALIs.Table (ALI).Compile_Errors then
+ Verbose_Msg (Full_Lib_File, "had errors, must be recompiled");
+ ALI := No_ALI_Id;
+ return;
+ end if;
+
-- Don't take Ali file into account if it was generated without
-- object.
@@ -992,23 +1318,28 @@ package body Make is
-- Check for matching compiler switches if needed
if Opt.Check_Switches then
- Prev_Switch := ASCII.Nul;
- Num_Args := 0;
+
+ -- First, collect all the switches
+
+ Collect_Arguments (Source_File, The_Args);
+
+ Prev_Switch := Dummy_Switch;
Get_Name_String (ALIs.Table (ALI).Sfile);
Switches_To_Check.Set_Last (0);
- for J in Gcc_Switches.First .. Gcc_Switches.Last loop
+ for J in 1 .. Last_Argument loop
- -- Skip non switches, -I and -o switches
+ -- Skip non switches -c, -I and -o switches
- if Gcc_Switches.Table (J) (1) = '-'
- and then Gcc_Switches.Table (J) (2) /= 'o'
- and then Gcc_Switches.Table (J) (2) /= 'I'
+ if Arguments (J) (1) = '-'
+ and then Arguments (J) (2) /= 'c'
+ and then Arguments (J) (2) /= 'o'
+ and then Arguments (J) (2) /= 'I'
then
Normalize_Compiler_Switches
- (Gcc_Switches.Table (J).all,
+ (Arguments (J).all,
Normalized_Switches,
Last_Norm_Switch);
@@ -1030,8 +1361,14 @@ package body Make is
-- orders between same switches, e.g -O -O2 is different
-- than -O2 -O, but -g -O is equivalent to -O -g.
- if Switches_To_Check.Table (J) (2) /= Prev_Switch then
- Prev_Switch := Switches_To_Check.Table (J) (2);
+ if Switches_To_Check.Table (J) (2) /= Prev_Switch (2) or else
+ (Prev_Switch'Length >= 6 and then
+ Prev_Switch (2 .. 5) = "gnat" and then
+ Switches_To_Check.Table (J)'Length >= 6 and then
+ Switches_To_Check.Table (J) (2 .. 5) = "gnat" and then
+ Prev_Switch (6) /= Switches_To_Check.Table (J) (6))
+ then
+ Prev_Switch := Switches_To_Check.Table (J);
Arg :=
Units.Table (ALIs.Table (ALI).First_Unit).First_Arg;
end if;
@@ -1041,8 +1378,6 @@ package body Make is
for K in Arg ..
Units.Table (ALIs.Table (ALI).First_Unit).Last_Arg
loop
- Num_Args := Num_Args + 1;
-
if
Switches_To_Check.Table (J).all = Args.Table (K).all
then
@@ -1055,7 +1390,8 @@ package body Make is
if not Switch_Found then
if Opt.Verbose_Mode then
Verbose_Msg (ALIs.Table (ALI).Sfile,
- "switch mismatch");
+ "switch mismatch """ &
+ Switches_To_Check.Table (J).all & '"');
end if;
ALI := No_ALI_Id;
@@ -1063,13 +1399,29 @@ package body Make is
end if;
end loop;
- if Num_Args /=
+ if Switches_To_Check.Last /=
Integer (Units.Table (ALIs.Table (ALI).First_Unit).Last_Arg -
Units.Table (ALIs.Table (ALI).First_Unit).First_Arg + 1)
then
if Opt.Verbose_Mode then
Verbose_Msg (ALIs.Table (ALI).Sfile,
- "different number of switches");
+ "different number of switches");
+
+ for K in Units.Table (ALIs.Table (ALI).First_Unit).First_Arg
+ .. Units.Table (ALIs.Table (ALI).First_Unit).Last_Arg
+ loop
+ Write_Str (Args.Table (K).all);
+ Write_Char (' ');
+ end loop;
+
+ Write_Eol;
+
+ for J in 1 .. Switches_To_Check.Last loop
+ Write_Str (Switches_To_Check.Table (J).all);
+ Write_Char (' ');
+ end loop;
+
+ Write_Eol;
end if;
ALI := No_ALI_Id;
@@ -1077,12 +1429,12 @@ package body Make is
end if;
end if;
- -- Get the source files and their time stamps. Note that some
+ -- Get the source files and their message digests. Note that some
-- sources may be missing if ALI is out-of-date.
Set_Source_Table (ALI);
- Modified_Source := Time_Stamp_Mismatch (ALI);
+ Modified_Source := Time_Stamp_Mismatch (ALI, Read_Only);
if Modified_Source /= No_File then
ALI := No_ALI_Id;
@@ -1117,6 +1469,26 @@ package body Make is
end if;
end Check;
+ ------------------------
+ -- Check_For_S_Switch --
+ ------------------------
+
+ procedure Check_For_S_Switch is
+ begin
+ -- By default, we generate an object file
+
+ Output_Is_Object := True;
+
+ for Arg in 1 .. Last_Argument loop
+ if Arguments (Arg).all = "-S" then
+ Output_Is_Object := False;
+
+ elsif Arguments (Arg).all = "-c" then
+ Output_Is_Object := True;
+ end if;
+ end loop;
+ end Check_For_S_Switch;
+
--------------------------
-- Check_Linker_Options --
--------------------------
@@ -1273,7 +1645,9 @@ package body Make is
if Opt = Linker_Switches.First
or else (Linker_Switches.Table (Opt - 1).all /= "-u"
and then
- Linker_Switches.Table (Opt - 1).all /= "-Xlinker")
+ Linker_Switches.Table (Opt - 1).all /= "-Xlinker"
+ and then
+ Linker_Switches.Table (Opt - 1).all /= "-L")
then
Name_Len := 0;
Add_Str_To_Name_Buffer (Linker_Switches.Table (Opt).all);
@@ -1283,6 +1657,201 @@ package body Make is
end Check_Linker_Options;
+ -----------------
+ -- Check_Steps --
+ -----------------
+
+ procedure Check_Steps is
+ begin
+ -- If either -c, -b or -l has been specified, we will not necessarily
+ -- execute all steps.
+
+ if Make_Steps then
+ Do_Compile_Step := Do_Compile_Step and Compile_Only;
+ Do_Bind_Step := Do_Bind_Step and Bind_Only;
+ Do_Link_Step := Do_Link_Step and Link_Only;
+
+ -- If -c has been specified, but not -b, ignore any potential -l
+
+ if Do_Compile_Step and then not Do_Bind_Step then
+ Do_Link_Step := False;
+ end if;
+ end if;
+ end Check_Steps;
+
+ -----------------------
+ -- Collect_Arguments --
+ -----------------------
+
+ procedure Collect_Arguments
+ (Source_File : File_Name_Type;
+ Args : Argument_List)
+ is
+ begin
+ Arguments_Collected := True;
+ Arguments_Project := No_Project;
+ Last_Argument := 0;
+ Add_Arguments (Args);
+
+ if Main_Project /= No_Project then
+ declare
+ Source_File_Name : constant String :=
+ Get_Name_String (Source_File);
+ Compiler_Package : Prj.Package_Id;
+ Switches : Prj.Variable_Value;
+ Data : Project_Data;
+
+ begin
+ Prj.Env.
+ Get_Reference
+ (Source_File_Name => Source_File_Name,
+ Project => Arguments_Project,
+ Path => Arguments_Path_Name);
+
+ -- If the source is not a source of a project file,
+ -- we simply add the saved gcc switches.
+
+ if Arguments_Project = No_Project then
+
+ Add_Arguments (The_Saved_Gcc_Switches.all);
+
+ else
+ -- We get the project directory for the relative path
+ -- switches and arguments.
+
+ Data := Projects.Table (Arguments_Project);
+
+ -- If the source is in an extended project, we go to
+ -- the ultimate extending project.
+
+ while Data.Extended_By /= No_Project loop
+ Arguments_Project := Data.Extended_By;
+ Data := Projects.Table (Arguments_Project);
+ end loop;
+
+ -- If building a dynamic or relocatable library, compile with
+ -- PIC option, if it exists.
+
+ if Data.Library and then Data.Library_Kind /= Static then
+ declare
+ PIC : constant String := MLib.Tgt.PIC_Option;
+
+ begin
+ if PIC /= "" then
+ Add_Arguments ((1 => new String'(PIC)));
+ end if;
+ end;
+ end if;
+
+ if Data.Dir_Path = null then
+ Data.Dir_Path :=
+ new String'(Get_Name_String (Data.Display_Directory));
+ Projects.Table (Arguments_Project) := Data;
+ end if;
+
+ -- We now look for package Compiler
+ -- and get the switches from this package.
+
+ Compiler_Package :=
+ Prj.Util.Value_Of
+ (Name => Name_Compiler,
+ In_Packages => Data.Decl.Packages);
+
+ if Compiler_Package /= No_Package then
+
+ -- If package Gnatmake.Compiler exists, we get
+ -- the specific switches for the current source,
+ -- or the global switches, if any.
+
+ Switches := Switches_Of
+ (Source_File => Source_File,
+ Source_File_Name => Source_File_Name,
+ Naming => Data.Naming,
+ In_Package => Compiler_Package,
+ Allow_ALI => False);
+
+ end if;
+
+ case Switches.Kind is
+
+ -- We have a list of switches. We add these switches,
+ -- plus the saved gcc switches.
+
+ when List =>
+
+ declare
+ Current : String_List_Id := Switches.Values;
+ Element : String_Element;
+ Number : Natural := 0;
+
+ begin
+ while Current /= Nil_String loop
+ Element := String_Elements.Table (Current);
+ Number := Number + 1;
+ Current := Element.Next;
+ end loop;
+
+ declare
+ New_Args : Argument_List (1 .. Number);
+
+ begin
+ Current := Switches.Values;
+
+ for Index in New_Args'Range loop
+ Element := String_Elements.Table (Current);
+ Get_Name_String (Element.Value);
+ New_Args (Index) :=
+ new String'(Name_Buffer (1 .. Name_Len));
+ Test_If_Relative_Path
+ (New_Args (Index), Parent => Data.Dir_Path);
+ Current := Element.Next;
+ end loop;
+
+ Add_Arguments
+ (Configuration_Pragmas_Switch
+ (Arguments_Project) &
+ New_Args & The_Saved_Gcc_Switches.all);
+ end;
+ end;
+
+ -- We have a single switch. We add this switch,
+ -- plus the saved gcc switches.
+
+ when Single =>
+ Get_Name_String (Switches.Value);
+
+ declare
+ New_Args : Argument_List :=
+ (1 => new String'
+ (Name_Buffer (1 .. Name_Len)));
+
+ begin
+ Test_If_Relative_Path
+ (New_Args (1), Parent => Data.Dir_Path);
+ Add_Arguments
+ (Configuration_Pragmas_Switch (Arguments_Project) &
+ New_Args & The_Saved_Gcc_Switches.all);
+ end;
+
+ -- We have no switches from Gnatmake.Compiler.
+ -- We add the saved gcc switches.
+
+ when Undefined =>
+ Add_Arguments
+ (Configuration_Pragmas_Switch (Arguments_Project) &
+ The_Saved_Gcc_Switches.all);
+ end case;
+ end if;
+ end;
+ end if;
+
+ -- Set Output_Is_Object, depending if there is a -S switch.
+ -- If the bind step is not performed, and there is a -S switch,
+ -- then we will not check for a valid object file.
+
+ Check_For_S_Switch;
+ end Collect_Arguments;
+
---------------------
-- Compile_Sources --
---------------------
@@ -1306,23 +1875,23 @@ package body Make is
function Compile
(S : Name_Id;
L : Name_Id;
- Args : Argument_List)
- return Process_Id;
+ Args : Argument_List) return Process_Id;
-- Compiles S using Args. If S is a GNAT predefined source
-- "-gnatpg" is added to Args. Non blocking call. L corresponds to the
-- expected library file name. Process_Id of the process spawned to
-- execute the compile.
- No_Mapping_File : constant Temp_File_Name := (others => ' ');
+ No_Mapping_File : constant Natural := 0;
type Compilation_Data is record
Pid : Process_Id;
Full_Source_File : File_Name_Type;
Lib_File : File_Name_Type;
Source_Unit : Unit_Name_Type;
- Mapping_File : Temp_File_Name := No_Mapping_File;
- Use_Mapping_File : Boolean := False;
- Syntax_Only : Boolean := False;
+ Mapping_File : Natural := No_Mapping_File;
+ Project : Project_Id := No_Project;
+ Syntax_Only : Boolean := False;
+ Output_Is_Object : Boolean := True;
end record;
Running_Compile : array (1 .. Max_Process) of Compilation_Data;
@@ -1358,36 +1927,33 @@ package body Make is
ALI : ALI_Id;
-- ALI Id of the current ALI file
+ Read_Only : Boolean := False;
+
Compilation_OK : Boolean;
Need_To_Compile : Boolean;
Pid : Process_Id;
Text : Text_Buffer_Ptr;
- Mfile : Temp_File_Name := No_Mapping_File;
-
- Data : Prj.Project_Data;
-
- Arg_Index : Natural;
- -- Index in Special_Args.Table of a given compilation file
+ Mfile : Natural := No_Mapping_File;
- Need_To_Check_Standard_Library : Boolean := Check_Readonly_Files;
+ Need_To_Check_Standard_Library : Boolean :=
+ Check_Readonly_Files and not Unique_Compile;
- Mapping_File_Arg : constant String_Access := new String'
- (1 => '-', 2 => 'g', 3 => 'n', 4 => 'a', 5 => 't', 6 => 'e', 7 => 'm',
- 8 .. 7 + Mfile'Length => ' ');
+ Mapping_File_Arg : String_Access;
procedure Add_Process
(Pid : Process_Id;
Sfile : File_Name_Type;
Afile : File_Name_Type;
Uname : Unit_Name_Type;
- Mfile : Temp_File_Name := No_Mapping_File;
- UMfile : Boolean := False);
+ Mfile : Natural := No_Mapping_File);
-- Adds process Pid to the current list of outstanding compilation
-- processes and record the full name of the source file Sfile that
-- we are compiling, the name of its library file Afile and the
- -- name of its unit Uname.
+ -- name of its unit Uname. If Mfile is not equal to No_Mapping_File,
+ -- it is the index of the mapping file used during compilation in the
+ -- array The_Mapping_File_Names.
procedure Await_Compile
(Sfile : out File_Name_Type;
@@ -1435,17 +2001,7 @@ package body Make is
function Bad_Compilation_Count return Natural;
-- Returns the number of compilation failures.
- procedure Debug_Msg (S : String; N : Name_Id);
- -- If Debug.Debug_Flag_W is set outputs string S followed by name N.
-
- function Configuration_Pragmas_Switch
- (For_Project : Project_Id)
- return Argument_List;
- -- Return an argument list of one element, if there is a configuration
- -- pragmas file to be specified for For_Project,
- -- otherwise return an empty argument list.
-
- procedure Get_Mapping_File;
+ procedure Get_Mapping_File (Project : Project_Id);
-- Get a mapping file name. If there is one to be reused, reuse it.
-- Otherwise, create a new mapping file.
@@ -1458,8 +2014,7 @@ package body Make is
Sfile : File_Name_Type;
Afile : File_Name_Type;
Uname : Unit_Name_Type;
- Mfile : Temp_File_Name := No_Mapping_File;
- UMfile : Boolean := False)
+ Mfile : Natural := No_Mapping_File)
is
OC1 : constant Positive := Outstanding_Compiles + 1;
@@ -1472,8 +2027,9 @@ package body Make is
Running_Compile (OC1).Lib_File := Afile;
Running_Compile (OC1).Source_Unit := Uname;
Running_Compile (OC1).Mapping_File := Mfile;
- Running_Compile (OC1).Use_Mapping_File := UMfile;
+ Running_Compile (OC1).Project := Arguments_Project;
Running_Compile (OC1).Syntax_Only := Syntax_Only;
+ Running_Compile (OC1).Output_Is_Object := Output_Is_Object;
Outstanding_Compiles := OC1;
end Add_Process;
@@ -1489,6 +2045,7 @@ package body Make is
OK : out Boolean)
is
Pid : Process_Id;
+ Project : Project_Id;
begin
pragma Assert (Outstanding_Compiles > 0);
@@ -1498,46 +2055,61 @@ package body Make is
Uname := No_Name;
OK := False;
- Wait_Process (Pid, OK);
+ -- The loop here is a work-around for a problem on VMS; in some
+ -- circumstances (shared library and several executables, for
+ -- example), there are child processes other than compilation
+ -- processes that are received. Until this problem is resolved,
+ -- we will ignore such processes.
- if Pid = Invalid_Pid then
- return;
- end if;
+ loop
+ Wait_Process (Pid, OK);
- for J in Running_Compile'First .. Outstanding_Compiles loop
- if Pid = Running_Compile (J).Pid then
- Sfile := Running_Compile (J).Full_Source_File;
- Afile := Running_Compile (J).Lib_File;
- Uname := Running_Compile (J).Source_Unit;
- Syntax_Only := Running_Compile (J).Syntax_Only;
+ if Pid = Invalid_Pid then
+ return;
+ end if;
- -- If a mapping file was used by this compilation,
- -- get its file name for reuse by a subsequent compilation
+ for J in Running_Compile'First .. Outstanding_Compiles loop
+ if Pid = Running_Compile (J).Pid then
+ Sfile := Running_Compile (J).Full_Source_File;
+ Afile := Running_Compile (J).Lib_File;
+ Uname := Running_Compile (J).Source_Unit;
+ Syntax_Only := Running_Compile (J).Syntax_Only;
+ Output_Is_Object := Running_Compile (J).Output_Is_Object;
+ Project := Running_Compile (J).Project;
+
+ -- If a mapping file was used by this compilation,
+ -- get its file name for reuse by a subsequent compilation
+
+ if Running_Compile (J).Mapping_File /= No_Mapping_File then
+ Last_Free_Indices (Project) :=
+ Last_Free_Indices (Project) + 1;
+ The_Free_Mapping_File_Indices
+ (Project, Last_Free_Indices (Project)) :=
+ Running_Compile (J).Mapping_File;
+ end if;
- if Running_Compile (J).Use_Mapping_File then
- Last_Mapping_File_Name := Last_Mapping_File_Name + 1;
- The_Mapping_File_Names (Last_Mapping_File_Name) :=
- Running_Compile (J).Mapping_File;
- end if;
+ -- To actually remove this Pid and related info from
+ -- Running_Compile replace its entry with the last valid
+ -- entry in Running_Compile.
- -- To actually remove this Pid and related info from
- -- Running_Compile replace its entry with the last valid
- -- entry in Running_Compile.
+ if J = Outstanding_Compiles then
+ null;
- if J = Outstanding_Compiles then
- null;
+ else
+ Running_Compile (J) :=
+ Running_Compile (Outstanding_Compiles);
+ end if;
- else
- Running_Compile (J) :=
- Running_Compile (Outstanding_Compiles);
+ Outstanding_Compiles := Outstanding_Compiles - 1;
+ return;
end if;
+ end loop;
- Outstanding_Compiles := Outstanding_Compiles - 1;
- return;
- end if;
- end loop;
+ -- This child process was not one of our compilation processes;
+ -- just ignore it for now.
- raise Program_Error;
+ -- raise Program_Error;
+ end loop;
end Await_Compile;
---------------------------
@@ -1556,251 +2128,77 @@ package body Make is
procedure Collect_Arguments_And_Compile (Source_File : File_Name_Type) is
begin
- -- If we use mapping file (-P or -C switches), then get one
+ -- If arguments have not yet been collected (in Check), collect them
+ -- now.
- if Create_Mapping_File then
- Get_Mapping_File;
+ if not Arguments_Collected then
+ Collect_Arguments (Source_File, Args);
end if;
- -- If no project file is used, then just call Compile with
- -- the specified Args.
-
- if Main_Project = No_Project then
- Pid := Compile (Full_Source_File, Lib_File, Args);
-
- -- A project file was used
-
- else
- -- First check if the current source is an immediate
- -- source of a project file.
-
- if Opt.Verbose_Mode then
- Write_Eol;
- Write_Line ("Establishing Project context.");
- end if;
-
- declare
- Source_File_Name : constant String :=
- Get_Name_String (Source_File);
- Current_Project : Prj.Project_Id;
- Path_Name : File_Name_Type := Source_File;
- Compiler_Package : Prj.Package_Id;
- Switches : Prj.Variable_Value;
- Object_File : String_Access;
-
- begin
- if Opt.Verbose_Mode then
- Write_Str ("Checking if the Project File exists for """);
- Write_Str (Source_File_Name);
- Write_Line (""".");
- end if;
-
- Prj.Env.
- Get_Reference
- (Source_File_Name => Source_File_Name,
- Project => Current_Project,
- Path => Path_Name);
-
- if Current_Project = No_Project then
-
- -- The current source is not an immediate source of any
- -- project file. Call Compile with the specified Args plus
- -- the saved gcc switches.
-
- if Opt.Verbose_Mode then
- Write_Str ("No Project File.");
- Write_Eol;
- end if;
-
- Pid := Compile
- (Full_Source_File,
- Lib_File,
- Args & The_Saved_Gcc_Switches.all);
-
- -- We now know the project of the current source
-
- else
- -- Set ADA_INCLUDE_PATH and ADA_OBJECTS_PATH if the project
- -- has changed.
+ -- If we use mapping file (-P or -C switches), then get one
- -- Note: this will modify these environment variables only
- -- for the current gnatmake process and all of its children
- -- (invocations of the compiler, the binder and the linker).
+ if Create_Mapping_File then
+ Get_Mapping_File (Arguments_Project);
+ end if;
- -- The caller's ADA_INCLUDE_PATH and ADA_OBJECTS_PATH are
- -- not affected.
+ -- If the source is part of a project file, we set the ADA_*_PATHs,
+ -- check for an eventual library project, and use the full path.
- Set_Ada_Paths (Current_Project, True);
+ if Arguments_Project /= No_Project then
+ Prj.Env.Set_Ada_Paths (Arguments_Project, True);
- Data := Projects.Table (Current_Project);
+ if MLib.Tgt.Support_For_Libraries /= MLib.Tgt.None then
+ declare
+ The_Data : Project_Data :=
+ Projects.Table (Arguments_Project);
+ Prj : Project_Id := Arguments_Project;
- -- Check if it is a library project that needs to be
- -- processed, only if it is not the main project.
+ begin
+ while The_Data.Extended_By /= No_Project loop
+ Prj := The_Data.Extended_By;
+ The_Data := Projects.Table (Prj);
+ end loop;
- if MLib.Tgt.Libraries_Are_Supported
- and then Current_Project /= Main_Project
- and then Data.Library
- and then not Data.Flag1
- then
- -- Add to the Q all sources of the project that have
- -- not been marked
+ if The_Data.Library and then not The_Data.Flag1 then
+ -- Add to the Q all sources of the project that
+ -- have not been marked
Insert_Project_Sources
- (The_Project => Current_Project, Into_Q => True);
+ (The_Project => Prj,
+ All_Projects => False,
+ Into_Q => True);
-- Now mark the project as processed
- Data.Flag1 := True;
- Projects.Table (Current_Project).Flag1 := True;
- end if;
-
- Get_Name_String (Data.Object_Directory);
-
- if Name_Buffer (Name_Len) = '/'
- or else Name_Buffer (Name_Len) = Directory_Separator
- then
- Object_File :=
- new String'
- (Name_Buffer (1 .. Name_Len) &
- Object_File_Name (Source_File_Name));
-
- else
- Object_File :=
- new String'
- (Name_Buffer (1 .. Name_Len) &
- Directory_Separator &
- Object_File_Name (Source_File_Name));
+ Projects.Table (Prj).Flag1 := True;
end if;
+ end;
+ end if;
- if Opt.Verbose_Mode then
- Write_Str ("Project file is """);
- Write_Str (Get_Name_String (Data.Name));
- Write_Str (""".");
- Write_Eol;
- end if;
-
- -- We know look for package Compiler
- -- and get the switches from this package.
-
- if Opt.Verbose_Mode then
- Write_Str ("Checking package Compiler.");
- Write_Eol;
- end if;
-
- Compiler_Package :=
- Prj.Util.Value_Of
- (Name => Name_Compiler,
- In_Packages => Data.Decl.Packages);
-
- if Compiler_Package /= No_Package then
-
- if Opt.Verbose_Mode then
- Write_Str ("Getting the switches.");
- Write_Eol;
- end if;
-
- -- If package Gnatmake.Compiler exists, we get
- -- the specific switches for the current source,
- -- or the global switches, if any.
-
- Switches := Switches_Of
- (Source_File => Source_File,
- Source_File_Name => Source_File_Name,
- Naming =>
- Projects.Table (Current_Project).Naming,
- In_Package => Compiler_Package,
- Allow_ALI => False);
-
- end if;
-
- case Switches.Kind is
-
- -- We have a list of switches. We add to Args
- -- these switches, plus the saved gcc switches.
-
- when List =>
-
- declare
- Current : String_List_Id := Switches.Values;
- Element : String_Element;
- Number : Natural := 0;
-
- begin
- while Current /= Nil_String loop
- Element := String_Elements.Table (Current);
- Number := Number + 1;
- Current := Element.Next;
- end loop;
-
- declare
- New_Args : Argument_List (1 .. Number);
-
- begin
- Current := Switches.Values;
-
- for Index in New_Args'Range loop
- Element := String_Elements.Table (Current);
- String_To_Name_Buffer (Element.Value);
- New_Args (Index) :=
- new String' (Name_Buffer (1 .. Name_Len));
- Test_If_Relative_Path
- (New_Args (Index), Parent => null);
- Current := Element.Next;
- end loop;
-
- Pid := Compile
- (Path_Name,
- Lib_File,
- Args & Output_Flag & Object_File &
- Configuration_Pragmas_Switch
- (Current_Project) &
- New_Args & The_Saved_Gcc_Switches.all);
- end;
- end;
-
- -- We have a single switch. We add to Args
- -- this switch, plus the saved gcc switches.
-
- when Single =>
- String_To_Name_Buffer (Switches.Value);
+ -- Change to the object directory of the project file, if it is
+ -- not the main project file.
- declare
- New_Args : Argument_List :=
- (1 => new String'
- (Name_Buffer (1 .. Name_Len)));
+ if Arguments_Project /= Main_Project then
+ Change_Dir
+ (Get_Name_String
+ (Projects.Table (Arguments_Project).Object_Directory));
+ end if;
- begin
- Test_If_Relative_Path
- (New_Args (1), Parent => null);
- Pid := Compile
- (Path_Name,
- Lib_File,
- Args &
- Output_Flag &
- Object_File &
- New_Args &
- Configuration_Pragmas_Switch (Current_Project) &
- The_Saved_Gcc_Switches.all);
- end;
+ Pid := Compile (Arguments_Path_Name, Lib_File,
+ Arguments (1 .. Last_Argument));
- -- We have no switches from Gnatmake.Compiler.
- -- We add to Args the saved gcc switches.
+ -- Change back to the object directory of the main project file,
+ -- if necessary.
- when Undefined =>
- if Opt.Verbose_Mode then
- Write_Str ("There are no switches.");
- Write_Eol;
- end if;
+ if Arguments_Project /= Main_Project then
+ Change_Dir
+ (Get_Name_String
+ (Projects.Table (Main_Project).Object_Directory));
+ end if;
- Pid := Compile
- (Path_Name,
- Lib_File,
- Args & Output_Flag & Object_File &
- Configuration_Pragmas_Switch (Current_Project) &
- The_Saved_Gcc_Switches.all);
- end case;
- end if;
- end;
+ else
+ Pid := Compile (Full_Source_File, Lib_File,
+ Arguments (1 .. Last_Argument));
end if;
end Collect_Arguments_And_Compile;
@@ -1808,8 +2206,8 @@ package body Make is
-- Compile --
-------------
- function Compile (S : Name_Id; L : Name_Id; Args : Argument_List)
- return Process_Id
+ function Compile
+ (S : Name_Id; L : Name_Id; Args : Argument_List) return Process_Id
is
Comp_Args : Argument_List (Args'First .. Args'Last + 8);
Comp_Next : Integer := Args'First;
@@ -1837,6 +2235,8 @@ package body Make is
-- Start of processing for Compile
begin
+ Enter_Into_Obsoleted (S);
+
-- By default, Syntax_Only is False
Syntax_Only := False;
@@ -1856,7 +2256,7 @@ package body Make is
elsif Args (J).all = "-gnatc" then
-- If we compile with -gnatc, the bind step and the link step
- -- are inhibited. We set Syntax_Only to True for the case when
+ -- are inhibited. We set Syntax_Only to False for the case when
-- -gnats was previously specified.
Do_Bind_Step := False;
@@ -1899,10 +2299,11 @@ package body Make is
Comp_Args (Comp_Last) := GNAT_Flag;
else
- Fail
+ Make_Failed
("not allowed to compile """ &
Get_Name_String (Fname) &
- """; use -a switch.");
+ """; use -a switch, or compile file with " &
+ """-gnatg"" switch");
end if;
end if;
end;
@@ -1911,14 +2312,14 @@ package body Make is
-- the gcc driver. If this is not the case then add the ada flag
-- "-x ada".
- if not Ada_File_Name (S) then
+ if not Ada_File_Name (S) and then not Targparm.AAMP_On_Target then
Comp_Last := Comp_Last + 1;
Comp_Args (Comp_Last) := Ada_Flag_1;
Comp_Last := Comp_Last + 1;
Comp_Args (Comp_Last) := Ada_Flag_2;
end if;
- if L /= Strip_Directory (L) then
+ if L /= Strip_Directory (L) or else Object_Directory_Path /= null then
-- Build -o argument.
@@ -1935,7 +2336,19 @@ package body Make is
Comp_Last := Comp_Last + 1;
Comp_Args (Comp_Last) := Output_Flag;
Comp_Last := Comp_Last + 1;
- Comp_Args (Comp_Last) := new String'(Name_Buffer (1 .. Name_Len));
+
+ -- If an object directory was specified, prepend the object file
+ -- name with this object directory.
+
+ if Object_Directory_Path /= null then
+ Comp_Args (Comp_Last) :=
+ new String'(Object_Directory_Path.all &
+ Name_Buffer (1 .. Name_Len));
+
+ else
+ Comp_Args (Comp_Last) :=
+ new String'(Name_Buffer (1 .. Name_Len));
+ end if;
end if;
if Create_Mapping_File then
@@ -1953,7 +2366,7 @@ package body Make is
Display (Gcc.all, Comp_Args (Args'First .. Comp_Last));
if Gcc_Path = null then
- Osint.Fail ("error, unable to locate " & Gcc.all);
+ Make_Failed ("error, unable to locate ", Gcc.all);
end if;
return
@@ -1961,65 +2374,33 @@ package body Make is
(Gcc_Path.all, Comp_Args (Args'First .. Comp_Last));
end Compile;
- ----------------------------------
- -- Configuration_Pragmas_Switch --
- ----------------------------------
-
- function Configuration_Pragmas_Switch
- (For_Project : Project_Id)
- return Argument_List
- is
- begin
- Prj.Env.Create_Config_Pragmas_File (For_Project, Main_Project);
-
- if Projects.Table (For_Project).Config_File_Name /= No_Name then
- return
- (1 => new String'("-gnatec" &
- Get_Name_String
- (Projects.Table (For_Project).Config_File_Name)));
-
- else
- return (1 .. 0 => null);
- end if;
- end Configuration_Pragmas_Switch;
-
- ---------------
- -- Debug_Msg --
- ---------------
-
- procedure Debug_Msg (S : String; N : Name_Id) is
- begin
- if Debug.Debug_Flag_W then
- Write_Str (" ... ");
- Write_Str (S);
- Write_Str (" ");
- Write_Name (N);
- Write_Eol;
- end if;
- end Debug_Msg;
-
----------------------
-- Get_Mapping_File --
----------------------
- procedure Get_Mapping_File is
+ procedure Get_Mapping_File (Project : Project_Id) is
begin
-- If there is a mapping file ready to be reused, reuse it
- if Last_Mapping_File_Name > 0 then
- Mfile := The_Mapping_File_Names (Last_Mapping_File_Name);
- Last_Mapping_File_Name := Last_Mapping_File_Name - 1;
+ if Last_Free_Indices (Project) > 0 then
+ Mfile := The_Free_Mapping_File_Indices
+ (Project, Last_Free_Indices (Project));
+ Last_Free_Indices (Project) := Last_Free_Indices (Project) - 1;
-- Otherwise, create and initialize a new one
else
- Init_Mapping_File (File_Name => Mfile);
+ Init_Mapping_File (Project => Project, File_Index => Mfile);
end if;
-- Put the name in the mapping file argument for the invocation
-- of the compiler.
- Mapping_File_Arg (8 .. Mapping_File_Arg'Last) := Mfile;
+ Free (Mapping_File_Arg);
+ Mapping_File_Arg :=
+ new String'("-gnatem=" &
+ Get_Name_String
+ (The_Mapping_File_Names (Project, Mfile)));
end Get_Mapping_File;
@@ -2079,7 +2460,10 @@ package body Make is
Good_ALI.Init;
Output.Set_Standard_Error;
- Init_Q;
+
+ if First_Q_Initialization then
+ Init_Q;
+ end if;
if Initialize_ALI_Data then
Initialize_ALI;
@@ -2096,18 +2480,13 @@ package body Make is
Opt.Check_Source_Files := True;
Opt.All_Sources := False;
- -- If the main source is marked, there is nothing to compile.
- -- This can happen when we have several main subprograms.
- -- For the first main, we always insert in the Q.
-
- if not Is_Marked (Main_Source) then
- Insert_Q (Main_Source);
- Mark (Main_Source);
- end if;
+ Insert_Q (Main_Source);
+ Mark (Main_Source);
- First_Compiled_File := No_File;
- Most_Recent_Obj_File := No_File;
- Main_Unit := False;
+ First_Compiled_File := No_File;
+ Most_Recent_Obj_File := No_File;
+ Most_Recent_Obj_Stamp := Empty_Time_Stamp;
+ Main_Unit := False;
-- Keep looping until there is no more work to do (the Q is empty)
-- and all the outstanding compilations have terminated
@@ -2140,6 +2519,13 @@ package body Make is
Lib_File := Osint.Lib_File_Name (Source_File);
Full_Lib_File := Osint.Full_Lib_File_Name (Lib_File);
+ -- If this source has already been compiled, the executable is
+ -- obsolete.
+
+ if Is_In_Obsoleted (Source_File) then
+ Executable_Obsolete := True;
+ end if;
+
-- If the library file is an Ada library skip it
if Full_Lib_File /= No_File
@@ -2147,11 +2533,15 @@ package body Make is
then
Verbose_Msg (Lib_File, "is in an Ada library", Prefix => " ");
- -- If the library file is a read-only library skip it
+ -- If the library file is a read-only library skip it, but only
+ -- if, when using project files, this library file is in the
+ -- right object directory (a read-only ALI file in the object
+ -- directory of a project being extended should not be skipped).
elsif Full_Lib_File /= No_File
and then not Check_Readonly_Files
and then Is_Readonly_Library (Full_Lib_File)
+ and then Is_In_Object_Directory (Source_File, Full_Lib_File)
then
Verbose_Msg
(Lib_File, "is a read-only library", Prefix => " ");
@@ -2173,7 +2563,8 @@ package body Make is
Fail
("not allowed to compile """ &
Get_Name_String (Source_File) &
- """; use -a switch.");
+ """; use -a switch, or compile file with " &
+ """-gnatg"" switch");
end if;
Verbose_Msg
@@ -2182,13 +2573,20 @@ package body Make is
-- The source file that we are checking can be located
else
+ Arguments_Collected := False;
+
-- Don't waste any time if we have to recompile anyway
Obj_Stamp := Empty_Time_Stamp;
Need_To_Compile := Force_Compilations;
if not Force_Compilations then
- Check (Lib_File, ALI, Obj_File, Obj_Stamp);
+ Read_Only :=
+ Full_Lib_File /= No_File
+ and then not Check_Readonly_Files
+ and then Is_Readonly_Library (Full_Lib_File);
+ Check (Source_File, Args, Lib_File, Read_Only,
+ ALI, Obj_File, Obj_Stamp);
Need_To_Compile := (ALI = No_ALI_Id);
end if;
@@ -2248,10 +2646,6 @@ package body Make is
end if;
- -- Check for special compilation flags
-
- Arg_Index := 0;
-
-- Start the compilation and record it. We can do this
-- because there is at least one free process.
@@ -2267,8 +2661,7 @@ package body Make is
Full_Source_File,
Lib_File,
Source_Unit,
- Mfile,
- Create_Mapping_File);
+ Mfile);
end if;
end if;
end if;
@@ -2300,11 +2693,14 @@ package body Make is
Opt.Check_Object_Consistency;
begin
- -- If compilation was not OK, don't check object
- -- consistency.
+ -- If compilation was not OK, or if output is not an
+ -- object file and we don't do the bind step, don't check
+ -- for object consistency.
Opt.Check_Object_Consistency :=
- Opt.Check_Object_Consistency and Compilation_OK;
+ Opt.Check_Object_Consistency
+ and Compilation_OK
+ and (Output_Is_Object or Do_Bind_Step);
Text := Read_Library_Info (Lib_File);
-- Restore Check_Object_Consistency to its initial value
@@ -2312,8 +2708,8 @@ package body Make is
Opt.Check_Object_Consistency := Saved_Object_Consistency;
end;
- -- If no ALI file was generated by this compilation nothing
- -- more to do, otherwise scan the ali file and record it.
+ -- If an ALI file was generated by this compilation, scan
+ -- the ALI file and record it.
-- If the scan fails, a previous ali file is inconsistent with
-- the unit just compiled.
@@ -2355,12 +2751,10 @@ package body Make is
end if;
end if;
- exit Make_Loop when Unique_Compile;
-
-- PHASE 3: Check if we recorded good ALI files. If yes process
-- them now in the order in which they have been recorded. There
-- are two occasions in which we record good ali files. The first is
- -- in phase 1 when, after scanning an existing ALI file we realise
+ -- in phase 1 when, after scanning an existing ALI file we realize
-- it is up-to-date, the second instance is after a successful
-- compilation.
@@ -2377,8 +2771,9 @@ package body Make is
-- The following adds the standard library (s-stalib) to the
-- list of files to be handled by gnatmake: this file and any
-- files it depends on are always included in every bind,
- -- except in No_Run_Time mode, even if they are not
- -- in the explicit dependency list.
+ -- even if they are not in the explicit dependency list.
+ -- Of course, it is not added if Suppress_Standard_Library
+ -- is True.
-- However, to avoid annoying output about s-stalib.ali being
-- read only, when "-v" is used, we add the standard library
@@ -2387,7 +2782,7 @@ package body Make is
if Need_To_Check_Standard_Library then
Need_To_Check_Standard_Library := False;
- if not ALIs.Table (ALI).No_Run_Time then
+ if not Targparm.Suppress_Standard_Library_On_Target then
declare
Sfile : Name_Id;
Add_It : Boolean := True;
@@ -2405,43 +2800,57 @@ package body Make is
Add_It := Find_File (Sfile, Osint.Source) /= No_File;
end if;
- if Add_It and then not Is_Marked (Sfile) then
- Insert_Q (Sfile);
- Mark (Sfile);
+ if Add_It then
+ if Is_Marked (Sfile) then
+ if Is_In_Obsoleted (Sfile) then
+ Executable_Obsolete := True;
+ end if;
+
+ else
+ Insert_Q (Sfile);
+ Mark (Sfile);
+ end if;
end if;
end;
end if;
end if;
-- Now insert in the Q the unmarked source files (i.e. those
- -- which have neever been inserted in the Q and hence never
- -- considered).
+ -- which have never been inserted in the Q and hence never
+ -- considered). Only do that if Unique_Compile is False.
- for J in
- ALIs.Table (ALI).First_Unit .. ALIs.Table (ALI).Last_Unit
- loop
- for K in
- Units.Table (J).First_With .. Units.Table (J).Last_With
+ if not Unique_Compile then
+ for J in
+ ALIs.Table (ALI).First_Unit .. ALIs.Table (ALI).Last_Unit
loop
- Sfile := Withs.Table (K).Sfile;
+ for K in
+ Units.Table (J).First_With .. Units.Table (J).Last_With
+ loop
+ Sfile := Withs.Table (K).Sfile;
+ Add_Dependency (ALIs.Table (ALI).Sfile, Sfile);
- if Sfile = No_File then
- Debug_Msg ("Skipping generic:", Withs.Table (K).Uname);
+ if Is_In_Obsoleted (Sfile) then
+ Executable_Obsolete := True;
+ end if;
- elsif Is_Marked (Sfile) then
- Debug_Msg ("Skipping marked file:", Sfile);
+ if Sfile = No_File then
+ Debug_Msg ("Skipping generic:", Withs.Table (K).Uname);
- elsif not Check_Readonly_Files
- and then Is_Internal_File_Name (Sfile)
- then
- Debug_Msg ("Skipping internal file:", Sfile);
+ elsif Is_Marked (Sfile) then
+ Debug_Msg ("Skipping marked file:", Sfile);
- else
- Insert_Q (Sfile, Withs.Table (K).Uname);
- Mark (Sfile);
- end if;
+ elsif not Check_Readonly_Files
+ and then Is_Internal_File_Name (Sfile)
+ then
+ Debug_Msg ("Skipping internal file:", Sfile);
+
+ else
+ Insert_Q (Sfile, Withs.Table (K).Uname);
+ Mark (Sfile);
+ end if;
+ end loop;
end loop;
- end loop;
+ end if;
end loop;
if Opt.Display_Compilation_Progress then
@@ -2462,38 +2871,185 @@ package body Make is
-- Delete any temporary configuration pragma file
- if Main_Project /= No_Project then
+ Delete_Temp_Config_Files;
+
+ end Compile_Sources;
+
+ ----------------------------------
+ -- Configuration_Pragmas_Switch --
+ ----------------------------------
+
+ function Configuration_Pragmas_Switch
+ (For_Project : Project_Id) return Argument_List
+ is
+ The_Packages : Package_Id;
+ Gnatmake : Package_Id;
+ Compiler : Package_Id;
+
+ Global_Attribute : Variable_Value := Nil_Variable_Value;
+ Local_Attribute : Variable_Value := Nil_Variable_Value;
+
+ Global_Attribute_Present : Boolean := False;
+ Local_Attribute_Present : Boolean := False;
+
+ Result : Argument_List (1 .. 3);
+ Last : Natural := 0;
+
+ function Absolute_Path
+ (Path : Name_Id;
+ Project : Project_Id) return String;
+ -- Returns an absolute path for a configuration pragmas file.
+
+ -------------------
+ -- Absolute_Path --
+ -------------------
+
+ function Absolute_Path
+ (Path : Name_Id;
+ Project : Project_Id) return String
+ is
+ begin
+ Get_Name_String (Path);
+
declare
- Success : Boolean;
+ Path_Name : constant String := Name_Buffer (1 .. Name_Len);
begin
- for Project in 1 .. Projects.Last loop
- if Projects.Table (Project).Config_File_Temp then
- if Opt.Verbose_Mode then
- Write_Str ("Deleting temp configuration file """);
- Write_Str (Get_Name_String
- (Projects.Table (Project).Config_File_Name));
- Write_Line ("""");
+ if Is_Absolute_Path (Path_Name) then
+ return Path_Name;
+
+ else
+ declare
+ Parent_Directory : constant String :=
+ Get_Name_String (Projects.Table (Project).Directory);
+
+ begin
+ if Parent_Directory (Parent_Directory'Last) =
+ Directory_Separator
+ then
+ return Parent_Directory & Path_Name;
+
+ else
+ return Parent_Directory & Directory_Separator & Path_Name;
end if;
+ end;
+ end if;
+ end;
+ end Absolute_Path;
- Delete_File
- (Name => Get_Name_String
- (Projects.Table (Project).Config_File_Name),
- Success => Success);
+ -- Start of processing for Configuration_Pragmas_Switch
+
+ begin
+ Prj.Env.Create_Config_Pragmas_File (For_Project, Main_Project);
+
+ if Projects.Table (For_Project).Config_File_Name /= No_Name then
+ Temporary_Config_File :=
+ Projects.Table (For_Project).Config_File_Temp;
+ Last := 1;
+ Result (1) :=
+ new String'
+ ("-gnatec=" &
+ Get_Name_String
+ (Projects.Table (For_Project).Config_File_Name));
+
+ else
+ Temporary_Config_File := False;
+ end if;
+
+ -- Check for attribute Builder'Global_Configuration_Pragmas
+
+ The_Packages := Projects.Table (Main_Project).Decl.Packages;
+ Gnatmake :=
+ Prj.Util.Value_Of
+ (Name => Name_Builder,
+ In_Packages => The_Packages);
+
+ if Gnatmake /= No_Package then
+ Global_Attribute := Prj.Util.Value_Of
+ (Variable_Name => Name_Global_Configuration_Pragmas,
+ In_Variables => Packages.Table (Gnatmake).Decl.Attributes);
+ Global_Attribute_Present :=
+ Global_Attribute /= Nil_Variable_Value
+ and then Get_Name_String (Global_Attribute.Value) /= "";
+
+ if Global_Attribute_Present then
+ declare
+ Path : constant String :=
+ Absolute_Path (Global_Attribute.Value, Main_Project);
+ begin
+ if not Is_Regular_File (Path) then
+ Make_Failed
+ ("cannot find configuration pragmas file ", Path);
+ end if;
- -- Make sure that we don't have a config file for this
- -- project, in case when there are several mains.
- -- In this case, we will recreate another config file:
- -- we cannot reuse the one that we just deleted!
+ Last := Last + 1;
+ Result (Last) := new String'("-gnatec=" & Path);
+ end;
+ end if;
+ end if;
+
+ -- Check for attribute Compiler'Local_Configuration_Pragmas
- Projects.Table (Project).Config_Checked := False;
- Projects.Table (Project).Config_File_Name := No_Name;
- Projects.Table (Project).Config_File_Temp := False;
+ The_Packages := Projects.Table (For_Project).Decl.Packages;
+ Compiler :=
+ Prj.Util.Value_Of
+ (Name => Name_Compiler,
+ In_Packages => The_Packages);
+
+ if Compiler /= No_Package then
+ Local_Attribute := Prj.Util.Value_Of
+ (Variable_Name => Name_Local_Configuration_Pragmas,
+ In_Variables => Packages.Table (Compiler).Decl.Attributes);
+ Local_Attribute_Present :=
+ Local_Attribute /= Nil_Variable_Value
+ and then Get_Name_String (Local_Attribute.Value) /= "";
+
+ if Local_Attribute_Present then
+ declare
+ Path : constant String :=
+ Absolute_Path (Local_Attribute.Value, For_Project);
+ begin
+ if not Is_Regular_File (Path) then
+ Make_Failed
+ ("cannot find configuration pragmas file ", Path);
end if;
- end loop;
- end;
+
+ Last := Last + 1;
+ Result (Last) := new String'("-gnatec=" & Path);
+ end;
+ end if;
end if;
- end Compile_Sources;
+
+ return Result (1 .. Last);
+ end Configuration_Pragmas_Switch;
+
+ ---------------
+ -- Debug_Msg --
+ ---------------
+
+ procedure Debug_Msg (S : String; N : Name_Id) is
+ begin
+ if Debug.Debug_Flag_W then
+ Write_Str (" ... ");
+ Write_Str (S);
+ Write_Str (" ");
+ Write_Name (N);
+ Write_Eol;
+ end if;
+ end Debug_Msg;
+
+ ---------------------------
+ -- Delete_All_Temp_Files --
+ ---------------------------
+
+ procedure Delete_All_Temp_Files is
+ begin
+ if Gnatmake_Called and not Debug.Debug_Flag_N then
+ Delete_Mapping_Files;
+ Delete_Temp_Config_Files;
+ Prj.Env.Delete_All_Path_Files;
+ end if;
+ end Delete_All_Temp_Files;
--------------------------
-- Delete_Mapping_Files --
@@ -2501,14 +3057,56 @@ package body Make is
procedure Delete_Mapping_Files is
Success : Boolean;
-
begin
- for Index in 1 .. Last_Mapping_File_Name loop
- Delete_File
- (Name => The_Mapping_File_Names (Index), Success => Success);
- end loop;
+ if not Debug.Debug_Flag_N then
+ if The_Mapping_File_Names /= null then
+ for Project in The_Mapping_File_Names'Range (1) loop
+ for Index in 1 .. Last_Mapping_File_Names (Project) loop
+ Delete_File
+ (Name => Get_Name_String
+ (The_Mapping_File_Names (Project, Index)),
+ Success => Success);
+ end loop;
+ end loop;
+ end if;
+ end if;
end Delete_Mapping_Files;
+ ------------------------------
+ -- Delete_Temp_Config_Files --
+ ------------------------------
+
+ procedure Delete_Temp_Config_Files is
+ Success : Boolean;
+ begin
+ if (not Debug.Debug_Flag_N) and Main_Project /= No_Project then
+ for Project in 1 .. Projects.Last loop
+ if Projects.Table (Project).Config_File_Temp then
+ if Opt.Verbose_Mode then
+ Write_Str ("Deleting temp configuration file """);
+ Write_Str (Get_Name_String
+ (Projects.Table (Project).Config_File_Name));
+ Write_Line ("""");
+ end if;
+
+ Delete_File
+ (Name => Get_Name_String
+ (Projects.Table (Project).Config_File_Name),
+ Success => Success);
+
+ -- Make sure that we don't have a config file for this
+ -- project, in case when there are several mains.
+ -- In this case, we will recreate another config file:
+ -- we cannot reuse the one that we just deleted!
+
+ Projects.Table (Project).Config_Checked := False;
+ Projects.Table (Project).Config_File_Name := No_Name;
+ Projects.Table (Project).Config_File_Temp := False;
+ end if;
+ end loop;
+ end if;
+ end Delete_Temp_Config_Files;
+
-------------
-- Display --
-------------
@@ -2526,12 +3124,36 @@ package body Make is
-- created when using a project file.
if Main_Project = No_Project
- or else Args (J)'Length /= 7 + Temp_File_Name'Length
- or else Args (J)'First /= 1
- or else Args (J)(1 .. 7) /= "-gnatem"
+ or else Debug.Debug_Flag_N
+ or else Args (J)'Length < 8
+ or else
+ Args (J)(Args (J)'First .. Args (J)'First + 6) /= "-gnatem"
then
- Write_Str (" ");
- Write_Str (Args (J).all);
+ -- When -dn is not specified, do not display the config
+ -- pragmas switch (-gnatec) for the temporary file created
+ -- by the project manager (always the first -gnatec switch).
+ -- Reset Temporary_Config_File to False so that the eventual
+ -- other -gnatec switches will be displayed.
+
+ if (not Debug.Debug_Flag_N)
+ and then Temporary_Config_File
+ and then Args (J)'Length > 7
+ and then Args (J)(Args (J)'First .. Args (J)'First + 6)
+ = "-gnatec"
+ then
+ Temporary_Config_File := False;
+
+ -- Do not display the -F=mapping_file switch for gnatbind,
+ -- if -dn is not specified.
+
+ elsif Debug.Debug_Flag_N
+ or else Args (J)'Length < 4
+ or else Args (J)(Args (J)'First .. Args (J)'First + 2) /=
+ "-F="
+ then
+ Write_Str (" ");
+ Write_Str (Args (J).all);
+ end if;
end if;
end loop;
@@ -2571,6 +3193,33 @@ package body Make is
return Q_Front >= Q.Last;
end Empty_Q;
+ --------------------------
+ -- Enter_Into_Obsoleted --
+ --------------------------
+
+ procedure Enter_Into_Obsoleted (F : Name_Id) is
+ Name : String := Get_Name_String (F);
+ First : Natural := Name'Last;
+ F2 : Name_Id := F;
+
+ begin
+ while First > Name'First
+ and then Name (First - 1) /= Directory_Separator
+ and then Name (First - 1) /= '/'
+ loop
+ First := First - 1;
+ end loop;
+
+ if First /= Name'First then
+ Name_Len := 0;
+ Add_Str_To_Name_Buffer (Name (First .. Name'Last));
+ F2 := Name_Find;
+ end if;
+
+ Debug_Msg ("New entry in Obsoleted table:", F2);
+ Obsoleted.Set (F2, True);
+ end Enter_Into_Obsoleted;
+
---------------------
-- Extract_Failure --
---------------------
@@ -2611,6 +3260,16 @@ package body Make is
Source_Unit := Unit;
end Extract_From_Q;
+ -----------------
+ -- Make_Failed --
+ -----------------
+
+ procedure Make_Failed (S1 : String; S2 : String := ""; S3 : String := "") is
+ begin
+ Delete_All_Temp_Files;
+ Osint.Fail (S1, S2, S3);
+ end Make_Failed;
+
--------------
-- Gnatmake --
--------------
@@ -2637,28 +3296,34 @@ package body Make is
-- Non_Std_Executable is set to True when there is a possibility
-- that the linker will not choose the correct executable file name.
- Executable_Obsolete : Boolean := False;
- -- Executable_Obsolete is set to True for the first obsolete main
- -- and is never reset to False. Any subsequent main will always
- -- be rebuild (if we rebuild mains), even in the case when it is not
- -- really necessary, because it is too hard to decide.
-
Current_Work_Dir : constant String_Access :=
new String'(Get_Current_Dir);
-- The current working directory, used to modify some relative path
-- switches on the command line when a project file is used.
begin
+ Gnatmake_Called := True;
+
+ Install_Int_Handler (Sigint_Intercepted'Access);
+
Do_Compile_Step := True;
Do_Bind_Step := True;
Do_Link_Step := True;
+ Obsoleted.Reset;
+
Make.Initialize;
+ Bind_Shared := No_Shared_Switch'Access;
+ Bind_Shared_Known := False;
+
+ Failed_Links.Set_Last (0);
+ Successful_Links.Set_Last (0);
+
if Hostparm.Java_VM then
Gcc := new String'("jgnat");
Gnatbind := new String'("jgnatbind");
- Gnatlink := new String '("jgnatlink");
+ Gnatlink := new String'("jgnatlink");
-- Do not check for an object file (".o") when compiling to
-- Java bytecode since ".class" files are generated instead.
@@ -2666,85 +3331,111 @@ package body Make is
Opt.Check_Object_Consistency := False;
end if;
- if Opt.Verbose_Mode then
- Targparm.Get_Target_Parameters;
+ if Main_Project /= No_Project then
- Write_Eol;
- Write_Str ("GNATMAKE ");
+ -- If the main project file is a library project file, main(s)
+ -- cannot be specified on the command line.
- if Targparm.High_Integrity_Mode_On_Target then
- Write_Str ("Pro High Integrity ");
- end if;
+ if Osint.Number_Of_Files /= 0 then
+ if Projects.Table (Main_Project).Library then
+ Make_Failed ("cannot specify a main program " &
+ "on the command line for a library project file");
+ end if;
- Write_Str (Gnatvsn.Gnat_Version_String);
- Write_Str (" Copyright 1995-2002 Free Software Foundation, Inc.");
- Write_Eol;
- end if;
+ -- If no mains have been specified on the command line,
+ -- and we are using a project file, we either find the main(s)
+ -- in the attribute Main of the main project, or we put all
+ -- the sources of the project file as mains.
- -- If no mains have been specified on the command line,
- -- and we are using a project file, we either find the main(s)
- -- in the attribute Main of the main project, or we put all
- -- the sources of the project file as mains.
+ else
+ declare
+ Value : String_List_Id := Projects.Table (Main_Project).Mains;
- if Main_Project /= No_Project and then Osint.Number_Of_Files = 0 then
- Name_Len := 4;
- Name_Buffer (1 .. 4) := "main";
+ begin
+ -- The attribute Main is an empty list or not specified,
+ -- or else gnatmake was invoked with the switch "-u".
- declare
- Main_Id : constant Name_Id := Name_Find;
+ if Value = Prj.Nil_String or else Unique_Compile then
- Mains : constant Prj.Variable_Value :=
- Prj.Util.Value_Of
- (Variable_Name => Main_Id,
- In_Variables =>
- Projects.Table (Main_Project).Decl.Attributes);
+ if (not Make_Steps) or else Compile_Only
+ or else not Projects.Table (Main_Project).Library
+ then
+ -- First make sure that the binder and the linker
+ -- will not be invoked.
- Value : String_List_Id := Mains.Values;
+ Do_Bind_Step := False;
+ Do_Link_Step := False;
- begin
- -- The attribute Main is an empty list or not specified,
- -- or else gnatmake was invoked with the switch "-u".
+ -- Put all the sources in the queue
- if Value = Prj.Nil_String or else Unique_Compile then
+ Insert_Project_Sources
+ (The_Project => Main_Project,
+ All_Projects => Unique_Compile_All_Projects,
+ Into_Q => False);
- -- First make sure that the binder and the linker
- -- will not be invoked.
+ -- If there are no sources to compile, we fail
- Do_Bind_Step := False;
- Do_Link_Step := False;
+ if Osint.Number_Of_Files = 0 then
+ Make_Failed ("no sources to compile");
+ end if;
+ end if;
- -- Set Unique_Compile if it was not already set
+ else
+ -- The attribute Main is not an empty list.
+ -- Put all the main subprograms in the list as if there
+ -- were specified on the command line.
+
+ while Value /= Prj.Nil_String loop
+ Get_Name_String (String_Elements.Table (Value).Value);
+ Osint.Add_File (Name_Buffer (1 .. Name_Len));
+ Value := String_Elements.Table (Value).Next;
+ end loop;
- Unique_Compile := True;
+ end if;
+ end;
+ end if;
+ end if;
- -- Put all the sources in the queue
+ if Opt.Verbose_Mode then
+ Write_Eol;
+ Write_Str ("GNATMAKE ");
+ Write_Str (Gnatvsn.Gnat_Version_String);
+ Write_Str (" Copyright 1995-2003 Free Software Foundation, Inc.");
+ Write_Eol;
+ end if;
- Insert_Project_Sources
- (The_Project => Main_Project, Into_Q => False);
+ if Osint.Number_Of_Files = 0 then
+ if Main_Project /= No_Project
+ and then Projects.Table (Main_Project).Library
+ then
+ if Do_Bind_Step
+ and then not Projects.Table (Main_Project).Standalone_Library
+ then
+ Make_Failed ("only stand-alone libraries may be bound");
+ end if;
- else
- -- The attribute Main is not an empty list.
- -- Put all the main subprograms in the list as if there were
- -- specified on the command line.
-
- while Value /= Prj.Nil_String loop
- String_To_Name_Buffer (String_Elements.Table (Value).Value);
- Osint.Add_File (Name_Buffer (1 .. Name_Len));
- Value := String_Elements.Table (Value).Next;
- end loop;
+ -- Add the default search directories to be able to find libgnat
- end if;
- end;
+ Osint.Add_Default_Search_Dirs;
- end if;
+ -- And bind and or link the library
- -- Output usage information if no files. Note that this can happen
- -- in the case of a project file that contains only subunits.
+ MLib.Prj.Build_Library
+ (For_Project => Main_Project,
+ Gnatbind => Gnatbind.all,
+ Gnatbind_Path => Gnatbind_Path,
+ Gcc => Gcc.all,
+ Gcc_Path => Gcc_Path,
+ Bind => Bind_Only,
+ Link => Link_Only);
+ Exit_Program (E_Success);
- if Osint.Number_Of_Files = 0 then
- Makeusg;
- Exit_Program (E_Fatal);
+ else
+ -- Output usage information if no files to compile
+ Makeusg;
+ Exit_Program (E_Fatal);
+ end if;
end if;
-- If -M was specified, behave as if -n was specified
@@ -2758,10 +3449,10 @@ package body Make is
Main_Source_File := Next_Main_Source;
- if Project_File_Name = null then
- Add_Switch ("-I-", Compiler, And_Save => True);
- Add_Switch ("-I-", Binder, And_Save => True);
+ Add_Switch ("-I-", Binder, And_Save => True);
+ Add_Switch ("-I-", Compiler, And_Save => True);
+ if Main_Project = No_Project then
if Opt.Look_In_Primary_Dir then
Add_Switch
@@ -2788,10 +3479,32 @@ package body Make is
if Main_Project /= No_Project then
- Change_Dir
- (Get_Name_String (Projects.Table (Main_Project).Object_Directory));
+ if Projects.Table (Main_Project).Object_Directory = No_Name then
+ Make_Failed ("no sources to compile");
+ end if;
+
+ -- Change the current directory to the object directory of the main
+ -- project.
+
+ begin
+ Change_Dir
+ (Get_Name_String
+ (Projects.Table (Main_Project).Object_Directory));
+
+ exception
+ when Directory_Error =>
+ Make_Failed ("unable to change working directory to """,
+ Get_Name_String
+ (Projects.Table (Main_Project).Object_Directory),
+ """");
+ end;
+
+ -- Source file lookups should be cached for efficiency.
+ -- Source files are not supposed to change.
- -- Find the file name of the main unit
+ Osint.Source_File_Data (Cache => True);
+
+ -- Find the file name of the (first) main unit
declare
Main_Source_File_Name : constant String :=
@@ -2799,12 +3512,14 @@ package body Make is
Main_Unit_File_Name : constant String :=
Prj.Env.File_Name_Of_Library_Unit_Body
(Name => Main_Source_File_Name,
- Project => Main_Project);
+ Project => Main_Project,
+ Main_Project_Only =>
+ not Unique_Compile);
The_Packages : constant Package_Id :=
Projects.Table (Main_Project).Decl.Packages;
- Gnatmake : constant Prj.Package_Id :=
+ Builder_Package : constant Prj.Package_Id :=
Prj.Util.Value_Of
(Name => Name_Builder,
In_Packages => The_Packages);
@@ -2817,16 +3532,15 @@ package body Make is
Linker_Package : constant Prj.Package_Id :=
Prj.Util.Value_Of
(Name => Name_Linker,
- In_Packages => The_Packages);
+ In_Packages => The_Packages);
begin
-- We fail if we cannot find the main source file
- -- as an immediate source of the main project file.
if Main_Unit_File_Name = "" then
- Fail ('"' & Main_Source_File_Name &
- """ is not a unit of project " &
- Project_File_Name.all & ".");
+ Make_Failed ('"' & Main_Source_File_Name,
+ """ is not a unit of project ",
+ Project_File_Name.all & ".");
else
-- Remove any directory information from the main
-- source file name.
@@ -2860,11 +3574,10 @@ package body Make is
end;
end if;
- -- If there is a package gnatmake in the main project file, add
- -- the switches from it. We also add the switches from packages
- -- gnatbind and gnatlink, if any.
+ -- If there is a package Builder in the main project file, add
+ -- the switches from it.
- if Gnatmake /= No_Package then
+ if Builder_Package /= No_Package then
-- If there is only one main, we attempt to get the gnatmake
-- switches for this main (if any). If there are no specific
@@ -2880,130 +3593,231 @@ package body Make is
Add_Switches
(File_Name => Main_Unit_File_Name,
- The_Package => Gnatmake,
+ The_Package => Builder_Package,
Program => None);
else
-- If there are several mains, we always get the general
-- gnatmake switches (if any).
- -- Note: As there is never a source with name " ",
- -- we are guaranteed to always get the gneneral switches.
+ -- Warn the user, if necessary, so that he is not surprized
+ -- that specific switches are not taken into account.
- Add_Switches
- (File_Name => " ",
- The_Package => Gnatmake,
- Program => None);
- end if;
+ declare
+ Defaults : constant Variable_Value :=
+ Prj.Util.Value_Of
+ (Name => Name_Ada,
+ Attribute_Or_Array_Name => Name_Default_Switches,
+ In_Package => Builder_Package);
+
+ Switches : constant Array_Element_Id :=
+ Prj.Util.Value_Of
+ (Name => Name_Switches,
+ In_Arrays =>
+ Packages.Table (Builder_Package).Decl.Arrays);
+
+ begin
+ if Defaults /= Nil_Variable_Value then
+ if (not Opt.Quiet_Output)
+ and then Switches /= No_Array_Element
+ then
+ Write_Line
+ ("Warning: using Builder'Default_Switches" &
+ "(""Ada""), as there are several mains");
+ end if;
+ -- As there is never a source with name " ", we are
+ -- guaranteed to always get the general switches.
+
+ Add_Switches
+ (File_Name => " ",
+ The_Package => Builder_Package,
+ Program => None);
+
+ elsif (not Opt.Quiet_Output)
+ and then Switches /= No_Array_Element
+ then
+ Write_Line
+ ("Warning: using no switches from package Builder," &
+ " as there are several mains");
+ end if;
+ end;
+ end if;
end if;
- if Binder_Package /= No_Package then
+ Osint.Add_Default_Search_Dirs;
- -- If there is only one main, we attempt to get the gnatbind
- -- switches for this main (if any). If there are no specific
- -- switch for this particular main, get the general gnatbind
- -- switches (if any).
+ -- Record the current last switch index for table Binder_Switches
+ -- and Linker_Switches, so that these tables may be reset before
+ -- for each main, before adding swiches from the project file
+ -- and from the command line.
- if Osint.Number_Of_Files = 1 then
- if Opt.Verbose_Mode then
- Write_Str ("Adding binder switches for """);
- Write_Str (Main_Unit_File_Name);
- Write_Line (""".");
- end if;
+ Last_Binder_Switch := Binder_Switches.Last;
+ Last_Linker_Switch := Linker_Switches.Last;
- Add_Switches
- (File_Name => Main_Unit_File_Name,
- The_Package => Binder_Package,
- Program => Binder);
+ Check_Steps;
- else
- -- If there are several mains, we always get the general
- -- gnatbind switches (if any).
+ -- Add binder switches from the project file for the first main
- -- Note: As there is never a source with name " ",
- -- we are guaranteed to always get the gneneral switches.
+ if Do_Bind_Step and Binder_Package /= No_Package then
+ if Opt.Verbose_Mode then
+ Write_Str ("Adding binder switches for """);
+ Write_Str (Main_Unit_File_Name);
+ Write_Line (""".");
+ end if;
- Add_Switches
- (File_Name => " ",
- The_Package => Binder_Package,
- Program => Binder);
+ Add_Switches
+ (File_Name => Main_Unit_File_Name,
+ The_Package => Binder_Package,
+ Program => Binder);
+ end if;
+
+ -- Add linker switches from the project file for the first main
+
+ if Do_Link_Step and Linker_Package /= No_Package then
+ if Opt.Verbose_Mode then
+ Write_Str ("Adding linker switches for""");
+ Write_Str (Main_Unit_File_Name);
+ Write_Line (""".");
end if;
+ Add_Switches
+ (File_Name => Main_Unit_File_Name,
+ The_Package => Linker_Package,
+ Program => Linker);
end if;
+ end;
+ end if;
- if Linker_Package /= No_Package then
+ -- Get the target parameters, which are only needed for a couple of
+ -- cases in gnatmake. Protect against an exception, such as the case
+ -- of system.ads missing from the library, and fail gracefully.
- -- If there is only one main, we attempt to get the
- -- gnatlink switches for this main (if any). If there are
- -- no specific switch for this particular main, we get the
- -- general gnatlink switches (if any).
+ begin
+ Targparm.Get_Target_Parameters;
- if Osint.Number_Of_Files = 1 then
- if Opt.Verbose_Mode then
- Write_Str ("Adding linker switches for""");
- Write_Str (Main_Unit_File_Name);
- Write_Line (""".");
- end if;
+ exception
+ when Unrecoverable_Error =>
+ Make_Failed ("*** make failed.");
+ end;
- Add_Switches
- (File_Name => Main_Unit_File_Name,
- The_Package => Linker_Package,
- Program => Linker);
+ Display_Commands (not Opt.Quiet_Output);
- else
- -- If there are several mains, we always get the general
- -- gnatlink switches (if any).
+ Check_Steps;
- -- Note: As there is never a source with name " ",
- -- we are guaranteed to always get the general switches.
+ if Main_Project /= No_Project then
- Add_Switches
- (File_Name => " ",
- The_Package => Linker_Package,
- Program => Linker);
+ -- For all library project, if the library file does not exist
+ -- put all the project sources in the queue, and flag the project
+ -- so that the library is generated.
+
+ if MLib.Tgt.Support_For_Libraries /= MLib.Tgt.None then
+ for Proj in Projects.First .. Projects.Last loop
+ if Projects.Table (Proj).Library then
+ Projects.Table (Proj).Flag1 :=
+ not MLib.Tgt.Library_Exists_For (Proj);
+
+ if Projects.Table (Proj).Flag1 then
+ if Opt.Verbose_Mode then
+ Write_Str
+ ("Library file does not exist for project """);
+ Write_Str
+ (Get_Name_String (Projects.Table (Proj).Name));
+ Write_Line ("""");
+ end if;
+
+ Insert_Project_Sources
+ (The_Project => Proj,
+ All_Projects => False,
+ Into_Q => True);
+ end if;
end if;
- end if;
- end;
- end if;
+ end loop;
+ end if;
- Display_Commands (not Opt.Quiet_Output);
+ -- If a relative path output file has been specified, we add
+ -- the exec directory.
- -- If we are using a project file, relative paths are forbidden in the
- -- project file, but we add the current working directory for any
- -- relative path on the command line.
+ for J in reverse 1 .. Saved_Linker_Switches.Last - 1 loop
+ if Saved_Linker_Switches.Table (J).all = Output_Flag.all then
+ declare
+ Exec_File_Name : constant String :=
+ Saved_Linker_Switches.Table (J + 1).all;
- if Main_Project /= No_Project then
+ begin
+ if not Is_Absolute_Path (Exec_File_Name) then
+ for Index in Exec_File_Name'Range loop
+ if Exec_File_Name (Index) = Directory_Separator then
+ Make_Failed ("relative executable (""",
+ Exec_File_Name,
+ """) with directory part not " &
+ "allowed when using project files");
+ end if;
+ end loop;
- for J in 1 .. Binder_Switches.Last loop
- Test_If_Relative_Path
- (Binder_Switches.Table (J), Parent => null);
- end loop;
+ Get_Name_String (Projects.Table
+ (Main_Project).Exec_Directory);
- for J in 1 .. Saved_Binder_Switches.Last loop
- Test_If_Relative_Path
- (Saved_Binder_Switches.Table (J), Parent => Current_Work_Dir);
- end loop;
+ if Name_Buffer (Name_Len) /= Directory_Separator then
+ Name_Len := Name_Len + 1;
+ Name_Buffer (Name_Len) := Directory_Separator;
+ end if;
- for J in 1 .. Linker_Switches.Last loop
- Test_If_Relative_Path
- (Linker_Switches.Table (J), Parent => null);
- end loop;
+ Name_Buffer (Name_Len + 1 ..
+ Name_Len + Exec_File_Name'Length) :=
+ Exec_File_Name;
+ Name_Len := Name_Len + Exec_File_Name'Length;
+ Saved_Linker_Switches.Table (J + 1) :=
+ new String'(Name_Buffer (1 .. Name_Len));
+ end if;
+ end;
- for J in 1 .. Saved_Linker_Switches.Last loop
- Test_If_Relative_Path
- (Saved_Linker_Switches.Table (J), Parent => Current_Work_Dir);
+ exit;
+ end if;
end loop;
- for J in 1 .. Gcc_Switches.Last loop
- Test_If_Relative_Path
- (Gcc_Switches.Table (J), Parent => null);
- end loop;
+ -- If we are using a project file, for relative paths we add the
+ -- current working directory for any relative path on the command
+ -- line and the project directory, for any relative path in the
+ -- project file.
- for J in 1 .. Saved_Gcc_Switches.Last loop
- Test_If_Relative_Path
- (Saved_Gcc_Switches.Table (J), Parent => Current_Work_Dir);
- end loop;
+ declare
+ Dir_Path : constant String_Access :=
+ new String'(Get_Name_String
+ (Projects.Table (Main_Project).Directory));
+ begin
+ for J in 1 .. Binder_Switches.Last loop
+ Test_If_Relative_Path
+ (Binder_Switches.Table (J),
+ Parent => Dir_Path, Including_L_Switch => False);
+ end loop;
+
+ for J in 1 .. Saved_Binder_Switches.Last loop
+ Test_If_Relative_Path
+ (Saved_Binder_Switches.Table (J),
+ Parent => Current_Work_Dir, Including_L_Switch => False);
+ end loop;
+
+ for J in 1 .. Linker_Switches.Last loop
+ Test_If_Relative_Path
+ (Linker_Switches.Table (J), Parent => Dir_Path);
+ end loop;
+
+ for J in 1 .. Saved_Linker_Switches.Last loop
+ Test_If_Relative_Path
+ (Saved_Linker_Switches.Table (J), Parent => Current_Work_Dir);
+ end loop;
+
+ for J in 1 .. Gcc_Switches.Last loop
+ Test_If_Relative_Path
+ (Gcc_Switches.Table (J), Parent => Dir_Path);
+ end loop;
+
+ for J in 1 .. Saved_Gcc_Switches.Last loop
+ Test_If_Relative_Path
+ (Saved_Gcc_Switches.Table (J), Parent => Current_Work_Dir);
+ end loop;
+ end;
end if;
-- We now put in the Binder_Switches and Linker_Switches tables,
@@ -3084,25 +3898,19 @@ package body Make is
end if;
-- Allocate as many temporary mapping file names as the maximum
- -- number of compilation processed.
+ -- number of compilation processed, for each possible project.
The_Mapping_File_Names :=
- new Temp_File_Names (1 .. Saved_Maximum_Processes);
-
- -- If either -c, -b or -l has been specified, we will not necessarily
- -- execute all steps.
-
- if Compile_Only or else Bind_Only or else Link_Only then
- Do_Compile_Step := Do_Compile_Step and Compile_Only;
- Do_Bind_Step := Do_Bind_Step and Bind_Only;
- Do_Link_Step := Do_Link_Step and Link_Only;
-
- -- If -c has been specified, but not -b, ignore any potential -l
+ new Temp_File_Names
+ (No_Project .. Projects.Last, 1 .. Saved_Maximum_Processes);
+ Last_Mapping_File_Names :=
+ new Indices'(No_Project .. Projects.Last => 0);
- if Do_Compile_Step and then not Do_Bind_Step then
- Do_Link_Step := False;
- end if;
- end if;
+ The_Free_Mapping_File_Indices :=
+ new Free_File_Indices
+ (No_Project .. Projects.Last, 1 .. Saved_Maximum_Processes);
+ Last_Free_Indices :=
+ new Indices'(No_Project .. Projects.Last => 0);
Bad_Compilation.Init;
@@ -3112,168 +3920,147 @@ package body Make is
Multiple_Main_Loop : for N_File in 1 .. Osint.Number_Of_Files loop
- if Do_Compile_Step then
- Recursive_Compilation_Step : declare
- Args : Argument_List (1 .. Gcc_Switches.Last);
+ -- First, find the executable name and path
- First_Compiled_File : Name_Id;
+ Executable := No_File;
+ Executable_Obsolete := False;
+ Non_Std_Executable := False;
- Youngest_Obj_File : Name_Id;
- Youngest_Obj_Stamp : Time_Stamp_Type;
+ -- Look inside the linker switches to see if the name
+ -- of the final executable program was specified.
- Executable_Stamp : Time_Stamp_Type;
- -- Executable is the final executable program.
-
- begin
- Executable := No_File;
- Non_Std_Executable := False;
+ for
+ J in reverse Linker_Switches.First .. Linker_Switches.Last
+ loop
+ if Linker_Switches.Table (J).all = Output_Flag.all then
+ pragma Assert (J < Linker_Switches.Last);
- for J in 1 .. Gcc_Switches.Last loop
- Args (J) := Gcc_Switches.Table (J);
- end loop;
+ -- We cannot specify a single executable for several
+ -- main subprograms!
- -- Look inside the linker switches to see if the name
- -- of the final executable program was specified.
+ if Osint.Number_Of_Files > 1 then
+ Fail
+ ("cannot specify a single executable " &
+ "for several mains");
+ end if;
- for
- J in reverse Linker_Switches.First .. Linker_Switches.Last
- loop
- if Linker_Switches.Table (J).all = Output_Flag.all then
- pragma Assert (J < Linker_Switches.Last);
+ Name_Len := Linker_Switches.Table (J + 1)'Length;
+ Name_Buffer (1 .. Name_Len) :=
+ Linker_Switches.Table (J + 1).all;
- -- We cannot specify a single executable for several
- -- main subprograms!
+ -- Put in canonical case to detect suffixs such as ".EXE" on
+ -- Windows or VMS.
- if Osint.Number_Of_Files > 1 then
- Fail
- ("cannot specify a single executable " &
- "for several mains");
- end if;
+ Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
- Name_Len := Linker_Switches.Table (J + 1)'Length;
- Name_Buffer (1 .. Name_Len) :=
- Linker_Switches.Table (J + 1).all;
+ -- If target has an executable suffix and it has not been
+ -- specified then it is added here.
- -- If target has an executable suffix and it has not been
- -- specified then it is added here.
+ if Executable_Suffix'Length /= 0
+ and then Name_Buffer
+ (Name_Len - Executable_Suffix'Length + 1 .. Name_Len)
+ /= Executable_Suffix
+ then
+ -- Get back the original name to keep the case on Windows
- if Executable_Suffix'Length /= 0
- and then Linker_Switches.Table (J + 1)
- (Name_Len - Executable_Suffix'Length + 1
- .. Name_Len) /= Executable_Suffix
- then
- Name_Buffer (Name_Len + 1 ..
- Name_Len + Executable_Suffix'Length) :=
- Executable_Suffix;
- Name_Len := Name_Len + Executable_Suffix'Length;
- end if;
+ Name_Buffer (1 .. Name_Len) :=
+ Linker_Switches.Table (J + 1).all;
- Executable := Name_Enter;
+ -- Add the executable suffix
- Verbose_Msg (Executable, "final executable");
- end if;
- end loop;
+ Name_Buffer (Name_Len + 1 ..
+ Name_Len + Executable_Suffix'Length) :=
+ Executable_Suffix;
+ Name_Len := Name_Len + Executable_Suffix'Length;
- -- If the name of the final executable program was not
- -- specified then construct it from the main input file.
+ else
+ -- Get back the original name to keep the case on Windows
- if Executable = No_File then
- if Main_Project = No_Project then
- Executable :=
- Executable_Name (Strip_Suffix (Main_Source_File));
+ Name_Buffer (1 .. Name_Len) :=
+ Linker_Switches.Table (J + 1).all;
+ end if;
- else
- -- If we are using a project file, we attempt to
- -- remove the body (or spec) termination of the main
- -- subprogram. We find it the the naming scheme of the
- -- project file. This will avoid to generate an
- -- executable "main.2" for a main subprogram
- -- "main.2.ada", when the body termination is ".2.ada".
+ Executable := Name_Enter;
- declare
- Body_Append : constant String :=
- Get_Name_String
- (Projects.Table
- (Main_Project).
- Naming.Current_Impl_Suffix);
-
- Spec_Append : constant String :=
- Get_Name_String
- (Projects.Table
- (Main_Project).
- Naming.Current_Spec_Suffix);
+ Verbose_Msg (Executable, "final executable");
+ end if;
+ end loop;
- begin
- Get_Name_String (Main_Source_File);
+ -- If the name of the final executable program was not
+ -- specified then construct it from the main input file.
- if Name_Len > Body_Append'Length
- and then Name_Buffer
- (Name_Len - Body_Append'Length + 1 .. Name_Len) =
- Body_Append
- then
- -- We have found the body termination. We remove it
- -- add the executable termination, if any.
+ if Executable = No_File then
+ if Main_Project = No_Project then
+ Executable :=
+ Executable_Name (Strip_Suffix (Main_Source_File));
- Name_Len := Name_Len - Body_Append'Length;
- Executable := Executable_Name (Name_Find);
+ else
+ -- If we are using a project file, we attempt to
+ -- remove the body (or spec) termination of the main
+ -- subprogram. We find it the the naming scheme of the
+ -- project file. This will avoid to generate an
+ -- executable "main.2" for a main subprogram
+ -- "main.2.ada", when the body termination is ".2.ada".
+
+ Executable := Prj.Util.Executable_Of
+ (Main_Project, Main_Source_File);
+ end if;
+ end if;
- elsif Name_Len > Spec_Append'Length
- and then
- Name_Buffer
- (Name_Len - Spec_Append'Length + 1 .. Name_Len) =
- Spec_Append
- then
- -- We have found the spec termination. We remove
- -- it, add the executable termination, if any.
+ if Main_Project /= No_Project then
+ declare
+ Exec_File_Name : constant String :=
+ Get_Name_String (Executable);
- Name_Len := Name_Len - Spec_Append'Length;
- Executable := Executable_Name (Name_Find);
+ begin
+ if not Is_Absolute_Path (Exec_File_Name) then
+ for Index in Exec_File_Name'Range loop
+ if Exec_File_Name (Index) = Directory_Separator then
+ Make_Failed ("relative executable (""",
+ Exec_File_Name,
+ """) with directory part not " &
+ "allowed when using project files");
+ end if;
+ end loop;
- else
- Executable :=
- Executable_Name (Strip_Suffix (Main_Source_File));
- end if;
+ Get_Name_String (Projects.Table
+ (Main_Project).Exec_Directory);
- end;
+ if
+ Name_Buffer (Name_Len) /= Directory_Separator
+ then
+ Name_Len := Name_Len + 1;
+ Name_Buffer (Name_Len) := Directory_Separator;
end if;
+
+ Name_Buffer (Name_Len + 1 ..
+ Name_Len + Exec_File_Name'Length) :=
+ Exec_File_Name;
+ Name_Len := Name_Len + Exec_File_Name'Length;
+ Executable := Name_Find;
+ Non_Std_Executable := True;
end if;
+ end;
- if Main_Project /= No_Project then
- declare
- Exec_File_Name : constant String :=
- Get_Name_String (Executable);
+ end if;
- begin
- if not Is_Absolute_Path (Exec_File_Name) then
- for Index in Exec_File_Name'Range loop
- if Exec_File_Name (Index) = Directory_Separator then
- Fail ("relative executable (""" &
- Exec_File_Name &
- """) with directory part not allowed " &
- "when using project files");
- end if;
- end loop;
+ if Do_Compile_Step then
+ Recursive_Compilation_Step : declare
+ Args : Argument_List (1 .. Gcc_Switches.Last);
- Get_Name_String (Projects.Table
- (Main_Project).Exec_Directory);
+ First_Compiled_File : Name_Id;
+ Youngest_Obj_File : Name_Id;
+ Youngest_Obj_Stamp : Time_Stamp_Type;
- if
- Name_Buffer (Name_Len) /= Directory_Separator
- then
- Name_Len := Name_Len + 1;
- Name_Buffer (Name_Len) := Directory_Separator;
- end if;
+ Executable_Stamp : Time_Stamp_Type;
+ -- Executable is the final executable program.
- Name_Buffer (Name_Len + 1 ..
- Name_Len + Exec_File_Name'Length) :=
- Exec_File_Name;
- Name_Len := Name_Len + Exec_File_Name'Length;
- Executable := Name_Find;
- Non_Std_Executable := True;
- end if;
- end;
+ Library_Rebuilt : Boolean := False;
- end if;
+ begin
+ for J in 1 .. Gcc_Switches.Last loop
+ Args (J) := Gcc_Switches.Table (J);
+ end loop;
-- Now we invoke Compile_Sources for the current main
@@ -3298,6 +4085,10 @@ package body Make is
Write_Eol;
end if;
+ -- Make sure the queue will be reinitialized for the next round
+
+ First_Q_Initialization := True;
+
Total_Compilation_Failures :=
Total_Compilation_Failures + Compilation_Failures;
@@ -3311,23 +4102,67 @@ package body Make is
end if;
end if;
- -- Regenerate libraries, if any and if object files
- -- have been regenerated
+ -- Regenerate libraries, if any, and if object files
+ -- have been regenerated.
if Main_Project /= No_Project
- and then MLib.Tgt.Libraries_Are_Supported
+ and then MLib.Tgt.Support_For_Libraries /= MLib.Tgt.None
+ and then (Do_Bind_Step or Unique_Compile_All_Projects
+ or not Compile_Only)
+ and then (Do_Link_Step or N_File = Osint.Number_Of_Files)
then
+ Library_Projs.Init;
- for Proj in Projects.First .. Projects.Last loop
+ declare
+ Proj2 : Project_Id;
+ Depth : Natural;
+ Current : Natural;
- if Proj /= Main_Project
- and then Projects.Table (Proj).Flag1
- then
- MLib.Prj.Build_Library (For_Project => Proj);
- end if;
+ begin
+ -- Put in Library_Projs table all library project
+ -- file ids when the library need to be rebuilt.
- end loop;
+ for Proj1 in Projects.First .. Projects.Last loop
+ if Projects.Table (Proj1).Library
+ and then not Projects.Table (Proj1).Flag1
+ then
+ MLib.Prj.Check_Library (Proj1);
+ end if;
+
+ if Projects.Table (Proj1).Flag1 then
+ Library_Projs.Increment_Last;
+ Current := Library_Projs.Last;
+ Depth := Projects.Table (Proj1).Depth;
+
+ -- Put the projects in decreasing depth order,
+ -- so that if libA depends on libB, libB is first
+ -- in order.
+
+ while Current > 1 loop
+ Proj2 := Library_Projs.Table (Current - 1);
+ exit when Projects.Table (Proj2).Depth >= Depth;
+ Library_Projs.Table (Current) := Proj2;
+ Current := Current - 1;
+ end loop;
+
+ Library_Projs.Table (Current) := Proj1;
+ Projects.Table (Proj1).Flag1 := False;
+ end if;
+ end loop;
+ end;
+
+ -- Build the libraries, if any need to be built
+
+ for J in 1 .. Library_Projs.Last loop
+ Library_Rebuilt := True;
+ MLib.Prj.Build_Library
+ (For_Project => Library_Projs.Table (J),
+ Gnatbind => Gnatbind.all,
+ Gnatbind_Path => Gnatbind_Path,
+ Gcc => Gcc.all,
+ Gcc_Path => Gcc_Path);
+ end loop;
end if;
if Opt.List_Dependencies then
@@ -3342,13 +4177,10 @@ package body Make is
elsif First_Compiled_File = No_File
and then not Do_Bind_Step
and then not Opt.Quiet_Output
+ and then not Library_Rebuilt
and then Osint.Number_Of_Files = 1
then
- if Unique_Compile then
- Inform (Msg => "object up to date.");
- else
- Inform (Msg => "objects up to date.");
- end if;
+ Inform (Msg => "objects up to date.");
elsif Opt.Do_Not_Execute
and then First_Compiled_File /= No_File
@@ -3392,13 +4224,24 @@ package body Make is
then
Executable_Stamp := File_Stamp (Executable);
- -- Once Executable_Obsolete is set to True, it is never
- -- reset to False, because it is too hard to accurately
- -- decide if a subsequent main need to be rebuilt or not.
+ if not Executable_Obsolete then
+ Executable_Obsolete :=
+ Youngest_Obj_Stamp > Executable_Stamp;
+ end if;
+
+ if not Executable_Obsolete then
+ for Index in reverse 1 .. Dependencies.Last loop
+ if Is_In_Obsoleted
+ (Dependencies.Table (Index).Depends_On)
+ then
+ Enter_Into_Obsoleted
+ (Dependencies.Table (Index).This);
+ end if;
+ end loop;
- Executable_Obsolete :=
- Executable_Obsolete
- or else Youngest_Obj_Stamp > Executable_Stamp;
+ Executable_Obsolete := Is_In_Obsoleted (Main_Source_File);
+ Dependencies.Init;
+ end if;
if not Executable_Obsolete then
@@ -3459,10 +4302,7 @@ package body Make is
-- main. So we set Executable_Obsolete to True to make sure that
-- the subsequent mains will be rebuilt.
- Executable_Obsolete := True;
-
- Main_ALI_In_Place_Mode_Step :
- declare
+ Main_ALI_In_Place_Mode_Step : declare
ALI_File : File_Name_Type;
Src_File : File_Name_Type;
@@ -3484,20 +4324,65 @@ package body Make is
end if;
if Main_ALI_File = No_File then
- Fail ("could not find the main ALI file");
+ Make_Failed ("could not find the main ALI file");
end if;
-
end Main_ALI_In_Place_Mode_Step;
if Do_Bind_Step then
Bind_Step : declare
Args : Argument_List
- (Binder_Switches.First .. Binder_Switches.Last);
+ (Binder_Switches.First .. Binder_Switches.Last + 1);
+ -- The arguments for the invocation of gnatbind
+
+ Last_Arg : Natural := Binder_Switches.Last;
+ -- Index of the last argument in Args
+
+ Mapping_FD : File_Descriptor := Invalid_FD;
+ -- A File Descriptor for an eventual mapping file
+
+ Mapping_Path : Name_Id := No_Name;
+ -- The path name of the mapping file
+
+ ALI_Unit : Name_Id := No_Name;
+ -- The unit name of an ALI file
+
+ ALI_Name : Name_Id := No_Name;
+ -- The file name of the ALI file
+
+ ALI_Project : Project_Id := No_Project;
+ -- The project of the ALI file
+
+ Bytes : Integer;
+ OK : Boolean := True;
+
+ Status : Boolean;
+ -- For call to Close
begin
+ -- If it is the first time the bind step is performed,
+ -- check if there are shared libraries, so that gnatbind is
+ -- called with -shared.
+
+ if not Bind_Shared_Known then
+ if Main_Project /= No_Project
+ and then MLib.Tgt.Support_For_Libraries /= MLib.Tgt.None
+ then
+ for Proj in Projects.First .. Projects.Last loop
+ if Projects.Table (Proj).Library and then
+ Projects.Table (Proj).Library_Kind /= Static
+ then
+ Bind_Shared := Shared_Switch'Access;
+ exit;
+ end if;
+ end loop;
+ end if;
+
+ Bind_Shared_Known := True;
+ end if;
+
-- Get all the binder switches
- for J in Binder_Switches.First .. Binder_Switches.Last loop
+ for J in Binder_Switches.First .. Last_Arg loop
Args (J) := Binder_Switches.Table (J);
end loop;
@@ -3506,57 +4391,454 @@ package body Make is
-- Put all the source directories in ADA_INCLUDE_PATH,
-- and all the object directories in ADA_OBJECTS_PATH
- Set_Ada_Paths (Main_Project, False);
+ Prj.Env.Set_Ada_Paths (Main_Project, False);
+
+ -- If switch -C was specified, create a binder mapping file
+
+ if Create_Mapping_File then
+ Tempdir.Create_Temp_File (Mapping_FD, Mapping_Path);
+
+ if Mapping_FD /= Invalid_FD then
+
+ -- Traverse all units
+
+ for J in Prj.Com.Units.First .. Prj.Com.Units.Last loop
+ declare
+ Unit : constant Prj.Com.Unit_Data :=
+ Prj.Com.Units.Table (J);
+ use Prj.Com;
+
+ begin
+ if Unit.Name /= No_Name then
+
+ -- If there is a body, put it in the mapping
+
+ if Unit.File_Names (Body_Part).Name /= No_Name
+ and then Unit.File_Names (Body_Part).Project
+ /= No_Project
+ then
+ Get_Name_String (Unit.Name);
+ Name_Buffer
+ (Name_Len + 1 .. Name_Len + 2) := "%b";
+ Name_Len := Name_Len + 2;
+ ALI_Unit := Name_Find;
+ ALI_Name :=
+ Lib_File_Name
+ (Unit.File_Names (Body_Part).Name);
+ ALI_Project :=
+ Unit.File_Names (Body_Part).Project;
+
+ -- Otherwise, if there is a spec, put it
+ -- in the mapping.
+
+ elsif Unit.File_Names (Specification).Name
+ /= No_Name
+ and then Unit.File_Names
+ (Specification).Project
+ /= No_Project
+ then
+ Get_Name_String (Unit.Name);
+ Name_Buffer
+ (Name_Len + 1 .. Name_Len + 2) := "%s";
+ Name_Len := Name_Len + 2;
+ ALI_Unit := Name_Find;
+ ALI_Name := Lib_File_Name
+ (Unit.File_Names (Specification).Name);
+ ALI_Project :=
+ Unit.File_Names (Specification).Project;
+
+ else
+ ALI_Name := No_Name;
+ end if;
+
+ -- If we have something to put in the mapping
+ -- then we do it now. However, if the project
+ -- is extended, we don't put anything in the
+ -- mapping file, because we do not know where
+ -- the ALI file is: it might be in the ext-
+ -- ended project obj dir as well as in the
+ -- extending project obj dir.
+
+ if ALI_Name /= No_Name
+ and then Projects.Table
+ (ALI_Project).Extended_By
+ = No_Project
+ and then Projects.Table
+ (ALI_Project).Extends
+ = No_Project
+ then
+ -- First line is the unit name
+
+ Get_Name_String (ALI_Unit);
+ Name_Len := Name_Len + 1;
+ Name_Buffer (Name_Len) := ASCII.LF;
+ Bytes :=
+ Write
+ (Mapping_FD,
+ Name_Buffer (1)'Address,
+ Name_Len);
+ OK := Bytes = Name_Len;
+
+ if OK then
+
+ -- Second line it the ALI file name
+
+ Get_Name_String (ALI_Name);
+ Name_Len := Name_Len + 1;
+ Name_Buffer (Name_Len) := ASCII.LF;
+ Bytes :=
+ Write
+ (Mapping_FD,
+ Name_Buffer (1)'Address,
+ Name_Len);
+ OK := Bytes = Name_Len;
+ end if;
+
+ if OK then
+
+ -- Third line it the ALI path name,
+ -- concatenation of the project
+ -- directory with the ALI file name.
+
+ declare
+ ALI : constant String :=
+ Get_Name_String (ALI_Name);
+ begin
+ Get_Name_String
+ (Projects.Table (ALI_Project).
+ Object_Directory);
+
+ if Name_Buffer (Name_Len) /=
+ Directory_Separator
+ then
+ Name_Len := Name_Len + 1;
+ Name_Buffer (Name_Len) :=
+ Directory_Separator;
+ end if;
+
+ Name_Buffer
+ (Name_Len + 1 ..
+ Name_Len + ALI'Length) := ALI;
+ Name_Len :=
+ Name_Len + ALI'Length + 1;
+ Name_Buffer (Name_Len) := ASCII.LF;
+ Bytes :=
+ Write
+ (Mapping_FD,
+ Name_Buffer (1)'Address,
+ Name_Len);
+ OK := Bytes = Name_Len;
+ end;
+ end if;
+
+ -- If OK is False, it means we were unable
+ -- to write a line. No point in continuing
+ -- with the other units.
+
+ exit when not OK;
+ end if;
+ end if;
+ end;
+ end loop;
+
+ Close (Mapping_FD, Status);
+
+ OK := OK and Status;
+
+ -- If the creation of the mapping file was successful,
+ -- we add the switch to the arguments of gnatbind.
+
+ if OK then
+ Last_Arg := Last_Arg + 1;
+ Args (Last_Arg) := new String'
+ ("-F=" & Get_Name_String (Mapping_Path));
+ end if;
+ end if;
+ end if;
+
end if;
- Bind (Main_ALI_File, Args);
+ begin
+ Bind (Main_ALI_File,
+ Bind_Shared.all & Args (Args'First .. Last_Arg));
+
+ exception
+ when others =>
+
+ -- If -dn was not specified, delete the temporary mapping
+ -- file, if one was created.
+
+ if not Debug.Debug_Flag_N
+ and then Mapping_Path /= No_Name
+ then
+ Delete_File (Get_Name_String (Mapping_Path), OK);
+ end if;
+
+ -- And reraise the exception
+
+ raise;
+ end;
+
+ -- If -dn was not specified, delete the temporary mapping file,
+ -- if one was created.
+
+ if not Debug.Debug_Flag_N and then Mapping_Path /= No_Name then
+ Delete_File (Get_Name_String (Mapping_Path), OK);
+ end if;
end Bind_Step;
end if;
if Do_Link_Step then
-
Link_Step : declare
There_Are_Libraries : Boolean := False;
Linker_Switches_Last : constant Integer := Linker_Switches.Last;
+ Path_Option : constant String_Access :=
+ MLib.Tgt.Linker_Library_Path_Option;
+ Current : Natural;
+ Proj2 : Project_Id;
+ Depth : Natural;
begin
+ if not Run_Path_Option then
+ Linker_Switches.Increment_Last;
+ Linker_Switches.Table (Linker_Switches.Last) :=
+ new String'("-R");
+ end if;
+
if Main_Project /= No_Project then
+ Library_Paths.Set_Last (0);
+ Library_Projs.Init;
+
+ if MLib.Tgt.Support_For_Libraries /= MLib.Tgt.None then
+ -- Check for library projects
+
+ for Proj1 in 1 .. Projects.Last loop
+ if Proj1 /= Main_Project
+ and then Projects.Table (Proj1).Library
+ then
+ -- Add this project to table Library_Projs
+
+ There_Are_Libraries := True;
+ Depth := Projects.Table (Proj1).Depth;
+ Library_Projs.Increment_Last;
+ Current := Library_Projs.Last;
+
+ -- Any project with a greater depth should be
+ -- after this project in the list.
+
+ while Current > 1 loop
+ Proj2 := Library_Projs.Table (Current - 1);
+ exit when Projects.Table (Proj2).Depth <= Depth;
+ Library_Projs.Table (Current) := Proj2;
+ Current := Current - 1;
+ end loop;
- if MLib.Tgt.Libraries_Are_Supported then
- Set_Libraries (Main_Project, There_Are_Libraries);
+ Library_Projs.Table (Current) := Proj1;
+
+ -- If it is not a static library and path option
+ -- is set, add it to the Library_Paths table.
+
+ if Projects.Table (Proj1).Library_Kind /= Static
+ and then Path_Option /= null
+ then
+ Library_Paths.Increment_Last;
+ Library_Paths.Table (Library_Paths.Last) :=
+ new String'
+ (Get_Name_String
+ (Projects.Table (Proj1).Library_Dir));
+ end if;
+ end if;
+ end loop;
+
+ for Index in 1 .. Library_Projs.Last loop
+ -- Add the -L switch
+
+ Linker_Switches.Increment_Last;
+ Linker_Switches.Table (Linker_Switches.Last) :=
+ new String'("-L" &
+ Get_Name_String
+ (Projects.Table
+ (Library_Projs.Table (Index)).
+ Library_Dir));
+
+ -- Add the -l switch
+
+ Linker_Switches.Increment_Last;
+ Linker_Switches.Table (Linker_Switches.Last) :=
+ new String'("-l" &
+ Get_Name_String
+ (Projects.Table
+ (Library_Projs.Table (Index)).
+ Library_Name));
+ end loop;
end if;
if There_Are_Libraries then
- -- Add -L<lib_dir> -lgnarl -lgnat -Wl,-rpath,<lib_dir>
+ -- If Path_Option is not null, create the switch
+ -- ("-Wl,-rpath," or equivalent) with all the non static
+ -- library dirs plus the standard GNAT library dir.
+ -- We do that only if Run_Path_Option is True
+ -- (not disabled by -R switch).
- Linker_Switches.Increment_Last;
- Linker_Switches.Table (Linker_Switches.Last) :=
- new String'("-L" & MLib.Utl.Lib_Directory);
- Linker_Switches.Increment_Last;
- Linker_Switches.Table (Linker_Switches.Last) :=
- new String'("-lgnarl");
- Linker_Switches.Increment_Last;
- Linker_Switches.Table (Linker_Switches.Last) :=
- new String'("-lgnat");
+ if Run_Path_Option and Path_Option /= null then
+ declare
+ Option : String_Access;
+ Length : Natural := Path_Option'Length;
+ Current : Natural;
- declare
- Option : constant String_Access :=
- MLib.Tgt.Linker_Library_Path_Option
- (MLib.Utl.Lib_Directory);
+ begin
+ for Index in
+ Library_Paths.First .. Library_Paths.Last
+ loop
+ -- Add the length of the library dir plus one
+ -- for the directory separator.
+
+ Length :=
+ Length +
+ Library_Paths.Table (Index)'Length + 1;
+ end loop;
+
+ -- Finally, add the length of the standard GNAT
+ -- library dir.
+
+ Length := Length + MLib.Utl.Lib_Directory'Length;
+ Option := new String (1 .. Length);
+ Option (1 .. Path_Option'Length) := Path_Option.all;
+ Current := Path_Option'Length;
+
+ -- Put each library dir followed by a dir separator
+
+ for Index in
+ Library_Paths.First .. Library_Paths.Last
+ loop
+ Option
+ (Current + 1 ..
+ Current +
+ Library_Paths.Table (Index)'Length) :=
+ Library_Paths.Table (Index).all;
+ Current :=
+ Current +
+ Library_Paths.Table (Index)'Length + 1;
+ Option (Current) := Path_Separator;
+ end loop;
+
+ -- Finally put the standard GNAT library dir
+
+ Option
+ (Current + 1 ..
+ Current + MLib.Utl.Lib_Directory'Length) :=
+ MLib.Utl.Lib_Directory;
+
+ -- And add the switch to the linker switches
- begin
- if Option /= null then
Linker_Switches.Increment_Last;
Linker_Switches.Table (Linker_Switches.Last) :=
Option;
- end if;
- end;
+ end;
+ end if;
+
end if;
-- Put the object directories in ADA_OBJECTS_PATH
- Set_Ada_Paths (Main_Project, False);
+ Prj.Env.Set_Ada_Paths (Main_Project, False);
+
+ -- Check for attributes Linker'Linker_Options in projects
+ -- other than the main project
+
+ declare
+ Linker_Package : Package_Id;
+ Options : Variable_Value;
+
+ begin
+ Linker_Opts.Init;
+
+ for Index in 1 .. Projects.Last loop
+ if Index /= Main_Project then
+ Linker_Package :=
+ Prj.Util.Value_Of
+ (Name => Name_Linker,
+ In_Packages =>
+ Projects.Table (Index).Decl.Packages);
+ Options :=
+ Prj.Util.Value_Of
+ (Name => Name_Ada,
+ Attribute_Or_Array_Name => Name_Linker_Options,
+ In_Package => Linker_Package);
+
+ -- If attribute is present, add the project with
+ -- the attribute to table Linker_Opts.
+
+ if Options /= Nil_Variable_Value then
+ Linker_Opts.Increment_Last;
+ Linker_Opts.Table (Linker_Opts.Last) :=
+ (Project => Index, Options => Options.Values);
+ end if;
+ end if;
+ end loop;
+ end;
+
+ declare
+ Opt1 : Linker_Options_Data;
+ Opt2 : Linker_Options_Data;
+ Depth : Natural;
+ Options : String_List_Id;
+ Option : Name_Id;
+ begin
+ -- Sort the project by increasing depths
+
+ for Index in 1 .. Linker_Opts.Last loop
+ Opt1 := Linker_Opts.Table (Index);
+ Depth := Projects.Table (Opt1.Project).Depth;
+
+ for J in Index + 1 .. Linker_Opts.Last loop
+ Opt2 := Linker_Opts.Table (J);
+
+ if
+ Projects.Table (Opt2.Project).Depth < Depth
+ then
+ Linker_Opts.Table (Index) := Opt2;
+ Linker_Opts.Table (J) := Opt1;
+ Opt1 := Opt2;
+ Depth :=
+ Projects.Table (Opt1.Project).Depth;
+ end if;
+ end loop;
+
+ -- If Dir_Path has not been computed for this project,
+ -- do it now.
+
+ if Projects.Table (Opt1.Project).Dir_Path = null then
+ Projects.Table (Opt1.Project).Dir_Path :=
+ new String'
+ (Get_Name_String
+ (Projects.Table (Opt1.Project). Directory));
+ end if;
+
+ Options := Opt1.Options;
+
+ -- Add each of the options to the linker switches
+
+ while Options /= Nil_String loop
+ Option := String_Elements.Table (Options).Value;
+ Options := String_Elements.Table (Options).Next;
+ Linker_Switches.Increment_Last;
+ Linker_Switches.Table (Linker_Switches.Last) :=
+ new String'(Get_Name_String (Option));
+
+ -- Object files and -L switches specified with
+ -- relative paths and must be converted to
+ -- absolute paths.
+
+ Test_If_Relative_Path
+ (Switch =>
+ Linker_Switches.Table (Linker_Switches.Last),
+ Parent => Projects.Table (Opt1.Project).Dir_Path,
+ Including_L_Switch => True);
+ end loop;
+ end loop;
+ end;
end if;
declare
@@ -3582,10 +4864,9 @@ package body Make is
Last_Arg := Last_Arg + 1;
Args (Last_Arg) := Linker_Switches.Table (J);
end if;
-
end loop;
- -- And invoke the linker
+ -- If need be, add the -o switch
if Non_Std_Executable then
Last_Arg := Last_Arg + 1;
@@ -3593,14 +4874,28 @@ package body Make is
Last_Arg := Last_Arg + 1;
Args (Last_Arg) :=
new String'(Get_Name_String (Executable));
+ end if;
+
+ -- And invoke the linker
+
+ begin
Link (Main_ALI_File, Args (Args'First .. Last_Arg));
+ Successful_Links.Increment_Last;
+ Successful_Links.Table (Successful_Links.Last) :=
+ Main_ALI_File;
- else
- Link
- (Main_ALI_File,
- Args (Args'First .. Last_Arg));
- end if;
+ exception
+ when Link_Failed =>
+ if Osint.Number_Of_Files = 1 or not Opt.Keep_Going then
+ raise;
+ else
+ Write_Line ("*** link failed");
+ Failed_Links.Increment_Last;
+ Failed_Links.Table (Failed_Links.Last) :=
+ Main_ALI_File;
+ end if;
+ end;
end;
Linker_Switches.Set_Last (Linker_Switches_Last);
@@ -3628,16 +4923,31 @@ package body Make is
Prj.Env.
File_Name_Of_Library_Unit_Body
(Name => Main_Source_File_Name,
- Project => Main_Project);
+ Project => Main_Project,
+ Main_Project_Only =>
+ not Unique_Compile);
+
+ The_Packages : constant Package_Id :=
+ Projects.Table (Main_Project).Decl.Packages;
+
+ Binder_Package : constant Prj.Package_Id :=
+ Prj.Util.Value_Of
+ (Name => Name_Binder,
+ In_Packages => The_Packages);
+
+ Linker_Package : constant Prj.Package_Id :=
+ Prj.Util.Value_Of
+ (Name => Name_Linker,
+ In_Packages => The_Packages);
begin
-- We fail if we cannot find the main source file
-- as an immediate source of the main project file.
if Main_Unit_File_Name = "" then
- Fail ('"' & Main_Source_File_Name &
- """ is not a unit of project " &
- Project_File_Name.all & ".");
+ Make_Failed ('"' & Main_Source_File_Name,
+ """ is not a unit of project ",
+ Project_File_Name.all & ".");
else
-- Remove any directory information from the main
@@ -3663,11 +4973,116 @@ package body Make is
Main_Source_File := Name_Find;
end;
end if;
+
+ -- We now deal with the binder and linker switches.
+ -- If no project file is used, there is nothing to do
+ -- because the binder and linker switches are the same
+ -- for all mains.
+
+ -- Reset the tables Binder_Switches and Linker_Switches
+
+ Binder_Switches.Set_Last (Last_Binder_Switch);
+ Linker_Switches.Set_Last (Last_Linker_Switch);
+
+ -- Add binder switches from the project file for this main,
+ -- if any.
+
+ if Do_Bind_Step and Binder_Package /= No_Package then
+ if Opt.Verbose_Mode then
+ Write_Str ("Adding binder switches for """);
+ Write_Str (Main_Unit_File_Name);
+ Write_Line (""".");
+ end if;
+
+ Add_Switches
+ (File_Name => Main_Unit_File_Name,
+ The_Package => Binder_Package,
+ Program => Binder);
+ end if;
+
+ -- Add linker switches from the project file for this main,
+ -- if any.
+
+ if Do_Link_Step and Linker_Package /= No_Package then
+ if Opt.Verbose_Mode then
+ Write_Str ("Adding linker switches for""");
+ Write_Str (Main_Unit_File_Name);
+ Write_Line (""".");
+ end if;
+
+ Add_Switches
+ (File_Name => Main_Unit_File_Name,
+ The_Package => Linker_Package,
+ Program => Linker);
+ end if;
+
+ -- As we are using a project file, for relative paths we add
+ -- the current working directory for any relative path on
+ -- the command line and the project directory, for any
+ -- relative path in the project file.
+
+ declare
+ Dir_Path : constant String_Access :=
+ new String'(Get_Name_String
+ (Projects.Table (Main_Project).Directory));
+ begin
+ for
+ J in Last_Binder_Switch + 1 .. Binder_Switches.Last
+ loop
+ Test_If_Relative_Path
+ (Binder_Switches.Table (J),
+ Parent => Dir_Path, Including_L_Switch => False);
+ end loop;
+
+ for
+ J in Last_Linker_Switch + 1 .. Linker_Switches.Last
+ loop
+ Test_If_Relative_Path
+ (Linker_Switches.Table (J), Parent => Dir_Path);
+ end loop;
+ end;
+
+ -- We now put in the Binder_Switches and Linker_Switches
+ -- tables, the binder and linker switches of the command
+ -- line that have been put in the Saved_ tables.
+ -- These switches will follow the project file switches.
+
+ for J in 1 .. Saved_Binder_Switches.Last loop
+ Add_Switch
+ (Saved_Binder_Switches.Table (J),
+ Binder,
+ And_Save => False);
+ end loop;
+
+ for J in 1 .. Saved_Linker_Switches.Last loop
+ Add_Switch
+ (Saved_Linker_Switches.Table (J),
+ Linker,
+ And_Save => False);
+ end loop;
end;
end if;
end if;
end loop Multiple_Main_Loop;
+ if Failed_Links.Last > 0 then
+ for Index in 1 .. Successful_Links.Last loop
+ Write_Str ("Linking of """);
+ Write_Str (Get_Name_String (Successful_Links.Table (Index)));
+ Write_Line (""" succeeded.");
+ end loop;
+
+ for Index in 1 .. Failed_Links.Last loop
+ Write_Str ("Linking of """);
+ Write_Str (Get_Name_String (Failed_Links.Table (Index)));
+ Write_Line (""" failed.");
+ end loop;
+
+ if Total_Compilation_Failures = 0 then
+ raise Compilation_Failed;
+ end if;
+ end if;
+
if Total_Compilation_Failures /= 0 then
List_Bad_Compilations;
raise Compilation_Failed;
@@ -3676,30 +5091,43 @@ package body Make is
-- Delete the temporary mapping file that was created if we are
-- using project files.
- Delete_Mapping_Files;
+ if not Debug.Debug_Flag_N then
+ Delete_Mapping_Files;
+ Prj.Env.Delete_All_Path_Files;
+ end if;
Exit_Program (E_Success);
exception
when Bind_Failed =>
- Delete_Mapping_Files;
- Osint.Fail ("*** bind failed.");
+ Make_Failed ("*** bind failed.");
when Compilation_Failed =>
- Delete_Mapping_Files;
+ if not Debug.Debug_Flag_N then
+ Delete_Mapping_Files;
+ Prj.Env.Delete_All_Path_Files;
+ end if;
+
Exit_Program (E_Fatal);
when Link_Failed =>
- Delete_Mapping_Files;
- Osint.Fail ("*** link failed.");
+ Make_Failed ("*** link failed.");
when X : others =>
- Delete_Mapping_Files;
Write_Line (Exception_Information (X));
- Osint.Fail ("INTERNAL ERROR. Please report.");
+ Make_Failed ("INTERNAL ERROR. Please report.");
end Gnatmake;
+ ----------
+ -- Hash --
+ ----------
+
+ function Hash (F : Name_Id) return Header_Num is
+ begin
+ return Header_Num (1 + F mod Max_Header);
+ end Hash;
+
--------------------
-- In_Ada_Lib_Dir --
--------------------
@@ -3736,21 +5164,51 @@ package body Make is
-- Init_Mapping_File --
-----------------------
- procedure Init_Mapping_File (File_Name : in out Temp_File_Name) is
+ procedure Init_Mapping_File
+ (Project : Project_Id;
+ File_Index : in out Natural)
+ is
FD : File_Descriptor;
+
+ Status : Boolean;
+ -- For call to Close
+
begin
- if Main_Project /= No_Project then
- Prj.Env.Create_Mapping_File (File_Name);
+ -- Increase the index of the last mapping file for this project
- else
- Create_Temp_File (FD, File_Name);
+ Last_Mapping_File_Names (Project) :=
+ Last_Mapping_File_Names (Project) + 1;
+
+ -- If there is a project file, call Create_Mapping_File with
+ -- the project id.
+
+ if Project /= No_Project then
+ Prj.Env.Create_Mapping_File
+ (Project,
+ The_Mapping_File_Names
+ (Project, Last_Mapping_File_Names (Project)));
+
+ -- Otherwise, just create an empty file
+ else
+ Tempdir.Create_Temp_File
+ (FD,
+ The_Mapping_File_Names
+ (No_Project, Last_Mapping_File_Names (No_Project)));
if FD = Invalid_FD then
- Fail ("disk full");
+ Make_Failed ("disk full");
end if;
- Close (FD);
+ Close (FD, Status);
+
+ if not Status then
+ Make_Failed ("disk full");
+ end if;
end if;
+
+ -- And return the index of the newly created file
+
+ File_Index := Last_Mapping_File_Names (Project);
end Init_Mapping_File;
------------
@@ -3794,6 +5252,10 @@ package body Make is
Prj.Initialize;
+ Dependencies.Init;
+
+ RTS_Specified := null;
+
Next_Arg := 1;
Scan_Args : while Next_Arg <= Argument_Count loop
Scan_Make_Arg (Argument (Next_Arg), And_Save => True);
@@ -3804,12 +5266,48 @@ package body Make is
Makeusg;
end if;
+ -- Test for trailing -P switch
+
+ if Project_File_Name_Present and then Project_File_Name = null then
+ Make_Failed ("project file name missing after -P");
+
-- Test for trailing -o switch
- if Opt.Output_File_Name_Present
+ elsif Opt.Output_File_Name_Present
and then not Output_File_Name_Seen
then
- Fail ("output file name missing after -o");
+ Make_Failed ("output file name missing after -o");
+
+ -- Test for trailing -D switch
+
+ elsif Opt.Object_Directory_Present
+ and then not Object_Directory_Seen then
+ Make_Failed ("object directory missing after -D");
+ end if;
+
+ -- Test for simultaneity of -i and -D
+
+ if Object_Directory_Path /= null and then In_Place_Mode then
+ Make_Failed ("-i and -D cannot be used simutaneously");
+ end if;
+
+ -- Deal with -C= switch
+
+ if Gnatmake_Mapping_File /= null then
+ -- First, check compatibility with other switches
+
+ if Project_File_Name /= null then
+ Make_Failed ("-C= switch is not compatible with -P switch");
+
+ elsif Saved_Maximum_Processes > 1 then
+ Make_Failed ("-C= switch is not compatible with -jnnn switch");
+ end if;
+
+ Fmap.Initialize (Gnatmake_Mapping_File.all);
+ Add_Switch
+ ("-gnatem=" & Gnatmake_Mapping_File.all,
+ Compiler,
+ And_Save => True);
end if;
if Project_File_Name /= null then
@@ -3838,11 +5336,11 @@ package body Make is
Prj.Pars.Parse
(Project => Main_Project,
- Project_File_Name => Project_File_Name.all);
+ Project_File_Name => Project_File_Name.all,
+ Packages_To_Check => Packages_To_Check_By_Gnatmake);
if Main_Project = No_Project then
- Fail ("""" & Project_File_Name.all &
- """ processing failed");
+ Make_Failed ("""", Project_File_Name.all, """ processing failed");
end if;
if Opt.Verbose_Mode then
@@ -3859,28 +5357,34 @@ package body Make is
Add_Source_Directories (Main_Project);
Add_Object_Directories (Main_Project);
- end if;
+ -- Compute depth of each project
- Osint.Add_Default_Search_Dirs;
+ Recursive_Compute_Depth
+ (Main_Project, Visited => No_Projects, Depth => 0);
- -- Mark the GNAT libraries if needed.
+ else
- -- Source file lookups should be cached for efficiency.
- -- Source files are not supposed to change.
+ Osint.Add_Default_Search_Dirs;
- Osint.Source_File_Data (Cache => True);
+ -- Source file lookups should be cached for efficiency.
+ -- Source files are not supposed to change. However, we do that now
+ -- only if no project file is used; if a project file is used, we
+ -- do it just after changing the directory to the object directory.
- -- Read gnat.adc file to initialize Fname.UF
+ Osint.Source_File_Data (Cache => True);
- Fname.UF.Initialize;
+ -- Read gnat.adc file to initialize Fname.UF
- begin
- Fname.SF.Read_Source_File_Name_Pragmas;
+ Fname.UF.Initialize;
- exception
- when Err : SFN_Scan.Syntax_Error_In_GNAT_ADC =>
- Osint.Fail (Exception_Message (Err));
- end;
+ begin
+ Fname.SF.Read_Source_File_Name_Pragmas;
+
+ exception
+ when Err : SFN_Scan.Syntax_Error_In_GNAT_ADC =>
+ Make_Failed (Exception_Message (Err));
+ end;
+ end if;
end Initialize;
-----------------------------------
@@ -3888,11 +5392,48 @@ package body Make is
-----------------------------------
procedure Insert_Project_Sources
- (The_Project : Project_Id;
- Into_Q : Boolean)
+ (The_Project : Project_Id;
+ All_Projects : Boolean;
+ Into_Q : Boolean)
is
+ Put_In_Q : Boolean := Into_Q;
Unit : Com.Unit_Data;
Sfile : Name_Id;
+ Extending : constant Boolean :=
+ Projects.Table (The_Project).Extends /= No_Project;
+
+ function Check_Project (P : Project_Id) return Boolean;
+ -- Returns True if P is The_Project or a project extended by
+ -- The_Project.
+
+ -------------------
+ -- Check_Project --
+ -------------------
+
+ function Check_Project (P : Project_Id) return Boolean is
+ begin
+ if All_Projects or P = The_Project then
+ return True;
+ elsif Extending then
+ declare
+ Data : Project_Data := Projects.Table (The_Project);
+
+ begin
+ loop
+ if P = Data.Extends then
+ return True;
+ end if;
+
+ Data := Projects.Table (Data.Extends);
+ exit when Data.Extends = No_Project;
+ end loop;
+ end;
+ end if;
+
+ return False;
+ end Check_Project;
+
+ -- Start of processing of Insert_Project_Sources
begin
-- For all the sources in the project files,
@@ -3901,13 +5442,16 @@ package body Make is
Unit := Com.Units.Table (Id);
Sfile := No_Name;
- -- If there is a source for the body,
+ -- If there is a source for the body, and the body has not been
+ -- locally removed,
- if Unit.File_Names (Com.Body_Part).Name /= No_Name then
+ if Unit.File_Names (Com.Body_Part).Name /= No_Name
+ and then Unit.File_Names (Com.Body_Part).Path /= Slash
+ then
- -- And it is a source of the specified project
+ -- And it is a source for the specified project
- if Unit.File_Names (Com.Body_Part).Project = The_Project then
+ if Check_Project (Unit.File_Names (Com.Body_Part).Project) then
-- If we don't have a spec, we cannot consider the source
-- if it is a subunit
@@ -3916,13 +5460,24 @@ package body Make is
declare
Src_Ind : Source_File_Index;
+ -- Here we are cheating a little bit: we don't want to
+ -- use Sinput.L, because it depends on the GNAT tree
+ -- (Atree, Sinfo, ...). So, we pretend that it is
+ -- a project file, and we use Sinput.P.
+ -- Source_File_Is_Subunit is just scanning through
+ -- the file until it finds one of the reserved words
+ -- separate, procedure, function, generic or package.
+ -- Fortunately, these Ada reserved words are also
+ -- reserved for project files.
+
begin
- Src_Ind := Sinput.L.Load_Source_File
- (Unit.File_Names (Com.Body_Part).Name);
+ Src_Ind := Sinput.P.Load_Project_File
+ (Get_Name_String
+ (Unit.File_Names (Com.Body_Part).Path));
-- If it is a subunit, discard it
- if Sinput.L.Source_File_Is_Subunit (Src_Ind) then
+ if Sinput.P.Source_File_Is_Subunit (Src_Ind) then
Sfile := No_Name;
else
@@ -3936,17 +5491,19 @@ package body Make is
end if;
elsif Unit.File_Names (Com.Specification).Name /= No_Name
- and then Unit.File_Names (Com.Specification).Project = The_Project
+ and then Unit.File_Names (Com.Specification).Path /= Slash
+ and then Check_Project (Unit.File_Names (Com.Specification).Project)
then
-- If there is no source for the body, but there is a source
- -- for the spec, then we take this one.
+ -- for the spec which has not been locally removed, then we take
+ -- this one.
Sfile := Unit.File_Names (Com.Specification).Name;
end if;
- -- If Into_Q is True, we insert into the Q
+ -- If Put_In_Q is True, we insert into the Q
- if Into_Q then
+ if Put_In_Q then
-- For the first source inserted into the Q, we need
-- to initialize the Q, but not for the subsequent sources.
@@ -3959,16 +5516,32 @@ package body Make is
-- is not marked.
if Sfile /= No_Name and then not Is_Marked (Sfile) then
+ if Opt.Verbose_Mode then
+ Write_Str ("Adding """);
+ Write_Str (Get_Name_String (Sfile));
+ Write_Line (""" to the queue");
+ end if;
+
Insert_Q (Sfile);
Mark (Sfile);
end if;
elsif Sfile /= No_Name then
- -- If Into_Q is False, we add the source as it it were
- -- specified on the command line.
+ -- If Put_In_Q is False, we add the source as it it were
+ -- specified on the command line, and we set Put_In_Q to True,
+ -- so that the following sources will be put directly in the
+ -- queue. This will allow parallel compilation processes if -jx
+ -- switch is used.
+
+ if Opt.Verbose_Mode then
+ Write_Str ("Adding """);
+ Write_Str (Get_Name_String (Sfile));
+ Write_Line (""" as if on the command line");
+ end if;
Osint.Add_File (Get_Name_String (Sfile));
+ Put_In_Q := True;
end if;
end loop;
end Insert_Project_Sources;
@@ -4035,6 +5608,126 @@ package body Make is
end if;
end Is_External_Assignment;
+ ---------------------
+ -- Is_In_Obsoleted --
+ ---------------------
+
+ function Is_In_Obsoleted (F : Name_Id) return Boolean is
+ begin
+ if F = No_File then
+ return False;
+
+ else
+ declare
+ Name : String := Get_Name_String (F);
+ First : Natural := Name'Last;
+ F2 : Name_Id := F;
+
+ begin
+ while First > Name'First
+ and then Name (First - 1) /= Directory_Separator
+ and then Name (First - 1) /= '/'
+ loop
+ First := First - 1;
+ end loop;
+
+ if First /= Name'First then
+ Name_Len := 0;
+ Add_Str_To_Name_Buffer (Name (First .. Name'Last));
+ F2 := Name_Find;
+ end if;
+
+ return Obsoleted.Get (F2);
+ end;
+ end if;
+ end Is_In_Obsoleted;
+
+ ----------------------------
+ -- Is_In_Object_Directory --
+ ----------------------------
+
+ function Is_In_Object_Directory
+ (Source_File : File_Name_Type;
+ Full_Lib_File : File_Name_Type) return Boolean
+ is
+ begin
+ -- There is something to check only when using project files.
+ -- Otherwise, this function returns True (last line of the function).
+
+ if Main_Project /= No_Project then
+ declare
+ Source_File_Name : constant String :=
+ Get_Name_String (Source_File);
+ Saved_Verbosity : constant Verbosity := Prj.Com.Current_Verbosity;
+ Project : Project_Id := No_Project;
+ Path_Name : Name_Id := No_Name;
+ Data : Project_Data;
+
+ begin
+ -- Call Get_Reference to know the ultimate extending project of
+ -- the source. Call it with verbosity default to avoid verbose
+ -- messages.
+
+ Prj.Com.Current_Verbosity := Default;
+ Prj.Env.
+ Get_Reference
+ (Source_File_Name => Source_File_Name,
+ Project => Project,
+ Path => Path_Name);
+ Prj.Com.Current_Verbosity := Saved_Verbosity;
+
+ -- If this source is in a project, check that the ALI file is
+ -- in its object directory. If it is not, return False, so that
+ -- the ALI file will not be skipped.
+
+ -- If the source is not in an extending project, we fall back to
+ -- the general case and return True at the end of the function.
+
+ if Project /= No_Project
+ and then Projects.Table (Project).Extends /= No_Project
+ then
+ Data := Projects.Table (Project);
+
+ declare
+ Object_Directory : constant String :=
+ Normalize_Pathname
+ (Get_Name_String
+ (Data.Object_Directory));
+
+ Olast : Natural := Object_Directory'Last;
+
+ Lib_File_Directory : constant String :=
+ Normalize_Pathname (Dir_Name
+ (Get_Name_String (Full_Lib_File)));
+
+ Llast : Natural := Lib_File_Directory'Last;
+
+ begin
+ -- For directories, Normalize_Pathname may or may not put
+ -- a directory separator at the end, depending on its input.
+ -- Remove any last directory separator before comparaison.
+ -- Returns True only if the two directories are the same.
+
+ if Object_Directory (Olast) = Directory_Separator then
+ Olast := Olast - 1;
+ end if;
+
+ if Lib_File_Directory (Llast) = Directory_Separator then
+ Llast := Llast - 1;
+ end if;
+
+ return Object_Directory (Object_Directory'First .. Olast) =
+ Lib_File_Directory (Lib_File_Directory'First .. Llast);
+ end;
+ end if;
+ end;
+ end if;
+
+ -- When the source is not in a project file, always return True
+
+ return True;
+ end Is_In_Object_Directory;
+
---------------
-- Is_Marked --
---------------
@@ -4049,21 +5742,21 @@ package body Make is
----------
procedure Link (ALI_File : File_Name_Type; Args : Argument_List) is
- Link_Args : Argument_List (Args'First .. Args'Last + 1);
+ Link_Args : Argument_List (1 .. Args'Length + 1);
Success : Boolean;
begin
- Link_Args (Args'Range) := Args;
-
Get_Name_String (ALI_File);
- Link_Args (Args'Last + 1) := new String'(Name_Buffer (1 .. Name_Len));
+ Link_Args (1) := new String'(Name_Buffer (1 .. Name_Len));
+
+ Link_Args (2 .. Args'Length + 1) := Args;
GNAT.OS_Lib.Normalize_Arguments (Link_Args);
Display (Gnatlink.all, Link_Args);
if Gnatlink_Path = null then
- Osint.Fail ("error, unable to locate " & Gnatlink.all);
+ Make_Failed ("error, unable to locate ", Gnatlink.all);
end if;
GNAT.OS_Lib.Spawn (Gnatlink_Path.all, Link_Args, Success);
@@ -4195,26 +5888,80 @@ package body Make is
Set_Name_Table_Byte (N, B or Mark);
end Mark_Directory;
- ----------------------
- -- Object_File_Name --
- ----------------------
+ -----------------------------
+ -- Recursive_Compute_Depth --
+ -----------------------------
+
+ procedure Recursive_Compute_Depth
+ (Project : Project_Id;
+ Visited : Project_Array;
+ Depth : Natural)
+ is
+ List : Project_List;
+ Proj : Project_Id;
+ OK : Boolean;
+ New_Visited : constant Project_Array := Visited & Project;
- function Object_File_Name (Source : String) return String is
begin
- -- If the source name has an extension, then replace it with
- -- the object suffix.
+ -- Nothing to do if there is no project
+
+ if Project = No_Project then
+ return;
+ end if;
+
+ -- If current depth of project is lower than Depth, adjust it
+
+ if Projects.Table (Project).Depth < Depth then
+ Projects.Table (Project).Depth := Depth;
+ end if;
+
+ List := Projects.Table (Project).Imported_Projects;
+
+ -- Visit each imported project
+
+ while List /= Empty_Project_List loop
+ Proj := Project_Lists.Table (List).Project;
+ List := Project_Lists.Table (List).Next;
+
+ OK := True;
+
+ -- To avoid endless loops due to cycles with limited widts,
+ -- do not revisit a project that is already in the chain of imports
+ -- that brought us here.
+
+ for J in Visited'Range loop
+ if Visited (J) = Proj then
+ OK := False;
+ exit;
+ end if;
+ end loop;
- for Index in reverse Source'First + 1 .. Source'Last loop
- if Source (Index) = '.' then
- return Source (Source'First .. Index - 1) & Object_Suffix;
+ if OK then
+ Recursive_Compute_Depth
+ (Project => Proj,
+ Visited => New_Visited,
+ Depth => Depth + 1);
end if;
end loop;
- -- If there is no dot, or if it is the first character, just add the
- -- object suffix.
+ -- Visit a project being extended, if any
- return Source & Object_Suffix;
- end Object_File_Name;
+ Recursive_Compute_Depth
+ (Project => Projects.Table (Project).Extends,
+ Visited => New_Visited,
+ Depth => Depth + 1);
+ end Recursive_Compute_Depth;
+
+ -----------------------
+ -- Sigint_Intercpted --
+ -----------------------
+
+ procedure Sigint_Intercepted is
+ begin
+ Write_Line ("*** Interrupted ***");
+ Delete_All_Temp_Files;
+ OS_Exit (1);
+ end Sigint_Intercepted;
-------------------
-- Scan_Make_Arg --
@@ -4228,15 +5975,30 @@ package body Make is
return;
end if;
+ -- If the previous switch has set the Project_File_Name_Present
+ -- flag (that is we have seen a -P alone), then the next argument is
+ -- the name of the project file.
+
+ if Project_File_Name_Present and then Project_File_Name = null then
+ if Argv (1) = '-' then
+ Make_Failed ("project file name missing after -P");
+
+ else
+ Project_File_Name_Present := False;
+ Project_File_Name := new String'(Argv);
+ end if;
+
-- If the previous switch has set the Output_File_Name_Present
-- flag (that is we have seen a -o), then the next argument is
-- the name of the output executable.
- if Opt.Output_File_Name_Present and then not Output_File_Name_Seen then
+ elsif Opt.Output_File_Name_Present
+ and then not Output_File_Name_Seen
+ then
Output_File_Name_Seen := True;
if Argv (1) = '-' then
- Fail ("output file name missing after -o");
+ Make_Failed ("output file name missing after -o");
else
Add_Switch ("-o", Linker, And_Save => And_Save);
@@ -4245,8 +6007,9 @@ package body Make is
-- specified explicitly.
if Executable_Suffix'Length /= 0
- and then Argv (Argv'Last - Executable_Suffix'Length + 1
- .. Argv'Last) /= Executable_Suffix
+ and then (Argv'Length <= Executable_Suffix'Length
+ or else Argv (Argv'Last - Executable_Suffix'Length + 1
+ .. Argv'Last) /= Executable_Suffix)
then
Add_Switch
(Argv & Executable_Suffix,
@@ -4257,7 +6020,41 @@ package body Make is
end if;
end if;
- -- Then check if we are dealing with -cargs/-bargs/-largs
+ -- If the previous switch has set the Object_Directory_Present flag
+ -- (that is we have seen a -D), then the next argument is
+ -- the path name of the object directory..
+
+ elsif Opt.Object_Directory_Present
+ and then not Object_Directory_Seen
+ then
+ Object_Directory_Seen := True;
+
+ if Argv (1) = '-' then
+ Make_Failed ("object directory path name missing after -D");
+
+ elsif not Is_Directory (Argv) then
+ Make_Failed ("cannot find object directory """, Argv, """");
+
+ else
+ Add_Lib_Search_Dir (Argv);
+
+ -- Specify the object directory to the binder
+
+ Add_Switch ("-aO" & Argv, Binder, And_Save => And_Save);
+
+ -- Record the object directory. Make sure it ends with a directory
+ -- separator.
+
+ if Argv (Argv'Last) = Directory_Separator then
+ Object_Directory_Path := new String'(Argv);
+
+ else
+ Object_Directory_Path :=
+ new String'(Argv & Directory_Separator);
+ end if;
+ end if;
+
+ -- Then check if we are dealing with -cargs/-bargs/-largs/-margs
elsif Argv = "-bargs"
or else
@@ -4284,7 +6081,8 @@ package body Make is
elsif Program_Args = Linker
and then Argv = "-o"
then
- Fail ("switch -o not allowed within a -largs. Use -o directly.");
+ Make_Failed ("switch -o not allowed within a -largs. " &
+ "Use -o directly.");
-- Check to see if we are reading switches after a -cargs,
-- -bargs or -largs switch. If yes save it.
@@ -4301,12 +6099,10 @@ package body Make is
elsif Program_Args = Compiler then
if Argv (3 .. Argv'Last) /= "-" then
Add_Src_Search_Dir (Argv (3 .. Argv'Last));
-
end if;
elsif Program_Args = Binder then
Add_Lib_Search_Dir (Argv (3 .. Argv'Last));
-
end if;
end if;
@@ -4319,7 +6115,7 @@ package body Make is
and then Argv (1 .. 6) = "--GCC="
then
declare
- Program_Args : Argument_List_Access :=
+ Program_Args : constant Argument_List_Access :=
Argument_String_To_List
(Argv (7 .. Argv'Last));
@@ -4342,7 +6138,7 @@ package body Make is
and then Argv (1 .. 11) = "--GNATBIND="
then
declare
- Program_Args : Argument_List_Access :=
+ Program_Args : constant Argument_List_Access :=
Argument_String_To_List
(Argv (12 .. Argv'Last));
@@ -4363,7 +6159,7 @@ package body Make is
and then Argv (1 .. 11) = "--GNATLINK="
then
declare
- Program_Args : Argument_List_Access :=
+ Program_Args : constant Argument_List_Access :=
Argument_String_To_List
(Argv (12 .. Argv'Last));
begin
@@ -4383,11 +6179,22 @@ package body Make is
then
Add_Switch (Argv, Compiler, And_Save => And_Save);
Add_Switch (Argv, Binder, And_Save => And_Save);
+ Add_Switch (Argv, Linker, And_Save => And_Save);
if Argv'Length <= 6 or else Argv (6) /= '=' then
- Osint.Fail ("missing path for --RTS");
+ Make_Failed ("missing path for --RTS");
else
+ -- Check that this is the first time we see this switch or
+ -- if it is not the first time, the same path is specified.
+
+ if RTS_Specified = null then
+ RTS_Specified := new String'(Argv (7 .. Argv'Last));
+
+ elsif RTS_Specified.all /= Argv (7 .. Argv'Last) then
+ Make_Failed ("--RTS cannot be specified multiple times");
+ end if;
+
-- Valid --RTS switch
Opt.No_Stdinc := True;
@@ -4395,10 +6202,11 @@ package body Make is
Opt.RTS_Switch := True;
declare
- Src_Path_Name : String_Ptr :=
+ Src_Path_Name : constant String_Ptr :=
Get_RTS_Search_Dir
(Argv (7 .. Argv'Last), Include);
- Lib_Path_Name : String_Ptr :=
+
+ Lib_Path_Name : constant String_Ptr :=
Get_RTS_Search_Dir
(Argv (7 .. Argv'Last), Objects);
@@ -4406,27 +6214,31 @@ package body Make is
if Src_Path_Name /= null and then
Lib_Path_Name /= null
then
- Add_Search_Dirs (Src_Path_Name, Include);
- Add_Search_Dirs (Lib_Path_Name, Objects);
+ -- Set the RTS_*_Path_Name variables, so that the correct
+ -- directories will be set when
+ -- Osint.Add_Default_Search_Dirs will be called later.
+
+ RTS_Src_Path_Name := Src_Path_Name;
+ RTS_Lib_Path_Name := Lib_Path_Name;
elsif Src_Path_Name = null
and Lib_Path_Name = null then
- Osint.Fail ("RTS path not valid: missing " &
- "adainclude and adalib directories");
+ Make_Failed ("RTS path not valid: missing " &
+ "adainclude and adalib directories");
elsif Src_Path_Name = null then
- Osint.Fail ("RTS path not valid: missing " &
- "adainclude directory");
+ Make_Failed ("RTS path not valid: missing adainclude " &
+ "directory");
elsif Lib_Path_Name = null then
- Osint.Fail ("RTS path not valid: missing " &
- "adalib directory");
+ Make_Failed ("RTS path not valid: missing adalib " &
+ "directory");
end if;
end;
end if;
else
- Fail ("unknown switch: ", Argv);
+ Make_Failed ("unknown switch: ", Argv);
end if;
-- If we have seen a regular switch process it
@@ -4434,7 +6246,7 @@ package body Make is
elsif Argv (1) = '-' then
if Argv'Length = 1 then
- Fail ("switch character cannot be followed by a blank");
+ Make_Failed ("switch character cannot be followed by a blank");
-- -I-
@@ -4446,7 +6258,7 @@ package body Make is
elsif (Argv'Length = 3 and then Argv (3) = '-')
or else (Argv'Length = 4 and then Argv (4) = '-')
then
- Fail ("trailing ""-"" at the end of ", Argv, " forbidden.");
+ Make_Failed ("trailing ""-"" at the end of ", Argv, " forbidden.");
-- -Idir
@@ -4454,13 +6266,7 @@ package body Make is
Add_Src_Search_Dir (Argv (3 .. Argv'Last));
Add_Lib_Search_Dir (Argv (3 .. Argv'Last));
Add_Switch (Argv, Compiler, And_Save => And_Save);
- Add_Switch ("-aO" & Argv (3 .. Argv'Last),
- Binder,
- And_Save => And_Save);
-
- -- No need to pass any source dir to the binder
- -- since gnatmake call it with the -x flag
- -- (ie do not check source time stamp)
+ Add_Switch (Argv, Binder, And_Save => And_Save);
-- -aIdir (to gcc this is like a -I switch)
@@ -4469,6 +6275,7 @@ package body Make is
Add_Switch ("-I" & Argv (4 .. Argv'Last),
Compiler,
And_Save => And_Save);
+ Add_Switch (Argv, Binder, And_Save => And_Save);
-- -aOdir
@@ -4503,17 +6310,40 @@ package body Make is
elsif Argv (2) = 'L' then
Add_Switch (Argv, Linker, And_Save => And_Save);
- -- For -gxxxxx,-pg : give the switch to both the compiler and the
- -- linker (except for -gnatxxx which is only for the compiler)
+ -- For -gxxxxx,-pg,-mxxx: give the switch to both the compiler and
+ -- the linker (except for -gnatxxx which is only for the compiler)
elsif
(Argv (2) = 'g' and then (Argv'Last < 5
or else Argv (2 .. 5) /= "gnat"))
or else Argv (2 .. Argv'Last) = "pg"
+ or else (Argv (2) = 'm' and then Argv'Last > 2)
then
Add_Switch (Argv, Compiler, And_Save => And_Save);
Add_Switch (Argv, Linker, And_Save => And_Save);
+ -- -C=<mapping file>
+
+ elsif Argv'Last > 2 and then Argv (2) = 'C' then
+ if And_Save then
+ if Argv (3) /= '=' or else Argv'Last <= 3 then
+ Make_Failed ("illegal switch ", Argv);
+ end if;
+
+ Gnatmake_Mapping_File := new String'(Argv (4 .. Argv'Last));
+ end if;
+
+ -- -D
+
+ elsif Argv'Last = 2 and then Argv (2) = 'D' then
+ if Project_File_Name /= null then
+ Make_Failed ("-D cannot be used in conjunction with a " &
+ "project file");
+
+ else
+ Scan_Make_Switches (Argv);
+ end if;
+
-- -d
elsif Argv (2) = 'd'
@@ -4521,6 +6351,17 @@ package body Make is
then
Opt.Display_Compilation_Progress := True;
+ -- -i
+
+ elsif Argv'Last = 2 and then Argv (2) = 'i' then
+ if Project_File_Name /= null then
+ Make_Failed ("-i cannot be used in conjunction with a " &
+ "project file");
+
+ else
+ Scan_Make_Switches (Argv);
+ end if;
+
-- -j (need to save the result)
elsif Argv (2) = 'j' then
@@ -4547,13 +6388,30 @@ package body Make is
Do_Bind_Step := False;
Do_Link_Step := False;
- -- -Pprj (only once, and only on the command line)
+ -- -U
- elsif Argv'Last > 2
- and then Argv (2) = 'P'
+ elsif Argv (2) = 'U'
+ and then Argv'Last = 2
then
+ Unique_Compile_All_Projects := True;
+ Unique_Compile := True;
+ Opt.Compile_Only := True;
+ Do_Bind_Step := False;
+ Do_Link_Step := False;
+
+ -- -Pprj or -P prj (only once, and only on the command line)
+
+ elsif Argv (2) = 'P' then
if Project_File_Name /= null then
- Fail ("cannot have several project files specified");
+ Make_Failed ("cannot have several project files specified");
+
+ elsif Object_Directory_Path /= null then
+ Make_Failed ("-D cannot be used in conjunction with a " &
+ "project file");
+
+ elsif In_Place_Mode then
+ Make_Failed ("-i cannot be used in conjunction with a " &
+ "project file");
elsif not And_Save then
@@ -4564,20 +6422,15 @@ package body Make is
("either the tool is not ""project-aware"" or " &
"a project file is specified inside a project file");
- else
- Project_File_Name := new String' (Argv (3 .. Argv'Last));
- end if;
+ elsif Argv'Last = 2 then
- -- -S (Assemble)
+ -- -P is used alone: the project file name is the next option
- -- Since no object file is created, don't check object
- -- consistency.
+ Project_File_Name_Present := True;
- elsif Argv (2) = 'S'
- and then Argv'Last = 2
- then
- Opt.Check_Object_Consistency := False;
- Add_Switch (Argv, Compiler, And_Save => And_Save);
+ else
+ Project_File_Name := new String'(Argv (3 .. Argv'Last));
+ end if;
-- -vPx (verbosity of the parsing of the project files)
@@ -4598,16 +6451,6 @@ package body Make is
end case;
end if;
- -- -Wx (need to save the result)
-
- elsif Argv (2) = 'W' then
- Scan_Make_Switches (Argv);
-
- if And_Save then
- Saved_WC_Encoding_Method := Wide_Character_Encoding_Method;
- Saved_WC_Encoding_Method_Set := True;
- end if;
-
-- -Xext=val (External assignment)
elsif Argv (2) = 'X'
@@ -4657,12 +6500,13 @@ package body Make is
-- By default all switches with more than one character
-- or one character switches which are not in 'a' .. 'z'
- -- (except 'C' and 'M') are passed to the compiler, unless we are
- -- dealing with a debug switch (starts with 'd')
+ -- (except 'C', 'F', and 'M') are passed to the compiler,
+ -- unless we are dealing with a debug switch (starts with 'd')
elsif Argv (2) /= 'd'
- and then Argv (2 .. Argv'Last) /= "M"
and then Argv (2 .. Argv'Last) /= "C"
+ and then Argv (2 .. Argv'Last) /= "F"
+ and then Argv (2 .. Argv'Last) /= "M"
and then (Argv'Length > 2 or else Argv (2) not in 'a' .. 'z')
then
Add_Switch (Argv, Compiler, And_Save => And_Save);
@@ -4680,155 +6524,6 @@ package body Make is
end if;
end Scan_Make_Arg;
- -------------------
- -- Set_Ada_Paths --
- -------------------
-
- procedure Set_Ada_Paths
- (For_Project : Prj.Project_Id;
- Including_Libraries : Boolean)
- is
- New_Ada_Include_Path : constant String_Access :=
- Prj.Env.Ada_Include_Path (For_Project);
-
- New_Ada_Objects_Path : constant String_Access :=
- Prj.Env.Ada_Objects_Path
- (For_Project, Including_Libraries);
-
- begin
- -- If ADA_INCLUDE_PATH needs to be changed (we are not using the same
- -- project file), set the new ADA_INCLUDE_PATH
-
- if New_Ada_Include_Path /= Current_Ada_Include_Path then
- Current_Ada_Include_Path := New_Ada_Include_Path;
-
- if Original_Ada_Include_Path'Length = 0 then
- Setenv ("ADA_INCLUDE_PATH",
- New_Ada_Include_Path.all);
-
- else
- -- If there existed an ADA_INCLUDE_PATH at the invocation of
- -- gnatmake, concatenate new ADA_INCLUDE_PATH with the original.
-
- Setenv ("ADA_INCLUDE_PATH",
- Original_Ada_Include_Path.all &
- Path_Separator &
- New_Ada_Include_Path.all);
- end if;
-
- if Opt.Verbose_Mode then
- declare
- Include_Path : constant String_Access :=
- Getenv ("ADA_INCLUDE_PATH");
-
- begin
- -- Display the new ADA_INCLUDE_PATH
-
- Write_Str ("ADA_INCLUDE_PATH = """);
- Prj.Util.Write_Str
- (S => Include_Path.all,
- Max_Length => Max_Line_Length,
- Separator => Path_Separator);
- Write_Str ("""");
- Write_Eol;
- end;
- end if;
- end if;
-
- -- If ADA_OBJECTS_PATH needs to be changed (we are not using the same
- -- project file), set the new ADA_OBJECTS_PATH
-
- if New_Ada_Objects_Path /= Current_Ada_Objects_Path then
- Current_Ada_Objects_Path := New_Ada_Objects_Path;
-
- if Original_Ada_Objects_Path'Length = 0 then
- Setenv ("ADA_OBJECTS_PATH",
- New_Ada_Objects_Path.all);
-
- else
- -- If there existed an ADA_OBJECTS_PATH at the invocation of
- -- gnatmake, concatenate new ADA_OBJECTS_PATH with the original.
-
- Setenv ("ADA_OBJECTS_PATH",
- Original_Ada_Objects_Path.all &
- Path_Separator &
- New_Ada_Objects_Path.all);
- end if;
-
- if Opt.Verbose_Mode then
- declare
- Objects_Path : constant String_Access :=
- Getenv ("ADA_OBJECTS_PATH");
-
- begin
- -- Display the new ADA_OBJECTS_PATH
-
- Write_Str ("ADA_OBJECTS_PATH = """);
- Prj.Util.Write_Str
- (S => Objects_Path.all,
- Max_Length => Max_Line_Length,
- Separator => Path_Separator);
- Write_Str ("""");
- Write_Eol;
- end;
- end if;
- end if;
-
- end Set_Ada_Paths;
-
- ---------------------
- -- Set_Library_For --
- ---------------------
-
- procedure Set_Library_For
- (Project : Project_Id;
- There_Are_Libraries : in out Boolean)
- is
- begin
- -- Case of library project
-
- if Projects.Table (Project).Library then
- There_Are_Libraries := True;
-
- -- Add the -L switch
-
- Linker_Switches.Increment_Last;
- Linker_Switches.Table (Linker_Switches.Last) :=
- new String'("-L" &
- Get_Name_String
- (Projects.Table (Project).Library_Dir));
-
- -- Add the -l switch
-
- Linker_Switches.Increment_Last;
- Linker_Switches.Table (Linker_Switches.Last) :=
- new String'("-l" &
- Get_Name_String
- (Projects.Table (Project).Library_Name));
-
- -- Add the Wl,-rpath switch if library non static
-
- if Projects.Table (Project).Library_Kind /= Static then
- declare
- Option : constant String_Access :=
- MLib.Tgt.Linker_Library_Path_Option
- (Get_Name_String
- (Projects.Table (Project).Library_Dir));
-
- begin
- if Option /= null then
- Linker_Switches.Increment_Last;
- Linker_Switches.Table (Linker_Switches.Last) :=
- Option;
- end if;
-
- end;
-
- end if;
-
- end if;
- end Set_Library_For;
-
-----------------
-- Switches_Of --
-----------------
@@ -4838,8 +6533,7 @@ package body Make is
Source_File_Name : String;
Naming : Naming_Data;
In_Package : Package_Id;
- Allow_ALI : Boolean)
- return Variable_Value
+ Allow_ALI : Boolean) return Variable_Value
is
Switches : Variable_Value;
@@ -4867,19 +6561,19 @@ package body Make is
Last : Positive := Source_File_Name'Length;
Spec_Suffix : constant String :=
Get_Name_String (Naming.Current_Spec_Suffix);
- Impl_Suffix : constant String :=
- Get_Name_String (Naming.Current_Impl_Suffix);
+ Body_Suffix : constant String :=
+ Get_Name_String (Naming.Current_Body_Suffix);
Truncated : Boolean := False;
begin
Name (1 .. Last) := Source_File_Name;
- if Last > Impl_Suffix'Length
- and then Name (Last - Impl_Suffix'Length + 1 .. Last) =
- Impl_Suffix
+ if Last > Body_Suffix'Length
+ and then Name (Last - Body_Suffix'Length + 1 .. Last) =
+ Body_Suffix
then
Truncated := True;
- Last := Last - Impl_Suffix'Length;
+ Last := Last - Body_Suffix'Length;
end if;
if not Truncated
@@ -4933,8 +6627,9 @@ package body Make is
---------------------------
procedure Test_If_Relative_Path
- (Switch : in out String_Access;
- Parent : String_Access)
+ (Switch : in out String_Access;
+ Parent : String_Access;
+ Including_L_Switch : Boolean := True)
is
begin
if Switch /= null then
@@ -4950,7 +6645,7 @@ package body Make is
if Sw'Length >= 3
and then (Sw (2) = 'A'
or else Sw (2) = 'I'
- or else Sw (2) = 'L')
+ or else (Including_L_Switch and then Sw (2) = 'L'))
then
Start := 3;
@@ -4965,18 +6660,20 @@ package body Make is
then
Start := 4;
- elsif Sw'Length >= 7
- and then Sw (2 .. 6) = "-RTS="
- then
- Start := 7;
else
return;
end if;
+ -- Because relative path arguments to --RTS= may be relative
+ -- to the search directory prefix, those relative path
+ -- arguments are not converted.
+
if not Is_Absolute_Path (Sw (Start .. Sw'Last)) then
- if Parent = null then
- Fail ("relative search path switches (""" & Sw &
- """) are not allowed inside project files");
+ if Parent = null or else Parent'Length = 0 then
+ Make_Failed
+ ("relative search path switches (""",
+ Sw,
+ """) are not allowed");
else
Switch :=
@@ -4987,6 +6684,18 @@ package body Make is
Sw (Start .. Sw'Last));
end if;
end if;
+
+ else
+ if not Is_Absolute_Path (Sw) then
+ if Parent = null or else Parent'Length = 0 then
+ Make_Failed
+ ("relative paths (""", Sw, """) are not allowed");
+
+ else
+ Switch :=
+ new String'(Parent.all & Directory_Separator & Sw);
+ end if;
+ end if;
end if;
end;
end if;
@@ -5036,4 +6745,8 @@ package body Make is
Write_Eol;
end Verbose_Msg;
+begin
+ Prj.Com.Fail := Make_Failed'Access;
+ MLib.Fail := Make_Failed'Access;
+ -- Make sure that in case of failure, the temp files will be deleted
end Make;