Merge tag 'upstream-tar/1.0.0_0alpha'

Upstream version 1.0.0~0alpha
This commit is contained in:
Jordan Justen 2015-01-19 10:06:51 -08:00
commit 217bc3dec1
12582 changed files with 1447153 additions and 675643 deletions

View File

@ -1,228 +1,808 @@
Initial author, project lead, target of blame:
Graydon Hoare <graydon@mozilla.com>
Other authors:
Rust was written by these fine people:
A.J. Gardner <mrhota@users.noreply.github.com>
Aaron Friel <mayreply@aaronfriel.com>
Aaron Laursen <aaronlaursen@gmail.com>
Aaron Liblong <liblonga@physics.utoronto.ca>
Aaron Raimist <aaron@aaronraimist.com>
Aaron Todd <github@opprobrio.us>
Aaron Turon <aturon@mozilla.com>
Aaron Weiss <aaronweiss74@gmail.com>
Adam Bozanich <adam.boz@gmail.com>
Adam Szkoda <adaszko@gmail.com>
Adolfo Ochagavía <aochagavia92@gmail.com>
Adrien Brault <adrien.brault@gmail.com>
Adrien Tétar <adri-from-59@hotmail.fr>
Ahmed Charles <ahmedcharles@gmail.com>
Aidan Cully <github@aidan.users.panix.com>
Akos Kiss <akiss@inf.u-szeged.hu>
Alan Andrade <alan.andradec@gmail.com>
Alan Williams <mralert@gmail.com>
Aleksander Balicki <balicki.aleksander@gmail.com>
Aleksandr Koshlo <sash7ko@gmail.com>
Alex Crichton <alex@alexcrichton.com>
Alex Gaynor <alex.gaynor@gmail.com>
Alex Lyon <arcterus@mail.com>
Alex Rønne Petersen <alex@lycus.org>
Alex Whitney <aw1209@ic.ac.uk>
Alexander Light <scialexlight@gmail.com>
Alexander Stavonin <a.stavonin@gmail.com>
Alexandre Gagnon <alxgnon@gmail.com>
Alexandros Tasos <sdi1100085@di.uoa.gr>
Alexei Sholik <alcosholik@gmail.com>
Alexis Beingessner <a.beingessner@gmail.com>
Alfie John <alfiej@fastmail.fm>
Ali Smesseim <smesseim.ali@gmail.com>
Alisdair Owens <awo101@zepler.net>
Aljaž "g5pw" Srebrnič <a2piratesoft@gmail.com>
Amy Unger <amy.e.unger@gmail.com>
Anders Kaseorg <andersk@mit.edu>
Andre Arko <andre@arko.net>
Andrea Canciani <ranma42@gmail.com>
Andreas Gal <gal@mozilla.com>
Andreas Martens <andreasm@fastmail.fm>
Andreas Neuhaus <zargony@zargony.com>
Andreas Ots <andreasots@gmail.com>
Andreas Tolfsen <ato@mozilla.com>
Andrei Formiga <archimedes_siracusa@hotmail.com>
Andrew Cann <shum@canndrew.org>
Andrew Chin <achin@eminence32.net>
Andrew Dunham <andrew@du.nham.ca>
Andrew Gallant <jamslam@gmail.com>
Andrew Paseltiner <apaseltiner@gmail.com>
Andrew Poelstra <asp11@sfu.ca>
Andrew Wagner <drewm1980@gmail.com>
Angus Lees <gus@inodes.org>
Anthony Juckel <ajuckel@gmail.com>
Anton Löfgren <anton.lofgren@gmail.com>
Arcterus <Arcterus@mail.com>
Ariel Ben-Yehuda <ariel.byd@gmail.com>
Arjan Topolovec <arjan.top@gmail.com>
Arkaitz Jimenez <arkaitzj@gmail.com>
Armin Ronacher <armin.ronacher@active-4.com>
Arpad Borsos <arpad.borsos@googlemail.com>
Artem <artemciy@gmail.com>
Arthur Liao <arthurtw8@gmail.com>
Ashok Gautham <ScriptDevil@gmail.com>
Austin Bonander <austin.bonander@gmail.com>
Austin King <shout@ozten.com>
Austin Seipp <mad.one@gmail.com>
Axel Viala <axel.viala@darnuria.eu>
Aydin Kim <ladinjin@hanmail.net>
auREAX <mark@xn--hwg34fba.ws>
Barosl Lee <vcs@barosl.com>
Ben Alpert <ben@benalpert.com>
Ben Blum <bblum@andrew.cmu.edu>
Ben Foppa <benjamin.foppa@gmail.com>
Ben Gamari <bgamari.foss@gmail.com>
Ben Harris <mail@bharr.is>
Ben Kelly <ben@wanderview.com>
Ben Noordhuis <info@bnoordhuis.nl>
Ben S <ogham@bsago.me>
Ben Striegel <ben.striegel@gmail.com>
Benjamin Adamson <adamson.benjamin@gmail.com>
Benjamin Herr <ben@0x539.de>
Benjamin Jackman <ben@jackman.biz>
Benjamin Kircher <benjamin.kircher@gmail.com>
Benjamin Peterson <benjamin@python.org>
Bheesham Persaud <bheesham123@hotmail.com>
Bilal Husain <bilal@bilalhusain.com>
Bill Fallon <bill.fallon@robos.li>
Bill Myers <bill_myers@outlook.com>
Bill Wendling <wendling@apple.com>
Birunthan Mohanathas <birunthan@mohanathas.com>
Björn Steinbrink <bsteinbr@gmail.com>
Boris Egorov <egorov@linux.com>
Bouke van der Bijl <boukevanderbijl@gmail.com>
Brandon Sanderson <singingboyo@gmail.com>
Brandon Waskiewicz <brandon.waskiewicz@gmail.com>
Branimir <branimir@volomp.com>
Brendan Cully <brendan@kublai.com>
Brendan Eich <brendan@mozilla.org>
Brendan McLoughlin <btmcloughlin@gmail.com>
Brendan Zabarauskas <bjzaba@yahoo.com.au>
Brett Cannon <brett@python.org>
Brian Anderson <banderson@mozilla.com>
Brian Dawn <brian.t.dawn@gmail.com>
Brian J Brennan <brianloveswords@gmail.com>
Brian J. Burg <burg@cs.washington.edu>
Brian Koropoff <bkoropoff@gmail.com>
Brian Leibig <brian.leibig@gmail.com>
Bruno de Oliveira Abinader <bruno.d@partner.samsung.com>
Bryan Dunsmore <dunsmoreb@gmail.com>
Byron Williams <byron@112percent.com>
Cadence Marseille <cadencemarseille@gmail.com>
Caitlin Potter <snowball@defpixel.com>
Cameron Zwarich <zwarich@mozilla.com>
Carl-Anton Ingmarsson <mail@carlanton.se>
Carlos <toqueteos@gmail.com>
Carol Nichols <cnichols@thinkthroughmath.com>
Carol Willing <carolcode@willingconsulting.com>
Carter Tazio Schonwald <carter.schonwald@gmail.com>
Chase Southwood <chase.southwood@gmail.com>
Chris Double <chris.double@double.co.nz>
Chris Morgan <me@chrismorgan.info>
Chris Nixon <chris.nixon@sigma.me.uk>
Chris Peterson <cpeterson@mozilla.com>
Chris Pressey <cpressey@gmail.com>
Chris Sainty <csainty@hotmail.com>
Chris Shea <cmshea@gmail.com>
Chris Wong <lambda.fairy@gmail.com>
Christoph Burgdorf <christoph.burgdorf@bvsn.org>
Christopher Bergqvist <spambox0@digitalpoetry.se>
Christopher Kendell <ckendell@outlook.com>
Chuck Ries <chuck.ries@gmail.com>
Clark Gaebel <cg.wowus.cg@gmail.com>
Clinton Ryan <clint.ryan3@gmail.com>
Cody P Schafer <dev@codyps.com>
Cody Schroeder <codys@cs.washington.edu>
Cole Mickens <cole.mickens@gmail.com>
Colin Davidson <colrdavidson@gmail.com>
Colin Sherratt <colin.sherratt@gmail.com>
Conrad Kleinespel <conradk@conradk.com>
Corey Farwell <coreyf+rust@rwell.org>
Corey Ford <corey@coreyford.name>
Corey Richardson <corey@octayn.net>
Cristi Burcă <scribu@gmail.com>
DJUrsus <colinvh@divitu.com>
Damian Gryski <damian@gryski.com>
Damien Grassart <damien@grassart.com>
Damien Radtke <dradtke@channeliq.com>
Damien Schoof <damien.schoof@gmail.com>
Daniel Brooks <db48x@db48x.net>
Daniel Farina <daniel@fdr.io>
Dan Albert <danalbert@google.com>
Dan Burkert <dan@danburkert.com>
Dan Connolly <dckc@madmode.com>
Dan Luu <danluu@gmail.com>
Daniel Brooks <db48x@db48x.net>
Daniel Fagnan <dnfagnan@gmail.com>
Daniel Farina <daniel@fdr.io>
Daniel Hofstetter <daniel.hofstetter@42dh.com>
Daniel Luz <dev@mernen.com>
Daniel MacDougall <dmacdougall@gmail.com>
Daniel Micay <danielmicay@gmail.com>
Daniel Patterson <dbp@riseup.net>
Daniel Ralston <Wubbulous@gmail.com>
Daniel Rosenwasser <DanielRosenwasser@gmail.com>
Daniel Ursache Dogariu <contact@danniel.net>
Dave Herman <dherman@mozilla.com>
Dave Hodder <dmh@dmh.org.uk>
David Creswick <dcrewi@gyrae.net>
David Forsythe <dforsythe@gmail.com>
David Halperin <halperin.dr@gmail.com>
David Klein <david.klein@baesystemsdetica.com>
David Manescu <david.manescu@gmail.com>
David Rajchenbach-Teller <dteller@mozilla.com>
David Renshaw <dwrenshaw@gmail.com>
David Vazgenovich Shakaryan <dvshakaryan@gmail.com>
Davis Silverman <sinistersnare@gmail.com>
Derecho <derecho@sector5d.org>
Derek Chiang <derekchiang93@gmail.com>
Derek Guenther <dguenther9@gmail.com>
Derek Harland <derek.harland@finq.co.nz>
Diego Giagio <diego@giagio.com>
Diego Ongaro <ongaro@cs.stanford.edu>
Diggory Hardy <diggory.hardy@gmail.com>
Dimitri Krassovski <labria@startika.com>
Dirk Gadsden <dirk@esherido.com>
Dirk Leifeld <leifeld@posteo.de>
Dirkjan Bussink <d.bussink@gmail.com>
Div Shekhar <div@pagerduty.com>
Dmitry Ermolov <epdmitry@yandex.ru>
Dmitry Promsky <dmitry@willworkforcookies.com>
Dmitry Vasiliev <dima@hlabs.org>
Do Nhat Minh <mrordinaire@gmail.com>
Donovan Preston <donovanpreston@gmail.com>
Douglas Young <rcxdude@gmail.com>
Drew Willcoxon <adw@mozilla.com>
Dylan Braithwaite <dylanbraithwaite1@gmail.com>
Dzmitry Malyshau <kvarkus@gmail.com>
Earl St Sauver <estsauver@gmail.com>
Eduard Bopp <eduard.bopp@aepsil0n.de>
Eduard Burtescu <edy.burt@gmail.com>
Eduardo Bautista <me@eduardobautista.com>
Edward Wang <edward.yu.wang@gmail.com>
Edward Z. Yang <ezyang@cs.stanford.edu>
Ehsanul Hoque <ehsanul@ehsanul.com>
Elliott Slaughter <elliottslaughter@gmail.com>
Elly Fong-Jones <elly@leptoquark.net>
Emanuel Rylke <ema-fox@web.de>
Eric Allen <ericpallen@gmail.com>
Eric Biggers <ebiggers3@gmail.com>
Eric Holk <eric.holk@gmail.com>
Eric Holmes <eric@ejholmes.net>
Eric Kidd <git@randomhacks.net>
Eric Martin <e.a.martin1337@gmail.com>
Eric Reed <ecreed@cs.washington.edu>
Erick Tryzelaar <erick.tryzelaar@gmail.com>
Erik Lyon <elyon001@local.fake>
Erik Price <erik.price16@gmail.com>
Erik Rose <erik@mozilla.com>
Erwan <erwan.ricq@gmail.com>
Etienne Millon <me@emillon.org>
Eunchong Yu <kroisse@gmail.com>
Evan Klitzke <evan@eklitzke.org>
Evan McClanahan <evan@evanmcc.com>
Evgeny Sologubov
Fabian Deutsch <fabian.deutsch@gmx.de>
Fabrice Desré <fabrice@desre.org>
FakeKane <andrewyli@gmail.com>
Falco Hirschenberger <falco.hirschenberger@gmail.com>
Fedor Indutny <fedor.indutny@gmail.com>
Felix Crux <felixc@felixcrux.com>
Felix Raimundo <felix.raimundo@telecom-paristech.fr>
Felix S. Klock II <pnkfelix@pnkfx.org>
Flaper Fesp <flaper87@gmail.com>
Flavio Percoco <flaper87@gmail.com>
Florian Gilcher <florian.gilcher@asquera.de>
Florian Hahn <flo@fhahn.com>
Florian Hartwig <florian.j.hartwig@gmail.com>
Florian Wilkens <floya@live.de>
Florian Zeitz <florob@babelmonkeys.de>
Francisco Souza <f@souza.cc>
Franklin Chen <franklinchen@franklinchen.com>
Gábor Horváth <xazax.hun@gmail.com>
Gabriel <g2p.code@gmail.com>
Gareth Daniel Smith <garethdanielsmith@gmail.com>
gifnksm <makoto.nksm@gmail.com>
Gary Linscott <glinscott@gmail.com>
Gary M. Josack <gary@byoteki.com>
Gavin Baker <gavinb@antonym.org>
Geoff Hill <geoff@geoffhill.org>
Geoffroy Couprie <geo.couprie@gmail.com>
George Papanikolaou <g3orge.app@gmail.com>
Georges Dubus <georges.dubus@gmail.com>
Gil Cottle <rc@redtown.org>
Gioele Barabucci <gioele@svario.it>
Gleb Kozyrev <gleb@gkoz.com>
Glenn Willen <gwillen@nerdnet.org>
Gonçalo Cabrita <_@gmcabrita.com>
Graham Fawcett <fawcett@uwindsor.ca>
Graham Fawcett <graham.fawcett@gmail.com>
Grahame Bowland <grahame@angrygoats.net>
Graydon Hoare <graydon@mozilla.com>
Grigoriy <ohaistarlight@gmail.com>
Guillaume Pinot <texitoi@texitoi.eu>
Gyorgy Andrasek <jurily@gmail.com>
Gábor Horváth <xazax.hun@gmail.com>
Gábor Lehel <glaebhoerl@gmail.com>
Haitao Li <lihaitao@gmail.com>
hansjorg <hansjorg@gmail.com>
Hanno Braun <mail@hannobraun.de>
Harry Marr <harry.marr@gmail.com>
Heather <heather@cynede.net>
Herman J. Radtke III <hermanradtke@gmail.com>
HeroesGrave <heroesgrave@gmail.com>
Hong Chulju <ang0123dev@gmail.com>
Honza Strnad <hanny.strnad@gmail.com>
Hugo Jobling <hello@thisishugo.com>
Huon Wilson <dbau.pp+github@gmail.com>
Ian Connolly <iconnolly@mozilla.com>
Ian D. Bollinger <ian.bollinger@gmail.com>
Ian Daniher <it.daniher@gmail.com>
Igor Bukanov <igor@mir2.org>
Ilya Dmitrichenko <ilya@xively.com>
Ilyong Cho <ilyoan@gmail.com>
Isaac Aggrey <isaac.aggrey@gmail.com>
Isaac Dupree <antispam@idupree.com>
Ivan Enderlin <ivan.enderlin@hoa-project.net>
Ivan Petkov <ivanppetkov@gmail.com>
Ivan Ukhov <ivan.ukhov@gmail.com>
Ivano Coppola <rgbfirefox@gmail.com>
J. J. Weber <jjweber@gmail.com>
J.C. Moyer <jmoyer1992@gmail.com>
JONNALAGADDA Srinivas <js@ojuslabs.com>
Jack Heizer <jack.heizer@gmail.com>
Jack Moffitt <jack@metajack.im>
Jacob Edelman <edelman.jd@gmail.com>
Jacob Harris Cryer Kragh <jhckragh@gmail.com>
Jacob Hegna <jacobhegna@gmail.com>
Jacob Parker <j3parker@csclub.uwaterloo.ca>
Jaemin Moon <jaemin.moon@samsung.com>
Jag Talon <talon.jag@gmail.com>
Jake Goulding <jake.goulding@gmail.com>
Jake Kaufman <theevocater@gmail.com>
Jake Kerr <kodafox@gmail.com>
Jake Scott <jake.net@gmail.com>
Jakub Bukaj <jakub@jakub.cc>
Jakub Wieczorek <jakubw@jakubw.net>
James Miller <bladeon@gmail.com>
James Deng <cnjamesdeng@gmail.com>
James Hurst <jamesrhurst@users.noreply.github.com>
James Lal <james@lightsofapollo.com>
James Laverack <james@jameslaverack.com>
James Miller <james@aatch.net>
James Rowe <jroweboy@gmail.com>
James Sanders <sanderjd@gmail.com>
James Tranovich <james@openhorizonlabs.com>
Jan Kobler <eng1@koblersystems.de>
Jan Niklas Hasse <jhasse@gmail.com>
Jannis Harder <jix@jixco.de>
Jared Roesch <roeschinc@gmail.com>
Jarod Liu <liuyuanzhi@gmail.com>
Jashank Jeremy <jashank@rulingia.com>
Jason Fager <jfager@gmail.com>
Jason Orendorff <jorendorff@mozilla.com>
Jason Thompson <jason@jthompson.ca>
Jason Toffaletti <jason@topsy.com>
Jauhien Piatlicki <jauhien@gentoo.org>
Jay Anderson <jayanderson0@gmail.com>
Jed Davis <jld@panix.com>
Jed Estep <aje@jhu.edu>
Jeff Balogh <jbalogh@mozilla.com>
Jeff Muizelaar <jmuizelaar@mozilla.com>
Jeff Olson <olson.jeffery@gmail.com>
Jeff Parsons <jeffdougson@gmail.com>
Jeffrey Yasskin <jyasskin@gmail.com>
Jeong YunWon <jeong@youknowone.org>
Jelte Fennema <github-tech@jeltef.nl>
Jens Nockert <jens@nockert.se>
Jeong YunWon <jeong@youknowone.org>
Jeremy Letang <letang.jeremy@gmail.com>
Jesse Jones <jesse9jones@gmail.com>
Jesse Luehrs <doy@tozt.net>
Jesse Ray <jesse@localhost.localdomain>
Jesse Ruderman <jruderman@gmail.com>
Jihyun Yu <jihyun@nclab.kaist.ac.kr>
Jim Apple <jbapple+rust@google.com>
Jim Blandy <jimb@red-bean.com>
Jim Radford <radford@blackbean.org>
Jimmie Elvenmark <flugsio@gmail.com>
Jimmy Lu <jimmy.lu.2011@gmail.com>
J. J. Weber <jjweber@gmail.com>
Jimmy Zelinskie <jimmyzelinskie@gmail.com>
Joe Pletcher <joepletcher@gmail.com>
Joe Schafer <joe@jschaf.com>
Johannes Hoff <johshoff@gmail.com>
Johannes Löthberg <johannes@kyriasis.com>
Johannes Muenzel <jmuenzel@gmail.com>
John Albietz <inthecloud247@gmail.com>
John Barker <jebarker@gmail.com>
John Clements <clements@racket-lang.org>
John Fresco <john.fresco@utah.edu>
John Gallagher <jgallagher@bignerdranch.com>
John Kleint <jk@hinge.co>
John Kåre Alsaker <john.kare.alsaker@gmail.com>
John Louis Walker <injyuw@gmail.com>
John Schmidt <john.schmidt.h@gmail.com>
John Simon <john@johnsoft.com>
Jon Haddad <jon@jonhaddad.com>
Jon Morton <jonanin@gmail.com>
Jonas Hietala <tradet.h@gmail.com>
Jonathan Bailey <jbailey@mozilla.com>
Jonathan Boyett <jonathan@failingservers.com>
Jonathan Reem <jonathan.reem@gmail.com>
Jonathan S <gereeter@gmail.com>
Jonathan Sternberg <jonathansternberg@gmail.com>
Joonas Javanainen <joonas.javanainen@gmail.com>
Jordi Boggiano <j.boggiano@seld.be>
Jorge Aparicio <japaricious@gmail.com>
Joris Rehm <joris.rehm@wakusei.fr>
Joseph Crail <jbcrail@gmail.com>
Joseph Martin <pythoner6@gmail.com>
Joseph Rushton Wakeling <joe@webdrake.net>
Josh Haberman <jhaberman@gmail.com>
Josh Matthews <josh@joshmatthews.net>
Josh Stone <cuviper@gmail.com>
Joshua Clark <joshua.clark@txstate.edu>
Joshua Wise <joshua@joshuawise.com>
Joshua Yanovski <pythonesque@gmail.com>
Julia Evans <julia@jvns.ca>
Julian Orth <ju.orth@gmail.com>
Junyoung Cho <june0.cho@samsung.com>
Jyun-Yan You <jyyou@cs.nctu.edu.tw>
JustAPerson <jpriest8@ymail.com>
Justin Noah <justinnoah@gmail.com>
Jyun-Yan You <jyyou.tw@gmail.com>
Kang Seonghoon <kang.seonghoon@mearie.org>
Kang Seonghoon <public+git@mearie.org>
Kasey Carrothers <kaseyc.808@gmail.com>
Keegan McAllister <kmcallister@mozilla.com>
Kelly Wilson <wilsonk@cpsc.ucalgary.ca>
Ken Tossell <ken@tossell.net>
Keshav Kini <keshav.kini@gmail.com>
Kevin Atkinson <kevina@cs.utah.edu>
Kevin Ballard <kevin@sb.org>
Kevin Butler <haqkrs@gmail.com>
Kevin Cantu <me@kevincantu.org>
klutzy <klutzytheklutzy@gmail.com>
Kevin Mehall <km@kevinmehall.net>
Kevin Murphy <kemurphy.cmu@gmail.com>
Kevin Walter <kevin.walter.private@googlemail.com>
Kevin Yap <me@kevinyap.ca>
Kiet Tran <ktt3ja@gmail.com>
Kyeongwoon Lee <kyeongwoon.lee@samsung.com>
Lars Bergstrom <lbergstrom@mozilla.com>
Laurence Tratt <laurie@tratt.net>
Laurent Bonnans <bonnans.l@gmail.com>
Lawrence Velázquez <larryv@alum.mit.edu>
Leah Hanson <astrieanna@gmail.com>
Lee Wondong <wdlee91@gmail.com>
LemmingAvalanche <haugsbakk@yahoo.no>
Lennart Kudling <github@kudling.de>
Léo Testard <leo.testard@gmail.com>
Liigo Zhuang <com.liigo@gmail.com>
Lindsey Kuper <lindsey@composition.al>
Lionel Flandrin <lionel.flandrin@parrot.com>
Luca Bruno <lucab@debian.org>
Luqman Aden <laden@csclub.uwaterloo.ca>
Luis de Bethencourt <luis@debethencourt.com>
Luke Metz <luke.metz@students.olin.edu>
Luqman Aden <me@luqman.ca>
Magnus Auvinen <magnus.auvinen@gmail.com>
Mahmut Bulut <mahmutbulut0@gmail.com>
Makoto Nakashima <makoto.nksm+github@gmail.com>
Manish Goregaokar <manishsmail@gmail.com>
Marcel Rodrigues <marcelgmr@gmail.com>
Margaret Meyerhofer <mmeyerho@andrew.cmu.edu>
Marijn Haverbeke <marijnh@gmail.com>
Mark Lacey <641@rudkx.com>
Mark Rowe <mrowe@bdash.net.nz>
Mark Sinclair <mark.edward.x@gmail.com>
Mark Vian <mrv.caseus@gmail.com>
Markus Siemens <siemens1993@gmail.com>
Markus Unterwaditzer <markus@unterwaditzer.net>
Marti Raudsepp <marti@juffo.org>
Martin DeMello <martindemello@gmail.com>
Martin Olsson <martin@minimum.se>
Martin Pool <mbp@sourcefrog.net>
Marvin Löbel <loebel.marvin@gmail.com>
Matej Lach <matej.lach@gmail.com>
Mateusz Czapliński <czapkofan@gmail.com>
Mathieu Poumeyrol <kali@zoy.org>
Mathijs van de Nes <git@mathijs.vd-nes.nl>
Matt Brubeck <mbrubeck@limpet.net>
Matt Carberry <carberry.matt@gmail.com>
Matt Coffin <mcoffin13@gmail.com>
Matt McPherrin <git@mcpherrin.ca>
Matt Murphy <matthew.john.murphy@gmail.com>
Matt Windsor <mattwindsor@btinternet.com>
Matthew Auld <matthew.auld@intel.com>
Matthew Iselin <matthew@theiselins.net>
Matthew McPherrin <matthew@mcpherrin.ca>
Matthew O'Connor <thegreendragon@gmail.com>
Matthias Einwag <matthias.einwag@live.com>
Matthijs Hofstra <thiezz@gmail.com>
Matthijs van der Vleuten <git@zr40.nl>
Max Penet <max.penet@gmail.com>
Maxim Kolganov <kolganov.mv@gmail.com>
Maxime Quandalle <maxime@quandalle.com>
Maximilian Haack <mxhaack@gmail.com>
Maya Nitu <maya_nitu@yahoo.com>
Meyer S. Jacobs <meyermagic@gmail.com>
Micah Chalmer <micah@micahchalmer.net>
Michael Arntzenius <daekharel@gmail.com>
Michael Bebenita <mbebenita@mozilla.com>
Michael Dagitses <dagitses@google.com>
Michael Darakananda <pongad@gmail.com>
Michael Fairley <michaelfairley@gmail.com>
Michael Gehring <mg@ebfe.org>
Michael Kainer <kaini1123@gmail.com>
Michael Letterle <michael.letterle@gmail.com>
Michael Matuzak <mmatuzak@gmail.com>
Michael Neumann <mneumann@ntecs.de>
Michael Pratt <michael@pratt.im>
Michael Reinhard <mcreinhard@users.noreply.github.com>
Michael Sproul <micsproul@gmail.com>
Michael Sullivan <sully@msully.net>
Michael Williams <m.t.williams@live.com>
Michael Woerister <michaelwoerister@gmail>
Michael Zhou <moz@google.com>
Mick Koch <kchmck@gmail.com>
Mickaël Delahaye <mickael.delahaye@gmail.com>
Mihnea Dobrescu-Balaur <mihnea@linux.com>
Mike Boutin <mike.boutin@gmail.com>
Mike Dilger <mike@efx.co.nz>
Mike Pedersen <noctune9@gmail.com>
Mike Robinson <mikeprobinsonuk@gmail.com>
Mikko Perttunen <cyndis@kapsi.fi>
Ms2ger <ms2ger@gmail.com>
Mukilan Thiagarajan <mukilanthiagarajan@gmail.com>
Mukilan Thiyagarajan <mukilanthiagarajan@gmail.com>
Murarth <murarth@gmail.com>
NODA, Kai <nodakai@gmail.com>
Nafis <nhoss2@gmail.com>
Nathan Froyd <froydnj@gmail.com>
Nathan Typanski <ntypanski@gmail.com>
Nathan Zadoks <nathan@nathan7.eu>
Nathaniel Herman <nherman@college.harvard.edu>
Neil Pankey <npankey@gmail.com>
NiccosSystem <niccossystem@gmail.com>
Nicholas Bishop <nicholasbishop@gmail.com>
Nick Cameron <ncameron@mozilla.com>
Nick Desaulniers <ndesaulniers@mozilla.com>
Nick Howell <howellnick@gmail.com>
Nicolas Silva <nical.silva@gmail.com>
Niels Egberts <git@nielsegberts.nl>
Niels langager Ellegaard <niels.ellegaard@gmail.com>
Nif Ward <nif.ward@gmail.com>
Nikita Pekin <contact@nikitapek.in>
Niklas Koep <niklas.koep@gmail.com>
Niko Matsakis <niko@alum.mit.edu>
Noam Yorav-Raphael <noamraph@gmail.com>
Noufal Ibrahim <noufal@nibrahim.net.in>
O S K Chaitanya <osk@medhas.org>
OGINO Masanori <masanori.ogino@gmail.com>
Oliver Schneider <oliver.schneider@kit.edu>
Olivier Saut <osaut@airpost.net>
Olle Jonsson <olle.jonsson@gmail.com>
Or Brostovski <tohava@gmail.com>
Oren Hazi <oren.hazi@gmail.com>
Orphée Lafond-Lummis <o@orftz.com>
Patrick Walton <pwalton@mozilla.com>
P1start <rewi-github@whanau.org>
Pablo Brasero <pablo@pablobm.com>
Palmer Cox <p@lmercox.com>
Paolo Falabella <paolo.falabella@gmail.com>
Pascal Hertleif <killercup@gmail.com>
Patrick Reisert <kpreisert@gmail.com>
Patrick Walton <pcwalton@mimiga.net>
Patrick Yevsukov <patrickyevsukov@users.noreply.github.com>
Patrik Kårlin <patrik.karlin@gmail.com>
Paul Collier <paul@paulcollier.ca>
Paul Stansifer <paul.stansifer@gmail.com>
Paul Woolcock <pwoolcoc+github@gmail.com>
Pavel Panchekha <me@pavpanchekha.com>
Pawel Olzacki <p.olzacki2@samsung.com>
Pedro Larroy <pedro.larroy@here.com>
Peer Aramillo Irizar <peer.aramillo.irizar@gmail.com>
Peter Atashian <retep998@gmail.com>
Peter Elmers <peter.elmers@yahoo.com>
Peter Hull <peterhull90@gmail.com>
Peter Marheine <peter@taricorp.net>
Peter Williams <peter@newton.cx>
Peter Zotov <whitequark@whitequark.org>
Petter Remen <petter.remen@gmail.com>
Phil Dawes <pdawes@drw.com>
Phil Ruffwind <rf@rufflewind.com>
Philip Munksgaard <pmunksgaard@gmail.com>
Philipp Brüschweiler <blei42@gmail.com>
Philipp Gesang <phg42.2a@gmail.com>
Piotr Czarnecki <pioczarn@gmail.com>
Piotr Jawniak <sawyer47@gmail.com>
Piotr Szotkowski <chastell@chastell.net>
Piotr Zolnierek <pz@anixe.pl>
Pradeep Kumar <gohanpra@gmail.com>
Prudhvi Krishna Surapaneni <me@prudhvi.net>
Pythoner6 <pythoner6@gmail.com>
Q.P.Liu <qpliu@yahoo.com>
Rafael Ávila de Espíndola <respindola@mozilla.com>
Ralph Bodenner <rkbodenner+github@gmail.com>
Ralph Giles <giles@thaumas.net>
Ramkumar Ramachandra <artagnon@gmail.com>
Randati <anttivan@gmail.com>
Raphael Catolino <raphael.catolino@gmail.com>
Raphael Speyer <rspeyer@gmail.com>
Ray Clanan <rclanan@utopianconcept.com>
Reilly Watson <reillywatson@gmail.com>
Renato Riccieri Santos Zannon <renato@rrsz.com.br>
Renato Zannon <renato@rrsz.com.br>
Reuben Morais <reuben.morais@gmail.com>
Ricardo M. Correia <rcorreia@wizy.org>
Rich Lane <rlane@club.cc.cmu.edu>
Richard Diamond <wichard@vitalitystudios.com>
Richo Healey <richo@psych0tik.net>
Rick Waldron <waldron.rick@gmail.com>
Ricky Taylor <rickytaylor26@gmail.com>
Rob Arnold <robarnold@cs.cmu.edu>
Rob Hoelz <rob@hoelz.ro>
Robert Buonpastore <robert.buonpastore@gmail.com>
Robert Clipsham <robert@octarineparrot.com>
Robert Gawdzik <rgawdzik@hotmail.com>
Robert Irelan <rirelan@gmail.com>
Robert Knight <robertknight@gmail.com>
Robert Millar <robert.millar@cantab.net>
Robin Gloster <robin@loc-com.de>
Robin Stocker <robin@nibor.org>
Rohit Joshi <rohit.joshi@capitalone.com>
Roland Tanglao <roland@rolandtanglao.com>
Rolf Timmermans <rolftimmermans@voormedia.com>
Rolf van de Krol <info@rolfvandekrol.nl>
Ron Dahlgren <ronald.dahlgren@gmail.com>
Roy Crihfield <rscrihf@gmail.com>
Roy Frostig <rfrostig@mozilla.com>
Russell <rpjohnst@gmail.com>
Ruud van Asseldonk <dev@veniogames.com>
Ryan Mulligan <ryan@ryantm.com>
Ryan Scheel <ryan.havvy@gmail.com>
Ryman <haqkrs@gmail.com>
Rüdiger Sonderfeld <ruediger@c-plusplus.de>
S Pradeep Kumar <gohanpra@gmail.com>
Salem Talha <salem.a.talha@gmail.com>
Samuel Chase <samebchase@gmail.com>
Samuel Neves <sneves@dei.uc.pt>
Sander Mathijs van Veen <smvv@kompiler.org>
Sangeun Kim <sammy.kim@samsung.com>
Sankha Narayan Guria <sankha93@gmail.com>
Santiago Pastorino <santiago@wyeworks.com>
Santiago Rodriguez <sanrodari@gmail.com>
Saurabh Anand <saurabhanandiit@gmail.com>
Scott Jenkins <scottdjwales@gmail.com>
Scott Lawrence <bytbox@gmail.com>
Sean Chalmers <sclhiannan@gmail.com>
Sean Collins <sean@cllns.com>
Sean Gillespie <sean.william.g@gmail.com>
Sean Jensen-Grey <seanj@xyke.com>
Sean McArthur <sean.monstar@gmail.com>
Sean Moon <ssamoon@ucla.edu>
Sean Stangl <sstangl@mozilla.com>
Sean T Allen <sean@monkeysnatchbanana.com>
Sebastian N. Fernandez <cachobot@gmail.com>
Seth Pink <sethpink@gmail.com>
Sebastian Zaha <sebastian.zaha@gmail.com>
Sebastien Martini <seb@dbzteam.org>
Seo Sanghyeon <sanxiyn@gmail.com>
sevrak <sevrak@rediffmail.com>
Seonghyun Kim <sh8281.kim@samsung.com>
Sergio Benitez <sbenitez@mit.edu>
Seth Pink <sethpink@gmail.com>
Seth Pollack <sethpollack@users.noreply.github.com>
Shamir Khodzha <khodzha.sh@gmail.com>
SiegeLord <slabode@aim.com>
Simon Barber-Dueck <sbarberdueck@gmail.com>
Simon Sapin <simon@exyr.org>
startling <tdixon51793@gmail.com>
Simon Persson <simon@flaskpost.org>
Simon Sapin <simon.sapin@exyr.org>
Simon Wollwage <mail.wollwage@gmail.com>
Simonas Kazlauskas <git@kazlauskas.me>
Son <leson.phung@gmail.com>
Squeaky <squeaky_pl@gmx.com>
Stefan Bucur <stefan.bucur@epfl.ch>
Stefan Plantikow <stefan.plantikow@googlemail.com>
Stepan Koltsov <stepan.koltsov@gmail.com>
Sterling Greene <sterling.greene@gmail.com>
Steve Klabnik <steve@steveklabnik.com>
Steven De Coeyer <steven@banteng.be>
Steven Fackler <sfackler@gmail.com>
Steven Sheldon <steven@sasheldon.com>
Steven Stewart-Gallus <sstewartgallus00@langara.bc.ca>
Strahinja Val Markovic <val@markovic.io>
Stuart Pernsteiner <stuart@pernsteiner.org>
Subhash Bhushan <subhash.bhushan@kaybus.com>
Sylvestre Ledru <sylvestre@debian.org>
Sébastien Chauvel <eichi237@mailoo.org>
Sébastien Crozet <developer@crozet.re>
Sébastien Paolacci <sebastien.paolacci@gmail.com>
Tamir Duberstein <tamird@squareup.com>
Taras Shpot <mrshpot@gmail.com>
Taylor Hutchison <seanthutchison@gmail.com>
Ted Horst <ted.horst@earthlink.net>
Thad Guidry <thadguidry@gmail.com>
Thomas Backman <serenity@exscape.org>
Thomas Daede <daede003@umn.edu>
Till Hoeppner <till@hoeppner.ws>
Tim Brooks <tim.brooks@staples.com>
Tim Chevalier <chevalier@alum.wellesley.edu>
Tim Joseph Dumol <tim@timdumol.com>
Tim Kuehn <tkuehn@cmu.edu>
Tim Taubert <tim@timtaubert.de>
Timon Rapp <timon@zaeda.net>
Timothée Ravier <tim@siosm.fr>
Titouan Vervack <tivervac@gmail.com>
Tobba <tobias.haegermarck@gmail.com>
Tobias Bucher <tobiasbucher5991@gmail.com>
Tohava <tohava@tohava-laptop.(none)>
Tom Jakubowski <tom@crystae.net>
Tom Lee <github@tomlee.co>
Tomas Sedovic <tomas@sedovic.cz>
Tommy M. McGuire <mcguire@crsr.net>
Tomoki Aonuma <uasi@99cm.org>
Tony Young <tony@rfw.name>
Torsten Weber <TorstenWeber12@gmail.com>
Trent Ogren <tedwardo2@gmail.com>
Trinick <slicksilver555@mac.com>
Tshepang Lekhonkhobe <tshepang@gmail.com>
Tuncer Ayaz <tuncer.ayaz@gmail.com>
TyOverby <ty@pre-alpha.com>
Tycho Sci <tychosci@gmail.com>
Tyler Bindon <martica@martica.org>
U-NOV2010\eugals
Ulysse Carion <ulysse@ulysse.io>
Utkarsh Kukreti <utkarshkukreti@gmail.com>
Uwe Dauernheim <uwe@dauernheim.net>
Vadim Chugunov <vadimcn@gmail.com>
Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Valentin Tsatskin <vtsatskin@mozilla.com>
Valerii Hiora <valerii.hiora@gmail.com>
Victor Berger <victor.berger@m4x.org>
Victor van den Elzen <victor.vde@gmail.com>
Vijay Korapaty <rust@korapaty.com>
Viktor Dahl <pazaconyoman@gmail.com>
Vincent Belliard <vincent@famillebelliard.fr>
Vinzent Steinberg <Vinzent.Steinberg@gmail.com>
Virgile Andreani <virgile.andreani@anbuco.fr>
Vitali Haravy <HumaneProgrammer@gmail.com>
Vivek Galatage <vivekgalatage@gmail.com>
Vladimir Matveev <vladimir.matweev@gmail.com>
Vladimir Pouzanov <farcaller@gmail.com>
Vladimir Smola <smola.vladimir@gmail.com>
Volker Mische <volker.mische@gmail.com>
Wade Mealing <wmealing@gmail.com>
William Ting <william.h.ting@gmail.com>
WebeWizard <webewizard@gmail.com>
Wendell Smith <wendell.smith@yale.edu>
William Ting <io@williamting.com>
Yasuhiro Fujii <y-fujii@mimosa-pudica.net>
YawarRaza7349 <YawarRaza7349@gmail.com>
Yazhong Liu <yorkiefixer@gmail.com>
Yehuda Katz <wycats@gmail.com>
York Xiang <bombless@126.com>
Young-il Choi <duddlf.choi@samsung.com>
Youngmin Yoo <youngmin.yoo@samsung.com>
Youngsoo Son <ysson83@gmail.com>
Yuri Albuquerque <yuridenommus@gmail.com>
Yuri Kunde Schlesner <yuriks@yuriks.net>
Zach Kamsler <smoo.master@gmail.com>
Zach Pomerantz <zmp@umich.edu>
Zack Corr <zack@z0w0.me>
Zack Slayton <zack.slayton@gmail.com>
Zbigniew Siciarz <zbigniew@siciarz.net>
Ziad Hatahet <hatahet@gmail.com>
Zooko Wilcox-O'Hearn <zooko@zooko.com>
aochagavia <aochagavia92@gmail.com>
areski <areski@gmail.com>
arturo <arturo@openframeworks.cc>
auREAX <mark@xn--hwg34fba.ws>
b1nd <clint.ryan3@gmail.com>
bachm <Ab@vapor.com>
blake2-ppc <ulrik.sverdrup@gmail.com>
bluss <bluss>
bombless <bombless@126.com>
bors <bors@rust-lang.org>
chitra
chromatic <chromatic@wgz.org>
comex <comexk@gmail.com>
crhino <piraino.chris@gmail.com>
dan@daramos.com <dan@daramos.com>
darkf <lw9k123@gmail.com>
dgoon <dgoon@dgoon.net>
donkopotamus <general@chocolate-fish.com>
eliovir <eliovir@gmail.com>
elszben <notgonna@tellyou>
flo-l <lacknerflo@gmail.com>
fort <e@mail.com>
free-Runner <aali07@students.poly.edu>
g3xzh <g3xzh@yahoo.com>
gamazeps <gamaz3ps@gmail.com>
gentlefolk <cemacken@gmail.com>
gifnksm <makoto.nksm@gmail.com>
hansjorg <hansjorg@gmail.com>
iancormac84 <wilnathan@gmail.com>
inrustwetrust <inrustwetrust@users.noreply.github.com>
jamesluke <jamesluke@users.noreply.github.com>
jbranchaud <jbranchaud@gmail.com>
jfager <jfager@gmail.com>
jmgrosen <jmgrosen@gmail.com>
jmu303 <muj@bc.edu>
joaoxsouls <joaoxsouls@gmail.com>
jrincayc <jrincayc@users.noreply.github.com>
juxiliary <juxiliary@gmail.com>
jxv <joevargas@hush.com>
klutzy <klutzytheklutzy@gmail.com>
korenchkin <korenchkin2@gmail.com>
kulakowski <george.kulakowski@gmail.com>
kvark <kvarkus@gmail.com>
kwantam <kwantam@gmail.com>
lpy <pylaurent1314@gmail.com>
lucy <ne.tetewi@gmail.com>
lyuts <dioxinu@gmail.com>
m-r-r <raybaudroigm@gmail.com>
maikklein <maikklein@googlemail.com>
masklinn <github.com@masklinn.net>
mchaput <matt@whoosh.ca>
mdinger <mdinger.bugzilla@gmail.com>
mitchmindtree <mitchell.nordine@gmail.com>
moonglum <moonglum@moonbeamlabs.com>
mr.Shu <mr@shu.io>
mrec <mike.capp@gmail.com>
musitdev <philippe.delrieu@free.fr>
nham <hamann.nick@gmail.com>
noam <noam@clusterfoo.com>
novalis <novalis@novalis.org>
oli-obk <github6541940@oli-obk.de>
olivren <o.renaud@gmx.fr>
osa1 <omeragacan@gmail.com>
qwitwa <qwitwa@gmail.com>
reedlepee <reedlepee123@gmail.com>
rjz <rj@rjzaworski.com>
sevrak <sevrak@rediffmail.com>
sheroze1123 <mss385@cornell.edu>
smenardpw <sebastien@knoglr.com>
sp3d <sp3d@github>
startling <tdixon51793@gmail.com>
th0114nd <th0114nd@gmail.com>
theptrk <patrick.tran06@gmail.com>
thiagopnts <thiagopnts@gmail.com>
tinaun <tinagma@gmail.com>
tshakah <tshakah@gmail.com>
ville-h <ville3.14159@gmail.com>
we <vadim.petrochenkov@gmail.com>
whataloadofwhat <unusualmoniker@gmail.com>
wickerwaka <martin.donlon@gmail.com>
xales <xales@naveria.com>
zofrex <zofrex@gmail.com>
zslayton <zack.slayton@gmail.com>
zzmp <zmp@umich.edu>

60
CONTRIBUTING.md Normal file
View File

@ -0,0 +1,60 @@
## How to submit a bug report
If you're just reporting a bug, please see:
http://doc.rust-lang.org/complement-bugreport.html
## Submitting an issue
Please submit issues here for bug reports or implementation details. For feature
requests, language changes, or major changes to the libraries, please submit an
issue against the [RFCs repository](https://github.com/rust-lang/rfcs).
## Pull request procedure
Pull requests should be targeted at Rust's `master` branch.
Before pushing to your Github repo and issuing the pull request,
please do two things:
1. [Rebase](http://git-scm.com/book/en/Git-Branching-Rebasing) your
local changes against the `master` branch. Resolve any conflicts
that arise.
2. Run the full Rust test suite with the `make check` command. You're
not off the hook even if you just stick to documentation; code
examples in the docs are tested as well! Although for simple
wording or grammar fixes, this is probably unnecessary.
Pull requests will be treated as "review requests", and we will give
feedback we expect to see corrected on
[style](https://github.com/rust-lang/rust/wiki/Note-style-guide) and
substance before pulling. Changes contributed via pull request should
focus on a single issue at a time, like any other. We will not accept
pull-requests that try to "sneak" unrelated changes in.
Normally, all pull requests must include regression tests (see
[Note-testsuite](https://github.com/rust-lang/rust/wiki/Note-testsuite))
that test your change. Occasionally, a change will be very difficult
to test for. In those cases, please include a note in your commit
message explaining why.
In the licensing header at the beginning of any files you change,
please make sure the listed date range includes the current year. For
example, if it's 2014, and you change a Rust file that was created in
2010, it should begin:
```
// Copyright 2010-2014 The Rust Project Developers.
```
# Coordination and communication
Get feedback from other developers on
[discuss.rust-lang.org][discuss], and
[#rust-internals][pound-rust-internals].
[pound-rust-internals]: http://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust-internals
[discuss]: http://discuss.rust-lang.org
For more details, please refer to
[Note-development-policy](https://github.com/rust-lang/rust/wiki/Note-development-policy).

301
COPYRIGHT
View File

@ -6,7 +6,7 @@ terms.
Longer version:
The Rust Project is copyright 2013, The Rust Project
The Rust Project is copyright 2014, The Rust Project
Developers (given in the file AUTHORS.txt).
Licensed under the Apache License, Version 2.0
@ -22,85 +22,6 @@ The Rust Project includes packages written by third parties.
The following third party packages are included, and carry
their own copyright notices and license terms:
* The ISAAC pseudo random number generation package. Code
for this package is found in the src/rt/isaac directory,
within this distribution. This package is redistributed
under the following terms, as noted in its source:
By Bob Jenkins, 1996, Public Domain
* The ACME large integer package. Code for this package is
found in the src/rt/bigint directory, within this
distribution. This package is redistributed under the
following terms, as noted in its source:
Copyright © 2000 by Jef Poskanzer <jef@mail.acme.com>.
All rights reserved.
Redistribution and use in source and binary forms, with
or without modification, are permitted provided that the
following conditions are met:
1. Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
2. Redistributions in binary form must reproduce the
above copyright notice, this list of conditions and
the following disclaimer in the documentation and/or
other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* The UTHASH hash table package. Code for this package is
found in the src/rt/uthash directory within this
distribution. This package is redistributed under the
following terms, as noted in its source:
Copyright (c) 2003-2009, Troy D. Hanson
http://uthash.sourceforge.net All rights reserved.
Redistribution and use in source and binary forms, with
or without modification, are permitted provided that the
following conditions are met:
* Redistributions of source code must retain the
above copyright notice, this list of conditions
and the following disclaimer.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGE.
* Two header files that are part of the Valgrind
package. These files are found at src/rt/vg/valgrind.h and
src/rt/vg/memcheck.h, within this distribution. These files
@ -199,63 +120,25 @@ their own copyright notices and license terms:
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGE.
* The auxiliary file src/etc/pkg/modpath.iss contains a
library routine compiled, by Inno Setup, into the Windows
installer binary. This file is licensed under the LGPL,
but, in our legal interpretation, this does not affect the
aggregate "collected work" license of the Rust
distribution (MIT) nor any other components of it. We
version 3, but, in our legal interpretation, this does not
affect the aggregate "collected work" license of the Rust
distribution (MIT/ASL2) nor any other components of it. We
believe that the terms governing distribution of the
binary Windows installer built from modpath.iss are
therefore LGPL, but not the terms governing distribution
of any of the files installed by such an installer (such
as the Rust compiler or runtime libraries themselves).
* The libuv asynchronous I/O library. Code for this package
is found in the src/libuv directory, within this
distribution. This package is redistributed under the
following terms, as noted in its source:
Copyright Joyent, Inc. and other Node contributors. All
rights reserved. Permission is hereby granted, free of
charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), to
deal in the Software without restriction, including
without limitation the rights to use, copy, modify,
merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom
the Software is furnished to do so, subject to the
following conditions:
The above copyright notice and this permission notice
shall be included in all copies or substantial portions
of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
* Additional libraries included in libuv carry separate
BSD-compatible licenses. See src/libuv/LICENSE for
details.
* The src/rt/miniz.c file, carrying an implementation of
RFC1950/RFC1951 DEFLATE, by Rich Geldreich
<richgel99@gmail.com>. All uses of this file are
permitted by the embedded "unlicense" notice
(effectively: public domain with warranty disclaimer).
* LLVM and Clang. Code for this package is found in
src/llvm.
* LLVM. Code for this package is found in src/llvm.
Copyright (c) 2003-2013 University of Illinois at
Urbana-Champaign. All rights reserved.
@ -304,11 +187,90 @@ their own copyright notices and license terms:
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS WITH THE SOFTWARE.
* Additional libraries included in LLVM carry separate
BSD-compatible licenses. See src/llvm/LICENSE.txt for
details.
* compiler-rt, in src/compiler-rt is dual licensed under
LLVM's license and MIT:
Copyright (c) 2009-2014 by the contributors listed in
CREDITS.TXT
All rights reserved.
Developed by:
LLVM Team
University of Illinois at Urbana-Champaign
http://llvm.org
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
documentation files (the "Software"), to deal with the
Software without restriction, including without
limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software
is furnished to do so, subject to the following
conditions:
* Redistributions of source code must retain the
above copyright notice, this list of conditions
and the following disclaimers.
* Redistributions in binary form must reproduce the
above copyright notice, this list of conditions
and the following disclaimers in the documentation
and/or other materials provided with the
distribution.
* Neither the names of the LLVM Team, University of
Illinois at Urbana-Champaign, nor the names of its
contributors may be used to endorse or promote
products derived from this Software without
specific prior written permission.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS WITH THE SOFTWARE.
========================================================
Copyright (c) 2009-2014 by the contributors listed in
CREDITS.TXT
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the
Software without restriction, including without
limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software
is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice
shall be included in all copies or substantial portions
of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
* Portions of the FFI code for interacting with the native ABI
is derived from the Clay programming language, which carries
@ -345,9 +307,100 @@ their own copyright notices and license terms:
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGE.
* Hoedown, the markdown parser, under src/rt/hoedown, is
licensed as follows.
Copyright (c) 2008, Natacha Porté
Copyright (c) 2011, Vicent Martí
Copyright (c) 2013, Devin Torres and the Hoedown authors
Permission to use, copy, modify, and distribute this
software for any purpose with or without fee is hereby
granted, provided that the above copyright notice and
this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR
DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* libbacktrace, under src/libbacktrace:
Copyright (C) 2012-2014 Free Software Foundation, Inc.
Written by Ian Lance Taylor, Google.
Redistribution and use in source and binary forms, with
or without modification, are permitted provided that the
following conditions are met:
(1) Redistributions of source code must retain the
above copyright notice, this list of conditions and
the following disclaimer.
(2) Redistributions in binary form must reproduce
the above copyright notice, this list of conditions
and the following disclaimer in the documentation
and/or other materials provided with the
distribution.
(3) The name of the author may not be used to
endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGE. */
* jemalloc, under src/jemalloc:
Copyright (C) 2002-2014 Jason Evans
<jasone@canonware.com>. All rights reserved.
Copyright (C) 2007-2012 Mozilla Foundation.
All rights reserved.
Copyright (C) 2009-2014 Facebook, Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice(s),
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice(s),
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S)
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S)
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGE.
* Additional copyright may be retained by contributors other
than Mozilla, the Rust Project Authors, or the parties
than Mozilla, the Rust Project Developers, or the parties
enumerated in this file. Such copyright can be determined
on a case-by-case basis by examining the author of each
portion of a file in the revision-control commit records

View File

@ -1,5 +1,4 @@
Copyright (c) 2006-2009 Graydon Hoare
Copyright (c) 2009-2013 Mozilla Foundation
Copyright (c) 2014 The Rust Project Developers
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated

View File

@ -8,7 +8,117 @@
# option. This file may not be copied, modified, or distributed
# except according to those terms.
# An explanation of how the build is structured:
# <help> \(^o^)/
#
# Greetings, adventurer! The Rust Build System is at your service.
#
# Whether you want a genuine copy of `rustc`, access to the latest and
# most authoritative Rust documentation, or even to investigate the
# most intimate workings of the compiler itself, you've come to the
# right place. Let's see what's on the menu.
#
# First, start with one of these build targets:
#
# * all - The default. Build a complete, bootstrapped compiler.
# `rustc` will be in `${target-triple}/stage2/bin/`. Run it
# directly from the build directory if you like. This also
# comes with docs in `doc/`.
#
# * check - Run the complete test suite
#
# * clean - Clean the build repertory. It is advised to run this
# command if you want to build Rust again, after an update
# of the git repository.
#
# * install - Install Rust. Note that installation is not necessary
# to use the compiler.
#
# * uninstall - Uninstall the binaries
#
# For tips on working with The Rust Build System, just:
#
# run `make tips`
#
# Otherwise
#
# run `make`
#
# </help>
#
# <tips>
#
# # The Rust Build System Tip Line
#
# There are a bazillion different targets you might want to build. Here
# are a few ideas.
#
# * docs - Build gobs of HTML documentation and put it into `doc/`
# * check-$(crate) - Test a crate, e.g. `check-std`
# * check-ref - Run the language reference tests
# * check-docs - Test the documentation examples
# * check-stage$(stage)-$(crate) - Test a crate in a specific stage
# * check-stage$(stage)-{rpass,rfail,cfail,rmake,...} - Run tests in src/test/
# * check-stage1-T-$(target)-H-$(host) - Run cross-compiled-tests
#
# Then mix in some of these environment variables to harness the
# ultimate power of The Rust Build System.
#
# * `VERBOSE=1` - Print all commands. Use this to see what's going on.
# * `RUSTFLAGS=...` - Add compiler flags to all `rustc` invocations
# * `JEMALLOC_FLAGS=...` - Pass flags to jemalloc's configure script
#
# * `TESTNAME=...` - Specify the name of tests to run
# * `CHECK_IGNORED=1` - Run normally-ignored tests
# * `PLEASE_BENCH=1` - Run crate benchmarks (enable `--bench` flag)
#
# * `CFG_ENABLE_VALGRIND=1` - Run tests under valgrind
# * `VALGRIND_COMPILE=1` - Run the compiler itself under valgrind
# (may require `CFG_ENABLE_VALGRIND`)
#
# * `NO_REBUILD=1` - Don't rebootstrap when testing std
# (and possibly other crates)
# * `NO_MKFILE_DEPS=1` - Don't rebuild for modified .mk files
#
# * `SAVE_TEMPS=1` - Use `--save-temps` flag on all `rustc` invocations
# * `ASM_COMMENTS=1` - Use `-Z asm-comments`
# * `TIME_PASSES=1` - Use `-Z time-passes`
# * `TIME_LLVM_PASSES=1` - Use `-Z time-llvm-passes`
# * `TRACE=1` - Use `-Z trace`
#
# # Rust recipes for build system success
#
# // Modifying libstd? Use this comment to run unit tests just on your change
# make check-stage1-std NO_REBUILD=1 NO_BENCH=1
#
# // Added a run-pass test? Use this to test running your test
# make check-stage1-rpass TESTNAME=my-shiny-new-test
#
# // Having trouble figuring out which test is failing? Turn off parallel tests
# make check-stage1-std RUST_TEST_TASKS=1
#
# This is hardly all there is to know of The Rust Build System's
# mysteries. The tale continues on the wiki[1][2].
#
# [1]: https://github.com/rust-lang/rust/wiki/Note-getting-started-developing-Rust
# [2]: https://github.com/rust-lang/rust/wiki/Note-testsuite
#
# If you really feel like getting your hands dirty, then:
#
# run `make nitty-gritty`
#
# </tips>
#
# <nitty-gritty>
#
# # The Rust Build System
#
# Gosh I wish there was something useful here (TODO).
#
# # An (old) explanation of how the build is structured:
#
# *Note: Hey, like, this is probably inaccurate, and is definitely
# an outdated and insufficient explanation of the remarkable
# Rust Build System.*
#
# There are multiple build stages (0-3) needed to verify that the
# compiler is properly self-hosting. Each stage is divided between
@ -33,7 +143,7 @@
# stageN - this is the system root, corresponding to, e.g. /usr
# bin - binaries compiled for the host
# lib - libraries used by the host compiler
# rustc - rustc's own place to organize libraries
# rustlib - rustc's own place to organize libraries
# $(target) - target-specific artifacts
# bin - binaries for target architectures
# lib - libraries for target architectures
@ -47,603 +157,106 @@
# libraries are managed and versioned without polluting the common
# areas of the filesystem.
#
# General rust binaries may stil live in the host bin directory; they
# General rust binaries may still live in the host bin directory; they
# will just link against the libraries in the target lib directory.
#
# Admittedly this is a little convoluted.
STAGES = 0 1 2 3
#
# </nitty-gritty>
#
######################################################################
# Residual auto-configuration
# Primary rules
######################################################################
# Recursive wildcard function
# http://blog.jgc.org/2011/07/gnu-make-recursive-wildcard-function.html
rwildcard=$(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2) \
$(filter $(subst *,%,$2),$d))
# Issue #9531: If you change the order of any of the following (or add
# new definitions), make sure definitions always precede their uses,
# especially for the dependency lists of recipes.
# First, load the variables exported by the configure script
include config.mk
# We track all of the object files we might build so that we can find
# and include all of the .d files in one fell swoop.
ALL_OBJ_FILES :=
MKFILE_DEPS := config.stamp $(call rwildcard,$(CFG_SRC_DIR)mk/,*)
NON_BUILD_HOST_TRIPLES = $(filter-out $(CFG_BUILD_TRIPLE),$(CFG_HOST_TRIPLES))
NON_BUILD_TARGET_TRIPLES = $(filter-out $(CFG_BUILD_TRIPLE),$(CFG_TARGET_TRIPLES))
ifneq ($(MAKE_RESTARTS),)
CFG_INFO := $(info cfg: make restarts: $(MAKE_RESTARTS))
endif
CFG_INFO := $(info cfg: build triple $(CFG_BUILD_TRIPLE))
CFG_INFO := $(info cfg: host triples $(CFG_HOST_TRIPLES))
CFG_INFO := $(info cfg: target triples $(CFG_TARGET_TRIPLES))
ifneq ($(wildcard $(NON_BUILD_HOST_TRIPLES)),)
CFG_INFO := $(info cfg: non-build host triples $(NON_BUILD_HOST_TRIPLES))
endif
ifneq ($(wildcard $(NON_BUILD_TARGET_TRIPLES)),)
CFG_INFO := $(info cfg: non-build target triples $(NON_BUILD_TARGET_TRIPLES))
endif
CFG_RUSTC_FLAGS := $(RUSTFLAGS)
CFG_GCCISH_CFLAGS :=
CFG_GCCISH_LINK_FLAGS :=
ifdef CFG_DISABLE_OPTIMIZE
$(info cfg: disabling rustc optimization (CFG_DISABLE_OPTIMIZE))
CFG_RUSTC_FLAGS +=
else
CFG_RUSTC_FLAGS += -O
endif
ifdef CFG_ENABLE_DEBUG
$(info cfg: enabling more debugging (CFG_ENABLE_DEBUG))
CFG_RUSTC_FLAGS += --cfg debug
CFG_GCCISH_CFLAGS += -DRUST_DEBUG
else
CFG_GCCISH_CFLAGS += -DRUST_NDEBUG
endif
ifdef SAVE_TEMPS
CFG_RUSTC_FLAGS += --save-temps
endif
ifdef ASM_COMMENTS
CFG_RUSTC_FLAGS += -Z asm-comments
endif
ifdef TIME_PASSES
CFG_RUSTC_FLAGS += -Z time-passes
endif
ifdef TIME_LLVM_PASSES
CFG_RUSTC_FLAGS += -Z time-llvm-passes
endif
ifdef TRACE
CFG_RUSTC_FLAGS += -Z trace
endif
ifndef DEBUG_BORROWS
RUSTFLAGS_STAGE1 += -Z no-debug-borrows
RUSTFLAGS_STAGE2 += -Z no-debug-borrows
endif
# platform-specific auto-configuration
include $(CFG_SRC_DIR)mk/platform.mk
# Run the stage1/2 compilers under valgrind
ifdef VALGRIND_COMPILE
CFG_VALGRIND_COMPILE :=$(CFG_VALGRIND)
else
CFG_VALGRIND_COMPILE :=
endif
# version-string calculation
CFG_GIT_DIR := $(CFG_SRC_DIR).git
CFG_RELEASE = 0.7
CFG_VERSION = $(CFG_RELEASE)
# windows exe's need numeric versions - don't use anything but
# numbers and dots here
CFG_VERSION_WIN = 0.7
ifneq ($(wildcard $(CFG_GIT)),)
ifneq ($(wildcard $(CFG_GIT_DIR)),)
CFG_VERSION += $(shell git --git-dir=$(CFG_GIT_DIR) log -1 \
--pretty=format:'(%h %ci)')
CFG_VER_HASH = $(shell git --git-dir=$(CFG_GIT_DIR) rev-parse HEAD)
endif
endif
ifdef CFG_ENABLE_VALGRIND
$(info cfg: enabling valgrind (CFG_ENABLE_VALGRIND))
else
CFG_VALGRIND :=
endif
ifdef CFG_BAD_VALGRIND
$(info cfg: disabling valgrind due to its unreliability on this platform)
CFG_VALGRIND :=
endif
######################################################################
# Target-and-rule "utility variables"
######################################################################
ifdef VERBOSE
Q :=
E =
else
Q := @
E = echo $(1)
endif
S := $(CFG_SRC_DIR)
define DEF_X
X_$(1) := $(CFG_EXE_SUFFIX_$(1))
endef
$(foreach target,$(CFG_TARGET_TRIPLES),\
$(eval $(call DEF_X,$(target))))
# Look in doc and src dirs.
VPATH := $(S)doc $(S)src
# "Source" files we generate in builddir along the way.
GENERATED :=
# Delete the built-in rules.
.SUFFIXES:
%:: %,v
%:: RCS/%,v
%:: RCS/%
%:: s.%
%:: SCCS/s.%
######################################################################
# Crates
######################################################################
define DEF_LIBS
CFG_RUNTIME_$(1) :=$(call CFG_LIB_NAME_$(1),rustrt)
CFG_RUSTLLVM_$(1) :=$(call CFG_LIB_NAME_$(1),rustllvm)
CFG_STDLIB_$(1) :=$(call CFG_LIB_NAME_$(1),std)
CFG_EXTRALIB_$(1) :=$(call CFG_LIB_NAME_$(1),extra)
CFG_LIBRUSTC_$(1) :=$(call CFG_LIB_NAME_$(1),rustc)
CFG_LIBSYNTAX_$(1) :=$(call CFG_LIB_NAME_$(1),syntax)
CFG_LIBRUSTPKG_$(1) :=$(call CFG_LIB_NAME_$(1),rustpkg)
CFG_LIBRUSTDOC_$(1) :=$(call CFG_LIB_NAME_$(1),rustdoc)
CFG_LIBRUSTI_$(1) :=$(call CFG_LIB_NAME_$(1),rusti)
CFG_LIBRUST_$(1) :=$(call CFG_LIB_NAME_$(1),rust)
EXTRALIB_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),extra)
STDLIB_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),std)
LIBRUSTC_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),rustc)
LIBSYNTAX_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),syntax)
LIBRUSTPKG_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),rustpkg)
LIBRUSTDOC_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),rustdoc)
LIBRUSTI_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),rusti)
LIBRUST_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),rust)
EXTRALIB_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),extra)
STDLIB_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),std)
LIBRUSTC_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),rustc)
LIBSYNTAX_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),syntax)
LIBRUSTPKG_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),rustpkg)
LIBRUSTDOC_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),rustdoc)
LIBRUSTI_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),rusti)
LIBRUST_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),rust)
endef
$(foreach target,$(CFG_TARGET_TRIPLES),\
$(eval $(call DEF_LIBS,$(target))))
######################################################################
# Standard library variables
######################################################################
STDLIB_CRATE := $(S)src/libstd/std.rs
STDLIB_INPUTS := $(wildcard $(addprefix $(S)src/libstd/, \
*.rs */*.rs */*/*rs */*/*/*rs))
######################################################################
# Extra library variables
######################################################################
EXTRALIB_CRATE := $(S)src/libextra/extra.rs
EXTRALIB_INPUTS := $(wildcard $(addprefix $(S)src/libextra/, \
*.rs */*.rs))
######################################################################
# rustc crate variables
######################################################################
COMPILER_CRATE := $(S)src/librustc/rustc.rs
COMPILER_INPUTS := $(wildcard $(addprefix $(S)src/librustc/, \
*.rs */*.rs */*/*.rs */*/*/*.rs))
LIBSYNTAX_CRATE := $(S)src/libsyntax/syntax.rs
LIBSYNTAX_INPUTS := $(wildcard $(addprefix $(S)src/libsyntax/, \
*.rs */*.rs */*/*.rs))
DRIVER_CRATE := $(S)src/driver/driver.rs
######################################################################
# LLVM macros
######################################################################
# FIXME: x86-ism
LLVM_COMPONENTS=x86 arm mips ipo bitreader bitwriter linker asmparser jit mcjit \
interpreter instrumentation
define DEF_LLVM_VARS
# The configure script defines these variables with the target triples
# separated by Z. This defines new ones with the expected format.
CFG_LLVM_BUILD_DIR_$(1):=$$(CFG_LLVM_BUILD_DIR_$(subst -,_,$(1)))
CFG_LLVM_INST_DIR_$(1):=$$(CFG_LLVM_INST_DIR_$(subst -,_,$(1)))
# Any rules that depend on LLVM should depend on LLVM_CONFIG
LLVM_CONFIG_$(1):=$$(CFG_LLVM_INST_DIR_$(1))/bin/llvm-config$$(X_$(1))
LLVM_MC_$(1):=$$(CFG_LLVM_INST_DIR_$(1))/bin/llvm-mc$$(X_$(1))
LLVM_VERSION_$(1)=$$(shell "$$(LLVM_CONFIG_$(1))" --version)
LLVM_BINDIR_$(1)=$$(shell "$$(LLVM_CONFIG_$(1))" --bindir)
LLVM_INCDIR_$(1)=$$(shell "$$(LLVM_CONFIG_$(1))" --includedir)
LLVM_LIBDIR_$(1)=$$(shell "$$(LLVM_CONFIG_$(1))" --libdir)
LLVM_LIBS_$(1)=$$(shell "$$(LLVM_CONFIG_$(1))" --libs $$(LLVM_COMPONENTS))
LLVM_LDFLAGS_$(1)=$$(shell "$$(LLVM_CONFIG_$(1))" --ldflags)
# On FreeBSD, it may search wrong headers (that are for pre-installed LLVM),
# so we replace -I with -iquote to ensure that it searches bundled LLVM first.
LLVM_CXXFLAGS_$(1)=$$(subst -I, -iquote , $$(shell "$$(LLVM_CONFIG_$(1))" --cxxflags))
LLVM_HOST_TRIPLE_$(1)=$$(shell "$$(LLVM_CONFIG_$(1))" --host-target)
LLVM_AS_$(1)=$$(CFG_LLVM_INST_DIR_$(1))/bin/llvm-as$$(X_$(1))
LLC_$(1)=$$(CFG_LLVM_INST_DIR_$(1))/bin/llc$$(X_$(1))
endef
$(foreach host,$(CFG_HOST_TRIPLES), \
$(eval $(call DEF_LLVM_VARS,$(host))))
######################################################################
# Exports for sub-utilities
######################################################################
# Note that any variable that re-configure should pick up needs to be
# exported
export CFG_SRC_DIR
export CFG_BUILD_DIR
export CFG_VERSION
export CFG_VERSION_WIN
export CFG_BUILD_TRIPLE
export CFG_LLVM_ROOT
export CFG_ENABLE_MINGW_CROSS
export CFG_PREFIX
export CFG_LIBDIR
######################################################################
# Subprograms
######################################################################
######################################################################
# Per-stage targets and runner
######################################################################
define SREQ
# $(1) is the stage number
# $(2) is the target triple
# $(3) is the host triple
# Destinations of artifacts for the host compiler
HROOT$(1)_H_$(3) = $(3)/stage$(1)
HBIN$(1)_H_$(3) = $$(HROOT$(1)_H_$(3))/bin
HLIB$(1)_H_$(3) = $$(HROOT$(1)_H_$(3))/$$(CFG_LIBDIR)
# Destinations of artifacts for target architectures
TROOT$(1)_T_$(2)_H_$(3) = $$(HLIB$(1)_H_$(3))/rustc/$(2)
TBIN$(1)_T_$(2)_H_$(3) = $$(TROOT$(1)_T_$(2)_H_$(3))/bin
TLIB$(1)_T_$(2)_H_$(3) = $$(TROOT$(1)_T_$(2)_H_$(3))/$$(CFG_LIBDIR)
# The name of the standard and extra libraries used by rustc
ifdef CFG_DISABLE_SHAREDSTD
HSTDLIB_DEFAULT$(1)_H_$(3) = \
$$(HLIB$(1)_H_$(3))/libstd.rlib
TSTDLIB_DEFAULT$(1)_T_$(2)_H_$(3) = \
$$(TLIB$(1)_T_$(2)_H_$(3))/libstd.rlib
HEXTRALIB_DEFAULT$(1)_H_$(3) = \
$$(HLIB$(1)_H_$(3))/libextra.rlib
TEXTRALIB_DEFAULT$(1)_T_$(2)_H_$(3) = \
$$(TLIB$(1)_T_$(2)_H_$(3))/libextra.rlib
HLIBRUSTC_DEFAULT$(1)_H_$(3) = \
$$(HLIB$(1)_H_$(3))/librustc.rlib
TLIBRUSTC_DEFAULT$(1)_T_$(2)_H_$(3) = \
$$(TLIB$(1)_T_$(2)_H_$(3))/librustc.rlib
else
HSTDLIB_DEFAULT$(1)_H_$(3) = \
$$(HLIB$(1)_H_$(3))/$(CFG_STDLIB_$(3))
TSTDLIB_DEFAULT$(1)_T_$(2)_H_$(3) = \
$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_STDLIB_$(2))
HEXTRALIB_DEFAULT$(1)_H_$(3) = \
$$(HLIB$(1)_H_$(3))/$(CFG_EXTRALIB_$(3))
TEXTRALIB_DEFAULT$(1)_T_$(2)_H_$(3) = \
$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_EXTRALIB_$(2))
HLIBRUSTC_DEFAULT$(1)_H_$(3) = \
$$(HLIB$(1)_H_$(3))/$(CFG_LIBRUSTC_$(3))
TLIBRUSTC_DEFAULT$(1)_T_$(2)_H_$(3) = \
$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTC_$(2))
endif
# Preqrequisites for using the stageN compiler
HSREQ$(1)_H_$(3) = \
$$(HBIN$(1)_H_$(3))/rustc$$(X_$(3)) \
$$(HLIB$(1)_H_$(3))/$(CFG_RUNTIME_$(3)) \
$$(HLIB$(1)_H_$(3))/$(CFG_RUSTLLVM_$(3)) \
$$(HSTDLIB_DEFAULT$(1)_H_$(3)) \
$$(HEXTRALIB_DEFAULT$(1)_H_$(3)) \
$$(HLIBSYNTAX_DEFAULT$(1)_H_$(3)) \
$$(HLIBRUSTC_DEFAULT$(1)_H_$(3)) \
$$(MKFILE_DEPS)
# Prerequisites for using the stageN compiler to build target artifacts
TSREQ$(1)_T_$(2)_H_$(3) = \
$$(HSREQ$(1)_H_$(3)) \
$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_RUNTIME_$(2)) \
$$(TLIB$(1)_T_$(2)_H_$(3))/libmorestack.a
# Prerequisites for a working stageN compiler and libraries, for a specific target
SREQ$(1)_T_$(2)_H_$(3) = \
$$(TSREQ$(1)_T_$(2)_H_$(3)) \
$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_STDLIB_$(2)) \
$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_EXTRALIB_$(2))
# Prerequisites for a working stageN compiler and libraries, for a specific target
CSREQ$(1)_T_$(2)_H_$(3) = \
$$(TSREQ$(1)_T_$(2)_H_$(3)) \
$$(HBIN$(1)_H_$(3))/rustpkg$$(X_$(3)) \
$$(HBIN$(1)_H_$(3))/rustdoc$$(X_$(3)) \
$$(HBIN$(1)_H_$(3))/rusti$$(X_$(3)) \
$$(HBIN$(1)_H_$(3))/rust$$(X_$(3)) \
$$(HLIB$(1)_H_$(3))/$(CFG_LIBRUSTPKG_$(3)) \
$$(HLIB$(1)_H_$(3))/$(CFG_LIBRUSTDOC_$(3)) \
$$(HLIB$(1)_H_$(3))/$(CFG_LIBRUSTI_$(3)) \
$$(HLIB$(1)_H_$(3))/$(CFG_LIBRUST_$(3)) \
$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_STDLIB_$(2)) \
$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_EXTRALIB_$(2)) \
$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBSYNTAX_$(2)) \
$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTC_$(2)) \
$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTPKG_$(2)) \
$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTDOC_$(2)) \
$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTI_$(2)) \
$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUST_$(2))
ifeq ($(1),0)
# Don't run the the stage0 compiler under valgrind - that ship has sailed
CFG_VALGRIND_COMPILE$(1) =
else
CFG_VALGRIND_COMPILE$(1) = $$(CFG_VALGRIND_COMPILE)
endif
# Add RUSTFLAGS_STAGEN values to the build command
EXTRAFLAGS_STAGE$(1) = $$(RUSTFLAGS_STAGE$(1))
CFGFLAG$(1)_T_$(2)_H_$(3) = stage$(1)
# Pass --cfg stage0 only for the build->host part of stage0;
# if you're building a cross config, the host->* parts are
# effectively stage1, since it uses the just-built stage0.
ifeq ($(1),0)
ifneq ($(strip $(CFG_BUILD_TRIPLE)),$(strip $(3)))
CFGFLAG$(1)_T_$(2)_H_$(3) = stage1
endif
endif
STAGE$(1)_T_$(2)_H_$(3) := \
$$(Q)$$(call CFG_RUN_TARG_$(3),$(1), \
$$(CFG_VALGRIND_COMPILE$(1)) \
$$(HBIN$(1)_H_$(3))/rustc$$(X_$(3)) \
--cfg $$(CFGFLAG$(1)_T_$(2)_H_$(3)) \
$$(CFG_RUSTC_FLAGS) $$(EXTRAFLAGS_STAGE$(1)) --target=$(2)) \
$$(RUSTC_FLAGS_$(2))
PERF_STAGE$(1)_T_$(2)_H_$(3) := \
$$(Q)$$(call CFG_RUN_TARG_$(3),$(1), \
$$(CFG_PERF_TOOL) \
$$(HBIN$(1)_H_$(3))/rustc$$(X_$(3)) \
--cfg $$(CFGFLAG$(1)_T_$(2)_H_$(3)) \
$$(CFG_RUSTC_FLAGS) $$(EXTRAFLAGS_STAGE$(1)) --target=$(2)) \
$$(RUSTC_FLAGS_$(2))
endef
$(foreach build,$(CFG_HOST_TRIPLES), \
$(eval $(foreach target,$(CFG_TARGET_TRIPLES), \
$(eval $(foreach stage,$(STAGES), \
$(eval $(call SREQ,$(stage),$(target),$(build))))))))
######################################################################
# rustc-H-targets
#
# Builds a functional Rustc for the given host.
######################################################################
define DEF_RUSTC_STAGE_TARGET
# $(1) == architecture
# $(2) == stage
rustc-stage$(2)-H-$(1): \
$$(foreach target,$$(CFG_TARGET_TRIPLES), \
$$(SREQ$(2)_T_$$(target)_H_$(1)))
endef
$(foreach host,$(CFG_HOST_TRIPLES), \
$(eval $(foreach stage,1 2 3, \
$(eval $(call DEF_RUSTC_STAGE_TARGET,$(host),$(stage))))))
rustc-stage1: rustc-stage1-H-$(CFG_BUILD_TRIPLE)
rustc-stage2: rustc-stage2-H-$(CFG_BUILD_TRIPLE)
rustc-stage3: rustc-stage3-H-$(CFG_BUILD_TRIPLE)
define DEF_RUSTC_TARGET
# $(1) == architecture
rustc-H-$(1): rustc-stage2-H-$(1)
endef
$(foreach host,$(CFG_TARGET_TRIPLES), \
$(eval $(call DEF_RUSTC_TARGET,$(host))))
rustc-stage1: rustc-stage1-H-$(CFG_BUILD_TRIPLE)
rustc-stage2: rustc-stage2-H-$(CFG_BUILD_TRIPLE)
rustc-stage3: rustc-stage3-H-$(CFG_BUILD_TRIPLE)
rustc: rustc-H-$(CFG_BUILD_TRIPLE)
rustc-H-all: $(foreach host,$(CFG_HOST_TRIPLES),rustc-H-$(host))
######################################################################
# Entrypoint rule
######################################################################
.DEFAULT_GOAL := all
ifneq ($(CFG_IN_TRANSITION),)
CFG_INFO := $(info cfg:)
CFG_INFO := $(info cfg: *** compiler is in snapshot transition ***)
CFG_INFO := $(info cfg: *** stage2 and later will not be built ***)
CFG_INFO := $(info cfg:)
#XXX This is surely busted
all: $(SREQ1$(CFG_BUILD_TRIPLE)) $(GENERATED) docs
else
define ALL_TARGET_N
ifneq ($$(findstring $(1),$$(CFG_HOST_TRIPLES)),)
# This is a host
all-target-$(1)-host-$(2): $$(CSREQ2_T_$(1)_H_$(2))
else
# This is a target only
all-target-$(1)-host-$(2): $$(SREQ2_T_$(1)_H_$(2))
endif
endef
$(foreach target,$(CFG_TARGET_TRIPLES), \
$(foreach host,$(CFG_HOST_TRIPLES), \
$(eval $(call ALL_TARGET_N,$(target),$(host)))))
ALL_TARGET_RULES = $(foreach target,$(CFG_TARGET_TRIPLES), \
$(foreach host,$(CFG_HOST_TRIPLES), \
all-target-$(target)-host-$(host)))
all: rustllvm/llvm-auto-clean-stamp \
$(ALL_TARGET_RULES) $(GENERATED) docs
endif
# This is used to independently force an LLVM clean rebuild
# when we changed something not otherwise captured by builtin
# dependencies. In these cases, commit a change that touches
# the stamp in the source dir.
rustllvm/llvm-auto-clean-stamp: $(S)src/rustllvm/llvm-auto-clean-trigger
$(Q)$(MAKE) clean-llvm
touch $@
######################################################################
# Re-configuration
######################################################################
ifndef CFG_DISABLE_MANAGE_SUBMODULES
# This is a pretty expensive operation but I don't see any way to avoid it
NEED_GIT_RECONFIG=$(shell cd "$(CFG_SRC_DIR)" && "$(CFG_GIT)" submodule status | grep -c '^\(+\|-\)')
else
NEED_GIT_RECONFIG=0
endif
ifeq ($(NEED_GIT_RECONFIG),0)
else
# If the submodules have changed then always execute config.mk
.PHONY: config.stamp
endif
Makefile config.mk: config.stamp
config.stamp: $(S)configure $(S)Makefile.in $(S)src/snapshots.txt
@$(call E, cfg: reconfiguring)
$(Q)$(S)configure $(CFG_CONFIGURE_ARGS)
######################################################################
# Primary-target makefiles
######################################################################
include $(CFG_SRC_DIR)mk/target.mk
include $(CFG_SRC_DIR)mk/host.mk
include $(CFG_SRC_DIR)mk/stage0.mk
# Just a few macros used everywhere
include $(CFG_SRC_DIR)mk/util.mk
# Reconfiguring when the makefiles or submodules change
include $(CFG_SRC_DIR)mk/reconfig.mk
# All crates and their dependencies
include $(CFG_SRC_DIR)mk/crates.mk
# Various bits of setup, common macros, and top-level rules
include $(CFG_SRC_DIR)mk/main.mk
# C and assembly components that are not LLVM
include $(CFG_SRC_DIR)mk/rt.mk
# Rules for crates in the target directories
include $(CFG_SRC_DIR)mk/target.mk
# Rules for crates in the host directories
include $(CFG_SRC_DIR)mk/host.mk
# Special rules for bootstrapping stage0
include $(CFG_SRC_DIR)mk/stage0.mk
# Rust-specific LLVM extensions
include $(CFG_SRC_DIR)mk/rustllvm.mk
include $(CFG_SRC_DIR)mk/tools.mk
# Documentation
include $(CFG_SRC_DIR)mk/docs.mk
# LLVM
include $(CFG_SRC_DIR)mk/llvm.mk
# Rules for installing debugger scripts
include $(CFG_SRC_DIR)mk/debuggers.mk
######################################################################
# Secondary makefiles, conditionalized for speed
######################################################################
ifneq ($(strip $(findstring dist,$(MAKECMDGOALS)) \
$(findstring check,$(MAKECMDGOALS)) \
$(findstring test,$(MAKECMDGOALS)) \
$(findstring tidy,$(MAKECMDGOALS)) \
$(findstring clean,$(MAKECMDGOALS))),)
CFG_INFO := $(info cfg: including dist rules)
include $(CFG_SRC_DIR)mk/dist.mk
endif
# Binary snapshots
ifneq ($(strip $(findstring snap,$(MAKECMDGOALS)) \
$(findstring clean,$(MAKECMDGOALS))),)
CFG_INFO := $(info cfg: including snap rules)
include $(CFG_SRC_DIR)mk/snap.mk
endif
ifneq ($(findstring reformat,$(MAKECMDGOALS)),)
CFG_INFO := $(info cfg: including reformat rules)
include $(CFG_SRC_DIR)mk/pp.mk
endif
# The test suite
ifneq ($(strip $(findstring check,$(MAKECMDGOALS)) \
$(findstring test,$(MAKECMDGOALS)) \
$(findstring perf,$(MAKECMDGOALS)) \
$(findstring tidy,$(MAKECMDGOALS))),)
CFG_INFO := $(info cfg: including test rules)
include $(CFG_SRC_DIR)mk/tests.mk
include $(CFG_SRC_DIR)mk/grammar.mk
endif
# Performance and benchmarking
ifneq ($(findstring perf,$(MAKECMDGOALS)),)
CFG_INFO := $(info cfg: including perf rules)
include $(CFG_SRC_DIR)mk/perf.mk
endif
# Copy all the distributables to another directory for binary install
ifneq ($(strip $(findstring prepare,$(MAKECMDGOALS)) \
$(findstring dist,$(MAKECMDGOALS)) \
$(findstring install,$(MAKECMDGOALS))),)
CFG_INFO := $(info cfg: including prepare rules)
include $(CFG_SRC_DIR)mk/prepare.mk
endif
# Source and binary distribution artifacts
ifneq ($(strip $(findstring dist,$(MAKECMDGOALS)) \
$(findstring install,$(MAKECMDGOALS)) \
$(findstring clean,$(MAKECMDGOALS))),)
CFG_INFO := $(info cfg: including dist rules)
include $(CFG_SRC_DIR)mk/dist.mk
endif
# (Unix) Installation from the build directory
ifneq ($(findstring install,$(MAKECMDGOALS)),)
CFG_INFO := $(info cfg: including install rules)
include $(CFG_SRC_DIR)mk/install.mk
endif
# Cleaning
ifneq ($(findstring clean,$(MAKECMDGOALS)),)
CFG_INFO := $(info cfg: including clean rules)
include $(CFG_SRC_DIR)mk/clean.mk
endif
ifneq ($(findstring install,$(MAKECMDGOALS)),)
ifdef DESTDIR
CFG_INFO := $(info cfg: setting CFG_PREFIX via DESTDIR, $(DESTDIR)/$(CFG_PREFIX))
CFG_PREFIX:=$(DESTDIR)/$(CFG_PREFIX)
export CFG_PREFIX
endif
CFG_INFO := $(info cfg: including install rules)
include $(CFG_SRC_DIR)mk/install.mk
endif
# CTAGS building
ifneq ($(strip $(findstring TAGS.emacs,$(MAKECMDGOALS)) \
$(findstring TAGS.vi,$(MAKECMDGOALS))),)
CFG_INFO := $(info cfg: including ctags rules)

143
README.md
View File

@ -3,65 +3,114 @@
This is a compiler for Rust, including standard libraries, tools and
documentation.
## Quick Start
## Installation
1. Download a [binary installer][installer] for your platform.
2. Read [The Rust Programming Language][trpl].
3. Enjoy!
The Rust compiler currently must be built from a [tarball], unless you
are on Windows, in which case using the [installer][win-exe] is
recommended.
> ***Note:*** Windows users can read the detailed
> [using Rust on Windows][win-wiki] notes on the wiki.
Since the Rust compiler is written in Rust, it must be built by
a precompiled "snapshot" version of itself (made in an earlier state
of development). As such, source builds require a connection to
the Internet, to fetch snapshots, and an OS that can execute the
available snapshot binaries.
[installer]: http://www.rust-lang.org/install.html
[trpl]: http://doc.rust-lang.org/book/index.html
[win-wiki]: https://github.com/rust-lang/rust/wiki/Using-Rust-on-Windows
## Building from Source
1. Make sure you have installed the dependencies:
* `g++` 4.7 or `clang++` 3.x
* `python` 2.6 or later (but not 3.x)
* `perl` 5.0 or later
* GNU `make` 3.81 or later
* `curl`
* `git`
2. Download and build Rust:
You can either download a [tarball] or build directly from the [repo].
To build from the [tarball] do:
$ curl -O https://static.rust-lang.org/dist/rust-nightly.tar.gz
$ tar -xzf rust-nightly.tar.gz
$ cd rust-nightly
Or to build from the [repo] do:
$ git clone https://github.com/rust-lang/rust.git
$ cd rust
Now that you have Rust's source code, you can configure and build it:
$ ./configure
$ make && make install
> ***Note:*** You may need to use `sudo make install` if you do not normally have
> permission to modify the destination directory. The install locations can
> be adjusted by passing a `--prefix` argument to `configure`. Various other
> options are also supported, pass `--help` for more information on them.
When complete, `make install` will place several programs into
`/usr/local/bin`: `rustc`, the Rust compiler, and `rustdoc`, the
API-documentation tool.
3. Read [The Rust Programming Language][trpl].
4. Enjoy!
### Building on Windows
To easily build on windows we can use [MSYS2](http://sourceforge.net/projects/msys2/):
1. Grab the latest MSYS2 installer and go through the installer.
2. Now from the MSYS2 terminal we want to install the mingw64 toolchain and the other
tools we need.
$ pacman -S mingw-w64-i686-toolchain
$ pacman -S base-devel
3. With that now start `mingw32_shell.bat` from where you installed MSYS2 (i.e. `C:\msys`).
4. From there just navigate to where you have Rust's source code, configure and build it:
$ ./configure
$ make && make install
[repo]: https://github.com/rust-lang/rust
[tarball]: https://static.rust-lang.org/dist/rust-nightly.tar.gz
[trpl]: http://doc.rust-lang.org/book/index.html
## Notes
Since the Rust compiler is written in Rust, it must be built by a
precompiled "snapshot" version of itself (made in an earlier state of
development). As such, source builds require a connection to the Internet, to
fetch snapshots, and an OS that can execute the available snapshot binaries.
Snapshot binaries are currently built and tested on several platforms:
* Windows (7, Server 2008 R2), x86 only
* Linux (various distributions), x86 and x86-64
* OSX 10.6 ("Snow Leopard") or greater, x86 and x86-64
* Windows (7, 8, Server 2008 R2), x86 and x86-64 (64-bit support added in Rust 0.12.0)
* Linux (2.6.18 or later, various distributions), x86 and x86-64
* OSX 10.7 (Lion) or greater, x86 and x86-64
You may find that other platforms work, but these are our "tier 1"
You may find that other platforms work, but these are our officially
supported build environments that are most likely to work.
> ***Note:*** Windows users should read the detailed
> [getting started][wiki-start] notes on the wiki. Even when using
> the binary installer the Windows build requires a MinGW installation,
> the precise details of which are not discussed here.
Rust currently needs about 1.5 GiB of RAM to build without swapping; if it hits
swap, it will take a very long time to build.
To build from source you will also need the following prerequisite
packages:
There is a lot more documentation in the [wiki].
* g++ 4.4 or clang++ 3.x
* python 2.6 or later (but not 3.x)
* perl 5.0 or later
* gnu make 3.81 or later
* curl
[wiki]: https://github.com/rust-lang/rust/wiki
Assuming you're on a relatively modern *nix system and have met the
prerequisites, something along these lines should work.
## Getting help and getting involved
$ curl -O http://static.rust-lang.org/dist/rust-0.7.tar.gz
$ tar -xzf rust-0.7.tar.gz
$ cd rust-0.7
$ ./configure
$ make && make install
The Rust community congregates in a few places:
You may need to use `sudo make install` if you do not normally have
permission to modify the destination directory. The install locations
can be adjusted by passing a `--prefix` argument to
`configure`. Various other options are also supported, pass `--help`
for more information on them.
When complete, `make install` will place several programs into
`/usr/local/bin`: `rustc`, the Rust compiler; `rustdoc`, the
API-documentation tool, and `rustpkg`, the Rust package manager and build system.
[wiki-start]: https://github.com/mozilla/rust/wiki/Note-getting-started-developing-Rust
[tarball]: http://static.rust-lang.org/dist/rust-0.7.tar.gz
[win-exe]: http://static.rust-lang.org/dist/rust-0.7-install.exe
* [StackOverflow] - Get help here.
* [/r/rust] - General discussion.
* [discuss.rust-lang.org] - For development of the Rust language itself.
[StackOverflow]: http://stackoverflow.com/questions/tagged/rust
[/r/rust]: http://reddit.com/r/rust
[discuss.rust-lang.org]: http://discuss.rust-lang.org/
## License
@ -70,9 +119,3 @@ and the Apache License (Version 2.0), with portions covered by various
BSD-like licenses.
See LICENSE-APACHE, LICENSE-MIT, and COPYRIGHT for details.
## More help
The [tutorial] is a good starting point.
[tutorial]: http://static.rust-lang.org/doc/tutorial.html

1386
RELEASES.md Normal file

File diff suppressed because it is too large Load Diff

859
configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -1,28 +0,0 @@
Pandoc, a universal document converter, is required to generate docs as HTML
from Rust's source code. It's available for most platforms here:
http://johnmacfarlane.net/pandoc/installing.html
Node.js (http://nodejs.org/) is also required for generating HTML from
the Markdown docs (reference manual, tutorials, etc.) distributed with
this git repository.
To generate all the docs, run `make docs` from the root of the repository.
This will convert the distributed Markdown docs to HTML and generate HTML doc
for the 'std' and 'extra' libraries.
To generate HTML documentation from one source file/crate, do something like:
rustdoc --output-dir html-doc/ --output-format html ../src/libstd/path.rs
(This, of course, requires that you've built/installed the `rustdoc` tool.)
To generate an HTML version of a doc from Markdown, without having Node.js
installed, do something like:
pandoc --from=markdown --to=html --number-sections -o rust.html rust.md
The syntax for pandoc flavored markdown can be found at:
http://johnmacfarlane.net/pandoc/README.html#pandocs-markdown
A nice quick reference (for non-pandoc markdown) is at:
http://kramdown.rubyforge.org/quickref.html

View File

@ -1,8 +0,0 @@
/*
Custom styles for the library docs generated by naturaldocs
*/
p {
text-indent: 0;
margin-bottom: 1em;
}

View File

@ -1,125 +0,0 @@
exports.htmlEscape = function(text) {
var replacements = {"<": "&lt;", ">": "&gt;",
"&": "&amp;", "\"": "&quot;"};
return text.replace(/[<>&"]/g, function(character) {
return replacements[character];
});
};
exports.splitLines = function(string){return string.split(/\r?\n/);};
// Counts the column offset in a string, taking tabs into account.
// Used mostly to find indentation.
function countColumn(string, end) {
tabSize = 4;
if (end == null) {
end = string.search(/[^\s\u00a0]/);
if (end == -1) end = string.length;
}
for (var i = 0, n = 0; i < end; ++i) {
if (string.charAt(i) == "\t") n += tabSize - (n % tabSize);
else ++n;
}
return n;
}
function StringStream(string) {
this.pos = this.start = 0;
this.string = string;
}
StringStream.prototype = {
eol: function() {return this.pos >= this.string.length;},
sol: function() {return this.pos == 0;},
peek: function() {return this.string.charAt(this.pos);},
next: function() {
if (this.pos < this.string.length)
return this.string.charAt(this.pos++);
},
eat: function(match) {
var ch = this.string.charAt(this.pos);
if (typeof match == "string") var ok = ch == match;
else var ok = ch && (match.test ? match.test(ch) : match(ch));
if (ok) {++this.pos; return ch;}
},
eatWhile: function(match) {
var start = this.pos;
while (this.eat(match)){}
return this.pos > start;
},
eatSpace: function() {
var start = this.pos;
while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos;
return this.pos > start;
},
skipToEnd: function() {this.pos = this.string.length;},
skipTo: function(ch) {
var found = this.string.indexOf(ch, this.pos);
if (found > -1) {this.pos = found; return true;}
},
backUp: function(n) {this.pos -= n;},
column: function() {return countColumn(this.string, this.start);},
indentation: function() {return countColumn(this.string);},
match: function(pattern, consume, caseInsensitive) {
if (typeof pattern == "string") {
function cased(str) {return caseInsensitive ? str.toLowerCase() : str;}
if (cased(this.string).indexOf(cased(pattern), this.pos) == this.pos) {
if (consume !== false) this.pos += pattern.length;
return true;
}
}
else {
var match = this.string.slice(this.pos).match(pattern);
if (match && consume !== false) this.pos += match[0].length;
return match;
}
},
current: function(){return this.string.slice(this.start, this.pos);}
};
exports.StringStream = StringStream;
exports.startState = function(mode, a1, a2) {
return mode.startState ? mode.startState(a1, a2) : true;
};
var modes = {}, mimeModes = {};
exports.defineMode = function(name, mode) { modes[name] = mode; };
exports.defineMIME = function(mime, spec) { mimeModes[mime] = spec; };
exports.getMode = function(options, spec) {
if (typeof spec == "string" && mimeModes.hasOwnProperty(spec))
spec = mimeModes[spec];
if (typeof spec == "string")
var mname = spec, config = {};
else if (spec != null)
var mname = spec.name, config = spec;
var mfactory = modes[mname];
if (!mfactory) throw new Error("Unknown mode: " + spec);
return mfactory(options, config || {});
};
exports.runMode = function(string, modespec, callback) {
var mode = exports.getMode({indentUnit: 2}, modespec);
var isNode = callback.nodeType == 1;
if (isNode) {
var node = callback, accum = [];
callback = function(string, style) {
if (string == "\n")
accum.push("<br>");
else if (style)
accum.push("<span class=\"cm-" + exports.htmlEscape(style) + "\">" + exports.htmlEscape(string) + "</span>");
else
accum.push(exports.htmlEscape(string));
}
}
var lines = exports.splitLines(string), state = exports.startState(mode);
for (var i = 0, e = lines.length; i < e; ++i) {
if (i) callback("\n");
var stream = new exports.StringStream(lines[i]);
while (!stream.eol()) {
var style = mode.token(stream, state);
callback(stream.current(), style, i, stream.start);
stream.start = stream.pos;
}
}
if (isNode)
node.innerHTML = accum.join("");
};

View File

@ -1,432 +0,0 @@
CodeMirror.defineMode("rust", function() {
var indentUnit = 4, altIndentUnit = 2;
var valKeywords = {
"if": "if-style", "while": "if-style", "loop": "if-style", "else": "else-style",
"do": "else-style", "return": "else-style",
"break": "atom", "cont": "atom", "const": "let", "resource": "fn",
"let": "let", "fn": "fn", "for": "for", "match": "match", "trait": "trait",
"impl": "impl", "type": "type", "enum": "enum", "struct": "atom", "mod": "mod",
"as": "op", "true": "atom", "false": "atom", "assert": "op", "check": "op",
"claim": "op", "extern": "ignore", "unsafe": "ignore", "import": "else-style",
"export": "else-style", "copy": "op", "log": "op",
"use": "op", "self": "atom", "pub": "atom", "priv": "atom"
};
var typeKeywords = function() {
var keywords = {"fn": "fn"};
var atoms = "bool uint int i8 i16 i32 i64 u8 u16 u32 u64 float f32 f64 str char".split(" ");
for (var i = 0, e = atoms.length; i < e; ++i) keywords[atoms[i]] = "atom";
return keywords;
}();
var operatorChar = /[+\-*&%=<>!?|\.@]/;
// Tokenizer
// Used as scratch variable to communicate multiple values without
// consing up tons of objects.
var tcat, content;
function r(tc, style) {
tcat = tc;
return style;
}
function tokenBase(stream, state) {
var ch = stream.next();
if (ch == '"') {
state.tokenize = tokenString;
return state.tokenize(stream, state);
}
if (ch == "'") {
tcat = "atom";
if (stream.eat("\\")) {
if (stream.skipTo("'")) { stream.next(); return "string"; }
else { return "error"; }
} else {
stream.next();
return stream.eat("'") ? "string" : "error";
}
}
if (ch == "/") {
if (stream.eat("/")) { stream.skipToEnd(); return "comment"; }
if (stream.eat("*")) {
state.tokenize = tokenComment(1);
return state.tokenize(stream, state);
}
}
if (ch == "#") {
if (stream.eat("[")) { tcat = "open-attr"; return null; }
stream.eatWhile(/\w/);
return r("macro", "meta");
}
if (ch == ":" && stream.match(":<")) {
return r("op", null);
}
if (ch.match(/\d/) || (ch == "." && stream.eat(/\d/))) {
var flp = false;
if (!stream.match(/^x[\da-f]+/i) && !stream.match(/^b[01]+/)) {
stream.eatWhile(/\d/);
if (stream.eat(".")) { flp = true; stream.eatWhile(/\d/); }
if (stream.match(/^e[+\-]?\d+/i)) { flp = true; }
}
if (flp) stream.match(/^f(?:32|64)/);
else stream.match(/^[ui](?:8|16|32|64)/);
return r("atom", "number");
}
if (ch.match(/[()\[\]{}:;,]/)) return r(ch, null);
if (ch == "-" && stream.eat(">")) return r("->", null);
if (ch.match(operatorChar)) {
stream.eatWhile(operatorChar);
return r("op", null);
}
stream.eatWhile(/\w/);
content = stream.current();
if (stream.match(/^::\w/)) {
stream.backUp(1);
return r("prefix", "variable-2");
}
if (state.keywords.propertyIsEnumerable(content))
return r(state.keywords[content], content.match(/true|false/) ? "atom" : "keyword");
return r("name", "variable");
}
function tokenString(stream, state) {
var ch, escaped = false;
while (ch = stream.next()) {
if (ch == '"' && !escaped) {
state.tokenize = tokenBase;
return r("atom", "string");
}
escaped = !escaped && ch == "\\";
}
// Hack to not confuse the parser when a string is split in
// pieces.
return r("op", "string");
}
function tokenComment(depth) {
return function(stream, state) {
var lastCh = null, ch;
while (ch = stream.next()) {
if (ch == "/" && lastCh == "*") {
if (depth == 1) {
state.tokenize = tokenBase;
break;
} else {
state.tokenize = tokenComment(depth - 1);
return state.tokenize(stream, state);
}
}
if (ch == "*" && lastCh == "/") {
state.tokenize = tokenComment(depth + 1);
return state.tokenize(stream, state);
}
lastCh = ch;
}
return "comment";
};
}
// Parser
var cx = {state: null, stream: null, marked: null, cc: null};
function pass() {
for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]);
}
function cont() {
pass.apply(null, arguments);
return true;
}
function pushlex(type, info) {
var result = function() {
var state = cx.state;
state.lexical = {indented: state.indented, column: cx.stream.column(),
type: type, prev: state.lexical, info: info};
};
result.lex = true;
return result;
}
function poplex() {
var state = cx.state;
if (state.lexical.prev) {
if (state.lexical.type == ")")
state.indented = state.lexical.indented;
state.lexical = state.lexical.prev;
}
}
function typecx() { cx.state.keywords = typeKeywords; }
function valcx() { cx.state.keywords = valKeywords; }
poplex.lex = typecx.lex = valcx.lex = true;
function commasep(comb, end) {
function more(type) {
if (type == ",") return cont(comb, more);
if (type == end) return cont();
return cont(more);
}
return function(type) {
if (type == end) return cont();
return pass(comb, more);
};
}
function stat_of(comb, tag) {
return cont(pushlex("stat", tag), comb, poplex, block);
}
function block(type) {
if (type == "}") return cont();
if (type == "let") return stat_of(letdef1, "let");
if (type == "fn") return stat_of(fndef);
if (type == "type") return cont(pushlex("stat"), tydef, endstatement, poplex, block);
if (type == "enum") return stat_of(tagdef);
if (type == "mod") return stat_of(mod);
if (type == "trait") return stat_of(trait);
if (type == "impl") return stat_of(impl);
if (type == "open-attr") return cont(pushlex("]"), commasep(expression, "]"), poplex);
if (type == "ignore" || type.match(/[\]\);,]/)) return cont(block);
return pass(pushlex("stat"), expression, poplex, endstatement, block);
}
function endstatement(type) {
if (type == ";") return cont();
return pass();
}
function expression(type) {
if (type == "atom" || type == "name") return cont(maybeop);
if (type == "{") return cont(pushlex("}"), exprbrace, poplex);
if (type.match(/[\[\(]/)) return matchBrackets(type, expression);
if (type.match(/[\]\)\};,]/)) return pass();
if (type == "if-style") return cont(expression, expression);
if (type == "else-style" || type == "op") return cont(expression);
if (type == "for") return cont(pattern, maybetype, inop, expression, expression);
if (type == "match") return cont(expression, altbody);
if (type == "fn") return cont(fndef);
if (type == "macro") return cont(macro);
return cont();
}
function maybeop(type) {
if (content == ".") return cont(maybeprop);
if (content == "::<"){return cont(typarams, maybeop);}
if (type == "op" || content == ":") return cont(expression);
if (type == "(" || type == "[") return matchBrackets(type, expression);
return pass();
}
function maybeprop(type) {
if (content.match(/^\w+$/)) {cx.marked = "variable"; return cont(maybeop);}
return pass(expression);
}
function exprbrace(type) {
if (type == "op") {
if (content == "|") return cont(blockvars, poplex, pushlex("}", "block"), block);
if (content == "||") return cont(poplex, pushlex("}", "block"), block);
}
if (content == "mut" || (content.match(/^\w+$/) && cx.stream.peek() == ":"
&& !cx.stream.match("::", false)))
return pass(record_of(expression));
return pass(block);
}
function record_of(comb) {
function ro(type) {
if (content == "mut" || content == "with") {cx.marked = "keyword"; return cont(ro);}
if (content.match(/^\w*$/)) {cx.marked = "variable"; return cont(ro);}
if (type == ":") return cont(comb, ro);
if (type == "}") return cont();
return cont(ro);
}
return ro;
}
function blockvars(type) {
if (type == "name") {cx.marked = "def"; return cont(blockvars);}
if (type == "op" && content == "|") return cont();
return cont(blockvars);
}
function letdef1(type) {
if (type.match(/[\]\)\};]/)) return cont();
if (content == "=") return cont(expression, letdef2);
if (type == ",") return cont(letdef1);
return pass(pattern, maybetype, letdef1);
}
function letdef2(type) {
if (type.match(/[\]\)\};,]/)) return pass(letdef1);
else return pass(expression, letdef2);
}
function maybetype(type) {
if (type == ":") return cont(typecx, rtype, valcx);
return pass();
}
function inop(type) {
if (type == "name" && content == "in") {cx.marked = "keyword"; return cont();}
return pass();
}
function fndef(type) {
if (content == "@" || content == "~") {cx.marked = "keyword"; return cont(fndef);}
if (type == "name") {cx.marked = "def"; return cont(fndef);}
if (content == "<") return cont(typarams, fndef);
if (type == "{") return pass(expression);
if (type == "(") return cont(pushlex(")"), commasep(argdef, ")"), poplex, fndef);
if (type == "->") return cont(typecx, rtype, valcx, fndef);
if (type == ";") return cont();
return cont(fndef);
}
function tydef(type) {
if (type == "name") {cx.marked = "def"; return cont(tydef);}
if (content == "<") return cont(typarams, tydef);
if (content == "=") return cont(typecx, rtype, valcx);
return cont(tydef);
}
function tagdef(type) {
if (type == "name") {cx.marked = "def"; return cont(tagdef);}
if (content == "<") return cont(typarams, tagdef);
if (content == "=") return cont(typecx, rtype, valcx, endstatement);
if (type == "{") return cont(pushlex("}"), typecx, tagblock, valcx, poplex);
return cont(tagdef);
}
function tagblock(type) {
if (type == "}") return cont();
if (type == "(") return cont(pushlex(")"), commasep(rtype, ")"), poplex, tagblock);
if (content.match(/^\w+$/)) cx.marked = "def";
return cont(tagblock);
}
function mod(type) {
if (type == "name") {cx.marked = "def"; return cont(mod);}
if (type == "{") return cont(pushlex("}"), block, poplex);
return pass();
}
function trait(type) {
if (type == "name") {cx.marked = "def"; return cont(trait);}
if (content == "<") return cont(typarams, trait);
if (type == "{") return cont(pushlex("}"), block, poplex);
return pass();
}
function impl(type) {
if (content == "<") return cont(typarams, impl);
if (content == "of" || content == "for") {cx.marked = "keyword"; return cont(rtype, impl);}
if (type == "name") {cx.marked = "def"; return cont(impl);}
if (type == "{") return cont(pushlex("}"), block, poplex);
return pass();
}
function typarams(type) {
if (content == ">") return cont();
if (content == ",") return cont(typarams);
if (content == ":") return cont(rtype, typarams);
return pass(rtype, typarams);
}
function argdef(type) {
if (type == "name") {cx.marked = "def"; return cont(argdef);}
if (type == ":") return cont(typecx, rtype, valcx);
return pass();
}
function rtype(type) {
if (type == "name") {cx.marked = "variable-3"; return cont(rtypemaybeparam); }
if (content == "mut") {cx.marked = "keyword"; return cont(rtype);}
if (type == "atom") return cont(rtypemaybeparam);
if (type == "op" || type == "obj") return cont(rtype);
if (type == "fn") return cont(fntype);
if (type == "{") return cont(pushlex("{"), record_of(rtype), poplex);
return matchBrackets(type, rtype);
}
function rtypemaybeparam(type) {
if (content == "<") return cont(typarams);
return pass();
}
function fntype(type) {
if (type == "(") return cont(pushlex("("), commasep(rtype, ")"), poplex, fntype);
if (type == "->") return cont(rtype);
return pass();
}
function pattern(type) {
if (type == "name") {cx.marked = "def"; return cont(patternmaybeop);}
if (type == "atom") return cont(patternmaybeop);
if (type == "op") return cont(pattern);
if (type.match(/[\]\)\};,]/)) return pass();
return matchBrackets(type, pattern);
}
function patternmaybeop(type) {
if (type == "op" && content == ".") return cont();
if (content == "to") {cx.marked = "keyword"; return cont(pattern);}
else return pass();
}
function altbody(type) {
if (type == "{") return cont(pushlex("}", "match"), altblock1, poplex);
return pass();
}
function altblock1(type) {
if (type == "}") return cont();
if (type == "|") return cont(altblock1);
if (content == "when") {cx.marked = "keyword"; return cont(expression, altblock2);}
if (type.match(/[\]\);,]/)) return cont(altblock1);
return pass(pattern, altblock2);
}
function altblock2(type) {
if (type == "{") return cont(pushlex("}", "match"), block, poplex, altblock1);
else return pass(altblock1);
}
function macro(type) {
if (type.match(/[\[\(\{]/)) return matchBrackets(type, expression);
return pass();
}
function matchBrackets(type, comb) {
if (type == "[") return cont(pushlex("]"), commasep(comb, "]"), poplex);
if (type == "(") return cont(pushlex(")"), commasep(comb, ")"), poplex);
if (type == "{") return cont(pushlex("}"), commasep(comb, "}"), poplex);
return cont();
}
function parse(state, stream, style) {
var cc = state.cc;
// Communicate our context to the combinators.
// (Less wasteful than consing up a hundred closures on every call.)
cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc;
while (true) {
var combinator = cc.length ? cc.pop() : block;
if (combinator(tcat)) {
while(cc.length && cc[cc.length - 1].lex)
cc.pop()();
return cx.marked || style;
}
}
}
return {
startState: function() {
return {
tokenize: tokenBase,
cc: [],
lexical: {indented: -indentUnit, column: 0, type: "top", align: false},
keywords: valKeywords,
indented: 0
};
},
token: function(stream, state) {
if (stream.sol()) {
if (!state.lexical.hasOwnProperty("align"))
state.lexical.align = false;
state.indented = stream.indentation();
}
if (stream.eatSpace()) return null;
tcat = content = null;
var style = state.tokenize(stream, state);
if (style == "comment") return style;
if (!state.lexical.hasOwnProperty("align"))
state.lexical.align = true;
if (tcat == "prefix") return style;
if (!content) content = stream.current();
return parse(state, stream, style);
},
indent: function(state, textAfter) {
if (state.tokenize != tokenBase) return 0;
var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical,
type = lexical.type, closing = firstChar == type;
if (type == "stat") return lexical.indented + indentUnit;
if (lexical.align) return lexical.column + (closing ? 0 : 1);
return lexical.indented + (closing ? 0 : (lexical.info == "match" ? altIndentUnit : indentUnit));
},
electricChars: "{}"
};
});
CodeMirror.defineMIME("text/x-rustsrc", "rust");

View File

@ -1,6 +0,0 @@
/* Display the full TOC */
#TOC ul ul {
display: block;
padding-left: 2em;
}

View File

@ -1,77 +0,0 @@
#!/usr/local/bin/node
/***
* Pandoc-style markdown preprocessor that drops extra directives
* included for running doc code, and that optionally, when
* --highlight is provided, replaces code blocks that are Rust code
* with highlighted HTML blocks. The directives recognized are:
*
* '## ignore' tells the test extractor (extract-tests.js) to ignore
* the block completely.
* '## notrust' makes the test extractor ignore the block, makes
* this script not highlight the block.
* '# [any text]' is a line that is stripped out by this script, and
* converted to a normal line of code (without the leading #) by
* the test extractor.
*/
var fs = require("fs");
CodeMirror = require("./lib/codemirror-node");
require("./lib/codemirror-rust");
function help() {
console.log("usage: " + process.argv[0] + " [--highlight] [-o outfile] [infile]");
process.exit(1);
}
var highlight = false, infile, outfile;
for (var i = 2; i < process.argv.length; ++i) {
var arg = process.argv[i];
if (arg == "--highlight") highlight = true;
else if (arg == "-o" && outfile == null && ++i < process.argv.length) outfile = process.argv[i];
else if (arg[0] != "-") infile = arg;
else help();
}
var lines = fs.readFileSync(infile || "/dev/stdin").toString().split(/\n\r?/g), cur = 0, line;
var out = outfile ? fs.createWriteStream(outfile) : process.stdout;
while ((line = lines[cur++]) != null) {
if (/^~~~/.test(line)) {
var block = "", bline;
var notRust =
/notrust/.test(line)
// These are all used by the language ref to indicate things
// that are not Rust source code
|| /ebnf/.test(line)
|| /abnf/.test(line)
|| /keyword/.test(line)
|| /field/.test(line)
|| /precedence/.test(line);
var isRust = !notRust;
while ((bline = lines[cur++]) != null) {
if (/^~~~/.test(bline)) break;
if (!/^\s*##? /.test(bline)) block += bline + "\n";
}
if (!highlight || !isRust)
out.write(line + "\n" + block + bline + "\n");
else {
var html = '<pre class="cm-s-default">', curstr = "", curstyle = null;
function add(str, style) {
if (style != curstyle) {
if (curstyle) html +=
'<span class="cm-' + CodeMirror.htmlEscape(curstyle) + '">' +
CodeMirror.htmlEscape(curstr) + "</span>";
else if (curstr) html += CodeMirror.htmlEscape(curstr);
curstr = str; curstyle = style;
} else curstr += str;
}
CodeMirror.runMode(block, "rust", add);
add("", "bogus"); // Flush pending string.
out.write(html + "</pre>\n");
}
} else {
out.write(line + "\n");
}
}

View File

@ -1,156 +0,0 @@
body {
padding: 1em 6em;
margin: 0;
margin-bottom: 4em;
font-family: "Helvetica Neue", Helvetica, sans-serif;
font-size: 12pt;
background-color: white;
color: black;
line-height: 1.6em;
min-width: 45em;
max-width: 60em;
}
h1 {
font-size: 24pt;
margin-top: 1.6em;
padding-left: 0.4em;
line-height: 1.6em;
background-color:#FFF2CE;
border-radius: 0.2em;
}
h2 {
font-size: 16pt;
margin-top: 1.6em;
padding: 0.2em 0.5em;
background-color:#FFF2CE;
border-radius: 0.4em;
}
h2 code {
color: #097334;
font-size: 16pt;
}
h3 {
font-size: 14pt;
color: black;
background-color:#D9E7FF;
border-radius: 0.4em;
padding: 0.2em 0.5em;
}
h3 code {
color: #541800;
font-size: 14pt;
font-style: italic;
}
h4 {
font-size: 11pt;
margin-top: 0em;
margin-bottom: 0em;
}
code {
font-size: 11pt;
}
pre {
margin-left: 1.1em;
padding: .4em .4em .4em .8em;
font-size: 10pt;
background-color: #F5F5F5;
border-radius: 0.5em;
border: 1px solid rgba(0, 0, 0, 0.15);
}
pre.rust {
background-color: #F3F6FF;
}
a, a:visited, a:link {
text-decoration: none;
color: rgb(0, 105, 214);
}
h1 a:link, h1 a:visited, h2 a:link, h2 a:visited,
h3 a:link, h3 a:visited { color: black; }
/* Code highlighting */
.cm-s-default span.cm-keyword {color: #708;}
.cm-s-default span.cm-atom {color: #219;}
.cm-s-default span.cm-number {color: #164;}
.cm-s-default span.cm-def {color: #00f;}
.cm-s-default span.cm-variable {color: black;}
.cm-s-default span.cm-variable-2 {color: #05a;}
.cm-s-default span.cm-variable-3 {color: #085;}
.cm-s-default span.cm-property {color: black;}
.cm-s-default span.cm-operator {color: black;}
.cm-s-default span.cm-comment {color: #a50;}
.cm-s-default span.cm-string {color: #a11;}
.cm-s-default span.cm-string-2 {color: #f50;}
.cm-s-default span.cm-meta {color: #555;}
.cm-s-default span.cm-error {color: #f00;}
.cm-s-default span.cm-qualifier {color: #555;}
.cm-s-default span.cm-builtin {color: #30a;}
.cm-s-default span.cm-bracket {color: #cc7;}
.cm-s-default span.cm-tag {color: #170;}
.cm-s-default span.cm-attribute {color: #00c;}
#versioninfo {
position: fixed;
bottom: 0px;
right: 0px;
background-color: white;
padding: 0.5em;
}
a.lessimportant {
color: gray;
font-size: 60%;
}
blockquote {
color: black;
border-left: solid 1px silver;
margin: 1em;
padding: 0.5em 1em 0.5em 1em;
}
/* Make the table under the tutorial's 'Types' section look nicer */
table {
border-top: 1px solid silver;
border-bottom: 1px solid silver;
padding: 0.8em;
font-size: smaller;
}
/* Also for the benefit of the type table */
td {
padding-right: 1em;
}
/* Only display one level of hierarchy in the TOC */
#TOC ul ul {
display: none;
}
#TOC ul {
list-style: none;
padding-left: 0px;
}
/* Adjust list alignment so rustdoc indexes don't align with blockquotes */
div.index ul {
padding-left: 1em;
}
ul {
margin-top: 0em
}
div.section.level3 {
margin-left: 1.0em;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,137 +0,0 @@
% Rustpkg Reference Manual
# Introduction
This document is the reference manual for the Rustpkg packaging and build tool for the Rust programming language.
## Disclaimer
Rustpkg is a work in progress, as is this reference manual.
If the actual behavior of rustpkg differs from the behavior described in this reference,
that reflects either an incompleteness or a bug in rustpkg.
# Package searching
rustpkg searches for packages using the `RUST_PATH` environment variable,
which is a colon-separated list (semicolon-separated on Windows) of directories.
Each directory in this list is a *workspace* for rustpkg.
`RUST_PATH` implicitly contains an entry for `./.rust` (as well as
`../.rust`, `../../.rust`,
and so on for every parent of `.` up to the filesystem root).
That means that if `RUST_PATH` is not set,
then rustpkg will still search for workspaces in `./.rust` and so on.
`RUST_PATH` also implicitly contains an entry for the system path:
`/usr/local` or the equivalent on Windows.
This entry comes after the implicit entries for `./.rust` and so on.
Finally, the last implicit entry in `RUST_PATH` is `~/.rust`
or the equivalent on Windows.
Each workspace may contain one or more packages.
When building code that contains one or more directives of the form `extern mod P`,
rustpkg automatically searches for packages named `P` in the `RUST_PATH` (as described above).
It builds those dependencies if necessary.
Thus, when using rustpkg,
there is no need for `-L` flags to tell the linker where to find libraries for external crates.
# Package structure
A valid workspace must contain each of the following subdirectories:
* 'src/': contains one subdirectory per package. Each subdirectory contains source files for a given package.
For example, if `foo` is a workspace containing the package `bar`,
then `foo/src/bar/main.rs` could be the `main` entry point for
building a `bar` executable.
* 'lib/': `rustpkg install` installs libraries into a target-specific subdirectory of this directory.
For example, on a 64-bit machine running Mac OS X,
if `foo` is a workspace containing the package `bar`,
rustpkg will install libraries for bar to `foo/lib/x86_64-apple-darwin/`.
The libraries will have names of the form `foo/lib/x86_64-apple-darwin/libbar-[hash].dylib`,
where [hash] is a hash of the package ID.
* 'bin/': `rustpkg install` installs executable binaries into a target-specific subdirectory of this directory.
For example, on a 64-bit machine running Mac OS X,
if `foo` is a workspace, containing the package `bar`,
rustpkg will install executables for `bar` to
`foo/bin/x86_64-apple-darwin/`.
The executables will have names of the form `foo/bin/x86_64-apple-darwin/bar`.
* 'build/': `rustpkg build` stores temporary build artifacts in a target-specific subdirectory of this directory.
For example, on a 64-bit machine running Mac OS X,
if `foo` is a workspace containing the package `bar` and `foo/src/bar/main.rs` exists,
then `rustpkg build` will create `foo/build/x86_64-apple-darwin/bar/main.o`.
# Package identifiers
A package identifier identifies a package uniquely.
A package can be stored in a workspace on the local file system,
or on a remote Web server, in which case the package ID resembles a URL.
For example, `github.com/mozilla/rust` is a package ID
that would refer to the git repository browsable at `http://github.com/mozilla/rust`.
A package ID can also specify a version, like:
`github.com/mozilla/rust#0.3`.
In this case, `rustpkg` will check that the repository `github.com/mozilla/rust` has a tag named `0.3`,
and report an error otherwise.
## Source files
rustpkg searches for four different fixed filenames in order to determine the crates to build:
* `main.rs`: Assumed to be a main entry point for building an executable.
* `lib.rs`: Assumed to be a library crate.
* `test.rs`: Assumed to contain tests declared with the `#[test]` attribute.
* `bench.rs`: Assumed to contain benchmarks declared with the `#[bench]` attribute.
## Versions
`rustpkg` packages do not need to declare their versions with an attribute inside one of the source files,
because `rustpkg` infers it from the version control system.
When building a package that is in a `git` repository,
`rustpkg` assumes that the most recent tag specifies the current version.
When building a package that is not under version control,
or that has no tags, `rustpkg` assumes the intended version is 0.1.
# Dependencies
rustpkg infers dependencies from `extern mod` directives.
Thus, there should be no need to pass a `-L` flag to rustpkg to tell it where to find a library.
(In the future, it will also be possible to write an `extern mod` directive referring to a remote package.)
# Custom build scripts
A file called `pkg.rs` at the root level in a workspace is called a *package script*.
If a package script exists, rustpkg executes it to build the package
rather than inferring crates as described previously.
Inside `pkg.rs`, it's possible to call back into rustpkg to finish up the build.
`rustpkg::api` contains functions to build, install, or clean libraries and executables
in the way rustpkg normally would without custom build logic.
# Command reference
## build
`rustpkg build foo` searches for a package with ID `foo`
and builds it in any workspace(s) where it finds one.
Supposing such packages are found in workspaces X, Y, and Z,
the command leaves behind files in `X`'s, `Y`'s, and `Z`'s `build` directories,
but not in their `lib` or `bin` directories.
## clean
`rustpkg clean foo` deletes the contents of `foo`'s `build` directory.
## install
`rustpkg install foo` builds the libraries and/or executables that are targets for `foo`,
and then installs them either into `foo`'s `lib` and `bin` directories,
or into the `lib` and `bin` subdirectories of the first entry in `RUST_PATH`.
## test
`rustpkg test foo` builds `foo`'s `test.rs` file if necessary,
then runs the resulting test executable.

View File

@ -1,663 +0,0 @@
% Rust Borrowed Pointers Tutorial
# Introduction
Borrowed pointers are one of the more flexible and powerful tools available in
Rust. A borrowed pointer can point anywhere: into the managed or exchange
heap, into the stack, and even into the interior of another data structure. A
borrowed pointer is as flexible as a C pointer or C++ reference. However,
unlike C and C++ compilers, the Rust compiler includes special static checks
that ensure that programs use borrowed pointers safely. Another advantage of
borrowed pointers is that they are invisible to the garbage collector, so
working with borrowed pointers helps reduce the overhead of automatic memory
management.
Despite their complete safety, a borrowed pointer's representation at runtime
is the same as that of an ordinary pointer in a C program. They introduce zero
overhead. The compiler does all safety checks at compile time.
Although borrowed pointers have rather elaborate theoretical
underpinnings (region pointers), the core concepts will be familiar to
anyone who has worked with C or C++. Therefore, the best way to explain
how they are used—and their limitations—is probably just to work
through several examples.
# By example
Borrowed pointers are called *borrowed* because they are only valid for
a limited duration. Borrowed pointers never claim any kind of ownership
over the data that they point to: instead, they are used for cases
where you would like to use data for a short time.
As an example, consider a simple struct type `Point`:
~~~
struct Point {x: float, y: float}
~~~
We can use this simple definition to allocate points in many different ways. For
example, in this code, each of these three local variables contains a
point, but allocated in a different place:
~~~
# struct Point {x: float, y: float}
let on_the_stack : Point = Point {x: 3.0, y: 4.0};
let managed_box : @Point = @Point {x: 5.0, y: 1.0};
let owned_box : ~Point = ~Point {x: 7.0, y: 9.0};
~~~
Suppose we wanted to write a procedure that computed the distance between any
two points, no matter where they were stored. For example, we might like to
compute the distance between `on_the_stack` and `managed_box`, or between
`managed_box` and `owned_box`. One option is to define a function that takes
two arguments of type `Point`—that is, it takes the points by value. But if we
define it this way, calling the function will cause the points to be
copied. For points, this is probably not so bad, but often copies are
expensive. Worse, if the data type contains mutable fields, copying can change
the semantics of your program in unexpected ways. So we'd like to define a
function that takes the points by pointer. We can use borrowed pointers to do
this:
~~~
# struct Point {x: float, y: float}
# fn sqrt(f: float) -> float { 0f }
fn compute_distance(p1: &Point, p2: &Point) -> float {
let x_d = p1.x - p2.x;
let y_d = p1.y - p2.y;
sqrt(x_d * x_d + y_d * y_d)
}
~~~
Now we can call `compute_distance()` in various ways:
~~~
# struct Point {x: float, y: float}
# let on_the_stack : Point = Point{x: 3.0, y: 4.0};
# let managed_box : @Point = @Point{x: 5.0, y: 1.0};
# let owned_box : ~Point = ~Point{x: 7.0, y: 9.0};
# fn compute_distance(p1: &Point, p2: &Point) -> float { 0f }
compute_distance(&on_the_stack, managed_box);
compute_distance(managed_box, owned_box);
~~~
Here, the `&` operator takes the address of the variable
`on_the_stack`; this is because `on_the_stack` has the type `Point`
(that is, a struct value) and we have to take its address to get a
value. We also call this _borrowing_ the local variable
`on_the_stack`, because we have created an alias: that is, another
name for the same data.
In contrast, we can pass the boxes `managed_box` and `owned_box` to
`compute_distance` directly. The compiler automatically converts a box like
`@Point` or `~Point` to a borrowed pointer like `&Point`. This is another form
of borrowing: in this case, the caller lends the contents of the managed or
owned box to the callee.
Whenever a caller lends data to a callee, there are some limitations on what
the caller can do with the original. For example, if the contents of a
variable have been lent out, you cannot send that variable to another task. In
addition, the compiler will reject any code that might cause the borrowed
value to be freed or overwrite its component fields with values of different
types (I'll get into what kinds of actions those are shortly). This rule
should make intuitive sense: you must wait for a borrower to return the value
that you lent it (that is, wait for the borrowed pointer to go out of scope)
before you can make full use of it again.
# Other uses for the & operator
In the previous example, the value `on_the_stack` was defined like so:
~~~
# struct Point {x: float, y: float}
let on_the_stack: Point = Point {x: 3.0, y: 4.0};
~~~
This declaration means that code can only pass `Point` by value to other
functions. As a consequence, we had to explicitly take the address of
`on_the_stack` to get a borrowed pointer. Sometimes however it is more
convenient to move the & operator into the definition of `on_the_stack`:
~~~
# struct Point {x: float, y: float}
let on_the_stack2: &Point = &Point {x: 3.0, y: 4.0};
~~~
Applying `&` to an rvalue (non-assignable location) is just a convenient
shorthand for creating a temporary and taking its address. A more verbose
way to write the same code is:
~~~
# struct Point {x: float, y: float}
let tmp = Point {x: 3.0, y: 4.0};
let on_the_stack2 : &Point = &tmp;
~~~
# Taking the address of fields
As in C, the `&` operator is not limited to taking the address of
local variables. It can also take the address of fields or
individual array elements. For example, consider this type definition
for `rectangle`:
~~~
struct Point {x: float, y: float} // as before
struct Size {w: float, h: float} // as before
struct Rectangle {origin: Point, size: Size}
~~~
Now, as before, we can define rectangles in a few different ways:
~~~
# struct Point {x: float, y: float}
# struct Size {w: float, h: float} // as before
# struct Rectangle {origin: Point, size: Size}
let rect_stack = &Rectangle {origin: Point {x: 1f, y: 2f},
size: Size {w: 3f, h: 4f}};
let rect_managed = @Rectangle {origin: Point {x: 3f, y: 4f},
size: Size {w: 3f, h: 4f}};
let rect_owned = ~Rectangle {origin: Point {x: 5f, y: 6f},
size: Size {w: 3f, h: 4f}};
~~~
In each case, we can extract out individual subcomponents with the `&`
operator. For example, I could write:
~~~
# struct Point {x: float, y: float} // as before
# struct Size {w: float, h: float} // as before
# struct Rectangle {origin: Point, size: Size}
# let rect_stack = &Rectangle {origin: Point {x: 1f, y: 2f}, size: Size {w: 3f, h: 4f}};
# let rect_managed = @Rectangle {origin: Point {x: 3f, y: 4f}, size: Size {w: 3f, h: 4f}};
# let rect_owned = ~Rectangle {origin: Point {x: 5f, y: 6f}, size: Size {w: 3f, h: 4f}};
# fn compute_distance(p1: &Point, p2: &Point) -> float { 0f }
compute_distance(&rect_stack.origin, &rect_managed.origin);
~~~
which would borrow the field `origin` from the rectangle on the stack
as well as from the managed box, and then compute the distance between them.
# Borrowing managed boxes and rooting
Weve seen a few examples so far of borrowing heap boxes, both managed
and owned. Up till this point, weve glossed over issues of
safety. As stated in the introduction, at runtime a borrowed pointer
is simply a pointer, nothing more. Therefore, avoiding C's problems
with dangling pointers requires a compile-time safety check.
The basis for the check is the notion of _lifetimes_. A lifetime is a
static approximation of the span of execution during which the pointer
is valid: it always corresponds to some expression or block within the
program. Code inside that expression can use the pointer without
restrictions. But if the pointer escapes from that expression (for
example, if the expression contains an assignment expression that
assigns the pointer to a mutable field of a data structure with a
broader scope than the pointer itself), the compiler reports an
error. We'll be discussing lifetimes more in the examples to come, and
a more thorough introduction is also available.
When the `&` operator creates a borrowed pointer, the compiler must
ensure that the pointer remains valid for its entire
lifetime. Sometimes this is relatively easy, such as when taking the
address of a local variable or a field that is stored on the stack:
~~~
struct X { f: int }
fn example1() {
let mut x = X { f: 3 };
let y = &mut x.f; // -+ L
... // |
} // -+
~~~
Here, the lifetime of the borrowed pointer `y` is simply L, the
remainder of the function body. The compiler need not do any other
work to prove that code will not free `x.f`. This is true even if the
code mutates `x`.
The situation gets more complex when borrowing data inside heap boxes:
~~~
# struct X { f: int }
fn example2() {
let mut x = @X { f: 3 };
let y = &x.f; // -+ L
... // |
} // -+
~~~
In this example, the value `x` is a heap box, and `y` is therefore a
pointer into that heap box. Again the lifetime of `y` is L, the
remainder of the function body. But there is a crucial difference:
suppose `x` were to be reassigned during the lifetime L? If the
compiler isn't careful, the managed box could become *unrooted*, and
would therefore be subject to garbage collection. A heap box that is
unrooted is one such that no pointer values in the heap point to
it. It would violate memory safety for the box that was originally
assigned to `x` to be garbage-collected, since a non-heap
pointer *`y`* still points into it.
> ***Note:*** Our current implementation implements the garbage collector
> using reference counting and cycle detection.
For this reason, whenever an `&` expression borrows the interior of a
managed box stored in a mutable location, the compiler inserts a
temporary that ensures that the managed box remains live for the
entire lifetime. So, the above example would be compiled as if it were
written
~~~
# struct X { f: int }
fn example2() {
let mut x = @X {f: 3};
let x1 = x;
let y = &x1.f; // -+ L
... // |
} // -+
~~~
Now if `x` is reassigned, the pointer `y` will still remain valid. This
process is called *rooting*.
# Borrowing owned boxes
The previous example demonstrated *rooting*, the process by which the
compiler ensures that managed boxes remain live for the duration of a
borrow. Unfortunately, rooting does not work for borrows of owned
boxes, because it is not possible to have two references to a owned
box.
For owned boxes, therefore, the compiler will only allow a borrow *if
the compiler can guarantee that the owned box will not be reassigned
or moved for the lifetime of the pointer*. This does not necessarily
mean that the owned box is stored in immutable memory. For example,
the following function is legal:
~~~
# fn some_condition() -> bool { true }
# struct Foo { f: int }
fn example3() -> int {
let mut x = ~Foo {f: 3};
if some_condition() {
let y = &x.f; // -+ L
return *y; // |
} // -+
x = ~Foo {f: 4};
...
# return 0;
}
~~~
Here, as before, the interior of the variable `x` is being borrowed
and `x` is declared as mutable. However, the compiler can prove that
`x` is not assigned anywhere in the lifetime L of the variable
`y`. Therefore, it accepts the function, even though `x` is mutable
and in fact is mutated later in the function.
It may not be clear why we are so concerned about mutating a borrowed
variable. The reason is that the runtime system frees any owned box
_as soon as its owning reference changes or goes out of
scope_. Therefore, a program like this is illegal (and would be
rejected by the compiler):
~~~ {.xfail-test}
fn example3() -> int {
let mut x = ~X {f: 3};
let y = &x.f;
x = ~X {f: 4}; // Error reported here.
*y
}
~~~
To make this clearer, consider this diagram showing the state of
memory immediately before the re-assignment of `x`:
~~~ {.notrust}
Stack Exchange Heap
x +----------+
| ~{f:int} | ----+
y +----------+ |
| &int | ----+
+----------+ | +---------+
+--> | f: 3 |
+---------+
~~~
Once the reassignment occurs, the memory will look like this:
~~~ {.notrust}
Stack Exchange Heap
x +----------+ +---------+
| ~{f:int} | -------> | f: 4 |
y +----------+ +---------+
| &int | ----+
+----------+ | +---------+
+--> | (freed) |
+---------+
~~~
Here you can see that the variable `y` still points at the old box,
which has been freed.
In fact, the compiler can apply the same kind of reasoning to any
memory that is _(uniquely) owned by the stack frame_. So we could
modify the previous example to introduce additional owned pointers
and structs, and the compiler will still be able to detect possible
mutations:
~~~ {.xfail-test}
fn example3() -> int {
struct R { g: int }
struct S { f: ~R }
let mut x = ~S {f: ~R {g: 3}};
let y = &x.f.g;
x = ~S {f: ~R {g: 4}}; // Error reported here.
x.f = ~R {g: 5}; // Error reported here.
*y
}
~~~
In this case, two errors are reported, one when the variable `x` is
modified and another when `x.f` is modified. Either modification would
invalidate the pointer `y`.
# Borrowing and enums
The previous example showed that the type system forbids any borrowing
of owned boxes found in aliasable, mutable memory. This restriction
prevents pointers from pointing into freed memory. There is one other
case where the compiler must be very careful to ensure that pointers
remain valid: pointers into the interior of an `enum`.
As an example, lets look at the following `shape` type that can
represent both rectangles and circles:
~~~
struct Point {x: float, y: float}; // as before
struct Size {w: float, h: float}; // as before
enum Shape {
Circle(Point, float), // origin, radius
Rectangle(Point, Size) // upper-left, dimensions
}
~~~
Now we might write a function to compute the area of a shape. This
function takes a borrowed pointer to a shape, to avoid the need for
copying.
~~~
# struct Point {x: float, y: float}; // as before
# struct Size {w: float, h: float}; // as before
# enum Shape {
# Circle(Point, float), // origin, radius
# Rectangle(Point, Size) // upper-left, dimensions
# }
# static tau: float = 6.28f;
fn compute_area(shape: &Shape) -> float {
match *shape {
Circle(_, radius) => 0.5 * tau * radius * radius,
Rectangle(_, ref size) => size.w * size.h
}
}
~~~
The first case matches against circles. Here, the pattern extracts the
radius from the shape variant and the action uses it to compute the
area of the circle. (Like any up-to-date engineer, we use the [tau
circle constant][tau] and not that dreadfully outdated notion of pi).
[tau]: http://www.math.utah.edu/~palais/pi.html
The second match is more interesting. Here we match against a
rectangle and extract its size: but rather than copy the `size`
struct, we use a by-reference binding to create a pointer to it. In
other words, a pattern binding like `ref size` binds the name `size`
to a pointer of type `&size` into the _interior of the enum_.
To make this more clear, let's look at a diagram of memory layout in
the case where `shape` points at a rectangle:
~~~ {.notrust}
Stack Memory
+-------+ +---------------+
| shape | ------> | rectangle( |
+-------+ | {x: float, |
| size | -+ | y: float}, |
+-------+ +----> | {w: float, |
| h: float}) |
+---------------+
~~~
Here you can see that rectangular shapes are composed of five words of
memory. The first is a tag indicating which variant this enum is
(`rectangle`, in this case). The next two words are the `x` and `y`
fields for the point and the remaining two are the `w` and `h` fields
for the size. The binding `size` is then a pointer into the inside of
the shape.
Perhaps you can see where the danger lies: if the shape were somehow
to be reassigned, perhaps to a circle, then although the memory used
to store that shape value would still be valid, _it would have a
different type_! The following diagram shows what memory would look
like if code overwrote `shape` with a circle:
~~~ {.notrust}
Stack Memory
+-------+ +---------------+
| shape | ------> | circle( |
+-------+ | {x: float, |
| size | -+ | y: float}, |
+-------+ +----> | float) |
| |
+---------------+
~~~
As you can see, the `size` pointer would be pointing at a `float`
instead of a struct. This is not good: dereferencing the second field
of a `float` as if it were a struct with two fields would be a memory
safety violation.
So, in fact, for every `ref` binding, the compiler will impose the
same rules as the ones we saw for borrowing the interior of a owned
box: it must be able to guarantee that the `enum` will not be
overwritten for the duration of the borrow. In fact, the compiler
would accept the example we gave earlier. The example is safe because
the shape pointer has type `&Shape`, which means "borrowed pointer to
immutable memory containing a `shape`". If, however, the type of that
pointer were `&mut Shape`, then the ref binding would be ill-typed.
Just as with owned boxes, the compiler will permit `ref` bindings
into data owned by the stack frame even if the data are mutable,
but otherwise it requires that the data reside in immutable memory.
# Returning borrowed pointers
So far, all of the examples we have looked at, use borrowed pointers in a
“downward” direction. That is, a method or code block creates a
borrowed pointer, then uses it within the same scope. It is also
possible to return borrowed pointers as the result of a function, but
as we'll see, doing so requires some explicit annotation.
For example, we could write a subroutine like this:
~~~
struct Point {x: float, y: float}
fn get_x<'r>(p: &'r Point) -> &'r float { &p.x }
~~~
Here, the function `get_x()` returns a pointer into the structure it
was given. The type of the parameter (`&'r Point`) and return type
(`&'r float`) both use a new syntactic form that we have not seen so
far. Here the identifier `r` names the lifetime of the pointer
explicitly. So in effect, this function declares that it takes a
pointer with lifetime `r` and returns a pointer with that same
lifetime.
In general, it is only possible to return borrowed pointers if they
are derived from a parameter to the procedure. In that case, the
pointer result will always have the same lifetime as one of the
parameters; named lifetimes indicate which parameter that
is.
In the previous examples, function parameter types did not include a
lifetime name. In those examples, the compiler simply creates a fresh
name for the lifetime automatically: that is, the lifetime name is
guaranteed to refer to a distinct lifetime from the lifetimes of all
other parameters.
Named lifetimes that appear in function signatures are conceptually
the same as the other lifetimes we have seen before, but they are a bit
abstract: they dont refer to a specific expression within `get_x()`,
but rather to some expression within the *caller of `get_x()`*. The
lifetime `r` is actually a kind of *lifetime parameter*: it is defined
by the caller to `get_x()`, just as the value for the parameter `p` is
defined by that caller.
In any case, whatever the lifetime of `r` is, the pointer produced by
`&p.x` always has the same lifetime as `p` itself: a pointer to a
field of a struct is valid as long as the struct is valid. Therefore,
the compiler accepts the function `get_x()`.
To emphasize this point, lets look at a variation on the example, this
time one that does not compile:
~~~ {.xfail-test}
struct Point {x: float, y: float}
fn get_x_sh(p: @Point) -> &float {
&p.x // Error reported here
}
~~~
Here, the function `get_x_sh()` takes a managed box as input and
returns a borrowed pointer. As before, the lifetime of the borrowed
pointer that will be returned is a parameter (specified by the
caller). That means that `get_x_sh()` promises to return a borrowed
pointer that is valid for as long as the caller would like: this is
subtly different from the first example, which promised to return a
pointer that was valid for as long as its pointer argument was valid.
Within `get_x_sh()`, we see the expression `&p.x` which takes the
address of a field of a managed box. The presence of this expression
implies that the compiler must guarantee that, so long as the
resulting pointer is valid, the managed box will not be reclaimed by
the garbage collector. But recall that `get_x_sh()` also promised to
return a pointer that was valid for as long as the caller wanted it to
be. Clearly, `get_x_sh()` is not in a position to make both of these
guarantees; in fact, it cannot guarantee that the pointer will remain
valid at all once it returns, as the parameter `p` may or may not be
live in the caller. Therefore, the compiler will report an error here.
In general, if you borrow a managed (or owned) box to create a
borrowed pointer, the pointer will only be valid within the function
and cannot be returned. This is why the typical way to return borrowed
pointers is to take borrowed pointers as input (the only other case in
which it can be legal to return a borrowed pointer is if the pointer
points at a static constant).
# Named lifetimes
Let's look at named lifetimes in more detail. Named lifetimes allow
for grouping of parameters by lifetime. For example, consider this
function:
~~~
# struct Point {x: float, y: float}; // as before
# struct Size {w: float, h: float}; // as before
# enum Shape {
# Circle(Point, float), // origin, radius
# Rectangle(Point, Size) // upper-left, dimensions
# }
# fn compute_area(shape: &Shape) -> float { 0f }
fn select<'r, T>(shape: &'r Shape, threshold: float,
a: &'r T, b: &'r T) -> &'r T {
if compute_area(shape) > threshold {a} else {b}
}
~~~
This function takes three borrowed pointers and assigns each the same
lifetime `r`. In practice, this means that, in the caller, the
lifetime `r` will be the *intersection of the lifetime of the three
region parameters*. This may be overly conservative, as in this
example:
~~~
# struct Point {x: float, y: float}; // as before
# struct Size {w: float, h: float}; // as before
# enum Shape {
# Circle(Point, float), // origin, radius
# Rectangle(Point, Size) // upper-left, dimensions
# }
# fn compute_area(shape: &Shape) -> float { 0f }
# fn select<'r, T>(shape: &Shape, threshold: float,
# a: &'r T, b: &'r T) -> &'r T {
# if compute_area(shape) > threshold {a} else {b}
# }
// -+ r
fn select_based_on_unit_circle<'r, T>( // |-+ B
threshold: float, a: &'r T, b: &'r T) -> &'r T { // | |
// | |
let shape = Circle(Point {x: 0., y: 0.}, 1.); // | |
select(&shape, threshold, a, b) // | |
} // |-+
// -+
~~~
In this call to `select()`, the lifetime of the first parameter shape
is B, the function body. Both of the second two parameters `a` and `b`
share the same lifetime, `r`, which is a lifetime parameter of
`select_based_on_unit_circle()`. The caller will infer the
intersection of these two lifetimes as the lifetime of the returned
value, and hence the return value of `select()` will be assigned a
lifetime of B. This will in turn lead to a compilation error, because
`select_based_on_unit_circle()` is supposed to return a value with the
lifetime `r`.
To address this, we can modify the definition of `select()` to
distinguish the lifetime of the first parameter from the lifetime of
the latter two. After all, the first parameter is not being
returned. Here is how the new `select()` might look:
~~~
# struct Point {x: float, y: float}; // as before
# struct Size {w: float, h: float}; // as before
# enum Shape {
# Circle(Point, float), // origin, radius
# Rectangle(Point, Size) // upper-left, dimensions
# }
# fn compute_area(shape: &Shape) -> float { 0f }
fn select<'r, 'tmp, T>(shape: &'tmp Shape, threshold: float,
a: &'r T, b: &'r T) -> &'r T {
if compute_area(shape) > threshold {a} else {b}
}
~~~
Here you can see that `shape`'s lifetime is now named `tmp`. The
parameters `a`, `b`, and the return value all have the lifetime `r`.
However, since the lifetime `tmp` is not returned, it would be more
concise to just omit the named lifetime for `shape` altogether:
~~~
# struct Point {x: float, y: float}; // as before
# struct Size {w: float, h: float}; // as before
# enum Shape {
# Circle(Point, float), // origin, radius
# Rectangle(Point, Size) // upper-left, dimensions
# }
# fn compute_area(shape: &Shape) -> float { 0f }
fn select<'r, T>(shape: &Shape, threshold: float,
a: &'r T, b: &'r T) -> &'r T {
if compute_area(shape) > threshold {a} else {b}
}
~~~
This is equivalent to the previous definition.
# Conclusion
So there you have it: a (relatively) brief tour of the borrowed pointer
system. For more details, we refer to the (yet to be written) reference
document on borrowed pointers, which will explain the full notation
and give more examples.

View File

@ -1,207 +0,0 @@
% Containers and iterators
# Containers
The container traits are defined in the `std::container` module.
## Unique and managed vectors
Vectors have `O(1)` indexing and removal from the end, along with `O(1)`
amortized insertion. Vectors are the most common container in Rust, and are
flexible enough to fit many use cases.
Vectors can also be sorted and used as efficient lookup tables with the
`std::vec::bsearch` function, if all the elements are inserted at one time and
deletions are unnecessary.
## Maps and sets
Maps are collections of unique keys with corresponding values, and sets are
just unique keys without a corresponding value. The `Map` and `Set` traits in
`std::container` define the basic interface.
The standard library provides three owned map/set types:
* `std::hashmap::HashMap` and `std::hashmap::HashSet`, requiring the keys to
implement `Eq` and `Hash`
* `std::trie::TrieMap` and `std::trie::TrieSet`, requiring the keys to be `uint`
* `extra::treemap::TreeMap` and `extra::treemap::TreeSet`, requiring the keys
to implement `TotalOrd`
These maps do not use managed pointers so they can be sent between tasks as
long as the key and value types are sendable. Neither the key or value type has
to be copyable.
The `TrieMap` and `TreeMap` maps are ordered, while `HashMap` uses an arbitrary
order.
Each `HashMap` instance has a random 128-bit key to use with a keyed hash,
making the order of a set of keys in a given hash table randomized. Rust
provides a [SipHash](https://131002.net/siphash/) implementation for any type
implementing the `IterBytes` trait.
## Double-ended queues
The `extra::deque` module implements a double-ended queue with `O(1)` amortized
inserts and removals from both ends of the container. It also has `O(1)`
indexing like a vector. The contained elements are not required to be copyable,
and the queue will be sendable if the contained type is sendable.
## Priority queues
The `extra::priority_queue` module implements a queue ordered by a key. The
contained elements are not required to be copyable, and the queue will be
sendable if the contained type is sendable.
Insertions have `O(log n)` time complexity and checking or popping the largest
element is `O(1)`. Converting a vector to a priority queue can be done
in-place, and has `O(n)` complexity. A priority queue can also be converted to
a sorted vector in-place, allowing it to be used for an `O(n log n)` in-place
heapsort.
# Iterators
## Iteration protocol
The iteration protocol is defined by the `Iterator` trait in the
`std::iterator` module. The minimal implementation of the trait is a `next`
method, yielding the next element from an iterator object:
~~~
/// An infinite stream of zeroes
struct ZeroStream;
impl Iterator<int> for ZeroStream {
fn next(&mut self) -> Option<int> {
Some(0)
}
}
~~~~
Reaching the end of the iterator is signalled by returning `None` instead of
`Some(item)`:
~~~
/// A stream of N zeroes
struct ZeroStream {
priv remaining: uint
}
impl ZeroStream {
fn new(n: uint) -> ZeroStream {
ZeroStream { remaining: n }
}
}
impl Iterator<int> for ZeroStream {
fn next(&mut self) -> Option<int> {
if self.remaining == 0 {
None
} else {
self.remaining -= 1;
Some(0)
}
}
}
~~~
## Container iterators
Containers implement iteration over the contained elements by returning an
iterator object. For example, vectors have four iterators available:
* `vector.iter()`, for immutable references to the elements
* `vector.mut_iter()`, for mutable references to the elements
* `vector.rev_iter()`, for immutable references to the elements in reverse order
* `vector.mut_rev_iter()`, for mutable references to the elements in reverse order
### Freezing
Unlike most other languages with external iterators, Rust has no *iterator
invalidation*. As long an iterator is still in scope, the compiler will prevent
modification of the container through another handle.
~~~
let mut xs = [1, 2, 3];
{
let _it = xs.iter();
// the vector is frozen for this scope, the compiler will statically
// prevent modification
}
// the vector becomes unfrozen again at the end of the scope
~~~
These semantics are due to most container iterators being implemented with `&`
and `&mut`.
## Iterator adaptors
The `IteratorUtil` trait implements common algorithms as methods extending
every `Iterator` implementation. For example, the `fold` method will accumulate
the items yielded by an `Iterator` into a single value:
~~~
let xs = [1, 9, 2, 3, 14, 12];
let result = xs.iter().fold(0, |accumulator, item| accumulator - *item);
assert_eq!(result, -41);
~~~
Some adaptors return an adaptor object implementing the `Iterator` trait itself:
~~~
let xs = [1, 9, 2, 3, 14, 12];
let ys = [5, 2, 1, 8];
let sum = xs.iter().chain_(ys.iter()).fold(0, |a, b| a + *b);
assert_eq!(sum, 57);
~~~
Note that some adaptors like the `chain_` method above use a trailing
underscore to work around an issue with method resolve. The underscores will be
dropped when they become unnecessary.
## For loops
The `for` loop syntax is currently in transition, and will switch from the old
closure-based iteration protocol to iterator objects. For now, the `advance`
adaptor is required as a compatibility shim to use iterators with for loops.
~~~
let xs = [2, 3, 5, 7, 11, 13, 17];
// print out all the elements in the vector
for xs.iter().advance |x| {
println(x.to_str())
}
// print out all but the first 3 elements in the vector
for xs.iter().skip(3).advance |x| {
println(x.to_str())
}
~~~
For loops are *often* used with a temporary iterator object, as above. They can
also advance the state of an iterator in a mutable location:
~~~
let xs = [1, 2, 3, 4, 5];
let ys = ["foo", "bar", "baz", "foobar"];
// create an iterator yielding tuples of elements from both vectors
let mut it = xs.iter().zip(ys.iter());
// print out the pairs of elements up to (&3, &"baz")
for it.advance |(x, y)| {
println(fmt!("%d %s", *x, *y));
if *x == 3 {
break;
}
}
// yield and print the last pair from the iterator
println(fmt!("last: %?", it.next()));
// the iterator is now fully consumed
assert!(it.next().is_none());
~~~

View File

@ -1,270 +0,0 @@
% Rust Foreign Function Interface Tutorial
# Introduction
This tutorial will use the [snappy](https://code.google.com/p/snappy/)
compression/decompression library as an introduction to writing bindings for
foreign code. Rust is currently unable to call directly into a C++ library, but
snappy includes a C interface (documented in
[`snappy-c.h`](https://code.google.com/p/snappy/source/browse/trunk/snappy-c.h)).
The following is a minimal example of calling a foreign function which will compile if snappy is
installed:
~~~~ {.xfail-test}
use std::libc::size_t;
#[link_args = "-lsnappy"]
extern {
fn snappy_max_compressed_length(source_length: size_t) -> size_t;
}
fn main() {
let x = unsafe { snappy_max_compressed_length(100) };
println(fmt!("max compressed length of a 100 byte buffer: %?", x));
}
~~~~
The `extern` block is a list of function signatures in a foreign library, in this case with the
platform's C ABI. The `#[link_args]` attribute is used to instruct the linker to link against the
snappy library so the symbols are resolved.
Foreign functions are assumed to be unsafe so calls to them need to be wrapped with `unsafe {}` as a
promise to the compiler that everything contained within truly is safe. C libraries often expose
interfaces that aren't thread-safe, and almost any function that takes a pointer argument isn't
valid for all possible inputs since the pointer could be dangling, and raw pointers fall outside of
Rust's safe memory model.
When declaring the argument types to a foreign function, the Rust compiler will not check if the
declaration is correct, so specifying it correctly is part of keeping the binding correct at
runtime.
The `extern` block can be extended to cover the entire snappy API:
~~~~ {.xfail-test}
use std::libc::{c_int, size_t};
#[link_args = "-lsnappy"]
extern {
fn snappy_compress(input: *u8,
input_length: size_t,
compressed: *mut u8,
compressed_length: *mut size_t) -> c_int;
fn snappy_uncompress(compressed: *u8,
compressed_length: size_t,
uncompressed: *mut u8,
uncompressed_length: *mut size_t) -> c_int;
fn snappy_max_compressed_length(source_length: size_t) -> size_t;
fn snappy_uncompressed_length(compressed: *u8,
compressed_length: size_t,
result: *mut size_t) -> c_int;
fn snappy_validate_compressed_buffer(compressed: *u8,
compressed_length: size_t) -> c_int;
}
~~~~
# Creating a safe interface
The raw C API needs to be wrapped to provide memory safety and make use of higher-level concepts
like vectors. A library can choose to expose only the safe, high-level interface and hide the unsafe
internal details.
Wrapping the functions which expect buffers involves using the `vec::raw` module to manipulate Rust
vectors as pointers to memory. Rust's vectors are guaranteed to be a contiguous block of memory. The
length is number of elements currently contained, and the capacity is the total size in elements of
the allocated memory. The length is less than or equal to the capacity.
~~~~ {.xfail-test}
pub fn validate_compressed_buffer(src: &[u8]) -> bool {
unsafe {
snappy_validate_compressed_buffer(vec::raw::to_ptr(src), src.len() as size_t) == 0
}
}
~~~~
The `validate_compressed_buffer` wrapper above makes use of an `unsafe` block, but it makes the
guarantee that calling it is safe for all inputs by leaving off `unsafe` from the function
signature.
The `snappy_compress` and `snappy_uncompress` functions are more complex, since a buffer has to be
allocated to hold the output too.
The `snappy_max_compressed_length` function can be used to allocate a vector with the maximum
required capacity to hold the compressed output. The vector can then be passed to the
`snappy_compress` function as an output parameter. An output parameter is also passed to retrieve
the true length after compression for setting the length.
~~~~ {.xfail-test}
pub fn compress(src: &[u8]) -> ~[u8] {
unsafe {
let srclen = src.len() as size_t;
let psrc = vec::raw::to_ptr(src);
let mut dstlen = snappy_max_compressed_length(srclen);
let mut dst = vec::with_capacity(dstlen as uint);
let pdst = vec::raw::to_mut_ptr(dst);
snappy_compress(psrc, srclen, pdst, &mut dstlen);
vec::raw::set_len(&mut dst, dstlen as uint);
dst
}
}
~~~~
Decompression is similar, because snappy stores the uncompressed size as part of the compression
format and `snappy_uncompressed_length` will retrieve the exact buffer size required.
~~~~ {.xfail-test}
pub fn uncompress(src: &[u8]) -> Option<~[u8]> {
unsafe {
let srclen = src.len() as size_t;
let psrc = vec::raw::to_ptr(src);
let mut dstlen: size_t = 0;
snappy_uncompressed_length(psrc, srclen, &mut dstlen);
let mut dst = vec::with_capacity(dstlen as uint);
let pdst = vec::raw::to_mut_ptr(dst);
if snappy_uncompress(psrc, srclen, pdst, &mut dstlen) == 0 {
vec::raw::set_len(&mut dst, dstlen as uint);
Some(dst)
} else {
None // SNAPPY_INVALID_INPUT
}
}
}
~~~~
For reference, the examples used here are also available as an [library on
GitHub](https://github.com/thestinger/rust-snappy).
# Destructors
Foreign libraries often hand off ownership of resources to the calling code,
which should be wrapped in a destructor to provide safety and guarantee their
release.
A type with the same functionality as owned boxes can be implemented by
wrapping `malloc` and `free`:
~~~~
use std::cast;
use std::libc::{c_void, size_t, malloc, free};
use std::ptr;
use std::unstable::intrinsics;
// a wrapper around the handle returned by the foreign code
pub struct Unique<T> {
priv ptr: *mut T
}
impl<T: Send> Unique<T> {
pub fn new(value: T) -> Unique<T> {
unsafe {
let ptr = malloc(std::sys::size_of::<T>() as size_t) as *mut T;
assert!(!ptr::is_null(ptr));
// `*ptr` is uninitialized, and `*ptr = value` would attempt to destroy it
intrinsics::move_val_init(&mut *ptr, value);
Unique{ptr: ptr}
}
}
// the 'r lifetime results in the same semantics as `&*x` with ~T
pub fn borrow<'r>(&'r self) -> &'r T {
unsafe { cast::copy_lifetime(self, &*self.ptr) }
}
// the 'r lifetime results in the same semantics as `&mut *x` with ~T
pub fn borrow_mut<'r>(&'r mut self) -> &'r mut T {
unsafe { cast::copy_mut_lifetime(self, &mut *self.ptr) }
}
}
#[unsafe_destructor]
impl<T: Send> Drop for Unique<T> {
fn drop(&self) {
unsafe {
let x = intrinsics::init(); // dummy value to swap in
// moving the object out is needed to call the destructor
ptr::replace_ptr(self.ptr, x);
free(self.ptr as *c_void)
}
}
}
// A comparison between the built-in ~ and this reimplementation
fn main() {
{
let mut x = ~5;
*x = 10;
} // `x` is freed here
{
let mut y = Unique::new(5);
*y.borrow_mut() = 10;
} // `y` is freed here
}
~~~~
# Linking
In addition to the `#[link_args]` attribute for explicitly passing arguments to the linker, an
`extern mod` block will pass `-lmodname` to the linker by default unless it has a `#[nolink]`
attribute applied.
# Unsafe blocks
Some operations, like dereferencing unsafe pointers or calling functions that have been marked
unsafe are only allowed inside unsafe blocks. Unsafe blocks isolate unsafety and are a promise to
the compiler that the unsafety does not leak out of the block.
Unsafe functions, on the other hand, advertise it to the world. An unsafe function is written like
this:
~~~~
unsafe fn kaboom(ptr: *int) -> int { *ptr }
~~~~
This function can only be called from an `unsafe` block or another `unsafe` function.
# Foreign calling conventions
Most foreign code exposes a C ABI, and Rust uses the platform's C calling convention by default when
calling foreign functions. Some foreign functions, most notably the Windows API, use other calling
conventions. Rust provides the `abi` attribute as a way to hint to the compiler which calling
convention to use:
~~~~
#[cfg(target_os = "win32")]
#[abi = "stdcall"]
#[link_name = "kernel32"]
extern {
fn SetEnvironmentVariableA(n: *u8, v: *u8) -> int;
}
~~~~
The `abi` attribute applies to a foreign module (it cannot be applied to a single function within a
module), and must be either `"cdecl"` or `"stdcall"`. The compiler may eventually support other
calling conventions.
# Interoperability with foreign code
Rust guarantees that the layout of a `struct` is compatible with the platform's representation in C.
A `#[packed]` attribute is available, which will lay out the struct members without padding.
However, there are currently no guarantees about the layout of an `enum`.
Rust's owned and managed boxes use non-nullable pointers as handles which point to the contained
object. However, they should not be manually created because they are managed by internal
allocators. Borrowed pointers can safely be assumed to be non-nullable pointers directly to the
type. However, breaking the borrow checking or mutability rules is not guaranteed to be safe, so
prefer using raw pointers (`*`) if that's needed because the compiler can't make as many assumptions
about them.
Vectors and strings share the same basic memory layout, and utilities are available in the `vec` and
`str` modules for working with C APIs. Strings are terminated with `\0` for interoperability with C,
but it should not be assumed because a slice will not always be nul-terminated. Instead, the
`str::as_c_str` function should be used.
The standard library includes type aliases and function definitions for the C standard library in
the `libc` module, and Rust links against `libc` and `libm` by default.

View File

@ -1,407 +0,0 @@
% Rust Macros Tutorial
# Introduction
Functions are the primary tool that programmers can use to build abstractions.
Sometimes, however, programmers want to abstract over compile-time syntax
rather than run-time values.
Macros provide syntactic abstraction.
For an example of how this can be useful, consider the following two code fragments,
which both pattern-match on their input and both return early in one case,
doing nothing otherwise:
~~~~
# enum t { special_a(uint), special_b(uint) };
# fn f() -> uint {
# let input_1 = special_a(0);
# let input_2 = special_a(0);
match input_1 {
special_a(x) => { return x; }
_ => {}
}
// ...
match input_2 {
special_b(x) => { return x; }
_ => {}
}
# return 0u;
# }
~~~~
This code could become tiresome if repeated many times.
However, no function can capture its functionality to make it possible
to abstract the repetition away.
Rust's macro system, however, can eliminate the repetition. Macros are
lightweight custom syntax extensions, themselves defined using the
`macro_rules!` syntax extension. The following `early_return` macro captures
the pattern in the above code:
~~~~
# enum t { special_a(uint), special_b(uint) };
# fn f() -> uint {
# let input_1 = special_a(0);
# let input_2 = special_a(0);
macro_rules! early_return(
($inp:expr $sp:ident) => ( // invoke it like `(input_5 special_e)`
match $inp {
$sp(x) => { return x; }
_ => {}
}
);
)
// ...
early_return!(input_1 special_a);
// ...
early_return!(input_2 special_b);
# return 0;
# }
~~~~
Macros are defined in pattern-matching style: in the above example, the text
`($inp:expr $sp:ident)` that appears on the left-hand side of the `=>` is the
*macro invocation syntax*, a pattern denoting how to write a call to the
macro. The text on the right-hand side of the `=>`, beginning with `match
$inp`, is the *macro transcription syntax*: what the macro expands to.
# Invocation syntax
The macro invocation syntax specifies the syntax for the arguments to the
macro. It appears on the left-hand side of the `=>` in a macro definition. It
conforms to the following rules:
1. It must be surrounded by parentheses.
2. `$` has special meaning (described below).
3. The `()`s, `[]`s, and `{}`s it contains must balance. For example, `([)` is
forbidden.
Otherwise, the invocation syntax is free-form.
To take as an argument a fragment of Rust code, write `$` followed by a name
(for use on the right-hand side), followed by a `:`, followed by a *fragment
specifier*. The fragment specifier denotes the sort of fragment to match. The
most common fragment specifiers are:
* `ident` (an identifier, referring to a variable or item. Examples: `f`, `x`,
`foo`.)
* `expr` (an expression. Examples: `2 + 2`; `if true then { 1 } else { 2 }`;
`f(42)`.)
* `ty` (a type. Examples: `int`, `~[(char, ~str)]`, `&T`.)
* `pat` (a pattern, usually appearing in a `match` or on the left-hand side of
a declaration. Examples: `Some(t)`; `(17, 'a')`; `_`.)
* `block` (a sequence of actions. Example: `{ log(error, "hi"); return 12; }`)
The parser interprets any token that's not preceded by a `$` literally. Rust's usual
rules of tokenization apply,
So `($x:ident -> (($e:expr)))`, though excessively fancy, would designate a macro
that could be invoked like: `my_macro!(i->(( 2+2 )))`.
## Invocation location
A macro invocation may take the place of (and therefore expand to)
an expression, an item, or a statement.
The Rust parser will parse the macro invocation as a "placeholder"
for whichever of those three nonterminals is appropriate for the location.
At expansion time, the output of the macro will be parsed as whichever of the
three nonterminals it stands in for. This means that a single macro might,
for example, expand to an item or an expression, depending on its arguments
(and cause a syntax error if it is called with the wrong argument for its
location). Although this behavior sounds excessively dynamic, it is known to
be useful under some circumstances.
# Transcription syntax
The right-hand side of the `=>` follows the same rules as the left-hand side,
except that a `$` need only be followed by the name of the syntactic fragment
to transcribe into the macro expansion; its type need not be repeated.
The right-hand side must be enclosed by delimiters, which the transcriber ignores.
Therefore `() => ((1,2,3))` is a macro that expands to a tuple expression,
`() => (let $x=$val)` is a macro that expands to a statement,
and `() => (1,2,3)` is a macro that expands to a syntax error
(since the transcriber interprets the parentheses on the right-hand-size as delimiters,
and `1,2,3` is not a valid Rust expression on its own).
Except for permissibility of `$name` (and `$(...)*`, discussed below), the
right-hand side of a macro definition is ordinary Rust syntax. In particular,
macro invocations (including invocations of the macro currently being defined)
are permitted in expression, statement, and item locations. However, nothing
else about the code is examined or executed by the macro system; execution
still has to wait until run-time.
## Interpolation location
The interpolation `$argument_name` may appear in any location consistent with
its fragment specifier (i.e., if it is specified as `ident`, it may be used
anywhere an identifier is permitted).
# Multiplicity
## Invocation
Going back to the motivating example, recall that `early_return` expanded into
a `match` that would `return` if the `match`'s scrutinee matched the
"special case" identifier provided as the second argument to `early_return`,
and do nothing otherwise. Now suppose that we wanted to write a
version of `early_return` that could handle a variable number of "special"
cases.
The syntax `$(...)*` on the left-hand side of the `=>` in a macro definition
accepts zero or more occurrences of its contents. It works much
like the `*` operator in regular expressions. It also supports a
separator token (a comma-separated list could be written `$(...),*`), and `+`
instead of `*` to mean "at least one".
~~~~
# enum t { special_a(uint),special_b(uint),special_c(uint),special_d(uint)};
# fn f() -> uint {
# let input_1 = special_a(0);
# let input_2 = special_a(0);
macro_rules! early_return(
($inp:expr, [ $($sp:ident)|+ ]) => (
match $inp {
$(
$sp(x) => { return x; }
)+
_ => {}
}
);
)
// ...
early_return!(input_1, [special_a|special_c|special_d]);
// ...
early_return!(input_2, [special_b]);
# return 0;
# }
~~~~
### Transcription
As the above example demonstrates, `$(...)*` is also valid on the right-hand
side of a macro definition. The behavior of `*` in transcription,
especially in cases where multiple `*`s are nested, and multiple different
names are involved, can seem somewhat magical and intuitive at first. The
system that interprets them is called "Macro By Example". The two rules to
keep in mind are (1) the behavior of `$(...)*` is to walk through one "layer"
of repetitions for all of the `$name`s it contains in lockstep, and (2) each
`$name` must be under at least as many `$(...)*`s as it was matched against.
If it is under more, it'll be repeated, as appropriate.
## Parsing limitations
For technical reasons, there are two limitations to the treatment of syntax
fragments by the macro parser:
1. The parser will always parse as much as possible of a Rust syntactic
fragment. For example, if the comma were omitted from the syntax of
`early_return!` above, `input_1 [` would've been interpreted as the beginning
of an array index. In fact, invoking the macro would have been impossible.
2. The parser must have eliminated all ambiguity by the time it reaches a
`$name:fragment_specifier` declaration. This limitation can result in parse
errors when declarations occur at the beginning of, or immediately after,
a `$(...)*`. For example, the grammar `$($t:ty)* $e:expr` will always fail to
parse because the parser would be forced to choose between parsing `t` and
parsing `e`. Changing the invocation syntax to require a distinctive token in
front can solve the problem. In the above example, `$(T $t:ty)* E $e:exp`
solves the problem.
# Macro argument pattern matching
Now consider code like the following:
## Motivation
~~~~
# enum t1 { good_1(t2, uint), bad_1 };
# pub struct t2 { body: t3 }
# enum t3 { good_2(uint), bad_2};
# fn f(x: t1) -> uint {
match x {
good_1(g1, val) => {
match g1.body {
good_2(result) => {
// complicated stuff goes here
return result + val;
},
_ => fail!("Didn't get good_2")
}
}
_ => return 0 // default value
}
# }
~~~~
All the complicated stuff is deeply indented, and the error-handling code is
separated from matches that fail. We'd like to write a macro that performs
a match, but with a syntax that suits the problem better. The following macro
can solve the problem:
~~~~
macro_rules! biased_match (
// special case: `let (x) = ...` is illegal, so use `let x = ...` instead
( ($e:expr) ~ ($p:pat) else $err:stmt ;
binds $bind_res:ident
) => (
let $bind_res = match $e {
$p => ( $bind_res ),
_ => { $err }
};
);
// more than one name; use a tuple
( ($e:expr) ~ ($p:pat) else $err:stmt ;
binds $( $bind_res:ident ),*
) => (
let ( $( $bind_res ),* ) = match $e {
$p => ( $( $bind_res ),* ),
_ => { $err }
};
)
)
# enum t1 { good_1(t2, uint), bad_1 };
# pub struct t2 { body: t3 }
# enum t3 { good_2(uint), bad_2};
# fn f(x: t1) -> uint {
biased_match!((x) ~ (good_1(g1, val)) else { return 0 };
binds g1, val )
biased_match!((g1.body) ~ (good_2(result) )
else { fail!("Didn't get good_2") };
binds result )
// complicated stuff goes here
return result + val;
# }
~~~~
This solves the indentation problem. But if we have a lot of chained matches
like this, we might prefer to write a single macro invocation. The input
pattern we want is clear:
~~~~
# macro_rules! b(
( $( ($e:expr) ~ ($p:pat) else $err:stmt ; )*
binds $( $bind_res:ident ),*
)
# => (0))
~~~~
However, it's not possible to directly expand to nested match statements. But
there is a solution.
## The recursive approach to macro writing
A macro may accept multiple different input grammars. The first one to
successfully match the actual argument to a macro invocation is the one that
"wins".
In the case of the example above, we want to write a recursive macro to
process the semicolon-terminated lines, one-by-one. So, we want the following
input patterns:
~~~~
# macro_rules! b(
( binds $( $bind_res:ident ),* )
# => (0))
~~~~
...and:
~~~~
# macro_rules! b(
( ($e :expr) ~ ($p :pat) else $err :stmt ;
$( ($e_rest:expr) ~ ($p_rest:pat) else $err_rest:stmt ; )*
binds $( $bind_res:ident ),*
)
# => (0))
~~~~
The resulting macro looks like this. Note that the separation into
`biased_match!` and `biased_match_rec!` occurs only because we have an outer
piece of syntax (the `let`) which we only want to transcribe once.
~~~~
macro_rules! biased_match_rec (
// Handle the first layer
( ($e :expr) ~ ($p :pat) else $err :stmt ;
$( ($e_rest:expr) ~ ($p_rest:pat) else $err_rest:stmt ; )*
binds $( $bind_res:ident ),*
) => (
match $e {
$p => {
// Recursively handle the next layer
biased_match_rec!($( ($e_rest) ~ ($p_rest) else $err_rest ; )*
binds $( $bind_res ),*
)
}
_ => { $err }
}
);
( binds $( $bind_res:ident ),* ) => ( ($( $bind_res ),*) )
)
// Wrap the whole thing in a `let`.
macro_rules! biased_match (
// special case: `let (x) = ...` is illegal, so use `let x = ...` instead
( $( ($e:expr) ~ ($p:pat) else $err:stmt ; )*
binds $bind_res:ident
) => (
let ( $( $bind_res ),* ) = biased_match_rec!(
$( ($e) ~ ($p) else $err ; )*
binds $bind_res
);
);
// more than one name: use a tuple
( $( ($e:expr) ~ ($p:pat) else $err:stmt ; )*
binds $( $bind_res:ident ),*
) => (
let ( $( $bind_res ),* ) = biased_match_rec!(
$( ($e) ~ ($p) else $err ; )*
binds $( $bind_res ),*
);
)
)
# enum t1 { good_1(t2, uint), bad_1 };
# pub struct t2 { body: t3 }
# enum t3 { good_2(uint), bad_2};
# fn f(x: t1) -> uint {
biased_match!(
(x) ~ (good_1(g1, val)) else { return 0 };
(g1.body) ~ (good_2(result) ) else { fail!("Didn't get good_2") };
binds val, result )
// complicated stuff goes here
return result + val;
# }
~~~~
This technique applies to many cases where transcribing a result all at once is not possible.
The resulting code resembles ordinary functional programming in some respects,
but has some important differences from functional programming.
The first difference is important, but also easy to forget: the transcription
(right-hand) side of a `macro_rules!` rule is literal syntax, which can only
be executed at run-time. If a piece of transcription syntax does not itself
appear inside another macro invocation, it will become part of the final
program. If it is inside a macro invocation (for example, the recursive
invocation of `biased_match_rec!`), it does have the opportunity to affect
transcription, but only through the process of attempted pattern matching.
The second, related, difference is that the evaluation order of macros feels
"backwards" compared to ordinary programming. Given an invocation
`m1!(m2!())`, the expander first expands `m1!`, giving it as input the literal
syntax `m2!()`. If it transcribes its argument unchanged into an appropriate
position (in particular, not as an argument to yet another macro invocation),
the expander will then proceed to evaluate `m2!()` (along with any other macro
invocations `m1!(m2!())` produced).
# A final note
Macros, as currently implemented, are not for the faint of heart. Even
ordinary syntax errors can be more difficult to debug when they occur inside a
macro, and errors caused by parse problems in generated code can be very
tricky. Invoking the `log_syntax!` macro can help elucidate intermediate
states, invoking `trace_macros!(true)` will automatically print those
intermediate states out, and passing the flag `--pretty expanded` as a
command-line argument to the compiler will show the result of expansion.

View File

@ -1,653 +0,0 @@
% Rust Tasks and Communication Tutorial
# Introduction
Rust provides safe concurrency through a combination
of lightweight, memory-isolated tasks and message passing.
This tutorial will describe the concurrency model in Rust, how it
relates to the Rust type system, and introduce
the fundamental library abstractions for constructing concurrent programs.
Rust tasks are not the same as traditional threads: rather,
they are considered _green threads_, lightweight units of execution that the Rust
runtime schedules cooperatively onto a small number of operating system threads.
On a multi-core system Rust tasks will be scheduled in parallel by default.
Because tasks are significantly
cheaper to create than traditional threads, Rust can create hundreds of
thousands of concurrent tasks on a typical 32-bit system.
In general, all Rust code executes inside a task, including the `main` function.
In order to make efficient use of memory Rust tasks have dynamically sized stacks.
A task begins its life with a small
amount of stack space (currently in the low thousands of bytes, depending on
platform), and acquires more stack as needed.
Unlike in languages such as C, a Rust task cannot accidentally write to
memory beyond the end of the stack, causing crashes or worse.
Tasks provide failure isolation and recovery. When a fatal error occurs in Rust
code as a result of an explicit call to `fail!()`, an assertion failure, or
another invalid operation, the runtime system destroys the entire
task. Unlike in languages such as Java and C++, there is no way to `catch` an
exception. Instead, tasks may monitor each other for failure.
Tasks use Rust's type system to provide strong memory safety guarantees. In
particular, the type system guarantees that tasks cannot share mutable state
with each other. Tasks communicate with each other by transferring _owned_
data through the global _exchange heap_.
## A note about the libraries
While Rust's type system provides the building blocks needed for safe
and efficient tasks, all of the task functionality itself is implemented
in the standard and extra libraries, which are still under development
and do not always present a consistent or complete interface.
For your reference, these are the standard modules involved in Rust
concurrency at this writing:
* [`std::task`] - All code relating to tasks and task scheduling,
* [`std::comm`] - The message passing interface,
* [`std::pipes`] - The underlying messaging infrastructure,
* [`extra::comm`] - Additional messaging types based on `std::pipes`,
* [`extra::sync`] - More exotic synchronization tools, including locks,
* [`extra::arc`] - The ARC (atomically reference counted) type,
for safely sharing immutable data,
* [`extra::future`] - A type representing values that may be computed concurrently and retrieved at a later time.
[`std::task`]: std/task.html
[`std::comm`]: std/comm.html
[`std::pipes`]: std/pipes.html
[`extra::comm`]: extra/comm.html
[`extra::sync`]: extra/sync.html
[`extra::arc`]: extra/arc.html
[`extra::future`]: extra/future.html
# Basics
The programming interface for creating and managing tasks lives
in the `task` module of the `std` library, and is thus available to all
Rust code by default. At its simplest, creating a task is a matter of
calling the `spawn` function with a closure argument. `spawn` executes the
closure in the new task.
~~~~
# use std::io::println;
# use std::task::spawn;
// Print something profound in a different task using a named function
fn print_message() { println("I am running in a different task!"); }
spawn(print_message);
// Print something more profound in a different task using a lambda expression
spawn( || println("I am also running in a different task!") );
// The canonical way to spawn is using `do` notation
do spawn {
println("I too am running in a different task!");
}
~~~~
In Rust, there is nothing special about creating tasks: a task is not a
concept that appears in the language semantics. Instead, Rust's type system
provides all the tools necessary to implement safe concurrency: particularly,
_owned types_. The language leaves the implementation details to the standard
library.
The `spawn` function has a very simple type signature: `fn spawn(f:
~fn())`. Because it accepts only owned closures, and owned closures
contain only owned data, `spawn` can safely move the entire closure
and all its associated state into an entirely different task for
execution. Like any closure, the function passed to `spawn` may capture
an environment that it carries across tasks.
~~~
# use std::io::println;
# use std::task::spawn;
# fn generate_task_number() -> int { 0 }
// Generate some state locally
let child_task_number = generate_task_number();
do spawn {
// Capture it in the remote task
println(fmt!("I am child number %d", child_task_number));
}
~~~
By default, the scheduler multiplexes tasks across the available cores, running
in parallel. Thus, on a multicore machine, running the following code
should interleave the output in vaguely random order.
~~~
# use std::io::print;
# use std::task::spawn;
# use std::int;
for int::range(0, 20) |child_task_number| {
do spawn {
print(fmt!("I am child number %d\n", child_task_number));
}
}
~~~
## Communication
Now that we have spawned a new task, it would be nice if we could
communicate with it. Recall that Rust does not have shared mutable
state, so one task may not manipulate variables owned by another task.
Instead we use *pipes*.
A pipe is simply a pair of endpoints: one for sending messages and another for
receiving messages. Pipes are low-level communication building-blocks and so
come in a variety of forms, each one appropriate for a different use case. In
what follows, we cover the most commonly used varieties.
The simplest way to create a pipe is to use the `pipes::stream`
function to create a `(Port, Chan)` pair. In Rust parlance, a *channel*
is a sending endpoint of a pipe, and a *port* is the receiving
endpoint. Consider the following example of calculating two results
concurrently:
~~~~
# use std::task::spawn;
# use std::comm::{stream, Port, Chan};
let (port, chan): (Port<int>, Chan<int>) = stream();
do spawn || {
let result = some_expensive_computation();
chan.send(result);
}
some_other_expensive_computation();
let result = port.recv();
# fn some_expensive_computation() -> int { 42 }
# fn some_other_expensive_computation() {}
~~~~
Let's examine this example in detail. First, the `let` statement creates a
stream for sending and receiving integers (the left-hand side of the `let`,
`(chan, port)`, is an example of a *destructuring let*: the pattern separates
a tuple into its component parts).
~~~~
# use std::comm::{stream, Chan, Port};
let (port, chan): (Port<int>, Chan<int>) = stream();
~~~~
The child task will use the channel to send data to the parent task,
which will wait to receive the data on the port. The next statement
spawns the child task.
~~~~
# use std::task::spawn;
# use std::comm::stream;
# fn some_expensive_computation() -> int { 42 }
# let (port, chan) = stream();
do spawn || {
let result = some_expensive_computation();
chan.send(result);
}
~~~~
Notice that the creation of the task closure transfers `chan` to the child
task implicitly: the closure captures `chan` in its environment. Both `Chan`
and `Port` are sendable types and may be captured into tasks or otherwise
transferred between them. In the example, the child task runs an expensive
computation, then sends the result over the captured channel.
Finally, the parent continues with some other expensive
computation, then waits for the child's result to arrive on the
port:
~~~~
# use std::comm::{stream};
# fn some_other_expensive_computation() {}
# let (port, chan) = stream::<int>();
# chan.send(0);
some_other_expensive_computation();
let result = port.recv();
~~~~
The `Port` and `Chan` pair created by `stream` enables efficient communication
between a single sender and a single receiver, but multiple senders cannot use
a single `Chan`, and multiple receivers cannot use a single `Port`. What if our
example needed to compute multiple results across a number of tasks? The
following program is ill-typed:
~~~ {.xfail-test}
# use std::task::{spawn};
# use std::comm::{stream, Port, Chan};
# fn some_expensive_computation() -> int { 42 }
let (port, chan) = stream();
do spawn {
chan.send(some_expensive_computation());
}
// ERROR! The previous spawn statement already owns the channel,
// so the compiler will not allow it to be captured again
do spawn {
chan.send(some_expensive_computation());
}
~~~
Instead we can use a `SharedChan`, a type that allows a single
`Chan` to be shared by multiple senders.
~~~
# use std::task::spawn;
# use std::comm::{stream, SharedChan};
# use std::uint;
let (port, chan) = stream();
let chan = SharedChan::new(chan);
for uint::range(0, 3) |init_val| {
// Create a new channel handle to distribute to the child task
let child_chan = chan.clone();
do spawn {
child_chan.send(some_expensive_computation(init_val));
}
}
let result = port.recv() + port.recv() + port.recv();
# fn some_expensive_computation(_i: uint) -> int { 42 }
~~~
Here we transfer ownership of the channel into a new `SharedChan` value. Like
`Chan`, `SharedChan` is a non-copyable, owned type (sometimes also referred to
as an *affine* or *linear* type). Unlike with `Chan`, though, the programmer
may duplicate a `SharedChan`, with the `clone()` method. A cloned
`SharedChan` produces a new handle to the same channel, allowing multiple
tasks to send data to a single port. Between `spawn`, `stream` and
`SharedChan`, we have enough tools to implement many useful concurrency
patterns.
Note that the above `SharedChan` example is somewhat contrived since
you could also simply use three `stream` pairs, but it serves to
illustrate the point. For reference, written with multiple streams, it
might look like the example below.
~~~
# use std::task::spawn;
# use std::comm::stream;
# use std::vec;
// Create a vector of ports, one for each child task
let ports = do vec::from_fn(3) |init_val| {
let (port, chan) = stream();
do spawn {
chan.send(some_expensive_computation(init_val));
}
port
};
// Wait on each port, accumulating the results
let result = ports.iter().fold(0, |accum, port| accum + port.recv() );
# fn some_expensive_computation(_i: uint) -> int { 42 }
~~~
## Backgrounding computations: Futures
With `extra::future`, rust has a mechanism for requesting a computation and getting the result
later.
The basic example below illustrates this.
~~~
# fn make_a_sandwich() {};
fn fib(n: uint) -> uint {
// lengthy computation returning an uint
12586269025
}
let mut delayed_fib = extra::future::spawn (|| fib(50) );
make_a_sandwich();
println(fmt!("fib(50) = %?", delayed_fib.get()))
~~~
The call to `future::spawn` returns immediately a `future` object regardless of how long it
takes to run `fib(50)`. You can then make yourself a sandwich while the computation of `fib` is
running. The result of the execution of the method is obtained by calling `get` on the future.
This call will block until the value is available (*i.e.* the computation is complete). Note that
the future needs to be mutable so that it can save the result for next time `get` is called.
Here is another example showing how futures allow you to background computations. The workload will
be distributed on the available cores.
~~~
# use std::vec;
# use std::uint;
fn partial_sum(start: uint) -> f64 {
let mut local_sum = 0f64;
for uint::range(start*100000, (start+1)*100000) |num| {
local_sum += (num as f64 + 1.0).pow(&-2.0);
}
local_sum
}
fn main() {
let mut futures = vec::from_fn(1000, |ind| do extra::future::spawn { partial_sum(ind) });
let mut final_res = 0f64;
for futures.mut_iter().advance |ft| {
final_res += ft.get();
}
println(fmt!("π^2/6 is not far from : %?", final_res));
}
~~~
## Sharing immutable data without copy: ARC
To share immutable data between tasks, a first approach would be to only use pipes as we have seen
previously. A copy of the data to share would then be made for each task. In some cases, this would
add up to a significant amount of wasted memory and would require copying the same data more than
necessary.
To tackle this issue, one can use an Atomically Reference Counted wrapper (`ARC`) as implemented in
the `extra` library of Rust. With an ARC, the data will no longer be copied for each task. The ARC
acts as a reference to the shared data and only this reference is shared and cloned.
Here is a small example showing how to use ARCs. We wish to run concurrently several computations on
a single large vector of floats. Each task needs the full vector to perform its duty.
~~~
# use std::vec;
# use std::uint;
# use std::rand;
use extra::arc::ARC;
fn pnorm(nums: &~[float], p: uint) -> float {
nums.iter().fold(0.0, |a,b| a+(*b).pow(&(p as float)) ).pow(&(1f / (p as float)))
}
fn main() {
let numbers = vec::from_fn(1000000, |_| rand::random::<float>());
println(fmt!("Inf-norm = %?", *numbers.iter().max().unwrap()));
let numbers_arc = ARC(numbers);
for uint::range(1,10) |num| {
let (port, chan) = stream();
chan.send(numbers_arc.clone());
do spawn {
let local_arc : ARC<~[float]> = port.recv();
let task_numbers = local_arc.get();
println(fmt!("%u-norm = %?", num, pnorm(task_numbers, num)));
}
}
}
~~~
The function `pnorm` performs a simple computation on the vector (it computes the sum of its items
at the power given as argument and takes the inverse power of this value). The ARC on the vector is
created by the line
~~~
# use extra::arc::ARC;
# use std::vec;
# use std::rand;
# let numbers = vec::from_fn(1000000, |_| rand::random::<float>());
let numbers_arc=ARC(numbers);
~~~
and a clone of it is sent to each task
~~~
# use extra::arc::ARC;
# use std::vec;
# use std::rand;
# let numbers=vec::from_fn(1000000, |_| rand::random::<float>());
# let numbers_arc = ARC(numbers);
# let (port, chan) = stream();
chan.send(numbers_arc.clone());
~~~
copying only the wrapper and not its contents.
Each task recovers the underlying data by
~~~
# use extra::arc::ARC;
# use std::vec;
# use std::rand;
# let numbers=vec::from_fn(1000000, |_| rand::random::<float>());
# let numbers_arc=ARC(numbers);
# let (port, chan) = stream();
# chan.send(numbers_arc.clone());
# let local_arc : ARC<~[float]> = port.recv();
let task_numbers = local_arc.get();
~~~
and can use it as if it were local.
The `arc` module also implements ARCs around mutable data that are not covered here.
# Handling task failure
Rust has a built-in mechanism for raising exceptions. The `fail!()` macro
(which can also be written with an error string as an argument: `fail!(
~reason)`) and the `assert!` construct (which effectively calls `fail!()`
if a boolean expression is false) are both ways to raise exceptions. When a
task raises an exception the task unwinds its stack---running destructors and
freeing memory along the way---and then exits. Unlike exceptions in C++,
exceptions in Rust are unrecoverable within a single task: once a task fails,
there is no way to "catch" the exception.
All tasks are, by default, _linked_ to each other. That means that the fates
of all tasks are intertwined: if one fails, so do all the others.
~~~
# use std::task::spawn;
# use std::task;
# fn do_some_work() { loop { task::yield() } }
# do task::try {
// Create a child task that fails
do spawn { fail!() }
// This will also fail because the task we spawned failed
do_some_work();
# };
~~~
While it isn't possible for a task to recover from failure, tasks may notify
each other of failure. The simplest way of handling task failure is with the
`try` function, which is similar to `spawn`, but immediately blocks waiting
for the child task to finish. `try` returns a value of type `Result<int,
()>`. `Result` is an `enum` type with two variants: `Ok` and `Err`. In this
case, because the type arguments to `Result` are `int` and `()`, callers can
pattern-match on a result to check whether it's an `Ok` result with an `int`
field (representing a successful result) or an `Err` result (representing
termination with an error).
~~~
# use std::task;
# fn some_condition() -> bool { false }
# fn calculate_result() -> int { 0 }
let result: Result<int, ()> = do task::try {
if some_condition() {
calculate_result()
} else {
fail!("oops!");
}
};
assert!(result.is_err());
~~~
Unlike `spawn`, the function spawned using `try` may return a value,
which `try` will dutifully propagate back to the caller in a [`Result`]
enum. If the child task terminates successfully, `try` will
return an `Ok` result; if the child task fails, `try` will return
an `Error` result.
[`Result`]: std/result.html
> ***Note:*** A failed task does not currently produce a useful error
> value (`try` always returns `Err(())`). In the
> future, it may be possible for tasks to intercept the value passed to
> `fail!()`.
TODO: Need discussion of `future_result` in order to make failure
modes useful.
But not all failures are created equal. In some cases you might need to
abort the entire program (perhaps you're writing an assert which, if
it trips, indicates an unrecoverable logic error); in other cases you
might want to contain the failure at a certain boundary (perhaps a
small piece of input from the outside world, which you happen to be
processing in parallel, is malformed and its processing task can't
proceed). Hence, you will need different _linked failure modes_.
## Failure modes
By default, task failure is _bidirectionally linked_, which means that if
either task fails, it kills the other one.
~~~
# use std::task;
# fn sleep_forever() { loop { task::yield() } }
# do task::try {
do spawn {
do spawn {
fail!(); // All three tasks will fail.
}
sleep_forever(); // Will get woken up by force, then fail
}
sleep_forever(); // Will get woken up by force, then fail
# };
~~~
If you want parent tasks to be able to kill their children, but do not want a
parent to fail automatically if one of its child task fails, you can call
`task::spawn_supervised` for _unidirectionally linked_ failure. The
function `task::try`, which we saw previously, uses `spawn_supervised`
internally, with additional logic to wait for the child task to finish
before returning. Hence:
~~~
# use std::comm::{stream, Chan, Port};
# use std::task::{spawn, try};
# use std::task;
# fn sleep_forever() { loop { task::yield() } }
# do task::try {
let (receiver, sender): (Port<int>, Chan<int>) = stream();
do spawn { // Bidirectionally linked
// Wait for the supervised child task to exist.
let message = receiver.recv();
// Kill both it and the parent task.
assert!(message != 42);
}
do try { // Unidirectionally linked
sender.send(42);
sleep_forever(); // Will get woken up by force
}
// Flow never reaches here -- parent task was killed too.
# };
~~~
Supervised failure is useful in any situation where one task manages
multiple fallible child tasks, and the parent task can recover
if any child fails. On the other hand, if the _parent_ (supervisor) fails,
then there is nothing the children can do to recover, so they should
also fail.
Supervised task failure propagates across multiple generations even if
an intermediate generation has already exited:
~~~
# use std::task;
# fn sleep_forever() { loop { task::yield() } }
# fn wait_for_a_while() { for 1000.times { task::yield() } }
# do task::try::<int> {
do task::spawn_supervised {
do task::spawn_supervised {
sleep_forever(); // Will get woken up by force, then fail
}
// Intermediate task immediately exits
}
wait_for_a_while();
fail!(); // Will kill grandchild even if child has already exited
# };
~~~
Finally, tasks can be configured to not propagate failure to each
other at all, using `task::spawn_unlinked` for _isolated failure_.
~~~
# use std::task;
# fn random() -> uint { 100 }
# fn sleep_for(i: uint) { for i.times { task::yield() } }
# do task::try::<()> {
let (time1, time2) = (random(), random());
do task::spawn_unlinked {
sleep_for(time2); // Won't get forced awake
fail!();
}
sleep_for(time1); // Won't get forced awake
fail!();
// It will take MAX(time1,time2) for the program to finish.
# };
~~~
## Creating a task with a bi-directional communication path
A very common thing to do is to spawn a child task where the parent
and child both need to exchange messages with each other. The
function `extra::comm::DuplexStream()` supports this pattern. We'll
look briefly at how to use it.
To see how `DuplexStream()` works, we will create a child task
that repeatedly receives a `uint` message, converts it to a string, and sends
the string in response. The child terminates when it receives `0`.
Here is the function that implements the child task:
~~~~
# use extra::comm::DuplexStream;
# use std::uint;
fn stringifier(channel: &DuplexStream<~str, uint>) {
let mut value: uint;
loop {
value = channel.recv();
channel.send(uint::to_str(value));
if value == 0 { break; }
}
}
~~~~
The implementation of `DuplexStream` supports both sending and
receiving. The `stringifier` function takes a `DuplexStream` that can
send strings (the first type parameter) and receive `uint` messages
(the second type parameter). The body itself simply loops, reading
from the channel and then sending its response back. The actual
response itself is simply the stringified version of the received value,
`uint::to_str(value)`.
Here is the code for the parent task:
~~~~
# use std::task::spawn;
# use std::uint;
# use extra::comm::DuplexStream;
# fn stringifier(channel: &DuplexStream<~str, uint>) {
# let mut value: uint;
# loop {
# value = channel.recv();
# channel.send(uint::to_str(value));
# if value == 0u { break; }
# }
# }
# fn main() {
let (from_child, to_child) = DuplexStream();
do spawn {
stringifier(&to_child);
};
from_child.send(22);
assert!(from_child.recv() == ~"22");
from_child.send(23);
from_child.send(0);
assert!(from_child.recv() == ~"23");
assert!(from_child.recv() == ~"0");
# }
~~~~
The parent task first calls `DuplexStream` to create a pair of bidirectional
endpoints. It then uses `task::spawn` to create the child task, which captures
one end of the communication channel. As a result, both parent and child can
send and receive data to and from the other.

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +0,0 @@
<div id='versioninfo'>
<center>
<img src="http://www.rust-lang.org/logos/rust-logo-32x32-blk.png"> <br>
<a href="http://rust-lang.org">Rust</a> VERSION <br>
<a href="http://github.com/mozilla/rust/commit/STAMP"
class='lessimportant'>SHORT_HASH</a>
</center>
</div>

View File

@ -1,6 +1,6 @@
.TH RUSTC "1" "July 2013" "rustc 0.7" "User Commands"
.TH RUSTC "1" "March 2014" "rustc 0.13.0" "User Commands"
.SH NAME
rustc \- rust compiler
rustc \- The Rust compiler
.SH SYNOPSIS
.B rustc
[\fIOPTIONS\fR] \fIINPUT\fR
@ -12,87 +12,54 @@ This program is a compiler for the Rust language, available at
.SH OPTIONS
.TP
\fB\-\-bin\fR
Compile an executable crate (default)
.TP
\fB\-c\fR
Compile and assemble, but do not link
\fB\-h\fR, \fB\-\-help\fR
Display the help message
.TP
\fB\-\-cfg\fR SPEC
Configure the compilation environment
.TP
\fB\-\-emit\-llvm\fR
Produce an LLVM bitcode file
.TP
\fB\-h\fR, \fB\-\-help\fR
Display this message
.TP
\fB\-L\fR PATH
Add a directory to the library search path
.TP
\fB\-\-lib\fR
Compile a library crate
\fB\-l\fR NAME[:KIND]
Link the generated crate(s) to the specified native library NAME. The optional
KIND can be one of, static, dylib, or framework. If omitted, dylib is assumed.
.TP
\fB\-\-linker\fR LINKER
Program to use for linking instead of the default
\fB\-\-crate-type\fR [bin|lib|rlib|dylib|staticlib]
Comma separated list of types of crates for the compiler to emit
.TP
\fB\-\-link-args\fR FLAGS
A space-separated list of flags passed to the linker
\fB\-\-crate-name NAME\fR
Specify the name of the crate being built
.TP
\fB\-\-ls\fR
List the symbols defined by a library crate
\fB\-\-emit\fR [asm|llvm-bc|llvm-ir|obj|link|dep-info]
Configure the output that rustc will produce
.TP
\fB\-\-no\-trans\fR
Run all passes except translation; no output
\fB\-\-print\fR [crate-name|file-names|sysroot]
Comma separated list of compiler information to print on stdout
.TP
\fB\-g\fR
Equivalent to \fI\-C\fR debuginfo=2
.TP
\fB\-O\fR
Equivalent to \fI\-\-opt\-level=2\fR
Equivalent to \fI\-C\fR opt-level=2
.TP
\fB\-o\fR FILENAME
Write output to <filename>
.TP
\fB\-\-opt\-level\fR LEVEL
Optimize with possible levels 0-3
.TP
\fB\-\-passes\fR NAMES
Comma- or space-separated list of optimization passes. Overrides
the default passes for the optimization level. A value of 'list'
will list the available passes.
Write output to <filename>. Ignored if multiple \fI\-\-emit\fR outputs are
specified.
.TP
\fB\-\-out\-dir\fR DIR
Write output to compiler-chosen filename in <dir>
Write output to compiler-chosen filename in <dir>. Ignored if \fI\-o\fR is
specified. Defaults to the current directory.
.TP
\fB\-\-parse\-only\fR
Parse only; do not compile, assemble, or link
.TP
\fB\-\-pretty\fR [TYPE]
Pretty-print the input instead of compiling; valid types are: normal
(un-annotated source), expanded (crates expanded), typed (crates
expanded, with type annotations), or identified (fully parenthesized,
AST nodes and blocks with IDs)
.TP
\fB\-S\fR
Compile only; do not assemble or link
.TP
\fB\-\-save\-temps\fR
Write intermediate files (.bc, .opt.bc, .o) in addition to normal output
.TP
\fB\-\-sysroot\fR PATH
Override the system root
\fB\-\-explain\fR OPT
Provide a detailed explanation of an error message
.TP
\fB\-\-test\fR
Build a test harness
.TP
\fB\-\-target\fR TRIPLE
Target triple cpu-manufacturer-kernel[-os] to compile for (see
http://sources.redhat.com/autobook/autobook/autobook_17.html
for detail)
.TP
\fB\-\-target-feature\fR TRIPLE
Target-specific attributes (see llc -mattr=help for detail)
.TP
\fB\-\-android-cross-path\fR PATH
The path to the Android NDK
Target triple cpu-manufacturer-kernel[-os] to compile for (see chapter 3.4 of
http://www.sourceware.org/autobook/ for details)
.TP
\fB\-W\fR help
Print 'lint' options and default settings
@ -109,32 +76,149 @@ Set lint denied
\fB\-F\fR OPT, \fB\-\-forbid\fR OPT
Set lint forbidden
.TP
\fB\-C\fR FLAG[=VAL], \fB\-\-codegen\fR FLAG[=VAL]
Set a codegen-related flag to the value specified. Use "-C help" to print
available flags. See CODEGEN OPTIONS below
.TP
\fB\-V\fR, \fB\-\-version\fR
Print version info and exit
.TP
\fB\-v\fR, \fB\-\-verbose\fR
Use verbose output
.TP
\fB\-\-extern\fR NAME=PATH
Specify where an external rust library is located
.TP
\fB\-\-sysroot\fR PATH
Override the system root
.TP
\fB\-Z\fR FLAG
Set internal debugging options. Use "-Z help" to print available options.
.TP
\fB\-v\fR, \fB\-\-version\fR
Print version info and exit
\fB\-\-color\fR auto|always|never
Configure coloring of output:
auto = colorize, if output goes to a tty (default);
always = always colorize output;
never = never colorize output
.SH CODEGEN OPTIONS
.TP
\fBar\fR=/path/to/ar
Path to the archive utility to use when assembling archives.
.TP
\fBlinker\fR=/path/to/cc
Path to the linker utility to use when linking libraries, executables, and
objects.
.TP
\fBlink-args\fR='-flag1 -flag2'
A space-separated list of extra arguments to pass to the linker when the linker
is invoked.
.TP
\fBlto\fR
Perform LLVM link-time optimizations.
.TP
\fBtarget-cpu\fR=help
Selects a target processor. If the value is 'help', then a list of available
CPUs is printed.
.TP
\fBtarget-feature\fR='+feature1,-feature2'
A comma-separated list of features to enable or disable for the target. A
preceding '+' enables a feature while a preceding '-' disables it. Available
features can be discovered through target-cpu=help.
.TP
\fBpasses\fR=list
A space-separated list of extra LLVM passes to run. A value of 'list' will
cause rustc to print all known passes and exit. The passes specified are
appended at the end of the normal pass manager.
.TP
\fBllvm-args\fR='-arg1 -arg2'
A space-separated list of arguments to pass through to LLVM.
.TP
\fBsave-temps\fR
If specified, the compiler will save more files (.bc, .o, .no-opt.bc) generated
throughout compilation in the output directory.
.TP
\fBrpath\fR
If specified, then the rpath value for dynamic libraries will be set in
either dynamic library or executable outputs.
.TP
\fBno-prepopulate-passes\fR
Suppresses pre-population of the LLVM pass manager that is run over the module.
.TP
\fBno-vectorize-loops\fR
Suppresses running the loop vectorization LLVM pass, regardless of optimization
level.
.TP
\fBno-vectorize-slp\fR
Suppresses running the LLVM SLP vectorization pass, regardless of optimization
level.
.TP
\fBsoft-float\fR
Generates software floating point library calls instead of hardware
instructions.
.TP
\fBprefer-dynamic\fR
Prefers dynamic linking to static linking.
.TP
\fBno-integrated-as\fR
Force usage of an external assembler rather than LLVM's integrated one.
.TP
\fBno-redzone\fR
Disable the use of the redzone.
.TP
\fBrelocation-model\fR=[pic,static,dynamic-no-pic]
The relocation model to use. (Default: pic)
.TP
\fBcode-model\fR=[small,kernel,medium,large]
Choose the code model to use.
.TP
\fBmetadata\fR=val
Metadata to mangle symbol names with.
.TP
\fBextra-filename\fR=val
Extra data to put in each output filename.
.TP
\fBcodegen-units\fR=val
Divide crate into N units to optimize in parallel.
.TP
\fBremark\fR=val
Print remarks for these optimization passes (space separated, or "all").
.TP
\fBno-stack-check\fR
Disable checks for stack exhaustion (a memory-safety hazard!).
.TP
\fBdebuginfo\fR=val
Debug info emission level:
0 = no debug info;
1 = line-tables only (for stacktraces and breakpoints);
2 = full debug info with variable and type information.
.TP
\fBopt-level\fR=val
Optimize with possible levels 0-3
.SH "EXAMPLES"
To build an executable from a source file with a main function:
$ rustc -o hello hello.rs
To build a library from a source file:
$ rustc --lib hello-lib.rs
$ rustc --crate-type=lib hello-lib.rs
To build either with a crate (.rc) file:
$ rustc hello.rc
To build either with a crate (.rs) file:
$ rustc hello.rs
To build an executable with debug info (experimental):
$ rustc -Z debug-info -o hello hello.rs
To build an executable with debug info:
$ rustc -g -o hello hello.rs
.SH "SEE ALSO"
rustdoc
.SH "BUGS"
See <\fBhttps://github.com/mozilla/rust/issues\fR> for issues.
See <\fBhttps://github.com/rust-lang/rust/issues\fR> for issues.
.SH "AUTHOR"
See \fBAUTHORS.txt\fR in the rust source distribution. Graydon Hoare
<\fIgraydon@mozilla.com\fR> is the project leader.
See \fBAUTHORS.txt\fR in the Rust source distribution.
.SH "COPYRIGHT"
This work is dual-licensed under Apache 2.0 and MIT terms. See \fBCOPYRIGHT\fR

106
man/rustdoc.1 Normal file
View File

@ -0,0 +1,106 @@
.TH RUSTDOC "1" "March 2014" "rustdoc 0.13.0" "User Commands"
.SH NAME
rustdoc \- generate documentation from Rust source code
.SH SYNOPSIS
.B rustdoc
[\fIOPTIONS\fR] \fIINPUT\fR
.SH DESCRIPTION
This tool generates API reference documentation by extracting comments from
source code written in the Rust language, available at
<\fBhttps://www.rust-lang.org\fR>. It accepts several input formats and provides
several output formats for the generated documentation.
.SH OPTIONS
.TP
-r --input-format <val>
html or json (default: inferred)
.TP
-w --output-format <val>
html or json (default: html)
.TP
-o --output <val>
where to place the output (default: doc/ for html, doc.json for json)
.TP
--passes <val>
space-separated list of passes to run (default: '')
.TP
--no-defaults
don't run the default passes
.TP
--plugins <val>
space-separated list of plugins to run (default: '')
.TP
--plugin-path <val>
directory to load plugins from (default: /tmp/rustdoc_ng/plugins)
.TP
-L --library-path <val>
directory to add to crate search path
.TP
--html-in-header <val>
file to add to <head>
.TP
--html-before-content <val>
file to add in <body>, before content
.TP
--html-after-content <val>
file to add in <body>, after content
.TP
-h, --help
Print help
.SH "OUTPUT FORMATS"
The rustdoc tool can generate output in either an HTML or JSON format.
If using an HTML format, then the specified output destination will be the root
directory of an HTML structure for all the documentation. Pages will be placed
into this directory, and source files will also possibly be rendered into it as
well.
If using a JSON format, then the specified output destination will have the
rustdoc output serialized as JSON into it. This output format exists to
pre-compile documentation for crates, and for usage in non-rustdoc tools. The
JSON output is the following hash:
{
"schema": VERSION,
"crate": ...,
"plugins": ...,
}
The schema version indicates what the structure of crate/plugins will look
like. Within a schema version the structure will remain the same. The `crate`
field will contain all relevant documentation for the source being documented,
and the `plugins` field will contain the output of the plugins run over the
crate.
.SH "EXAMPLES"
To generate documentation for the source in the current directory:
$ rustdoc hello.rs
List all available passes that rustdoc has, along with default passes:
$ rustdoc --passes list
To precompile the documentation for a crate, and then use it to render html at
a later date:
$ rustdoc -w json hello.rs
$ rustdoc doc.json
The generated HTML can be viewed with any standard web browser.
.SH "SEE ALSO"
rustc
.SH "BUGS"
See <\fBhttps://github.com/rust-lang/rust/issues\fR> for issues.
.SH "AUTHOR"
See \fBAUTHORS.txt\fR in the Rust source distribution.
.SH "COPYRIGHT"
This work is dual-licensed under Apache 2.0 and MIT terms. See \fBCOPYRIGHT\fR
file in the rust source distribution.

View File

@ -0,0 +1,30 @@
# aarch64-unknown-linux-gnu configuration
CROSS_PREFIX_aarch64-unknown-linux-gnu=aarch64-linux-gnu-
CC_aarch64-unknown-linux-gnu=gcc
CXX_aarch64-unknown-linux-gnu=g++
CPP_aarch64-unknown-linux-gnu=gcc -E
AR_aarch64-unknown-linux-gnu=ar
CFG_LIB_NAME_aarch64-unknown-linux-gnu=lib$(1).so
CFG_STATIC_LIB_NAME_aarch64-unknown-linux-gnu=lib$(1).a
CFG_LIB_GLOB_aarch64-unknown-linux-gnu=lib$(1)-*.so
CFG_LIB_DSYM_GLOB_aarch64-unknown-linux-gnu=lib$(1)-*.dylib.dSYM
CFG_JEMALLOC_CFLAGS_aarch64-unknown-linux-gnu := -D__aarch64__ $(CFLAGS)
CFG_GCCISH_CFLAGS_aarch64-unknown-linux-gnu := -Wall -g -fPIC -D__aarch64__ $(CFLAGS)
CFG_GCCISH_CXXFLAGS_aarch64-unknown-linux-gnu := -fno-rtti $(CXXFLAGS)
CFG_GCCISH_LINK_FLAGS_aarch64-unknown-linux-gnu := -shared -fPIC -g
CFG_GCCISH_DEF_FLAG_aarch64-unknown-linux-gnu := -Wl,--export-dynamic,--dynamic-list=
CFG_GCCISH_PRE_LIB_FLAGS_aarch64-unknown-linux-gnu := -Wl,-whole-archive
CFG_GCCISH_POST_LIB_FLAGS_aarch64-unknown-linux-gnu := -Wl,-no-whole-archive
CFG_DEF_SUFFIX_aarch64-unknown-linux-gnu := .linux.def
CFG_LLC_FLAGS_aarch64-unknown-linux-gnu :=
CFG_INSTALL_NAME_aarch64-unknown-linux-gnu =
CFG_EXE_SUFFIX_aarch64-unknown-linux-gnu :=
CFG_WINDOWSY_aarch64-unknown-linux-gnu :=
CFG_UNIXY_aarch64-unknown-linux-gnu := 1
CFG_PATH_MUNGE_aarch64-unknown-linux-gnu := true
CFG_LDPATH_aarch64-unknown-linux-gnu :=
CFG_RUN_aarch64-unknown-linux-gnu=$(2)
CFG_RUN_TARG_aarch64-unknown-linux-gnu=$(call CFG_RUN_aarch64-unknown-linux-gnu,,$(2))
RUSTC_FLAGS_aarch64-unknown-linux-gnu :=
RUSTC_CROSS_FLAGS_aarch64-unknown-linux-gnu :=
CFG_GNU_TRIPLE_aarch64-unknown-linux-gnu := aarch64-unknown-linux-gnu

35
mk/cfg/arm-apple-ios.mk Normal file
View File

@ -0,0 +1,35 @@
# arm-apple-ios configuration
CFG_SDK_NAME_arm-apple-ios = iphoneos
CFG_SDK_ARCHS_arm-apple-ios = armv7
ifneq ($(findstring darwin,$(CFG_OSTYPE)),)
CFG_IOS_SDK = $(shell xcrun --show-sdk-path -sdk iphoneos 2>/dev/null)
CFG_IOS_FLAGS = -target armv7-apple-ios -isysroot $(CFG_IOS_SDK) -mios-version-min=7.0
CC_arm-apple-ios = $(shell xcrun -find -sdk iphoneos clang)
CXX_arm-apple-ios = $(shell xcrun -find -sdk iphoneos clang++)
CPP_arm-apple-ios = $(shell xcrun -find -sdk iphoneos clang++)
AR_arm-apple-ios = $(shell xcrun -find -sdk iphoneos ar)
endif
CFG_LIB_NAME_arm-apple-ios = lib$(1).a
CFG_LIB_GLOB_arm-apple-ios = lib$(1)-*.a
CFG_STATIC_LIB_NAME_arm-apple-ios=lib$(1).a
CFG_LIB_DSYM_GLOB_arm-apple-ios = lib$(1)-*.a.dSYM
CFG_JEMALLOC_CFLAGS_arm-apple-ios := -arch armv7 -mfpu=vfp3 $(CFG_IOS_FLAGS)
CFG_GCCISH_CFLAGS_arm-apple-ios := -Wall -Werror -g -fPIC $(CFG_IOS_FLAGS) -mfpu=vfp3 -arch armv7
CFG_GCCISH_CXXFLAGS_arm-apple-ios := -fno-rtti $(CFG_IOS_FLAGS) -I$(CFG_IOS_SDK)/usr/include/c++/4.2.1
CFG_GCCISH_LINK_FLAGS_arm-apple-ios := -lpthread -syslibroot $(CFG_IOS_SDK) -Wl,-no_compact_unwind
CFG_GCCISH_DEF_FLAG_arm-apple-ios := -Wl,-exported_symbols_list,
CFG_GCCISH_PRE_LIB_FLAGS_arm-apple-ios :=
CFG_GCCISH_POST_LIB_FLAGS_arm-apple-ios :=
CFG_DEF_SUFFIX_arm-apple-ios := .darwin.def
CFG_LLC_FLAGS_arm-apple-ios := -mattr=+vfp3,+v7,+thumb2,+neon -march=arm
CFG_INSTALL_NAME_arm-apple-ios = -Wl,-install_name,@rpath/$(1)
CFG_EXE_SUFFIX_arm-apple-ios :=
CFG_WINDOWSY_arm-apple-ios :=
CFG_UNIXY_arm-apple-ios := 1
CFG_PATH_MUNGE_arm-apple-ios := true
CFG_LDPATH_arm-apple-ios :=
CFG_RUN_arm-apple-ios = $(2)
CFG_RUN_TARG_arm-apple-ios = $(call CFG_RUN_arm-apple-ios,,$(2))
RUSTC_FLAGS_arm-apple-ios := -C relocation_model=pic
RUSTC_CROSS_FLAGS_arm-apple-ios :=-C relocation_model=pic
CFG_GNU_TRIPLE_arm-apple-ios := arm-apple-ios

View File

@ -0,0 +1,29 @@
# arm-linux-androideabi configuration
CC_arm-linux-androideabi=$(CFG_ANDROID_CROSS_PATH)/bin/arm-linux-androideabi-gcc
CXX_arm-linux-androideabi=$(CFG_ANDROID_CROSS_PATH)/bin/arm-linux-androideabi-g++
CPP_arm-linux-androideabi=$(CFG_ANDROID_CROSS_PATH)/bin/arm-linux-androideabi-gcc -E
AR_arm-linux-androideabi=$(CFG_ANDROID_CROSS_PATH)/bin/arm-linux-androideabi-ar
CFG_LIB_NAME_arm-linux-androideabi=lib$(1).so
CFG_STATIC_LIB_NAME_arm-linux-androideabi=lib$(1).a
CFG_LIB_GLOB_arm-linux-androideabi=lib$(1)-*.so
CFG_LIB_DSYM_GLOB_arm-linux-androideabi=lib$(1)-*.dylib.dSYM
CFG_JEMALLOC_CFLAGS_arm-linux-androideabi := -D__arm__ -DANDROID -D__ANDROID__ $(CFLAGS)
CFG_GCCISH_CFLAGS_arm-linux-androideabi := -Wall -g -fPIC -D__arm__ -DANDROID -D__ANDROID__ $(CFLAGS)
CFG_GCCISH_CXXFLAGS_arm-linux-androideabi := -fno-rtti $(CXXFLAGS)
CFG_GCCISH_LINK_FLAGS_arm-linux-androideabi := -shared -fPIC -ldl -g -lm -lsupc++
CFG_GCCISH_DEF_FLAG_arm-linux-androideabi := -Wl,--export-dynamic,--dynamic-list=
CFG_GCCISH_PRE_LIB_FLAGS_arm-linux-androideabi := -Wl,-whole-archive
CFG_GCCISH_POST_LIB_FLAGS_arm-linux-androideabi := -Wl,-no-whole-archive
CFG_DEF_SUFFIX_arm-linux-androideabi := .android.def
CFG_LLC_FLAGS_arm-linux-androideabi :=
CFG_INSTALL_NAME_arm-linux-androideabi =
CFG_EXE_SUFFIX_arm-linux-androideabi :=
CFG_WINDOWSY_arm-linux-androideabi :=
CFG_UNIXY_arm-linux-androideabi := 1
CFG_PATH_MUNGE_arm-linux-androideabi := true
CFG_LDPATH_arm-linux-androideabi :=
CFG_RUN_arm-linux-androideabi=
CFG_RUN_TARG_arm-linux-androideabi=
RUSTC_FLAGS_arm-linux-androideabi :=
RUSTC_CROSS_FLAGS_arm-linux-androideabi :=
CFG_GNU_TRIPLE_arm-linux-androideabi := arm-linux-androideabi

View File

@ -0,0 +1,30 @@
# arm-unknown-linux-gnueabi configuration
CROSS_PREFIX_arm-unknown-linux-gnueabi=arm-linux-gnueabi-
CC_arm-unknown-linux-gnueabi=gcc
CXX_arm-unknown-linux-gnueabi=g++
CPP_arm-unknown-linux-gnueabi=gcc -E
AR_arm-unknown-linux-gnueabi=ar
CFG_LIB_NAME_arm-unknown-linux-gnueabi=lib$(1).so
CFG_STATIC_LIB_NAME_arm-unknown-linux-gnueabi=lib$(1).a
CFG_LIB_GLOB_arm-unknown-linux-gnueabi=lib$(1)-*.so
CFG_LIB_DSYM_GLOB_arm-unknown-linux-gnueabi=lib$(1)-*.dylib.dSYM
CFG_JEMALLOC_CFLAGS_arm-unknown-linux-gnueabi := -D__arm__ -mfpu=vfp $(CFLAGS)
CFG_GCCISH_CFLAGS_arm-unknown-linux-gnueabi := -Wall -g -fPIC -D__arm__ -mfpu=vfp $(CFLAGS)
CFG_GCCISH_CXXFLAGS_arm-unknown-linux-gnueabi := -fno-rtti $(CXXFLAGS)
CFG_GCCISH_LINK_FLAGS_arm-unknown-linux-gnueabi := -shared -fPIC -g
CFG_GCCISH_DEF_FLAG_arm-unknown-linux-gnueabi := -Wl,--export-dynamic,--dynamic-list=
CFG_GCCISH_PRE_LIB_FLAGS_arm-unknown-linux-gnueabi := -Wl,-whole-archive
CFG_GCCISH_POST_LIB_FLAGS_arm-unknown-linux-gnueabi := -Wl,-no-whole-archive
CFG_DEF_SUFFIX_arm-unknown-linux-gnueabi := .linux.def
CFG_LLC_FLAGS_arm-unknown-linux-gnueabi :=
CFG_INSTALL_NAME_arm-unknown-linux-gnueabi =
CFG_EXE_SUFFIX_arm-unknown-linux-gnueabi :=
CFG_WINDOWSY_arm-unknown-linux-gnueabi :=
CFG_UNIXY_arm-unknown-linux-gnueabi := 1
CFG_PATH_MUNGE_arm-unknown-linux-gnueabi := true
CFG_LDPATH_arm-unknown-linux-gnueabi :=
CFG_RUN_arm-unknown-linux-gnueabi=$(2)
CFG_RUN_TARG_arm-unknown-linux-gnueabi=$(call CFG_RUN_arm-unknown-linux-gnueabi,,$(2))
RUSTC_FLAGS_arm-unknown-linux-gnueabi :=
RUSTC_CROSS_FLAGS_arm-unknown-linux-gnueabi :=
CFG_GNU_TRIPLE_arm-unknown-linux-gnueabi := arm-unknown-linux-gnueabi

View File

@ -0,0 +1,30 @@
# arm-unknown-linux-gnueabihf configuration
CROSS_PREFIX_arm-unknown-linux-gnueabihf=arm-linux-gnueabihf-
CC_arm-unknown-linux-gnueabihf=gcc
CXX_arm-unknown-linux-gnueabihf=g++
CPP_arm-unknown-linux-gnueabihf=gcc -E
AR_arm-unknown-linux-gnueabihf=ar
CFG_LIB_NAME_arm-unknown-linux-gnueabihf=lib$(1).so
CFG_STATIC_LIB_NAME_arm-unknown-linux-gnueabihf=lib$(1).a
CFG_LIB_GLOB_arm-unknown-linux-gnueabihf=lib$(1)-*.so
CFG_LIB_DSYM_GLOB_arm-unknown-linux-gnueabihf=lib$(1)-*.dylib.dSYM
CFG_JEMALLOC_CFLAGS_arm-unknown-linux-gnueabihf := -D__arm__ $(CFLAGS)
CFG_GCCISH_CFLAGS_arm-unknown-linux-gnueabihf := -Wall -g -fPIC -D__arm__ $(CFLAGS)
CFG_GCCISH_CXXFLAGS_arm-unknown-linux-gnueabihf := -fno-rtti $(CXXFLAGS)
CFG_GCCISH_LINK_FLAGS_arm-unknown-linux-gnueabihf := -shared -fPIC -g
CFG_GCCISH_DEF_FLAG_arm-unknown-linux-gnueabihf := -Wl,--export-dynamic,--dynamic-list=
CFG_GCCISH_PRE_LIB_FLAGS_arm-unknown-linux-gnueabihf := -Wl,-whole-archive
CFG_GCCISH_POST_LIB_FLAGS_arm-unknown-linux-gnueabihf := -Wl,-no-whole-archive
CFG_DEF_SUFFIX_arm-unknown-linux-gnueabihf := .linux.def
CFG_LLC_FLAGS_arm-unknown-linux-gnueabihf :=
CFG_INSTALL_NAME_ar,-unknown-linux-gnueabihf =
CFG_EXE_SUFFIX_arm-unknown-linux-gnueabihf :=
CFG_WINDOWSY_arm-unknown-linux-gnueabihf :=
CFG_UNIXY_arm-unknown-linux-gnueabihf := 1
CFG_PATH_MUNGE_arm-unknown-linux-gnueabihf := true
CFG_LDPATH_arm-unknown-linux-gnueabihf :=
CFG_RUN_arm-unknown-linux-gnueabihf=$(2)
CFG_RUN_TARG_arm-unknown-linux-gnueabihf=$(call CFG_RUN_arm-unknown-linux-gnueabihf,,$(2))
RUSTC_FLAGS_arm-unknown-linux-gnueabihf := -C target-feature=+v6,+vfp2
RUSTC_CROSS_FLAGS_arm-unknown-linux-gnueabihf :=
CFG_GNU_TRIPLE_arm-unknown-linux-gnueabihf := arm-unknown-linux-gnueabihf

33
mk/cfg/i386-apple-ios.mk Normal file
View File

@ -0,0 +1,33 @@
# i386-apple-ios configuration
CFG_SDK_NAME_i386-apple-ios = iphonesimulator
CFG_SDK_ARCHS_i386-apple-ios = i386
ifneq ($(findstring darwin,$(CFG_OSTYPE)),)
CFG_IOSSIM_SDK = $(shell xcrun --show-sdk-path -sdk iphonesimulator 2>/dev/null)
CFG_IOSSIM_FLAGS = -target i386-apple-ios -isysroot $(CFG_IOSSIM_SDK) -mios-simulator-version-min=7.0
CC_i386-apple-ios = $(shell xcrun -find -sdk iphonesimulator clang)
CXX_i386-apple-ios = $(shell xcrun -find -sdk iphonesimulator clang++)
CPP_i386-apple-ios = $(shell xcrun -find -sdk iphonesimulator clang++)
AR_i386-apple-ios = $(shell xcrun -find -sdk iphonesimulator ar)
endif
CFG_LIB_NAME_i386-apple-ios = lib$(1).a
CFG_LIB_GLOB_i386-apple-ios = lib$(1)-*.dylib
CFG_STATIC_LIB_NAME_i386-apple-ios=lib$(1).a
CFG_LIB_DSYM_GLOB_i386-apple-ios = lib$(1)-*.dylib.dSYM
CFG_GCCISH_CFLAGS_i386-apple-ios = -Wall -Werror -g -fPIC -m32 $(CFG_IOSSIM_FLAGS)
CFG_GCCISH_CXXFLAGS_i386-apple-ios = -fno-rtti $(CFG_IOSSIM_FLAGS) -I$(CFG_IOSSIM_SDK)/usr/include/c++/4.2.1
CFG_GCCISH_LINK_FLAGS_i386-apple-ios = -lpthread -Wl,-no_compact_unwind -m32 -Wl,-syslibroot $(CFG_IOSSIM_SDK)
CFG_GCCISH_DEF_FLAG_i386-apple-ios = -Wl,-exported_symbols_list,
CFG_GCCISH_PRE_LIB_FLAGS_i386-apple-ios =
CFG_GCCISH_POST_LIB_FLAGS_i386-apple-ios =
CFG_DEF_SUFFIX_i386-apple-ios = .darwin.def
CFG_LLC_FLAGS_i386-apple-ios =
CFG_INSTALL_NAME_i386-apple-ios = -Wl,-install_name,@rpath/$(1)
CFG_EXE_SUFFIX_i386-apple-ios =
CFG_WINDOWSY_i386-apple-ios =
CFG_UNIXY_i386-apple-ios = 1
CFG_PATH_MUNGE_i386-apple-ios = true
CFG_LDPATH_i386-apple-ios =
CFG_RUN_i386-apple-ios = $(2)
CFG_RUN_TARG_i386-apple-ios = $(call CFG_RUN_i386-apple-ios,,$(2))
CFG_JEMALLOC_CFLAGS_i386-apple-ios = $(CFG_IOSSIM_FLAGS) -target i386-apple-ios -Wl,-syslibroot $(CFG_IOSSIM_SDK) -Wl,-no_compact_unwind
CFG_GNU_TRIPLE_i386-apple-ios := i386-apple-ios

View File

@ -0,0 +1,27 @@
# i686-apple-darwin configuration
CC_i686-apple-darwin=$(CC)
CXX_i686-apple-darwin=$(CXX)
CPP_i686-apple-darwin=$(CPP)
AR_i686-apple-darwin=$(AR)
CFG_LIB_NAME_i686-apple-darwin=lib$(1).dylib
CFG_STATIC_LIB_NAME_i686-apple-darwin=lib$(1).a
CFG_LIB_GLOB_i686-apple-darwin=lib$(1)-*.dylib
CFG_LIB_DSYM_GLOB_i686-apple-darwin=lib$(1)-*.dylib.dSYM
CFG_JEMALLOC_CFLAGS_i686-apple-darwin := -m32 -arch i386 $(CFLAGS)
CFG_GCCISH_CFLAGS_i686-apple-darwin := -Wall -Werror -g -fPIC -m32 -arch i386 $(CFLAGS)
CFG_GCCISH_CXXFLAGS_i686-apple-darwin := -fno-rtti $(CXXFLAGS)
CFG_GCCISH_LINK_FLAGS_i686-apple-darwin := -dynamiclib -pthread -framework CoreServices -m32
CFG_GCCISH_DEF_FLAG_i686-apple-darwin := -Wl,-exported_symbols_list,
CFG_GCCISH_PRE_LIB_FLAGS_i686-apple-darwin :=
CFG_GCCISH_POST_LIB_FLAGS_i686-apple-darwin :=
CFG_DEF_SUFFIX_i686-apple-darwin := .darwin.def
CFG_LLC_FLAGS_i686-apple-darwin :=
CFG_INSTALL_NAME_i686-apple-darwin = -Wl,-install_name,@rpath/$(1)
CFG_EXE_SUFFIX_i686-apple-darwin :=
CFG_WINDOWSY_i686-apple-darwin :=
CFG_UNIXY_i686-apple-darwin := 1
CFG_PATH_MUNGE_i686-apple-darwin := true
CFG_LDPATH_i686-apple-darwin :=
CFG_RUN_i686-apple-darwin=$(2)
CFG_RUN_TARG_i686-apple-darwin=$(call CFG_RUN_i686-apple-darwin,,$(2))
CFG_GNU_TRIPLE_i686-apple-darwin := i686-apple-darwin

View File

@ -0,0 +1,28 @@
# i686-pc-windows-gnu configuration
CROSS_PREFIX_i686-pc-windows-gnu=i686-w64-mingw32-
CC_i686-pc-windows-gnu=gcc
CXX_i686-pc-windows-gnu=g++
CPP_i686-pc-windows-gnu=gcc -E
AR_i686-pc-windows-gnu=ar
CFG_LIB_NAME_i686-pc-windows-gnu=$(1).dll
CFG_STATIC_LIB_NAME_i686-pc-windows-gnu=$(1).lib
CFG_LIB_GLOB_i686-pc-windows-gnu=$(1)-*.dll
CFG_LIB_DSYM_GLOB_i686-pc-windows-gnu=$(1)-*.dylib.dSYM
CFG_JEMALLOC_CFLAGS_i686-pc-windows-gnu := -march=i686 -m32 -D_WIN32_WINNT=0x0600 $(CFLAGS)
CFG_GCCISH_CFLAGS_i686-pc-windows-gnu := -Wall -Werror -g -m32 -D_WIN32_WINNT=0x0600 $(CFLAGS)
CFG_GCCISH_CXXFLAGS_i686-pc-windows-gnu := -fno-rtti $(CXXFLAGS)
CFG_GCCISH_LINK_FLAGS_i686-pc-windows-gnu := -shared -g -m32
CFG_GCCISH_DEF_FLAG_i686-pc-windows-gnu :=
CFG_GCCISH_PRE_LIB_FLAGS_i686-pc-windows-gnu :=
CFG_GCCISH_POST_LIB_FLAGS_i686-pc-windows-gnu :=
CFG_DEF_SUFFIX_i686-pc-windows-gnu := .windows.def
CFG_LLC_FLAGS_i686-pc-windows-gnu :=
CFG_INSTALL_NAME_i686-pc-windows-gnu =
CFG_EXE_SUFFIX_i686-pc-windows-gnu := .exe
CFG_WINDOWSY_i686-pc-windows-gnu := 1
CFG_UNIXY_i686-pc-windows-gnu :=
CFG_PATH_MUNGE_i686-pc-windows-gnu :=
CFG_LDPATH_i686-pc-windows-gnu :=$(CFG_LDPATH_i686-pc-windows-gnu):$(PATH)
CFG_RUN_i686-pc-windows-gnu=PATH="$(CFG_LDPATH_i686-pc-windows-gnu):$(1)" $(2)
CFG_RUN_TARG_i686-pc-windows-gnu=$(call CFG_RUN_i686-pc-windows-gnu,$(HLIB$(1)_H_$(CFG_BUILD)),$(2))
CFG_GNU_TRIPLE_i686-pc-windows-gnu := i686-w64-mingw32

View File

@ -0,0 +1,27 @@
# i686-unknown-linux-gnu configuration
CC_i686-unknown-linux-gnu=$(CC)
CXX_i686-unknown-linux-gnu=$(CXX)
CPP_i686-unknown-linux-gnu=$(CPP)
AR_i686-unknown-linux-gnu=$(AR)
CFG_LIB_NAME_i686-unknown-linux-gnu=lib$(1).so
CFG_STATIC_LIB_NAME_i686-unknown-linux-gnu=lib$(1).a
CFG_LIB_GLOB_i686-unknown-linux-gnu=lib$(1)-*.so
CFG_LIB_DSYM_GLOB_i686-unknown-linux-gnu=lib$(1)-*.dylib.dSYM
CFG_JEMALLOC_CFLAGS_i686-unknown-linux-gnu := -m32 $(CFLAGS)
CFG_GCCISH_CFLAGS_i686-unknown-linux-gnu := -Wall -Werror -g -fPIC -m32 $(CFLAGS)
CFG_GCCISH_CXXFLAGS_i686-unknown-linux-gnu := -fno-rtti $(CXXFLAGS)
CFG_GCCISH_LINK_FLAGS_i686-unknown-linux-gnu := -shared -fPIC -ldl -pthread -lrt -g -m32
CFG_GCCISH_DEF_FLAG_i686-unknown-linux-gnu := -Wl,--export-dynamic,--dynamic-list=
CFG_GCCISH_PRE_LIB_FLAGS_i686-unknown-linux-gnu := -Wl,-whole-archive
CFG_GCCISH_POST_LIB_FLAGS_i686-unknown-linux-gnu := -Wl,-no-whole-archive
CFG_DEF_SUFFIX_i686-unknown-linux-gnu := .linux.def
CFG_LLC_FLAGS_i686-unknown-linux-gnu :=
CFG_INSTALL_NAME_i686-unknown-linux-gnu =
CFG_EXE_SUFFIX_i686-unknown-linux-gnu =
CFG_WINDOWSY_i686-unknown-linux-gnu :=
CFG_UNIXY_i686-unknown-linux-gnu := 1
CFG_PATH_MUNGE_i686-unknown-linux-gnu := true
CFG_LDPATH_i686-unknown-linux-gnu :=
CFG_RUN_i686-unknown-linux-gnu=$(2)
CFG_RUN_TARG_i686-unknown-linux-gnu=$(call CFG_RUN_i686-unknown-linux-gnu,,$(2))
CFG_GNU_TRIPLE_i686-unknown-linux-gnu := i686-unknown-linux-gnu

View File

@ -0,0 +1,28 @@
# mips-unknown-linux-gnu configuration
CC_mips-unknown-linux-gnu=mips-linux-gnu-gcc
CXX_mips-unknown-linux-gnu=mips-linux-gnu-g++
CPP_mips-unknown-linux-gnu=mips-linux-gnu-gcc -E
AR_mips-unknown-linux-gnu=mips-linux-gnu-ar
CFG_LIB_NAME_mips-unknown-linux-gnu=lib$(1).so
CFG_STATIC_LIB_NAME_mips-unknown-linux-gnu=lib$(1).a
CFG_LIB_GLOB_mips-unknown-linux-gnu=lib$(1)-*.so
CFG_LIB_DSYM_GLOB_mips-unknown-linux-gnu=lib$(1)-*.dylib.dSYM
CFG_JEMALLOC_CFLAGS_mips-unknown-linux-gnu := -mips32r2 -msoft-float -mabi=32 -mno-compact-eh $(CFLAGS)
CFG_GCCISH_CFLAGS_mips-unknown-linux-gnu := -Wall -g -fPIC -mips32r2 -msoft-float -mabi=32 -mno-compact-eh $(CFLAGS)
CFG_GCCISH_CXXFLAGS_mips-unknown-linux-gnu := -fno-rtti $(CXXFLAGS)
CFG_GCCISH_LINK_FLAGS_mips-unknown-linux-gnu := -shared -fPIC -g -mips32r2 -msoft-float -mabi=32
CFG_GCCISH_DEF_FLAG_mips-unknown-linux-gnu := -Wl,--export-dynamic,--dynamic-list=
CFG_GCCISH_PRE_LIB_FLAGS_mips-unknown-linux-gnu := -Wl,-whole-archive
CFG_GCCISH_POST_LIB_FLAGS_mips-unknown-linux-gnu := -Wl,-no-whole-archive
CFG_DEF_SUFFIX_mips-unknown-linux-gnu := .linux.def
CFG_LLC_FLAGS_mips-unknown-linux-gnu :=
CFG_INSTALL_NAME_mips-unknown-linux-gnu =
CFG_EXE_SUFFIX_mips-unknown-linux-gnu :=
CFG_WINDOWSY_mips-unknown-linux-gnu :=
CFG_UNIXY_mips-unknown-linux-gnu := 1
CFG_PATH_MUNGE_mips-unknown-linux-gnu := true
CFG_LDPATH_mips-unknown-linux-gnu :=
CFG_RUN_mips-unknown-linux-gnu=
CFG_RUN_TARG_mips-unknown-linux-gnu=
RUSTC_FLAGS_mips-unknown-linux-gnu := -C target-cpu=mips32r2 -C target-feature="+mips32r2,+o32" -C soft-float
CFG_GNU_TRIPLE_mips-unknown-linux-gnu := mips-unknown-linux-gnu

View File

@ -0,0 +1,28 @@
# mipsel-unknown-linux-gnu configuration
CC_mipsel-unknown-linux-gnu=mipsel-unknown-linux-gnu-gcc
CXX_mipsel-unknown-linux-gnu=mipsel-unknown-linux-gnu-g++
CPP_mipsel-unknown-linux-gnu=mipsel-unknown-linux-gnu-gcc
AR_mipsel-unknown-linux-gnu=mipsel-unknown-linux-gnu-ar
CFG_LIB_NAME_mipsel-unknown-linux-gnu=lib$(1).so
CFG_STATIC_LIB_NAME_mipsel-unknown-linux-gnu=lib$(1).a
CFG_LIB_GLOB_mipsel-unknown-linux-gnu=lib$(1)-*.so
CFG_LIB_DSYM_GLOB_mipsel-unknown-linux-gnu=lib$(1)-*.dylib.dSYM
CFG_JEMALLOC_CFLAGS_mipsel-unknown-linux-gnu := -mips32 -mabi=32 $(CFLAGS)
CFG_GCCISH_CFLAGS_mipsel-unknown-linux-gnu := -Wall -g -fPIC -mips32 -mabi=32 $(CFLAGS)
CFG_GCCISH_CXXFLAGS_mipsel-unknown-linux-gnu := -fno-rtti $(CXXFLAGS)
CFG_GCCISH_LINK_FLAGS_mipsel-unknown-linux-gnu := -shared -fPIC -g -mips32
CFG_GCCISH_DEF_FLAG_mipsel-unknown-linux-gnu := -Wl,--export-dynamic,--dynamic-list=
CFG_GCCISH_PRE_LIB_FLAGS_mipsel-unknown-linux-gnu := -Wl,-whole-archive
CFG_GCCISH_POST_LIB_FLAGS_mipsel-unknown-linux-gnu := -Wl,-no-whole-archive
CFG_DEF_SUFFIX_mipsel-unknown-linux-gnu := .linux.def
CFG_LLC_FLAGS_mipsel-unknown-linux-gnu :=
CFG_INSTALL_NAME_mipsel-unknown-linux-gnu =
CFG_EXE_SUFFIX_mipsel-unknown-linux-gnu :=
CFG_WINDOWSY_mipsel-unknown-linux-gnu :=
CFG_UNIXY_mipsel-unknown-linux-gnu := 1
CFG_PATH_MUNGE_mipsel-unknown-linux-gnu := true
CFG_LDPATH_mipsel-unknown-linux-gnu :=
CFG_RUN_mipsel-unknown-linux-gnu=
CFG_RUN_TARG_mipsel-unknown-linux-gnu=
RUSTC_FLAGS_mipsel-unknown-linux-gnu := -C target-cpu=mips32 -C target-feature="+mips32,+o32"
CFG_GNU_TRIPLE_mipsel-unknown-linux-gnu := mipsel-unknown-linux-gnu

View File

@ -0,0 +1,27 @@
# x86_64-apple-darwin configuration
CC_x86_64-apple-darwin=$(CC)
CXX_x86_64-apple-darwin=$(CXX)
CPP_x86_64-apple-darwin=$(CPP)
AR_x86_64-apple-darwin=$(AR)
CFG_LIB_NAME_x86_64-apple-darwin=lib$(1).dylib
CFG_STATIC_LIB_NAME_x86_64-apple-darwin=lib$(1).a
CFG_LIB_GLOB_x86_64-apple-darwin=lib$(1)-*.dylib
CFG_LIB_DSYM_GLOB_x86_64-apple-darwin=lib$(1)-*.dylib.dSYM
CFG_JEMALLOC_CFLAGS_x86_64-apple-darwin := -m64 -arch x86_64 $(CFLAGS)
CFG_GCCISH_CFLAGS_x86_64-apple-darwin := -Wall -Werror -g -fPIC -m64 -arch x86_64 $(CFLAGS)
CFG_GCCISH_CXXFLAGS_x86_64-apple-darwin := -fno-rtti $(CXXFLAGS)
CFG_GCCISH_LINK_FLAGS_x86_64-apple-darwin := -dynamiclib -pthread -framework CoreServices -m64
CFG_GCCISH_DEF_FLAG_x86_64-apple-darwin := -Wl,-exported_symbols_list,
CFG_GCCISH_PRE_LIB_FLAGS_x86_64-apple-darwin :=
CFG_GCCISH_POST_LIB_FLAGS_x86_64-apple-darwin :=
CFG_DEF_SUFFIX_x86_64-apple-darwin := .darwin.def
CFG_LLC_FLAGS_x86_64-apple-darwin :=
CFG_INSTALL_NAME_x86_64-apple-darwin = -Wl,-install_name,@rpath/$(1)
CFG_EXE_SUFFIX_x86_64-apple-darwin :=
CFG_WINDOWSY_x86_64-apple-darwin :=
CFG_UNIXY_x86_64-apple-darwin := 1
CFG_PATH_MUNGE_x86_64-apple-darwin := true
CFG_LDPATH_x86_64-apple-darwin :=
CFG_RUN_x86_64-apple-darwin=$(2)
CFG_RUN_TARG_x86_64-apple-darwin=$(call CFG_RUN_x86_64-apple-darwin,,$(2))
CFG_GNU_TRIPLE_x86_64-apple-darwin := x86_64-apple-darwin

View File

@ -0,0 +1,28 @@
# x86_64-pc-windows-gnu configuration
CROSS_PREFIX_x86_64-pc-windows-gnu=x86_64-w64-mingw32-
CC_x86_64-pc-windows-gnu=gcc
CXX_x86_64-pc-windows-gnu=g++
CPP_x86_64-pc-windows-gnu=gcc -E
AR_x86_64-pc-windows-gnu=ar
CFG_LIB_NAME_x86_64-pc-windows-gnu=$(1).dll
CFG_STATIC_LIB_NAME_x86_64-pc-windows-gnu=$(1).lib
CFG_LIB_GLOB_x86_64-pc-windows-gnu=$(1)-*.dll
CFG_LIB_DSYM_GLOB_x86_64-pc-windows-gnu=$(1)-*.dylib.dSYM
CFG_JEMALLOC_CFLAGS_x86_64-pc-windows-gnu := -m64 -D_WIN32_WINNT=0x0600 $(CFLAGS)
CFG_GCCISH_CFLAGS_x86_64-pc-windows-gnu := -Wall -Werror -g -m64 -D_WIN32_WINNT=0x0600 $(CFLAGS)
CFG_GCCISH_CXXFLAGS_x86_64-pc-windows-gnu := -fno-rtti $(CXXFLAGS)
CFG_GCCISH_LINK_FLAGS_x86_64-pc-windows-gnu := -shared -g -m64
CFG_GCCISH_DEF_FLAG_x86_64-pc-windows-gnu :=
CFG_GCCISH_PRE_LIB_FLAGS_x86_64-pc-windows-gnu :=
CFG_GCCISH_POST_LIB_FLAGS_x86_64-pc-windows-gnu :=
CFG_DEF_SUFFIX_x86_64-pc-windows-gnu := .windows.def
CFG_LLC_FLAGS_x86_64-pc-windows-gnu :=
CFG_INSTALL_NAME_x86_64-pc-windows-gnu =
CFG_EXE_SUFFIX_x86_64-pc-windows-gnu := .exe
CFG_WINDOWSY_x86_64-pc-windows-gnu := 1
CFG_UNIXY_x86_64-pc-windows-gnu :=
CFG_PATH_MUNGE_x86_64-pc-windows-gnu :=
CFG_LDPATH_x86_64-pc-windows-gnu :=$(CFG_LDPATH_x86_64-pc-windows-gnu):$(PATH)
CFG_RUN_x86_64-pc-windows-gnu=PATH="$(CFG_LDPATH_x86_64-pc-windows-gnu):$(1)" $(2)
CFG_RUN_TARG_x86_64-pc-windows-gnu=$(call CFG_RUN_x86_64-pc-windows-gnu,$(HLIB$(1)_H_$(CFG_BUILD)),$(2))
CFG_GNU_TRIPLE_x86_64-pc-windows-gnu := x86_64-w64-mingw32

View File

@ -0,0 +1,26 @@
# x86_64-pc-dragonfly-elf configuration
CC_x86_64-unknown-dragonfly=$(CC)
CXX_x86_64-unknown-dragonfly=$(CXX)
CPP_x86_64-unknown-dragonfly=$(CPP)
AR_x86_64-unknown-dragonfly=$(AR)
CFG_LIB_NAME_x86_64-unknown-dragonfly=lib$(1).so
CFG_STATIC_LIB_NAME_x86_64-unknown-dragonfly=lib$(1).a
CFG_LIB_GLOB_x86_64-unknown-dragonfly=lib$(1)-*.so
CFG_LIB_DSYM_GLOB_x86_64-unknown-dragonfly=$(1)-*.dylib.dSYM
CFG_JEMALLOC_CFLAGS_x86_64-unknown-dragonfly := -m64 -I/usr/include -I/usr/local/include $(CFLAGS)
CFG_GCCISH_CFLAGS_x86_64-unknown-dragonfly := -Wall -Werror -g -fPIC -m64 -I/usr/include -I/usr/local/include $(CFLAGS)
CFG_GCCISH_LINK_FLAGS_x86_64-unknown-dragonfly := -shared -fPIC -g -pthread -lrt -m64
CFG_GCCISH_DEF_FLAG_x86_64-unknown-dragonfly := -Wl,--export-dynamic,--dynamic-list=
CFG_GCCISH_PRE_LIB_FLAGS_x86_64-unknown-dragonfly := -Wl,-whole-archive
CFG_GCCISH_POST_LIB_FLAGS_x86_64-unknown-dragonfly := -Wl,-no-whole-archive
CFG_DEF_SUFFIX_x86_64-unknown-dragonfly := .bsd.def
CFG_LLC_FLAGS_x86_64-unknown-dragonfly :=
CFG_INSTALL_NAME_x86_64-unknown-dragonfly =
CFG_EXE_SUFFIX_x86_64-unknown-dragonfly :=
CFG_WINDOWSY_x86_64-unknown-dragonfly :=
CFG_UNIXY_x86_64-unknown-dragonfly := 1
CFG_PATH_MUNGE_x86_64-unknown-dragonfly :=
CFG_LDPATH_x86_64-unknown-dragonfly :=
CFG_RUN_x86_64-unknown-dragonfly=$(2)
CFG_RUN_TARG_x86_64-unknown-dragonfly=$(call CFG_RUN_x86_64-unknown-dragonfly,,$(2))
CFG_GNU_TRIPLE_x86_64-unknown-dragonfly := x86_64-unknown-dragonfly

View File

@ -0,0 +1,26 @@
# x86_64-unknown-freebsd configuration
CC_x86_64-unknown-freebsd=$(CC)
CXX_x86_64-unknown-freebsd=$(CXX)
CPP_x86_64-unknown-freebsd=$(CPP)
AR_x86_64-unknown-freebsd=$(AR)
CFG_LIB_NAME_x86_64-unknown-freebsd=lib$(1).so
CFG_STATIC_LIB_NAME_x86_64-unknown-freebsd=lib$(1).a
CFG_LIB_GLOB_x86_64-unknown-freebsd=lib$(1)-*.so
CFG_LIB_DSYM_GLOB_x86_64-unknown-freebsd=$(1)-*.dylib.dSYM
CFG_JEMALLOC_CFLAGS_x86_64-unknown-freebsd := -I/usr/local/include $(CFLAGS)
CFG_GCCISH_CFLAGS_x86_64-unknown-freebsd := -Wall -Werror -g -fPIC -I/usr/local/include $(CFLAGS)
CFG_GCCISH_LINK_FLAGS_x86_64-unknown-freebsd := -shared -fPIC -g -pthread -lrt
CFG_GCCISH_DEF_FLAG_x86_64-unknown-freebsd := -Wl,--export-dynamic,--dynamic-list=
CFG_GCCISH_PRE_LIB_FLAGS_x86_64-unknown-freebsd := -Wl,-whole-archive
CFG_GCCISH_POST_LIB_FLAGS_x86_64-unknown-freebsd := -Wl,-no-whole-archive
CFG_DEF_SUFFIX_x86_64-unknown-freebsd := .bsd.def
CFG_LLC_FLAGS_x86_64-unknown-freebsd :=
CFG_INSTALL_NAME_x86_64-unknown-freebsd =
CFG_EXE_SUFFIX_x86_64-unknown-freebsd :=
CFG_WINDOWSY_x86_64-unknown-freebsd :=
CFG_UNIXY_x86_64-unknown-freebsd := 1
CFG_PATH_MUNGE_x86_64-unknown-freebsd :=
CFG_LDPATH_x86_64-unknown-freebsd :=
CFG_RUN_x86_64-unknown-freebsd=$(2)
CFG_RUN_TARG_x86_64-unknown-freebsd=$(call CFG_RUN_x86_64-unknown-freebsd,,$(2))
CFG_GNU_TRIPLE_x86_64-unknown-freebsd := x86_64-unknown-freebsd

View File

@ -0,0 +1,28 @@
# x86_64-unknown-linux-gnu configuration
CC_x86_64-unknown-linux-gnu=$(CC)
CXX_x86_64-unknown-linux-gnu=$(CXX)
CPP_x86_64-unknown-linux-gnu=$(CPP)
AR_x86_64-unknown-linux-gnu=$(AR)
CFG_LIB_NAME_x86_64-unknown-linux-gnu=lib$(1).so
CFG_STATIC_LIB_NAME_x86_64-unknown-linux-gnu=lib$(1).a
CFG_LIB_GLOB_x86_64-unknown-linux-gnu=lib$(1)-*.so
CFG_LIB_DSYM_GLOB_x86_64-unknown-linux-gnu=lib$(1)-*.dylib.dSYM
CFG_JEMALLOC_CFLAGS_x86_64-unknown-linux-gnu := -m64
CFG_GCCISH_CFLAGS_x86_64-unknown-linux-gnu := -Wall -Werror -g -fPIC -m64
CFG_GCCISH_CXXFLAGS_x86_64-unknown-linux-gnu := -fno-rtti
CFG_GCCISH_LINK_FLAGS_x86_64-unknown-linux-gnu := -shared -fPIC -ldl -pthread -lrt -g -m64
CFG_GCCISH_DEF_FLAG_x86_64-unknown-linux-gnu := -Wl,--export-dynamic,--dynamic-list=
CFG_GCCISH_PRE_LIB_FLAGS_x86_64-unknown-linux-gnu := -Wl,-whole-archive
CFG_GCCISH_POST_LIB_FLAGS_x86_64-unknown-linux-gnu := -Wl,-no-whole-archive
CFG_DEF_SUFFIX_x86_64-unknown-linux-gnu := .linux.def
CFG_LLC_FLAGS_x86_64-unknown-linux-gnu :=
CFG_INSTALL_NAME_x86_64-unknown-linux-gnu =
CFG_EXE_SUFFIX_x86_64-unknown-linux-gnu =
CFG_WINDOWSY_x86_64-unknown-linux-gnu :=
CFG_UNIXY_x86_64-unknown-linux-gnu := 1
CFG_PATH_MUNGE_x86_64-unknown-linux-gnu := true
CFG_LDPATH_x86_64-unknown-linux-gnu :=
CFG_RUN_x86_64-unknown-linux-gnu=$(2)
CFG_RUN_TARG_x86_64-unknown-linux-gnu=$(call CFG_RUN_x86_64-unknown-linux-gnu,,$(2))
CFG_GNU_TRIPLE_x86_64-unknown-linux-gnu := x86_64-unknown-linux-gnu

View File

@ -12,15 +12,21 @@
# Cleanup
######################################################################
CLEAN_STAGE_RULES = \
$(foreach stage, $(STAGES), \
$(foreach host, $(CFG_HOST_TRIPLES), \
clean$(stage)_H_$(host) \
$(foreach target, $(CFG_TARGET_TRIPLES), \
CLEAN_STAGE_RULES := \
$(foreach stage, $(STAGES), \
$(foreach host, $(CFG_HOST), \
clean$(stage)_H_$(host) \
$(foreach target, $(CFG_TARGET), \
clean$(stage)_T_$(target)_H_$(host))))
CLEAN_LLVM_RULES = \
$(foreach target, $(CFG_HOST_TRIPLES), \
CLEAN_STAGE_RULES := $(CLEAN_STAGE_RULES) \
$(foreach host, $(CFG_HOST), clean-generic-H-$(host))
CLEAN_STAGE_RULES := $(CLEAN_STAGE_RULES) \
$(foreach host, $(CFG_TARGET), clean-generic-T-$(host))
CLEAN_LLVM_RULES = \
$(foreach target, $(CFG_HOST), \
clean-llvm$(target))
.PHONY: clean clean-all clean-misc clean-llvm
@ -33,102 +39,83 @@ clean: clean-misc $(CLEAN_STAGE_RULES)
clean-misc:
@$(call E, cleaning)
$(Q)find rustllvm rt $(CFG_BUILD_TRIPLE)/test \
-name '*.[odasS]' -o \
-name '*.so' -o \
-name '*.dylib' -o \
-name '*.dll' -o \
-name '*.def' -o \
-name '*.bc' \
| xargs rm -f
$(Q)find rustllvm rt $(CFG_BUILD_TRIPLE)\
-name '*.dSYM' \
| xargs rm -Rf
$(Q)rm -f $(RUNTIME_OBJS) $(RUNTIME_DEF)
$(Q)rm -f $(RUSTLLVM_LIB_OBJS) $(RUSTLLVM_OBJS_OBJS) $(RUSTLLVM_DEF)
$(Q)rm -Rf $(DOCS)
$(Q)rm -Rf $(GENERATED)
$(Q)rm -f tmp/*
$(Q)rm -Rf rust-stage0-*.tar.bz2 $(PKG_NAME)-*.tar.gz dist
$(Q)rm -Rf $(foreach ext, \
html aux cp fn ky log pdf pg toc tp vr cps, \
$(wildcard doc/*.$(ext) \
doc/*/*.$(ext) \
doc/*/*/*.$(ext)))
$(Q)rm -Rf doc/version.md
$(Q)rm -Rf $(foreach sub, index styles files search javascript, \
$(wildcard doc/*/$(sub)))
$(Q)rm -Rf tmp/*
$(Q)rm -Rf rust-stage0-*.tar.bz2 $(PKG_NAME)-*.tar.gz $(PKG_NAME)-*.exe
$(Q)rm -Rf dist/*
$(Q)rm -Rf doc
define CLEAN_GENERIC
clean-generic-$(2)-$(1):
$(Q)find $(1)/rustllvm \
$(1)/rt \
$(1)/test \
$(1)/stage* \
-type f \( \
-name '*.[odasS]' -o \
-name '*.so' -o \
-name '*.dylib' -o \
-name '*.rlib' -o \
-name 'stamp.*' -o \
-name '*.lib' -o \
-name '*.dll' -o \
-name '*.def' -o \
-name '*.py' -o \
-name '*.pyc' -o \
-name '*.bc' \
\) \
| xargs rm -f
$(Q)find $(1) \
-name '*.dSYM' \
| xargs rm -Rf
endef
$(foreach host, $(CFG_HOST), $(eval $(call CLEAN_GENERIC,$(host),H)))
$(foreach targ, $(CFG_TARGET), $(eval $(call CLEAN_GENERIC,$(targ),T)))
define CLEAN_HOST_STAGE_N
clean$(1)_H_$(2):
$(Q)rm -f $$(HBIN$(1)_H_$(2))/rustc$(X_$(2))
$(Q)rm -f $$(HBIN$(1)_H_$(2))/rustpkg$(X_$(2))
$(Q)rm -f $$(HBIN$(1)_H_$(2))/serializer$(X_$(2))
$(Q)rm -f $$(HBIN$(1)_H_$(2))/rustdoc$(X_$(2))
$(Q)rm -f $$(HBIN$(1)_H_$(2))/rusti$(X_$(2))
$(Q)rm -f $$(HBIN$(1)_H_$(2))/rust$(X_$(2))
$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_LIBRUSTPKG_$(2))
$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_LIBRUSTDOC_$(2))
$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_RUNTIME_$(2))
$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_STDLIB_$(2))
$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_EXTRALIB_$(2))
$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_LIBRUSTC_$(2))
$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_LIBSYNTAX_$(2))
$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_LIBRUSTI_$(2))
$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_LIBRUST_$(2))
$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(STDLIB_GLOB_$(2))
$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(EXTRALIB_GLOB_$(2))
$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBRUSTC_GLOB_$(2))
$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBSYNTAX_GLOB_$(2))
$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBRUSTPKG_GLOB_$(2))
$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBRUSTDOC_GLOB_$(2))
$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBRUSTI_GLOB_$(2))
$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBRUST_GLOB_$(2))
$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_RUSTLLVM_$(2))
$(Q)rm -f $$(HLIB$(1)_H_$(2))/libstd.rlib
clean$(1)_H_$(2): \
$$(foreach crate,$$(CRATES),clean$(1)_H_$(2)-lib-$$(crate)) \
$$(foreach tool,$$(TOOLS) $$(DEBUGGER_BIN_SCRIPTS_ALL),clean$(1)_H_$(2)-tool-$$(tool))
$$(Q)rm -fr $(2)/rt/libbacktrace
clean$(1)_H_$(2)-tool-%:
$$(Q)rm -f $$(HBIN$(1)_H_$(2))/$$*$$(X_$(2))
clean$(1)_H_$(2)-lib-%:
$$(Q)rm -f $$(HLIB$(1)_H_$(2))/$$(call CFG_LIB_GLOB_$(2),$$*)
$$(Q)rm -f $$(HLIB$(1)_H_$(2))/$$(call CFG_RLIB_GLOB,$$*)
endef
$(foreach host, $(CFG_HOST_TRIPLES), \
$(foreach host, $(CFG_HOST), \
$(eval $(foreach stage, $(STAGES), \
$(eval $(call CLEAN_HOST_STAGE_N,$(stage),$(host))))))
define CLEAN_TARGET_STAGE_N
clean$(1)_T_$(2)_H_$(3):
$(Q)rm -f $$(TBIN$(1)_T_$(2)_H_$(3))/rustc$(X_$(2))
$(Q)rm -f $$(TBIN$(1)_T_$(2)_H_$(3))/rustpkg$(X_$(2))
$(Q)rm -f $$(TBIN$(1)_T_$(2)_H_$(3))/serializer$(X_$(2))
$(Q)rm -f $$(TBIN$(1)_T_$(2)_H_$(3))/rustdoc$(X_$(2))
$(Q)rm -f $$(TBIN$(1)_T_$(2)_H_$(3))/rusti$(X_$(2))
$(Q)rm -f $$(TBIN$(1)_T_$(2)_H_$(3))/rust$(X_$(2))
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTPKG_$(2))
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTDOC_$(2))
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_RUNTIME_$(2))
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_STDLIB_$(2))
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_EXTRALIB_$(2))
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTC_$(2))
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBSYNTAX_$(2))
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTI_$(2))
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUST_$(2))
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(STDLIB_GLOB_$(2))
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(EXTRALIB_GLOB_$(2))
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(LIBRUSTC_GLOB_$(2))
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(LIBSYNTAX_GLOB_$(2))
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(LIBRUSTPKG_GLOB_$(2))
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(LIBRUSTDOC_GLOB_$(2))
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(LIBRUSTI_GLOB_$(2))
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(LIBRUST_GLOB_$(2))
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_RUSTLLVM_$(2))
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/libstd.rlib
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/libmorestack.a
clean$(1)_T_$(2)_H_$(3): \
$$(foreach crate,$$(CRATES),clean$(1)_T_$(2)_H_$(3)-lib-$$(crate)) \
$$(foreach tool,$$(TOOLS) $$(DEBUGGER_BIN_SCRIPTS_ALL),clean$(1)_T_$(2)_H_$(3)-tool-$$(tool))
$$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/libmorestack.a
$$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/libcompiler-rt.a
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/librun_pass_stage* # For unix
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/run_pass_stage* # For windows
clean$(1)_T_$(2)_H_$(3)-tool-%:
$$(Q)rm -f $$(TBIN$(1)_T_$(2)_H_$(3))/$$*$$(X_$(2))
clean$(1)_T_$(2)_H_$(3)-lib-%:
$$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$$(call CFG_LIB_GLOB_$(2),$$*)
$$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$$(call CFG_RLIB_GLOB,$$*)
endef
$(foreach host, $(CFG_HOST_TRIPLES), \
$(eval $(foreach target, $(CFG_TARGET_TRIPLES), \
$(foreach host, $(CFG_HOST), \
$(eval $(foreach target, $(CFG_TARGET), \
$(eval $(foreach stage, 0 1 2 3, \
$(eval $(call CLEAN_TARGET_STAGE_N,$(stage),$(target),$(host))))))))
@ -142,5 +129,5 @@ clean-llvm$(1): ;
endif
endef
$(foreach host, $(CFG_HOST_TRIPLES), \
$(foreach host, $(CFG_HOST), \
$(eval $(call DEF_CLEAN_LLVM_HOST,$(host))))

152
mk/crates.mk Normal file
View File

@ -0,0 +1,152 @@
# Copyright 2014 The Rust Project Developers. See the COPYRIGHT
# file at the top-level directory of this distribution and at
# http://rust-lang.org/COPYRIGHT.
#
# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
# option. This file may not be copied, modified, or distributed
# except according to those terms.
################################################################################
# Rust's standard distribution of crates and tools
#
# The crates outlined below are the standard distribution of libraries provided
# in a rust installation. These rules are meant to abstract over the
# dependencies (both native and rust) of crates and basically generate all the
# necessary makefile rules necessary to build everything.
#
# Here's an explanation of the variables below
#
# TARGET_CRATES
# This list of crates will be built for all targets, including
# cross-compiled targets
#
# HOST_CRATES
# This list of crates will be compiled for only host targets. Note that
# this set is explicitly *not* a subset of TARGET_CRATES, but rather it is
# a disjoint set. Nothing in the TARGET_CRATES set can depend on crates in
# the HOST_CRATES set, but the HOST_CRATES set can depend on target
# crates.
#
# TOOLS
# A list of all tools which will be built as part of the compilation
# process. It is currently assumed that most tools are built through
# src/driver/driver.rs with a particular configuration (there's a
# corresponding library providing the implementation)
#
# DEPS_<crate>
# These lists are the dependencies of the <crate> that is to be built.
# Rust dependencies are listed bare (i.e. std) and native
# dependencies have a "native:" prefix (i.e. native:hoedown). All deps
# will be built before the crate itself is built.
#
# TOOL_DEPS_<tool>/TOOL_SOURCE_<tool>
# Similar to the DEPS variable, this is the library crate dependencies
# list for tool as well as the source file for the specified tool
#
# You shouldn't need to modify much other than these variables. Crates are
# automatically generated for all stage/host/target combinations.
################################################################################
TARGET_CRATES := libc std flate arena term \
serialize getopts collections test rand \
log regex graphviz core rbml alloc \
unicode
RUSTC_CRATES := rustc rustc_typeck rustc_borrowck rustc_resolve rustc_driver \
rustc_trans rustc_back rustc_llvm
HOST_CRATES := syntax $(RUSTC_CRATES) rustdoc fmt_macros
CRATES := $(TARGET_CRATES) $(HOST_CRATES)
TOOLS := compiletest rustdoc rustc rustbook
DEPS_core :=
DEPS_libc := core
DEPS_unicode := core
DEPS_alloc := core libc native:jemalloc
DEPS_std := core libc rand alloc collections unicode \
native:rust_builtin native:backtrace native:rustrt_native
DEPS_graphviz := std
DEPS_syntax := std term serialize log fmt_macros arena libc
DEPS_rustc_driver := arena flate getopts graphviz libc rustc rustc_back rustc_borrowck \
rustc_typeck rustc_resolve log syntax serialize rustc_llvm rustc_trans
DEPS_rustc_trans := arena flate getopts graphviz libc rustc rustc_back \
log syntax serialize rustc_llvm
DEPS_rustc_typeck := rustc syntax
DEPS_rustc_borrowck := rustc log graphviz syntax
DEPS_rustc_resolve := rustc log syntax
DEPS_rustc := syntax flate arena serialize getopts rbml \
log graphviz rustc_llvm rustc_back
DEPS_rustc_llvm := native:rustllvm libc std
DEPS_rustc_back := std syntax rustc_llvm flate log libc
DEPS_rustdoc := rustc rustc_driver native:hoedown serialize getopts \
test
DEPS_flate := std native:miniz
DEPS_arena := std
DEPS_graphviz := std
DEPS_glob := std
DEPS_serialize := std log
DEPS_rbml := std log serialize
DEPS_term := std log
DEPS_getopts := std
DEPS_collections := core alloc unicode
DEPS_num := std
DEPS_test := std getopts serialize rbml term regex native:rust_test_helpers
DEPS_rand := core
DEPS_log := std regex
DEPS_regex := std
DEPS_fmt_macros = std
TOOL_DEPS_compiletest := test getopts
TOOL_DEPS_rustdoc := rustdoc
TOOL_DEPS_rustc := rustc_driver
TOOL_DEPS_rustbook := std regex rustdoc
TOOL_SOURCE_compiletest := $(S)src/compiletest/compiletest.rs
TOOL_SOURCE_rustdoc := $(S)src/driver/driver.rs
TOOL_SOURCE_rustc := $(S)src/driver/driver.rs
TOOL_SOURCE_rustbook := $(S)src/rustbook/main.rs
ONLY_RLIB_core := 1
ONLY_RLIB_libc := 1
ONLY_RLIB_alloc := 1
ONLY_RLIB_rand := 1
ONLY_RLIB_collections := 1
ONLY_RLIB_unicode := 1
################################################################################
# You should not need to edit below this line
################################################################################
DOC_CRATES := $(filter-out rustc, \
$(filter-out rustc_trans, \
$(filter-out rustc_typeck, \
$(filter-out rustc_borrowck, \
$(filter-out rustc_resolve, \
$(filter-out rustc_driver, \
$(filter-out log, \
$(filter-out regex, \
$(filter-out getopts, \
$(filter-out syntax, $(CRATES)))))))))))
COMPILER_DOC_CRATES := rustc rustc_trans rustc_borrowck rustc_resolve \
rustc_typeck rustc_driver syntax
# This macro creates some simple definitions for each crate being built, just
# some munging of all of the parameters above.
#
# $(1) is the crate to generate variables for
define RUST_CRATE
CRATEFILE_$(1) := $$(S)src/lib$(1)/lib.rs
RSINPUTS_$(1) := $$(call rwildcard,$(S)src/lib$(1)/,*.rs)
RUST_DEPS_$(1) := $$(filter-out native:%,$$(DEPS_$(1)))
NATIVE_DEPS_$(1) := $$(patsubst native:%,%,$$(filter native:%,$$(DEPS_$(1))))
endef
$(foreach crate,$(CRATES),$(eval $(call RUST_CRATE,$(crate))))
# Similar to the macro above for crates, this macro is for tools
#
# $(1) is the crate to generate variables for
define RUST_TOOL
TOOL_INPUTS_$(1) := $$(call rwildcard,$$(dir $$(TOOL_SOURCE_$(1))),*.rs)
endef
$(foreach crate,$(TOOLS),$(eval $(call RUST_TOOL,$(crate))))

View File

@ -15,7 +15,24 @@
.PHONY: TAGS.emacs TAGS.vi
CTAGS_OPTS=--options=${CFG_SRC_DIR}/src/etc/ctags.rust -R ${CFG_SRC_DIR}/src
# This is using a blacklist approach, probably more durable than a whitelist.
# We exclude: external dependencies (llvm, rt/{msvc,vg}),
# tests (compiletest, test) and a couple of other things (rt/arch, etc)
CTAGS_LOCATIONS=$(patsubst ${CFG_SRC_DIR}src/llvm,, \
$(patsubst ${CFG_SRC_DIR}src/compiletest,, \
$(patsubst ${CFG_SRC_DIR}src/test,, \
$(patsubst ${CFG_SRC_DIR}src/etc,, \
$(patsubst ${CFG_SRC_DIR}src/rt,, \
$(patsubst ${CFG_SRC_DIR}src/rt/arch,, \
$(patsubst ${CFG_SRC_DIR}src/rt/msvc,, \
$(patsubst ${CFG_SRC_DIR}src/rt/vg,, \
$(wildcard ${CFG_SRC_DIR}src/*) $(wildcard ${CFG_SRC_DIR}src/rt/*) \
))))))))
CTAGS_OPTS=--options="${CFG_SRC_DIR}src/etc/ctags.rust" --languages=-javascript --recurse ${CTAGS_LOCATIONS}
# We could use `--languages=Rust`, but there is value in producing tags for the
# C++ parts of the code base too (at the time of writing, those are .h and .cpp
# files in src/rt, src/rt/sync and src/rustllvm); we mainly just want to
# exclude the external dependencies.
TAGS.emacs:
ctags -e -f $@ ${CTAGS_OPTS}

134
mk/debuggers.mk Normal file
View File

@ -0,0 +1,134 @@
# Copyright 2014 The Rust Project Developers. See the COPYRIGHT
# file at the top-level directory of this distribution and at
# http://rust-lang.org/COPYRIGHT.
#
# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
# option. This file may not be copied, modified, or distributed
# except according to those terms.
######################################################################
# Copy debugger related scripts
######################################################################
## GDB ##
DEBUGGER_RUSTLIB_ETC_SCRIPTS_GDB=gdb_load_rust_pretty_printers.py \
gdb_rust_pretty_printing.py
DEBUGGER_RUSTLIB_ETC_SCRIPTS_GDB_ABS=\
$(foreach script,$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_GDB), \
$(CFG_SRC_DIR)src/etc/$(script))
DEBUGGER_BIN_SCRIPTS_GDB=rust-gdb
DEBUGGER_BIN_SCRIPTS_GDB_ABS=\
$(foreach script,$(DEBUGGER_BIN_SCRIPTS_GDB), \
$(CFG_SRC_DIR)src/etc/$(script))
## LLDB ##
DEBUGGER_RUSTLIB_ETC_SCRIPTS_LLDB=lldb_rust_formatters.py
DEBUGGER_RUSTLIB_ETC_SCRIPTS_LLDB_ABS=\
$(foreach script,$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_LLDB), \
$(CFG_SRC_DIR)src/etc/$(script))
DEBUGGER_BIN_SCRIPTS_LLDB=rust-lldb
DEBUGGER_BIN_SCRIPTS_LLDB_ABS=\
$(foreach script,$(DEBUGGER_BIN_SCRIPTS_LLDB), \
$(CFG_SRC_DIR)src/etc/$(script))
## ALL ##
DEBUGGER_RUSTLIB_ETC_SCRIPTS_ALL=$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_GDB) \
$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_LLDB)
DEBUGGER_RUSTLIB_ETC_SCRIPTS_ALL_ABS=$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_GDB_ABS) \
$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_LLDB_ABS)
DEBUGGER_BIN_SCRIPTS_ALL=$(DEBUGGER_BIN_SCRIPTS_GDB) \
$(DEBUGGER_BIN_SCRIPTS_LLDB)
DEBUGGER_BIN_SCRIPTS_ALL_ABS=$(DEBUGGER_BIN_SCRIPTS_GDB_ABS) \
$(DEBUGGER_BIN_SCRIPTS_LLDB_ABS)
# $(1) - the stage to copy to
# $(2) - the host triple
define DEF_INSTALL_DEBUGGER_SCRIPTS_HOST
tmp/install-debugger-scripts$(1)_H_$(2)-gdb.done: \
$$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_GDB_ABS) \
$$(DEBUGGER_BIN_SCRIPTS_GDB_ABS)
$(Q)mkdir -p $$(HBIN$(1)_H_$(2))
$(Q)mkdir -p $$(HLIB$(1)_H_$(2))/rustlib/etc
$(Q)install $$(DEBUGGER_BIN_SCRIPTS_GDB_ABS) $$(HBIN$(1)_H_$(2))
$(Q)install $$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_GDB_ABS) $$(HLIB$(1)_H_$(2))/rustlib/etc
$(Q)touch $$@
tmp/install-debugger-scripts$(1)_H_$(2)-lldb.done: \
$$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_LLDB_ABS) \
$$(DEBUGGER_BIN_SCRIPTS_LLDB_ABS)
$(Q)mkdir -p $$(HBIN$(1)_H_$(2))
$(Q)mkdir -p $$(HLIB$(1)_H_$(2))/rustlib/etc
$(Q)install $$(DEBUGGER_BIN_SCRIPTS_LLDB_ABS) $$(HBIN$(1)_H_$(2))
$(Q)install $$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_LLDB_ABS) $$(HLIB$(1)_H_$(2))/rustlib/etc
$(Q)touch $$@
tmp/install-debugger-scripts$(1)_H_$(2)-all.done: \
$$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_ALL_ABS) \
$$(DEBUGGER_BIN_SCRIPTS_ALL_ABS)
$(Q)mkdir -p $$(HBIN$(1)_H_$(2))
$(Q)mkdir -p $$(HLIB$(1)_H_$(2))/rustlib/etc
$(Q)install $$(DEBUGGER_BIN_SCRIPTS_ALL_ABS) $$(HBIN$(1)_H_$(2))
$(Q)install $$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_ALL_ABS) $$(HLIB$(1)_H_$(2))/rustlib/etc
$(Q)touch $$@
tmp/install-debugger-scripts$(1)_H_$(2)-none.done:
$(Q)touch $$@
endef
# Expand host make-targets for all stages
$(foreach stage,$(STAGES), \
$(foreach host,$(CFG_HOST), \
$(eval $(call DEF_INSTALL_DEBUGGER_SCRIPTS_HOST,$(stage),$(host)))))
# $(1) is the stage number
# $(2) is the target triple
# $(3) is the host triple
define DEF_INSTALL_DEBUGGER_SCRIPTS_TARGET
tmp/install-debugger-scripts$(1)_T_$(2)_H_$(3)-gdb.done: \
$$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_GDB_ABS) \
$$(DEBUGGER_BIN_SCRIPTS_GDB_ABS)
$(Q)mkdir -p $$(TBIN$(1)_T_$(2)_H_$(3))
$(Q)mkdir -p $$(TLIB$(1)_T_$(2)_H_$(3))/rustlib/etc
$(Q)install $(DEBUGGER_BIN_SCRIPTS_GDB_ABS) $$(TBIN$(1)_T_$(2)_H_$(3))
$(Q)install $(DEBUGGER_RUSTLIB_ETC_SCRIPTS_GDB_ABS) $$(TLIB$(1)_T_$(2)_H_$(3))/rustlib/etc
$(Q)touch $$@
tmp/install-debugger-scripts$(1)_T_$(2)_H_$(3)-lldb.done: \
$$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_LLDB_ABS) \
$$(DEBUGGER_BIN_SCRIPTS_LLDB_ABS)
$(Q)mkdir -p $$(TBIN$(1)_T_$(2)_H_$(3))
$(Q)mkdir -p $$(TLIB$(1)_T_$(2)_H_$(3))/rustlib/etc
$(Q)install $(DEBUGGER_BIN_SCRIPTS_LLDB_ABS) $$(TBIN$(1)_T_$(2)_H_$(3))
$(Q)install $(DEBUGGER_RUSTLIB_ETC_SCRIPTS_LLDB_ABS) $$(TLIB$(1)_T_$(2)_H_$(3))/rustlib/etc
$(Q)touch $$@
tmp/install-debugger-scripts$(1)_T_$(2)_H_$(3)-all.done: \
$$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_ALL_ABS) \
$$(DEBUGGER_BIN_SCRIPTS_ALL_ABS)
$(Q)mkdir -p $$(TBIN$(1)_T_$(2)_H_$(3))
$(Q)mkdir -p $$(TLIB$(1)_T_$(2)_H_$(3))/rustlib/etc
$(Q)install $(DEBUGGER_BIN_SCRIPTS_ALL_ABS) $$(TBIN$(1)_T_$(2)_H_$(3))
$(Q)install $(DEBUGGER_RUSTLIB_ETC_SCRIPTS_ALL_ABS) $$(TLIB$(1)_T_$(2)_H_$(3))/rustlib/etc
$(Q)touch $$@
tmp/install-debugger-scripts$(1)_T_$(2)_H_$(3)-none.done:
$(Q)touch $$@
endef
# Expand target make-targets for all stages
$(foreach stage,$(STAGES), \
$(foreach target,$(CFG_TARGET), \
$(foreach host,$(CFG_HOST), \
$(eval $(call DEF_INSTALL_DEBUGGER_SCRIPTS_TARGET,$(stage),$(target),$(host))))))

View File

@ -1,72 +1,76 @@
# Copyright 2014 The Rust Project Developers. See the COPYRIGHT
# file at the top-level directory of this distribution and at
# http://rust-lang.org/COPYRIGHT.
#
# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
# option. This file may not be copied, modified, or distributed
# except according to those terms.
######################################################################
# Distribution
######################################################################
PKG_NAME := rust
PKG_DIR = $(PKG_NAME)-$(CFG_RELEASE)
PKG_TAR = $(PKG_DIR).tar.gz
# Primary targets:
#
# * dist - make all distribution artifacts
# * distcheck - sanity check dist artifacts
# * dist-tar-src - source tarballs
# * dist-tar-bins - Ad-hoc Unix binary installers
# * dist-docs - Stage docs for upload
ifdef CFG_ISCC
PKG_ISS = $(wildcard $(S)src/etc/pkg/*.iss)
PKG_ICO = $(S)src/etc/pkg/rust-logo.ico
PKG_EXE = $(PKG_DIR)-install.exe
endif
PKG_NAME := $(CFG_PACKAGE_NAME)
DOC_PKG_NAME := rust-docs-$(CFG_PACKAGE_VERS)
MINGW_PKG_NAME := rust-mingw-$(CFG_PACKAGE_VERS)
PKG_GITMODULES := $(S)src/libuv $(S)src/llvm
# License suitable for displaying in a popup
LICENSE.txt: $(S)COPYRIGHT $(S)LICENSE-APACHE $(S)LICENSE-MIT
cat $^ > $@
######################################################################
# Source tarball
######################################################################
PKG_TAR = dist/$(PKG_NAME)-src.tar.gz
PKG_GITMODULES := $(S)src/llvm $(S)src/compiler-rt \
$(S)src/rt/hoedown $(S)src/jemalloc
PKG_FILES := \
$(S)COPYRIGHT \
$(S)LICENSE-APACHE \
$(S)LICENSE-MIT \
$(S)AUTHORS.txt \
$(S)CONTRIBUTING.md \
$(S)README.md \
$(S)RELEASES.md \
$(S)configure $(S)Makefile.in \
$(S)man \
$(S)doc \
$(addprefix $(S)src/, \
README.txt \
driver \
librustpkg \
librusti \
librust \
librustc \
compiletest \
doc \
driver \
etc \
libextra \
libstd \
libsyntax \
$(foreach crate,$(CRATES),lib$(crate)) \
libcoretest \
libbacktrace \
rt \
librustdoc \
rustllvm \
snapshots.txt \
rust-installer \
rustbook \
test) \
$(PKG_GITMODULES) \
$(filter-out Makefile config.stamp config.mk, \
$(MKFILE_DEPS))
$(filter-out config.stamp, \
$(MKFILES_FOR_TARBALL))
UNROOTED_PKG_FILES := $(patsubst $(S)%,./%,$(PKG_FILES))
ifdef CFG_ISCC
LICENSE.txt: $(S)COPYRIGHT $(S)LICENSE-APACHE $(S)LICENSE-MIT
cat $^ > $@
%.iss: $(S)src/etc/pkg/%.iss
cp $< $@
%.ico: $(S)src/etc/pkg/%.ico
cp $< $@
$(PKG_EXE): rust.iss modpath.iss LICENSE.txt rust-logo.ico \
$(PKG_FILES) $(CSREQ3_T_$(CFG_BUILD_TRIPLE)_H_$(CFG_BUILD_TRIPLE))
@$(call E, ISCC: $@)
$(Q)"$(CFG_ISCC)" $<
endif
$(PKG_TAR): $(PKG_FILES)
@$(call E, making dist dir)
$(Q)rm -Rf dist
$(Q)mkdir -p dist/$(PKG_DIR)
$(Q)rm -Rf tmp/dist/$(PKG_NAME)
$(Q)mkdir -p tmp/dist/$(PKG_NAME)
$(Q)tar \
-C $(S) \
--exclude-vcs \
@ -77,42 +81,206 @@ $(PKG_TAR): $(PKG_FILES)
--exclude=*/llvm/test/*/*/*.ll \
--exclude=*/llvm/test/*/*/*.td \
--exclude=*/llvm/test/*/*/*.s \
-c $(UNROOTED_PKG_FILES) | tar -x -C dist/$(PKG_DIR)
$(Q)tar -czf $(PKG_TAR) -C dist $(PKG_DIR)
$(Q)rm -Rf dist
-c $(UNROOTED_PKG_FILES) | tar -x -C tmp/dist/$(PKG_NAME)
@$(call E, making $@)
$(Q)tar -czf $(PKG_TAR) -C tmp/dist $(PKG_NAME)
$(Q)rm -Rf tmp/dist/$(PKG_NAME)
dist-tar-src: $(PKG_TAR)
distcheck-tar-src: dist-tar-src
$(Q)rm -Rf tmp/distcheck/$(PKG_NAME)
$(Q)rm -Rf tmp/distcheck/srccheck
$(Q)mkdir -p tmp/distcheck
@$(call E, unpacking $(PKG_TAR) in tmp/distcheck/$(PKG_NAME))
$(Q)cd tmp/distcheck && tar -xzf ../../$(PKG_TAR)
@$(call E, configuring in tmp/distcheck/srccheck)
$(Q)mkdir -p tmp/distcheck/srccheck
$(Q)cd tmp/distcheck/srccheck && ../$(PKG_NAME)/configure
@$(call E, making 'check' in tmp/distcheck/srccheck)
$(Q)+make -C tmp/distcheck/srccheck check
@$(call E, making 'clean' in tmp/distcheck/srccheck)
$(Q)+make -C tmp/distcheck/srccheck clean
$(Q)rm -Rf tmp/distcheck/$(PKG_NAME)
$(Q)rm -Rf tmp/distcheck/srccheck
######################################################################
# Unix binary installer tarballs
######################################################################
NON_INSTALLED_PREFIXES=COPYRIGHT,LICENSE-APACHE,LICENSE-MIT,README.md,version
define DEF_INSTALLER
$$(eval $$(call DEF_PREPARE,dir-$(1)))
dist-install-dir-$(1): PREPARE_HOST=$(1)
dist-install-dir-$(1): PREPARE_TARGETS=$(2)
dist-install-dir-$(1): PREPARE_DEST_DIR=tmp/dist/$$(PKG_NAME)-$(1)-image
dist-install-dir-$(1): PREPARE_DIR_CMD=$(DEFAULT_PREPARE_DIR_CMD)
dist-install-dir-$(1): PREPARE_BIN_CMD=$(DEFAULT_PREPARE_BIN_CMD)
dist-install-dir-$(1): PREPARE_LIB_CMD=$(DEFAULT_PREPARE_LIB_CMD)
dist-install-dir-$(1): PREPARE_MAN_CMD=$(DEFAULT_PREPARE_MAN_CMD)
dist-install-dir-$(1): PREPARE_CLEAN=true
dist-install-dir-$(1): prepare-base-dir-$(1) docs compiler-docs
$$(Q)$$(PREPARE_MAN_CMD) $$(S)COPYRIGHT $$(PREPARE_DEST_DIR)
$$(Q)$$(PREPARE_MAN_CMD) $$(S)LICENSE-APACHE $$(PREPARE_DEST_DIR)
$$(Q)$$(PREPARE_MAN_CMD) $$(S)LICENSE-MIT $$(PREPARE_DEST_DIR)
$$(Q)$$(PREPARE_MAN_CMD) $$(S)README.md $$(PREPARE_DEST_DIR)
$$(Q)mkdir -p $$(PREPARE_DEST_DIR)/share/doc/rust
$$(Q)$$(PREPARE_MAN_CMD) $$(S)COPYRIGHT $$(PREPARE_DEST_DIR)/share/doc/rust
$$(Q)$$(PREPARE_MAN_CMD) $$(S)LICENSE-APACHE $$(PREPARE_DEST_DIR)/share/doc/rust
$$(Q)$$(PREPARE_MAN_CMD) $$(S)LICENSE-MIT $$(PREPARE_DEST_DIR)/share/doc/rust
$$(Q)$$(PREPARE_MAN_CMD) $$(S)README.md $$(PREPARE_DEST_DIR)/share/doc/rust
# This tiny morsel of metadata is used by rust-packaging
$$(Q)echo "$(CFG_VERSION)" > $$(PREPARE_DEST_DIR)/version
dist/$$(PKG_NAME)-$(1).tar.gz: dist-install-dir-$(1)
@$(call E, build: $$@)
# Copy essential gcc components into installer
ifdef CFG_WINDOWSY_$(1)
$$(Q)rm -Rf tmp/dist/win-rust-gcc-$(1)
$$(Q)$$(CFG_PYTHON) $$(S)src/etc/make-win-dist.py tmp/dist/$$(PKG_NAME)-$(1)-image tmp/dist/win-rust-gcc-$(1) $(1)
$$(Q)cp -r $$(S)src/etc/third-party tmp/dist/$$(PKG_NAME)-$(1)-image/share/doc/
endif
$$(Q)$$(S)src/rust-installer/gen-installer.sh \
--product-name=Rust \
--verify-bin=rustc \
--rel-manifest-dir=rustlib \
--success-message=Rust-is-ready-to-roll. \
--image-dir=tmp/dist/$$(PKG_NAME)-$(1)-image \
--work-dir=tmp/dist \
--output-dir=dist \
--non-installed-prefixes=$$(NON_INSTALLED_PREFIXES) \
--package-name=$$(PKG_NAME)-$(1) \
--component-name=rustc \
--legacy-manifest-dirs=rustlib,cargo
$$(Q)rm -R tmp/dist/$$(PKG_NAME)-$(1)-image
dist-doc-install-dir-$(1): docs compiler-docs
$$(Q)mkdir -p tmp/dist/$$(DOC_PKG_NAME)-$(1)-image/share/doc/rust
$$(Q)cp -r doc tmp/dist/$$(DOC_PKG_NAME)-$(1)-image/share/doc/rust/html
dist/$$(DOC_PKG_NAME)-$(1).tar.gz: dist-doc-install-dir-$(1)
@$(call E, build: $$@)
$$(Q)$$(S)src/rust-installer/gen-installer.sh \
--product-name=Rust-Documentation \
--rel-manifest-dir=rustlib \
--success-message=Rust-documentation-is-installed. \
--image-dir=tmp/dist/$$(DOC_PKG_NAME)-$(1)-image \
--work-dir=tmp/dist \
--output-dir=dist \
--package-name=$$(DOC_PKG_NAME)-$(1) \
--component-name=rust-docs \
--legacy-manifest-dirs=rustlib,cargo \
--bulk-dirs=share/doc/rust/html
$$(Q)rm -R tmp/dist/$$(DOC_PKG_NAME)-$(1)-image
dist-mingw-install-dir-$(1):
$$(Q)mkdir -p tmp/dist/rust-mingw-tmp-$(1)-image
$$(Q)rm -Rf tmp/dist/$$(MINGW_PKG_NAME)-$(1)-image
$$(Q)$$(CFG_PYTHON) $$(S)src/etc/make-win-dist.py \
tmp/dist/rust-mingw-tmp-$(1)-image tmp/dist/$$(MINGW_PKG_NAME)-$(1)-image $(1)
dist/$$(MINGW_PKG_NAME)-$(1).tar.gz: dist-mingw-install-dir-$(1)
@$(call E, build: $$@)
$$(Q)$$(S)src/rust-installer/gen-installer.sh \
--product-name=Rust-MinGW \
--rel-manifest-dir=rustlib \
--success-message=Rust-MinGW-is-installed. \
--image-dir=tmp/dist/$$(MINGW_PKG_NAME)-$(1)-image \
--work-dir=tmp/dist \
--output-dir=dist \
--package-name=$$(MINGW_PKG_NAME)-$(1) \
--component-name=rust-mingw \
--legacy-manifest-dirs=rustlib,cargo
$$(Q)rm -R tmp/dist/$$(MINGW_PKG_NAME)-$(1)-image
endef
ifneq ($(CFG_ENABLE_DIST_HOST_ONLY),)
$(foreach host,$(CFG_HOST),\
$(eval $(call DEF_INSTALLER,$(host),$(host))))
else
$(foreach host,$(CFG_HOST),\
$(eval $(call DEF_INSTALLER,$(host),$(CFG_TARGET))))
endif
dist-install-dirs: $(foreach host,$(CFG_HOST),dist-install-dir-$(host))
ifdef CFG_WINDOWSY_$(CFG_BUILD)
MAYBE_MINGW_TARBALLS=$(foreach host,$(CFG_HOST),dist/$(MINGW_PKG_NAME)-$(host).tar.gz)
endif
ifeq ($(CFG_DISABLE_DOCS),)
MAYBE_DOC_TARBALLS=$(foreach host,$(CFG_HOST),dist/$(DOC_PKG_NAME)-$(host).tar.gz)
endif
dist-tar-bins: $(foreach host,$(CFG_HOST),dist/$(PKG_NAME)-$(host).tar.gz) \
$(MAYBE_DOC_TARBALLS) $(MAYBE_MINGW_TARBALLS)
# Just try to run the compiler for the build host
distcheck-tar-bins: dist-tar-bins
@$(call E, checking binary tarball)
$(Q)rm -Rf tmp/distcheck/$(PKG_NAME)-$(CFG_BUILD)
$(Q)rm -Rf tmp/distcheck/tarbininstall
$(Q)mkdir -p tmp/distcheck
$(Q)cd tmp/distcheck && tar -xzf ../../dist/$(PKG_NAME)-$(CFG_BUILD).tar.gz
$(Q)mkdir -p tmp/distcheck/tarbininstall
$(Q)sh tmp/distcheck/$(PKG_NAME)-$(CFG_BUILD)/install.sh --prefix=tmp/distcheck/tarbininstall
$(Q)sh tmp/distcheck/$(PKG_NAME)-$(CFG_BUILD)/install.sh --prefix=tmp/distcheck/tarbininstall --uninstall
$(Q)rm -Rf tmp/distcheck/$(PKG_NAME)-$(CFG_BUILD)
$(Q)rm -Rf tmp/distcheck/tarbininstall
######################################################################
# Docs
######################################################################
# Just copy the docs to a folder under dist with the appropriate name
# for uploading to S3
dist-docs: docs compiler-docs
$(Q) rm -Rf dist/doc
$(Q) mkdir -p dist/doc/
$(Q) cp -r doc dist/doc/$(CFG_PACKAGE_VERS)
distcheck-docs: dist-docs
######################################################################
# Primary targets (dist, distcheck)
######################################################################
MAYBE_DIST_TAR_SRC=dist-tar-src
MAYBE_DISTCHECK_TAR_SRC=distcheck-tar-src
# FIXME #13224: On OS X don't produce tarballs simply because --exclude-vcs don't work.
# This is a huge hack because I just don't have time to figure out another solution.
ifeq ($(CFG_OSTYPE), apple-darwin)
MAYBE_DIST_TAR_SRC=
MAYBE_DISTCHECK_TAR_SRC=
endif
# Don't bother with source tarballs on windows just because we historically haven't.
ifeq ($(CFG_OSTYPE), pc-windows-gnu)
MAYBE_DIST_TAR_SRC=
MAYBE_DISTCHECK_TAR_SRC=
endif
ifneq ($(CFG_DISABLE_DOCS),)
MAYBE_DIST_DOCS=
MAYBE_DISTCHECK_DOCS=
else
MAYBE_DIST_DOCS=dist-docs
MAYBE_DISTCHECK_DOCS=distcheck-docs
endif
dist: $(MAYBE_DIST_TAR_SRC) dist-tar-bins $(MAYBE_DIST_DOCS)
distcheck: $(MAYBE_DISTCHECK_TAR_SRC) distcheck-tar-bins $(MAYBE_DISTCHECK_DOCS)
$(Q)rm -Rf tmp/distcheck
@echo
@echo -----------------------------------------------
@echo "Rust ready for distribution (see ./dist)"
@echo -----------------------------------------------
.PHONY: dist distcheck
ifdef CFG_WINDOWSY_$(CFG_BUILD_TRIPLE)
dist: $(PKG_EXE)
distcheck: dist
@echo
@echo -----------------------------------------------
@echo $(PKG_EXE) ready for distribution
@echo -----------------------------------------------
else
dist: $(PKG_TAR)
distcheck: $(PKG_TAR)
$(Q)rm -Rf dist
$(Q)mkdir -p dist
@$(call E, unpacking $(PKG_TAR) in dist/$(PKG_DIR))
$(Q)cd dist && tar -xzf ../$(PKG_TAR)
@$(call E, configuring in dist/$(PKG_DIR)-build)
$(Q)mkdir -p dist/$(PKG_DIR)-build
$(Q)cd dist/$(PKG_DIR)-build && ../$(PKG_DIR)/configure
@$(call E, making 'check' in dist/$(PKG_DIR)-build)
$(Q)+make -C dist/$(PKG_DIR)-build check
@$(call E, making 'clean' in dist/$(PKG_DIR)-build)
$(Q)+make -C dist/$(PKG_DIR)-build clean
$(Q)rm -Rf dist
@echo
@echo -----------------------------------------------
@echo $(PKG_TAR) ready for distribution
@echo -----------------------------------------------
endif

View File

@ -1,4 +1,4 @@
# Copyright 2012 The Rust Project Developers. See the COPYRIGHT
# Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
# file at the top-level directory of this distribution and at
# http://rust-lang.org/COPYRIGHT.
#
@ -9,228 +9,274 @@
# except according to those terms.
######################################################################
# Doc variables and rules
# The various pieces of standalone documentation.
#
# The DOCS variable is their names (with no file extension).
#
# PDF_DOCS lists the targets for which PDF documentation should be
# build.
#
# RUSTDOC_FLAGS_xyz variables are extra arguments to pass to the
# rustdoc invocation for xyz.
#
# RUSTDOC_DEPS_xyz are extra dependencies for the rustdoc invocation
# on xyz.
#
# L10N_LANGS are the languages for which the docs have been
# translated.
######################################################################
DOCS := index intro tutorial complement-bugreport \
complement-lang-faq complement-design-faq complement-project-faq \
rustdoc reference
DOCS :=
PDF_DOCS := reference
RUSTDOC_DEPS_reference := doc/full-toc.inc
RUSTDOC_FLAGS_reference := --html-in-header=doc/full-toc.inc
######################################################################
# Docs, from pandoc, rustdoc (which runs pandoc), and node
######################################################################
L10N_LANGS := ja
doc/rust.css: rust.css
@$(call E, cp: $@)
$(Q)cp -a $< $@ 2> /dev/null
# Generally no need to edit below here.
# The options are passed to the documentation generators.
RUSTDOC_HTML_OPTS_NO_CSS = --html-before-content=doc/version_info.html \
--html-in-header=doc/favicon.inc \
--html-after-content=doc/footer.inc \
--markdown-playground-url='http://play.rust-lang.org/'
RUSTDOC_HTML_OPTS = $(RUSTDOC_HTML_OPTS_NO_CSS) --markdown-css rust.css
PANDOC_BASE_OPTS := --standalone --toc --number-sections
PANDOC_TEX_OPTS = $(PANDOC_BASE_OPTS) --from=markdown --to=latex \
--include-before-body=doc/version.tex \
--include-before-body=doc/footer.tex \
--include-in-header=doc/uptack.tex
PANDOC_EPUB_OPTS = $(PANDOC_BASE_OPTS) --to=epub
# The rustdoc executable...
RUSTDOC_EXE = $(HBIN2_H_$(CFG_BUILD))/rustdoc$(X_$(CFG_BUILD))
# ...with rpath included in case --disable-rpath was provided to
# ./configure
RUSTDOC = $(RPATH_VAR2_T_$(CFG_BUILD)_H_$(CFG_BUILD)) $(RUSTDOC_EXE)
# The rustbook executable...
RUSTBOOK_EXE = $(HBIN2_H_$(CFG_BUILD))/rustbook$(X_$(CFG_BUILD))
# ...with rpath included in case --disable-rpath was provided to
# ./configure
RUSTBOOK = $(RPATH_VAR2_T_$(CFG_BUILD)_H_$(CFG_BUILD)) $(RUSTBOOK_EXE)
D := $(S)src/doc
DOC_TARGETS := trpl
COMPILER_DOC_TARGETS :=
DOC_L10N_TARGETS :=
# If NO_REBUILD is set then break the dependencies on rustdoc so we
# build the documentation without having to rebuild rustdoc.
ifeq ($(NO_REBUILD),)
HTML_DEPS := $(RUSTDOC_EXE)
else
HTML_DEPS :=
endif
# Check for the various external utilities for the EPUB/PDF docs:
ifeq ($(CFG_LUALATEX),)
$(info cfg: no lualatex found, deferring to xelatex)
ifeq ($(CFG_XELATEX),)
$(info cfg: no xelatex found, deferring to pdflatex)
ifeq ($(CFG_PDFLATEX),)
$(info cfg: no pdflatex found, disabling LaTeX docs)
NO_PDF_DOCS = 1
else
CFG_LATEX := $(CFG_PDFLATEX)
endif
else
CFG_LATEX := $(CFG_XELATEX)
XELATEX = 1
endif
else
CFG_LATEX := $(CFG_LUALATEX)
endif
doc/manual.css: manual.css
@$(call E, cp: $@)
$(Q)cp -a $< $@ 2> /dev/null
ifeq ($(CFG_PANDOC),)
$(info cfg: no pandoc found, omitting docs)
NO_DOCS = 1
$(info cfg: no pandoc found, omitting PDF and EPUB docs)
ONLY_HTML_DOCS = 1
endif
ifeq ($(CFG_NODE),)
$(info cfg: no node found, omitting docs)
NO_DOCS = 1
endif
ifneq ($(NO_DOCS),1)
DOCS += doc/rust.html
doc/rust.html: rust.md doc/version_info.html doc/rust.css doc/manual.css
@$(call E, pandoc: $@)
$(Q)$(CFG_NODE) $(S)doc/prep.js --highlight $< | \
"$(CFG_PANDOC)" \
--standalone --toc \
--section-divs \
--number-sections \
--from=markdown --to=html \
--css=rust.css \
--css=manual.css \
--include-before-body=doc/version_info.html \
--output=$@
DOCS += doc/rust.tex
doc/rust.tex: rust.md doc/version.md
@$(call E, pandoc: $@)
$(Q)$(CFG_NODE) $(S)doc/prep.js $< | \
"$(CFG_PANDOC)" \
--standalone --toc \
--number-sections \
--include-before-body=doc/version.md \
--from=markdown --to=latex \
--output=$@
DOCS += doc/rustpkg.html
doc/rustpkg.html: rustpkg.md doc/version_info.html doc/rust.css doc/manual.css
@$(call E, pandoc: $@)
$(Q)$(CFG_NODE) $(S)doc/prep.js --highlight $< | \
"$(CFG_PANDOC)" \
--standalone --toc \
--section-divs \
--number-sections \
--from=markdown --to=html \
--css=rust.css \
--css=manual.css \
--include-before-body=doc/version_info.html \
--output=$@
DOCS += doc/tutorial.html
doc/tutorial.html: tutorial.md doc/version_info.html doc/rust.css
@$(call E, pandoc: $@)
$(Q)$(CFG_NODE) $(S)doc/prep.js --highlight $< | \
$(CFG_PANDOC) --standalone --toc \
--section-divs --number-sections \
--from=markdown --to=html --css=rust.css \
--include-before-body=doc/version_info.html \
--output=$@
DOCS += doc/tutorial-macros.html
doc/tutorial-macros.html: tutorial-macros.md doc/version_info.html \
doc/rust.css
@$(call E, pandoc: $@)
$(Q)$(CFG_NODE) $(S)doc/prep.js --highlight $< | \
$(CFG_PANDOC) --standalone --toc \
--section-divs --number-sections \
--from=markdown --to=html --css=rust.css \
--include-before-body=doc/version_info.html \
--output=$@
DOCS += doc/tutorial-container.html
doc/tutorial-container.html: tutorial-container.md doc/version_info.html doc/rust.css
@$(call E, pandoc: $@)
$(Q)$(CFG_NODE) $(S)doc/prep.js --highlight $< | \
$(CFG_PANDOC) --standalone --toc \
--section-divs --number-sections \
--from=markdown --to=html --css=rust.css \
--include-before-body=doc/version_info.html \
--output=$@
DOCS += doc/tutorial-ffi.html
doc/tutorial-ffi.html: tutorial-ffi.md doc/version_info.html doc/rust.css
@$(call E, pandoc: $@)
$(Q)$(CFG_NODE) $(S)doc/prep.js --highlight $< | \
$(CFG_PANDOC) --standalone --toc \
--section-divs --number-sections \
--from=markdown --to=html --css=rust.css \
--include-before-body=doc/version_info.html \
--output=$@
DOCS += doc/tutorial-borrowed-ptr.html
doc/tutorial-borrowed-ptr.html: tutorial-borrowed-ptr.md doc/version_info.html doc/rust.css
@$(call E, pandoc: $@)
$(Q)$(CFG_NODE) $(S)doc/prep.js --highlight $< | \
$(CFG_PANDOC) --standalone --toc \
--section-divs --number-sections \
--from=markdown --to=html --css=rust.css \
--include-before-body=doc/version_info.html \
--output=$@
DOCS += doc/tutorial-tasks.html
doc/tutorial-tasks.html: tutorial-tasks.md doc/version_info.html doc/rust.css
@$(call E, pandoc: $@)
$(Q)$(CFG_NODE) $(S)doc/prep.js --highlight $< | \
$(CFG_PANDOC) --standalone --toc \
--section-divs --number-sections \
--from=markdown --to=html --css=rust.css \
--include-before-body=doc/version_info.html \
--output=$@
ifeq ($(CFG_PDFLATEX),)
$(info cfg: no pdflatex found, omitting doc/rust.pdf)
else
ifeq ($(CFG_XETEX),)
$(info cfg: no xetex found, disabling doc/rust.pdf)
else
ifeq ($(CFG_LUATEX),)
$(info cfg: lacking luatex, disabling pdflatex)
else
DOCS += doc/rust.pdf
doc/rust.pdf: doc/rust.tex
@$(call E, pdflatex: $@)
$(Q)$(CFG_PDFLATEX) \
-interaction=batchmode \
-output-directory=doc \
$<
endif
endif
endif
endif # No pandoc / node
######################################################################
# LLnextgen (grammar analysis from refman)
# Rust version
######################################################################
ifeq ($(CFG_LLNEXTGEN),)
$(info cfg: no llnextgen found, omitting grammar-verification)
doc/version.tex: $(MKFILE_DEPS) $(wildcard $(D)/*.*) | doc/
@$(call E, version-stamp: $@)
$(Q)echo "$(CFG_VERSION)" >$@
HTML_DEPS += doc/version_info.html
doc/version_info.html: $(D)/version_info.html.template $(MKFILE_DEPS) \
$(wildcard $(D)/*.*) | doc/
@$(call E, version-info: $@)
$(Q)sed -e "s/VERSION/$(CFG_RELEASE)/; \
s/SHORT_HASH/$(CFG_SHORT_VER_HASH)/; \
s/STAMP/$(CFG_VER_HASH)/;" $< >$@
GENERATED += doc/version.tex doc/version_info.html
######################################################################
# Docs, from rustdoc and sometimes pandoc
######################################################################
doc/:
@mkdir -p $@
HTML_DEPS += doc/rust.css
doc/rust.css: $(D)/rust.css | doc/
@$(call E, cp: $@)
$(Q)cp -a $< $@ 2> /dev/null
HTML_DEPS += doc/favicon.inc
doc/favicon.inc: $(D)/favicon.inc | doc/
@$(call E, cp: $@)
$(Q)cp -a $< $@ 2> /dev/null
doc/full-toc.inc: $(D)/full-toc.inc | doc/
@$(call E, cp: $@)
$(Q)cp -a $< $@ 2> /dev/null
HTML_DEPS += doc/footer.inc
doc/footer.inc: $(D)/footer.inc | doc/
@$(call E, cp: $@)
$(Q)cp -a $< $@ 2> /dev/null
# The (english) documentation for each doc item.
define DEF_SHOULD_BUILD_PDF_DOC
SHOULD_BUILD_PDF_DOC_$(1) = 1
endef
$(foreach docname,$(PDF_DOCS),$(eval $(call DEF_SHOULD_BUILD_PDF_DOC,$(docname))))
doc/footer.tex: $(D)/footer.inc | doc/
@$(call E, pandoc: $@)
$(CFG_PANDOC) --from=html --to=latex $< --output=$@
doc/uptack.tex: $(D)/uptack.tex | doc/
$(Q)cp $< $@
# HTML (rustdoc)
DOC_TARGETS += doc/not_found.html
doc/not_found.html: $(D)/not_found.md $(HTML_DEPS) | doc/
@$(call E, rustdoc: $@)
$(Q)$(RUSTDOC) $(RUSTDOC_HTML_OPTS_NO_CSS) \
--markdown-css http://doc.rust-lang.org/rust.css $<
define DEF_DOC
# HTML (rustdoc)
DOC_TARGETS += doc/$(1).html
doc/$(1).html: $$(D)/$(1).md $$(HTML_DEPS) $$(RUSTDOC_DEPS_$(1)) | doc/
@$$(call E, rustdoc: $$@)
$$(Q)$$(RUSTDOC) $$(RUSTDOC_HTML_OPTS) $$(RUSTDOC_FLAGS_$(1)) $$<
ifneq ($(ONLY_HTML_DOCS),1)
# EPUB (pandoc directly)
DOC_TARGETS += doc/$(1).epub
doc/$(1).epub: $$(D)/$(1).md | doc/
@$$(call E, pandoc: $$@)
$$(CFG_PANDOC) $$(PANDOC_EPUB_OPTS) $$< --output=$$@
# PDF (md =(pandoc)=> tex =(pdflatex)=> pdf)
DOC_TARGETS += doc/$(1).tex
doc/$(1).tex: $$(D)/$(1).md doc/uptack.tex doc/footer.tex doc/version.tex | doc/
@$$(call E, pandoc: $$@)
$$(CFG_PANDOC) $$(PANDOC_TEX_OPTS) $$< --output=$$@
ifneq ($(NO_PDF_DOCS),1)
ifeq ($$(SHOULD_BUILD_PDF_DOC_$(1)),1)
DOC_TARGETS += doc/$(1).pdf
ifneq ($(XELATEX),1)
doc/$(1).pdf: doc/$(1).tex
@$$(call E, latex compiler: $$@)
$$(Q)$$(CFG_LATEX) \
-interaction=batchmode \
-output-directory=doc \
$$<
else
.PHONY: verify-grammar
# The version of xelatex on the snap bots seemingly ingores -output-directory
# So we'll output to . and move to the doc directory manually.
# This will leave some intermediate files in the build directory.
doc/$(1).pdf: doc/$(1).tex
@$$(call E, latex compiler: $$@)
$$(Q)$$(CFG_LATEX) \
-interaction=batchmode \
-output-directory=. \
$$<
$$(Q)mv ./$(1).pdf $$@
endif # XELATEX
endif # SHOULD_BUILD_PDF_DOCS_$(1)
endif # NO_PDF_DOCS
doc/rust.g: rust.md $(S)src/etc/extract_grammar.py
@$(call E, extract_grammar: $@)
$(Q)$(CFG_PYTHON) $(S)src/etc/extract_grammar.py $< >$@
endif # ONLY_HTML_DOCS
verify-grammar: doc/rust.g
@$(call E, LLnextgen: $<)
$(Q)$(CFG_LLNEXTGEN) --generate-lexer-wrapper=no $< >$@
$(Q)rm -f doc/rust.c doc/rust.h
endif
endef
$(foreach docname,$(DOCS),$(eval $(call DEF_DOC,$(docname))))
######################################################################
# Rustdoc (libstd/extra)
######################################################################
ifeq ($(CFG_PANDOC),)
$(info cfg: no pandoc found, omitting library doc build)
else
# The rustdoc executable
RUSTDOC = $(HBIN2_H_$(CFG_BUILD_TRIPLE))/rustdoc$(X_$(CFG_BUILD_TRIPLE))
# The library documenting macro
# $(1) - The output directory
# $(2) - The crate file
# $(3) - The crate soruce files
define libdoc
doc/$(1)/index.html: $(2) $(3) $$(RUSTDOC) doc/$(1)/rust.css
@$$(call E, rustdoc: $$@)
$(Q)$(RUSTDOC) $(2) --output-dir=doc/$(1)
#
# $(1) - The crate name (std/extra)
#
# Passes --cfg stage2 to rustdoc because it uses the stage2 librustc.
define DEF_LIB_DOC
doc/$(1)/rust.css: rust.css
@$$(call E, cp: $$@)
$(Q)cp $$< $$@
DOCS += doc/$(1)/index.html
endef
$(eval $(call libdoc,std,$(STDLIB_CRATE),$(STDLIB_INPUTS)))
$(eval $(call libdoc,extra,$(EXTRALIB_CRATE),$(EXTRALIB_INPUTS)))
# If NO_REBUILD is set then break the dependencies on rustdoc so we
# build crate documentation without having to rebuild rustdoc.
ifeq ($(NO_REBUILD),)
LIB_DOC_DEP_$(1) = \
$$(CRATEFILE_$(1)) \
$$(RSINPUTS_$(1)) \
$$(RUSTDOC_EXE) \
$$(foreach dep,$$(RUST_DEPS_$(1)), \
$$(TLIB2_T_$(CFG_BUILD)_H_$(CFG_BUILD))/stamp.$$(dep)) \
$$(foreach dep,$$(filter $$(DOC_CRATES), $$(RUST_DEPS_$(1))), \
doc/$$(dep)/)
else
LIB_DOC_DEP_$(1) = $$(CRATEFILE_$(1)) $$(RSINPUTS_$(1))
endif
doc/$(1)/:
$$(Q)mkdir -p $$@
$(2) += doc/$(1)/index.html
doc/$(1)/index.html: CFG_COMPILER_HOST_TRIPLE = $(CFG_TARGET)
doc/$(1)/index.html: $$(LIB_DOC_DEP_$(1)) doc/$(1)/
@$$(call E, rustdoc: $$@)
$$(Q)CFG_LLVM_LINKAGE_FILE=$$(LLVM_LINKAGE_PATH_$(CFG_BUILD)) \
$$(RUSTDOC) --cfg dox --cfg stage2 $$<
endef
$(foreach crate,$(DOC_CRATES),$(eval $(call DEF_LIB_DOC,$(crate),DOC_TARGETS)))
$(foreach crate,$(COMPILER_DOC_CRATES),$(eval $(call DEF_LIB_DOC,$(crate),COMPILER_DOC_TARGETS)))
ifdef CFG_DISABLE_DOCS
$(info cfg: disabling doc build (CFG_DISABLE_DOCS))
DOCS :=
DOC_TARGETS :=
COMPILER_DOC_TARGETS :=
endif
docs: $(DOC_TARGETS)
compiler-docs: $(COMPILER_DOC_TARGETS)
doc/version.md: $(MKFILE_DEPS) $(wildcard $(S)doc/*.*)
@$(call E, version-stamp: $@)
$(Q)echo "$(CFG_VERSION)" >$@
trpl: doc/book/index.html
doc/version_info.html: version_info.html.template $(MKFILE_DEPS) \
$(wildcard $(S)doc/*.*)
@$(call E, version-info: $@)
sed -e "s/VERSION/$(CFG_RELEASE)/; s/SHORT_HASH/$(shell echo \
$(CFG_VER_HASH) | head -c 8)/;\
s/STAMP/$(CFG_VER_HASH)/;" $< >$@
GENERATED += doc/version.md doc/version_info.html
docs: $(DOCS)
doc/book/index.html: $(RUSTBOOK_EXE) $(wildcard $(S)/src/doc/trpl/*.md)
$(Q)rm -rf doc/book
$(Q)$(RUSTBOOK) build $(S)src/doc/trpl doc/book

69
mk/grammar.mk Normal file
View File

@ -0,0 +1,69 @@
# Copyright 2014 The Rust Project Developers. See the COPYRIGHT
# file at the top-level directory of this distribution and at
# http://rust-lang.org/COPYRIGHT.
#
# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
# option. This file may not be copied, modified, or distributed
# except according to those terms.
BG = $(CFG_BUILD_DIR)/grammar/
SG = $(S)src/grammar/
B = $(CFG_BUILD_DIR)/$(CFG_BUILD)/stage2/
L = $(B)lib/rustlib/$(CFG_BUILD)/lib
LD = $(CFG_BUILD)/stage2/lib/rustlib/$(CFG_BUILD)/lib/
RUSTC = $(STAGE2_T_$(CFG_BUILD)_H_$(CFG_BUILD))
# Run the reference lexer against libsyntax and compare the tokens and spans.
# If "// ignore-lexer-test" is present in the file, it will be ignored.
#
# $(1) is the file to test.
define LEXER_TEST
grep "// ignore-lexer-test" $(1) ; \
if [ $$? -eq 1 ]; then \
CLASSPATH=$(B)grammar $(CFG_GRUN) RustLexer tokens -tokens < $(1) \
| $(B)grammar/verify $(1) ; \
fi
endef
$(BG):
$(Q)mkdir -p $(BG)
$(BG)RustLexer.class: $(BG) $(SG)RustLexer.g4
$(Q)$(CFG_ANTLR4) -o $(BG) $(SG)RustLexer.g4
$(Q)$(CFG_JAVAC) -d $(BG) $(BG)RustLexer.java
check-build-lexer-verifier: $(BG)verify
ifeq ($(NO_REBUILD),)
VERIFY_DEPS := rustc-stage2-H-$(CFG_BUILD) $(LD)stamp.rustc
else
VERIFY_DEPS :=
endif
$(BG)verify: $(BG) $(SG)verify.rs $(VERIFY_DEPS)
$(Q)$(RUSTC) --out-dir $(BG) -L $(L) $(SG)verify.rs
ifdef CFG_JAVAC
ifdef CFG_ANTLR4
ifdef CFG_GRUN
check-lexer: $(BG) $(BG)RustLexer.class check-build-lexer-verifier
$(info Verifying libsyntax against the reference lexer ...)
$(Q)$(SG)check.sh $(S) "$(BG)" \
"$(CFG_GRUN)" "$(BG)verify" "$(BG)RustLexer.tokens"
else
$(info cfg: grun not available, skipping lexer test...)
check-lexer:
endif
else
$(info cfg: antlr4 not available, skipping lexer test...)
check-lexer:
endif
else
$(info cfg: javac not available, skipping lexer test...)
check-lexer:
endif

View File

@ -8,136 +8,77 @@
# option. This file may not be copied, modified, or distributed
# except according to those terms.
# CP_HOST_STAGE_N template: arg 1 is the N we're promoting *from*, arg
# 2 is N+1. Must be invoked to promote target artifacts to host
# artifacts for stage 1-3 (stage0 host artifacts come from the
# snapshot). Arg 3 is the triple we're copying FROM and arg 4 is the
# triple we're copying TO.
# Generic rule for copying any target crate to a host crate. This rule will also
# promote any dependent rust crates up to their host locations as well
#
# The easiest way to read this template is to assume we're promoting
# stage1 to stage2 and mentally gloss $(1) as 1, $(2) as 2.
# $(1) - the stage to copy from
# $(2) - the stage to copy to
# $(3) - the host triple
# $(4) - the target triple (same as $(3))
# $(5) - the name of the crate being processed
define CP_HOST_STAGE_N_CRATE
define CP_HOST_STAGE_N
# Host libraries and executables (stage$(2)/bin/rustc and its runtime needs)
# Note: $(3) and $(4) are both the same!
$$(HBIN$(2)_H_$(4))/rustc$$(X_$(4)): \
$$(TBIN$(1)_T_$(4)_H_$(3))/rustc$$(X_$(4)) \
$$(HLIB$(2)_H_$(4))/$(CFG_RUNTIME_$(4)) \
$$(HLIB$(2)_H_$(4))/$(CFG_RUSTLLVM_$(4)) \
$$(HLIB$(2)_H_$(4))/$(CFG_LIBRUSTC_$(4)) \
$$(HSTDLIB_DEFAULT$(2)_H_$(4)) \
$$(HEXTRALIB_DEFAULT$(2)_H_$(4)) \
| $$(HBIN$(2)_H_$(4))/
@$$(call E, cp: $$@)
$$(Q)cp $$< $$@
$$(HLIB$(2)_H_$(4))/$(CFG_LIBRUSTC_$(4)): \
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTC_$(4)) \
$$(HLIB$(2)_H_$(4))/$(CFG_LIBSYNTAX_$(4)) \
$$(HLIB$(2)_H_$(4))/$(CFG_RUNTIME_$(4)) \
$$(HLIB$(2)_H_$(4))/$(CFG_RUSTLLVM_$(4)) \
$$(HSTDLIB_DEFAULT$(2)_H_$(4)) \
$$(HEXTRALIB_DEFAULT$(2)_H_$(4)) \
ifeq ($$(ONLY_RLIB_$(5)),)
$$(HLIB$(2)_H_$(4))/stamp.$(5): \
$$(TLIB$(1)_T_$(3)_H_$(4))/stamp.$(5) \
$$(RUST_DEPS_$(5):%=$$(HLIB$(2)_H_$(4))/stamp.%) \
| $$(HLIB$(2)_H_$(4))/
@$$(call E, cp: $$@)
@$$(call E, cp: $$(@D)/lib$(5))
$$(call REMOVE_ALL_OLD_GLOB_MATCHES, \
$$(dir $$@)$$(call CFG_LIB_GLOB_$(3),$(5)))
$$(Q)cp $$< $$@
$$(Q)cp -R $$(TLIB$(1)_T_$(4)_H_$(3))/$(LIBRUSTC_GLOB_$(4)) \
$(wildcard $$(TLIB$(1)_T_$(4)_H_$(3))/$(LIBRUSTC_DSYM_GLOB_$(4))) \
$$(Q)cp -R $$(TLIB$(1)_T_$(3)_H_$(4))/$$(call CFG_LIB_GLOB_$(3),$(5)) \
$$(HLIB$(2)_H_$(4))
$$(HLIB$(2)_H_$(4))/$(CFG_LIBSYNTAX_$(4)): \
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBSYNTAX_$(4)) \
$$(HLIB$(2)_H_$(4))/$(CFG_RUNTIME_$(4)) \
$$(HLIB$(2)_H_$(4))/$(CFG_RUSTLLVM_$(4)) \
$$(HSTDLIB_DEFAULT$(2)_H_$(4)) \
$$(HEXTRALIB_DEFAULT$(2)_H_$(4)) \
| $$(HLIB$(2)_H_$(4))/
@$$(call E, cp: $$@)
$$(Q)cp $$< $$@
$$(Q)cp -R $$(TLIB$(1)_T_$(4)_H_$(3))/$(LIBSYNTAX_GLOB_$(4)) \
$$(wildcard $$(TLIB$(1)_T_$(4)_H_$(3))/$(LIBSYNTAX_DSYM_GLOB_$(4))) \
$$(HLIB$(2)_H_$(4))
$$(HLIB$(2)_H_$(4))/$(CFG_RUNTIME_$(4)): \
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_RUNTIME_$(4)) \
| $$(HLIB$(2)_H_$(4))/
@$$(call E, cp: $$@)
$$(Q)cp $$< $$@
$$(HLIB$(2)_H_$(4))/$(CFG_STDLIB_$(4)): \
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_STDLIB_$(4)) \
$$(HLIB$(2)_H_$(4))/$(CFG_RUNTIME_$(4)) \
| $$(HLIB$(2)_H_$(4))/
@$$(call E, cp: $$@)
$$(Q)cp $$< $$@
# Subtle: We do not let the shell expand $(STDLIB_DSYM_GLOB) directly rather
# we use Make's $$(wildcard) facility. The reason is that, on mac, when using
# USE_SNAPSHOT_STDLIB, we copy the std.dylib file out of the snapshot.
# In that case, there is no .dSYM file. Annoyingly, bash then refuses to expand
# glob, and cp reports an error because libstd-*.dylib.dsym does not exist.
# Make instead expands the glob to nothing, which gives us the correct behavior.
# (Copy .dsym file if it exists, but do nothing otherwise)
$$(Q)cp -R $$(TLIB$(1)_T_$(4)_H_$(3))/$(STDLIB_GLOB_$(4)) \
$$(wildcard $$(TLIB$(1)_T_$(4)_H_$(3))/$(STDLIB_DSYM_GLOB_$(4))) \
$$(HLIB$(2)_H_$(4))
$$(HLIB$(2)_H_$(4))/$(CFG_EXTRALIB_$(4)): \
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_EXTRALIB_$(4)) \
$$(HLIB$(2)_H_$(4))/$(CFG_STDLIB_$(4)) \
$$(HLIB$(2)_H_$(4))/$(CFG_RUNTIME_$(4)) \
| $$(HLIB$(2)_H_$(4))/
@$$(call E, cp: $$@)
$$(Q)cp $$< $$@
$$(Q)cp -R $$(TLIB$(1)_T_$(4)_H_$(3))/$(EXTRALIB_GLOB_$(4)) \
$$(wildcard $$(TLIB$(1)_T_$(4)_H_$(3))/$(EXTRALIB_DSYM_GLOB_$(4))) \
$$(HLIB$(2)_H_$(4))
$$(HLIB$(2)_H_$(4))/libstd.rlib: \
$$(TLIB$(1)_T_$(4)_H_$(3))/libstd.rlib \
$$(HLIB$(2)_H_$(4))/$$(CFG_RUNTIME_$(4)) \
| $$(HLIB$(2)_H_$(4))/
@$$(call E, cp: $$@)
$$(Q)cp $$< $$@
$$(HLIB$(2)_H_$(4))/libextra.rlib: \
$$(TLIB$(1)_T_$(4)_H_$(3))/libextra.rlib \
$$(HLIB$(2)_H_$(4))/libstd.rlib \
$$(HLIB$(2)_H_$(4))/$$(CFG_RUNTIME_$(4)) \
| $$(HLIB$(2)_H_$(4))/
@$$(call E, cp: $$@)
$$(Q)cp $$< $$@
$$(HLIB$(2)_H_$(4))/librustc.rlib: \
$$(TLIB$(1)_T_$(4)_H_$(3))/librustc.rlib \
$$(HLIB$(2)_H_$(4))/libstd.rlib \
$$(HLIB$(2)_H_$(4))/libextra.rlib \
$$(HLIB$(2)_H_$(4))/$$(CFG_RUNTIME_$(4)) \
| $$(HLIB$(2)_H_$(4))/
@$$(call E, cp: $$@)
$$(Q)cp $$< $$@
$$(HLIB$(2)_H_$(4))/$(CFG_RUSTLLVM_$(4)): \
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_RUSTLLVM_$(4)) \
| $$(HLIB$(2)_H_$(4))/
@$$(call E, cp: $$@)
$$(Q)cp $$< $$@
$$(HBIN$(2)_H_$(4))/:
mkdir -p $$@
ifneq ($(CFG_LIBDIR),bin)
$$(HLIB$(2)_H_$(4))/:
mkdir -p $$@
$$(call LIST_ALL_OLD_GLOB_MATCHES, \
$$(dir $$@)$$(call CFG_LIB_GLOB_$(3),$(5)))
else
$$(HLIB$(2)_H_$(4))/stamp.$(5):
$$(Q)touch $$@
endif
endef
$(foreach t,$(CFG_HOST_TRIPLES), \
$(eval $(call CP_HOST_STAGE_N,0,1,$(t),$(t))) \
$(eval $(call CP_HOST_STAGE_N,1,2,$(t),$(t))) \
# Same as the above macro, but for tools instead of crates
define CP_HOST_STAGE_N_TOOL
$$(HBIN$(2)_H_$(4))/$(5)$$(X_$(3)): \
$$(TBIN$(1)_T_$(3)_H_$(4))/$(5)$$(X_$(3)) \
$$(TOOL_DEPS_$(5):%=$$(HLIB$(2)_H_$(4))/stamp.%) \
| $$(HBIN$(2)_H_$(4))/
@$$(call E, cp: $$@)
$$(Q)cp $$< $$@
endef
# Miscellaneous rules for just making a few directories.
#
# $(1) - the stage to copy from
# $(2) - the stage to copy to
# $(3) - the target triple
# $(4) - the host triple (same as $(3))
define CP_HOST_STAGE_N
ifneq ($(CFG_LIBDIR_RELATIVE),bin)
$$(HLIB$(2)_H_$(4))/:
@mkdir -p $$@
endif
endef
$(foreach t,$(CFG_HOST), \
$(eval $(call CP_HOST_STAGE_N,0,1,$(t),$(t))) \
$(eval $(call CP_HOST_STAGE_N,1,2,$(t),$(t))) \
$(eval $(call CP_HOST_STAGE_N,2,3,$(t),$(t))))
$(foreach crate,$(CRATES), \
$(foreach t,$(CFG_HOST), \
$(eval $(call CP_HOST_STAGE_N_CRATE,0,1,$(t),$(t),$(crate))) \
$(eval $(call CP_HOST_STAGE_N_CRATE,1,2,$(t),$(t),$(crate))) \
$(eval $(call CP_HOST_STAGE_N_CRATE,2,3,$(t),$(t),$(crate)))))
$(foreach tool,$(TOOLS), \
$(foreach t,$(CFG_HOST), \
$(eval $(call CP_HOST_STAGE_N_TOOL,0,1,$(t),$(t),$(tool))) \
$(eval $(call CP_HOST_STAGE_N_TOOL,1,2,$(t),$(t),$(tool))) \
$(eval $(call CP_HOST_STAGE_N_TOOL,2,3,$(t),$(t),$(tool)))))

View File

@ -8,152 +8,55 @@
# option. This file may not be copied, modified, or distributed
# except according to those terms.
# FIXME: Docs are currently not installed from the stageN dirs.
# For consistency it might be desirable for stageN to be an exact
# mirror of the installation directory structure.
# Installation macro. Call with source directory as arg 1,
# destination directory as arg 2, and filename/libname-glob as arg 3
ifdef VERBOSE
INSTALL = install -m755 $(1)/$(3) $(2)/$(3)
INSTALL_LIB = install -m644 `ls -drt1 $(1)/$(3) | tail -1` $(2)/
ifdef CFG_DISABLE_VERIFY_INSTALL
MAYBE_DISABLE_VERIFY=--disable-verify
else
INSTALL = $(Q)$(call E, install: $(2)/$(3)) && install -m755 $(1)/$(3) $(2)/$(3)
INSTALL_LIB = $(Q)$(call E, install_lib: $(2)/$(3)) && \
install -m644 `ls -drt1 $(1)/$(3) | tail -1` $(2)/
MAYBE_DISABLE_VERIFY=
endif
# The stage we install from
ISTAGE = 2
install:
ifeq (root user, $(USER) $(patsubst %,user,$(SUDO_USER)))
# Build the dist as the original user
$(Q)sudo -u "$$SUDO_USER" $(MAKE) prepare_install
else
$(Q)$(MAKE) prepare_install
endif
ifeq ($(CFG_DISABLE_DOCS),)
$(Q)cd tmp/empty_dir && sh ../../tmp/dist/$(DOC_PKG_NAME)-$(CFG_BUILD)/install.sh --prefix="$(DESTDIR)$(CFG_PREFIX)" --libdir="$(DESTDIR)$(CFG_LIBDIR)" --mandir="$(DESTDIR)$(CFG_MANDIR)" "$(MAYBE_DISABLE_VERIFY)"
endif
$(Q)cd tmp/empty_dir && sh ../../tmp/dist/$(PKG_NAME)-$(CFG_BUILD)/install.sh --prefix="$(DESTDIR)$(CFG_PREFIX)" --libdir="$(DESTDIR)$(CFG_LIBDIR)" --mandir="$(DESTDIR)$(CFG_MANDIR)" "$(MAYBE_DISABLE_VERIFY)"
# Remove tmp files because it's a decent amount of disk space
$(Q)rm -R tmp/dist
PREFIX_ROOT = $(CFG_PREFIX)
PREFIX_BIN = $(PREFIX_ROOT)/bin
PREFIX_LIB = $(PREFIX_ROOT)/$(CFG_LIBDIR)
define INSTALL_PREPARE_N
# $(1) is the target triple
# $(2) is the host triple
# T{B,L} == Target {Bin, Lib} for stage ${ISTAGE}
TB$(1)$(2) = $$(TBIN$$(ISTAGE)_T_$(1)_H_$(2))
TL$(1)$(2) = $$(TLIB$$(ISTAGE)_T_$(1)_H_$(2))
# PT{R,B,L} == Prefix Target {Root, Bin, Lib}
PTR$(1)$(2) = $$(PREFIX_LIB)/rustc/$(1)
PTB$(1)$(2) = $$(PTR$(1)$(2))/bin
PTL$(1)$(2) = $$(PTR$(1)$(2))/$(CFG_LIBDIR)
endef
$(foreach target,$(CFG_TARGET_TRIPLES), \
$(eval $(call INSTALL_PREPARE_N,$(target),$(CFG_BUILD_TRIPLE))))
define INSTALL_TARGET_N
install-target-$(1)-host-$(2): $$(TSREQ$$(ISTAGE)_T_$(1)_H_$(2)) $$(SREQ$$(ISTAGE)_T_$(1)_H_$(2))
$$(Q)mkdir -p $$(PTL$(1)$(2))
$$(Q)$$(call INSTALL_LIB,$$(TL$(1)$(2)),$$(PTL$(1)$(2)),$$(CFG_RUNTIME_$(1)))
$$(Q)$$(call INSTALL_LIB, \
$$(TL$(1)$(2)),$$(PTL$(1)$(2)),$$(STDLIB_GLOB_$(1)))
$$(Q)$$(call INSTALL_LIB, \
$$(TL$(1)$(2)),$$(PTL$(1)$(2)),$$(EXTRALIB_GLOB_$(1)))
$$(Q)$$(call INSTALL_LIB,$$(TL$(1)$(2)),$$(PTL$(1)$(2)),libmorestack.a)
endef
define INSTALL_HOST_N
install-target-$(1)-host-$(2): $$(CSREQ$$(ISTAGE)_T_$(1)_H_$(2))
$$(Q)mkdir -p $$(PTL$(1)$(2))
$$(Q)$$(call INSTALL_LIB,$$(TL$(1)$(2)),$$(PTL$(1)$(2)),$$(CFG_RUNTIME_$(1)))
$$(Q)$$(call INSTALL_LIB, \
$$(TL$(1)$(2)),$$(PTL$(1)$(2)),$$(STDLIB_GLOB_$(1)))
$$(Q)$$(call INSTALL_LIB, \
$$(TL$(1)$(2)),$$(PTL$(1)$(2)),$$(EXTRALIB_GLOB_$(1)))
$$(Q)$$(call INSTALL_LIB, \
$$(TL$(1)$(2)),$$(PTL$(1)$(2)),$$(LIBRUSTC_GLOB_$(1)))
$$(Q)$$(call INSTALL_LIB, \
$$(TL$(1)$(2)),$$(PTL$(1)$(2)),$$(LIBSYNTAX_GLOB_$(1)))
$$(Q)$$(call INSTALL_LIB, \
$$(TL$(1)$(2)),$$(PTL$(1)$(2)),$$(LIBRUSTPKG_GLOB_$(1)))
$$(Q)$$(call INSTALL_LIB, \
$$(TL$(1)$(2)),$$(PTL$(1)$(2)),$$(LIBRUSTDOC_GLOB_$(1)))
$$(Q)$$(call INSTALL_LIB, \
$$(TL$(1)$(2)),$$(PTL$(1)$(2)),$$(LIBRUSTI_GLOB_$(1)))
$$(Q)$$(call INSTALL_LIB, \
$$(TL$(1)$(2)),$$(PTL$(1)$(2)),$$(LIBRUST_GLOB_$(1)))
$$(Q)$$(call INSTALL_LIB,$$(TL$(1)$(2)),$$(PTL$(1)$(2)),libmorestack.a)
endef
$(foreach target,$(CFG_TARGET_TRIPLES), \
$(if $(findstring $(target), $(CFG_BUILD_TRIPLE)), \
$(eval $(call INSTALL_HOST_N,$(target),$(CFG_BUILD_TRIPLE))), \
$(eval $(call INSTALL_TARGET_N,$(target),$(CFG_BUILD_TRIPLE)))))
INSTALL_TARGET_RULES = $(foreach target,$(CFG_TARGET_TRIPLES), \
install-target-$(target)-host-$(CFG_BUILD_TRIPLE))
install: all install-host install-targets
# Shorthand for build/stageN/bin
HB = $(HBIN$(ISTAGE)_H_$(CFG_BUILD_TRIPLE))
HB2 = $(HBIN2_H_$(CFG_BUILD_TRIPLE))
# Shorthand for build/stageN/lib
HL = $(HLIB$(ISTAGE)_H_$(CFG_BUILD_TRIPLE))
# Shorthand for the prefix bin directory
PHB = $(PREFIX_BIN)
# Shorthand for the prefix bin directory
PHL = $(PREFIX_LIB)
install-host: $(CSREQ$(ISTAGE)_T_$(CFG_BUILD_TRIPLE)_H_$(CFG_BUILD_TRIPLE))
$(Q)mkdir -p $(PREFIX_BIN)
$(Q)mkdir -p $(PREFIX_LIB)
$(Q)mkdir -p $(PREFIX_ROOT)/share/man/man1
$(Q)$(call INSTALL,$(HB2),$(PHB),rustc$(X_$(CFG_BUILD_TRIPLE)))
$(Q)$(call INSTALL,$(HB2),$(PHB),rustpkg$(X_$(CFG_BUILD_TRIPLE)))
$(Q)$(call INSTALL,$(HB2),$(PHB),rustdoc$(X_$(CFG_BUILD_TRIPLE)))
$(Q)$(call INSTALL,$(HB2),$(PHB),rusti$(X_$(CFG_BUILD_TRIPLE)))
$(Q)$(call INSTALL,$(HB2),$(PHB),rust$(X_$(CFG_BUILD_TRIPLE)))
$(Q)$(call INSTALL_LIB,$(HL),$(PHL),$(STDLIB_GLOB_$(CFG_BUILD_TRIPLE)))
$(Q)$(call INSTALL_LIB,$(HL),$(PHL),$(EXTRALIB_GLOB_$(CFG_BUILD_TRIPLE)))
$(Q)$(call INSTALL_LIB,$(HL),$(PHL),$(LIBRUSTC_GLOB_$(CFG_BUILD_TRIPLE)))
$(Q)$(call INSTALL_LIB,$(HL),$(PHL),$(LIBSYNTAX_GLOB_$(CFG_BUILD_TRIPLE)))
$(Q)$(call INSTALL_LIB,$(HL),$(PHL),$(LIBRUSTI_GLOB_$(CFG_BUILD_TRIPLE)))
$(Q)$(call INSTALL_LIB,$(HL),$(PHL),$(LIBRUST_GLOB_$(CFG_BUILD_TRIPLE)))
$(Q)$(call INSTALL_LIB,$(HL),$(PHL),$(LIBRUSTPKG_GLOB_$(CFG_BUILD_TRIPLE)))
$(Q)$(call INSTALL_LIB,$(HL),$(PHL),$(LIBRUSTDOC_GLOB_$(CFG_BUILD_TRIPLE)))
$(Q)$(call INSTALL,$(HL),$(PHL),$(CFG_RUNTIME_$(CFG_BUILD_TRIPLE)))
$(Q)$(call INSTALL,$(HL),$(PHL),$(CFG_RUSTLLVM_$(CFG_BUILD_TRIPLE)))
$(Q)$(call INSTALL,$(S)/man, \
$(PREFIX_ROOT)/share/man/man1,rustc.1)
install-targets: $(INSTALL_TARGET_RULES)
HOST_LIB_FROM_HL_GLOB = \
$(patsubst $(HL)/%,$(PHL)/%,$(wildcard $(HL)/$(1)))
prepare_install: dist-tar-bins | tmp/empty_dir
uninstall:
$(Q)rm -f $(PHB)/rustc$(X_$(CFG_BUILD_TRIPLE))
$(Q)rm -f $(PHB)/rustpkg$(X_$(CFG_BUILD_TRIPLE))
$(Q)rm -f $(PHB)/rusti$(X_$(CFG_BUILD_TRIPLE))
$(Q)rm -f $(PHB)/rust$(X_$(CFG_BUILD_TRIPLE))
$(Q)rm -f $(PHB)/rustdoc$(X_$(CFG_BUILD_TRIPLE))
$(Q)rm -f $(PHL)/$(CFG_RUSTLLVM_$(CFG_BUILD_TRIPLE))
$(Q)rm -f $(PHL)/$(CFG_RUNTIME_$(CFG_BUILD_TRIPLE))
$(Q)for i in \
$(call HOST_LIB_FROM_HL_GLOB,$(STDLIB_GLOB_$(CFG_BUILD_TRIPLE))) \
$(call HOST_LIB_FROM_HL_GLOB,$(EXTRALIB_GLOB_$(CFG_BUILD_TRIPLE))) \
$(call HOST_LIB_FROM_HL_GLOB,$(LIBRUSTC_GLOB_$(CFG_BUILD_TRIPLE))) \
$(call HOST_LIB_FROM_HL_GLOB,$(LIBSYNTAX_GLOB_$(CFG_BUILD_TRIPLE))) \
$(call HOST_LIB_FROM_HL_GLOB,$(LIBRUSTPKG_GLOB_$(CFG_BUILD_TRIPLE))) \
$(call HOST_LIB_FROM_HL_GLOB,$(LIBRUSTDOC_GLOB_$(CFG_BUILD_TRIPLE))) \
$(call HOST_LIB_FROM_HL_GLOB,$(LIBRUSTI_GLOB_$(CFG_BUILD_TRIPLE))) \
$(call HOST_LIB_FROM_HL_GLOB,$(LIBRUST_GLOB_$(CFG_BUILD_TRIPLE))) \
; \
do rm -f $$i ; \
done
$(Q)rm -Rf $(PHL)/rustc
$(Q)rm -f $(PREFIX_ROOT)/share/man/man1/rustc.1
ifeq (root user, $(USER) $(patsubst %,user,$(SUDO_USER)))
# Build the dist as the original user
$(Q)sudo -u "$$SUDO_USER" $(MAKE) prepare_uninstall
else
$(Q)$(MAKE) prepare_uninstall
endif
ifeq ($(CFG_DISABLE_DOCS),)
$(Q)cd tmp/empty_dir && sh ../../tmp/dist/$(DOC_PKG_NAME)-$(CFG_BUILD)/install.sh --uninstall --prefix="$(DESTDIR)$(CFG_PREFIX)" --libdir="$(DESTDIR)$(CFG_LIBDIR)" --mandir="$(DESTDIR)$(CFG_MANDIR)"
endif
$(Q)cd tmp/empty_dir && sh ../../tmp/dist/$(PKG_NAME)-$(CFG_BUILD)/install.sh --uninstall --prefix="$(DESTDIR)$(CFG_PREFIX)" --libdir="$(DESTDIR)$(CFG_LIBDIR)" --mandir="$(DESTDIR)$(CFG_MANDIR)"
# Remove tmp files because it's a decent amount of disk space
$(Q)rm -R tmp/dist
prepare_uninstall: dist-tar-bins | tmp/empty_dir
.PHONY: install prepare_install uninstall prepare_uninstall
tmp/empty_dir:
mkdir -p $@
######################################################################
# Android remote installation
######################################################################
# Android runtime setup
# FIXME: This probably belongs somewhere else
# target platform specific variables
# for arm-linux-androidabi
@ -161,10 +64,10 @@ define DEF_ADB_DEVICE_STATUS
CFG_ADB_DEVICE_STATUS=$(1)
endef
$(foreach target,$(CFG_TARGET_TRIPLES), \
$(foreach target,$(CFG_TARGET), \
$(if $(findstring $(target),"arm-linux-androideabi"), \
$(if $(findstring adb,$(CFG_ADB)), \
$(if $(findstring device,$(shell adb devices 2>/dev/null | grep -E '^[_A-Za-z0-9-]+[[:blank:]]+device')), \
$(if $(findstring device,$(shell $(CFG_ADB) devices 2>/dev/null | grep -E '^[_A-Za-z0-9-]+[[:blank:]]+device')), \
$(info install: install-runtime-target for $(target) enabled \
$(info install: android device attached) \
$(eval $(call DEF_ADB_DEVICE_STATUS, true))), \
@ -201,26 +104,25 @@ endif
define INSTALL_RUNTIME_TARGET_N
install-runtime-target-$(1)-host-$(2): $$(TSREQ$$(ISTAGE)_T_$(1)_H_$(2)) $$(SREQ$$(ISTAGE)_T_$(1)_H_$(2))
$(Q)$(call ADB_SHELL,mkdir,$(CFG_RUNTIME_PUSH_DIR))
$(Q)$(call ADB_PUSH,$$(TL$(1)$(2))/$$(CFG_RUNTIME_$(1)),$(CFG_RUNTIME_PUSH_DIR))
$(Q)$(call ADB_PUSH,$$(TL$(1)$(2))/$$(STDLIB_GLOB_$(1)),$(CFG_RUNTIME_PUSH_DIR))
$(Q)$(call ADB_PUSH,$$(TL$(1)$(2))/$$(EXTRALIB_GLOB_$(1)),$(CFG_RUNTIME_PUSH_DIR))
$$(Q)$$(call ADB_SHELL,mkdir,$(CFG_RUNTIME_PUSH_DIR))
$$(Q)$$(foreach crate,$$(TARGET_CRATES), \
$$(call ADB_PUSH,$$(TL$(1)$(2))/$$(call CFG_LIB_GLOB_$(1),$$(crate)), \
$$(CFG_RUNTIME_PUSH_DIR));)
endef
define INSTALL_RUNTIME_TARGET_CLEANUP_N
install-runtime-target-$(1)-cleanup:
$(Q)$(call ADB,remount)
$(Q)$(call ADB_SHELL,rm,$(CFG_RUNTIME_PUSH_DIR)/$(CFG_RUNTIME_$(1)))
$(Q)$(call ADB_SHELL,rm,$(CFG_RUNTIME_PUSH_DIR)/$(STDLIB_GLOB_$(1)))
$(Q)$(call ADB_SHELL,rm,$(CFG_RUNTIME_PUSH_DIR)/$(EXTRALIB_GLOB_$(1)))
$$(Q)$$(call ADB,remount)
$$(Q)$$(foreach crate,$$(TARGET_CRATES), \
$$(call ADB_SHELL,rm,$$(CFG_RUNTIME_PUSH_DIR)/$$(call CFG_LIB_GLOB_$(1),$$(crate)));)
endef
$(eval $(call INSTALL_RUNTIME_TARGET_N,arm-linux-androideabi,$(CFG_BUILD_TRIPLE)))
$(eval $(call INSTALL_RUNTIME_TARGET_N,arm-linux-androideabi,$(CFG_BUILD)))
$(eval $(call INSTALL_RUNTIME_TARGET_CLEANUP_N,arm-linux-androideabi))
install-runtime-target: \
install-runtime-target-arm-linux-androideabi-cleanup \
install-runtime-target-arm-linux-androideabi-host-$(CFG_BUILD_TRIPLE)
install-runtime-target-arm-linux-androideabi-host-$(CFG_BUILD)
else
install-runtime-target:
@echo "No device to install runtime library"

View File

@ -14,7 +14,9 @@ LLVM_DEPS := $(S)/.gitmodules
else
# This is just a rough approximation of LLVM deps
LLVM_DEPS=$(call rwildcard,$(CFG_LLVM_SRC_DIR),*cpp *hpp)
LLVM_DEPS_SRC=$(call rwildcard,$(CFG_LLVM_SRC_DIR)lib,*cpp *hpp)
LLVM_DEPS_INC=$(call rwildcard,$(CFG_LLVM_SRC_DIR)include,*cpp *hpp)
LLVM_DEPS=$(LLVM_DEPS_SRC) $(LLVM_DEPS_INC)
endif
define DEF_LLVM_RULES
@ -22,13 +24,53 @@ define DEF_LLVM_RULES
# If CFG_LLVM_ROOT is defined then we don't build LLVM ourselves
ifeq ($(CFG_LLVM_ROOT),)
$$(LLVM_CONFIG_$(1)): $$(LLVM_DEPS)
LLVM_STAMP_$(1) = $$(CFG_LLVM_BUILD_DIR_$(1))/llvm-auto-clean-stamp
$$(LLVM_CONFIG_$(1)): $$(LLVM_DEPS) $$(LLVM_STAMP_$(1))
@$$(call E, make: llvm)
$$(Q)$$(MAKE) -C $$(CFG_LLVM_BUILD_DIR_$(1)) $$(CFG_LLVM_BUILD_ENV)
$$(Q)$$(MAKE) -C $$(CFG_LLVM_BUILD_DIR_$(1)) $$(CFG_LLVM_BUILD_ENV_$(1)) ONLY_TOOLS="$$(LLVM_TOOLS)"
$$(Q)touch $$(LLVM_CONFIG_$(1))
endif
# This is used to independently force an LLVM clean rebuild
# when we changed something not otherwise captured by builtin
# dependencies. In these cases, commit a change that touches
# the stamp in the source dir.
$$(LLVM_STAMP_$(1)): $(S)src/rustllvm/llvm-auto-clean-trigger
@$$(call E, make: cleaning llvm)
$(Q)$(MAKE) clean-llvm$(1)
@$$(call E, make: done cleaning llvm)
touch $$@
ifeq ($$(CFG_ENABLE_LLVM_STATIC_STDCPP),1)
LLVM_STDCPP_LOCATION_$(1) = $$(shell $$(CC_$(1)) $$(CFG_GCCISH_CFLAGS_$(1)) \
-print-file-name=libstdc++.a)
else
LLVM_STDCPP_LOCATION_$(1) =
endif
# LLVM linkage:
LLVM_LINKAGE_PATH_$(1):=$$(abspath $$(RT_OUTPUT_DIR_$(1))/llvmdeps.rs)
$$(LLVM_LINKAGE_PATH_$(1)): $(S)src/etc/mklldeps.py $$(LLVM_CONFIG_$(1))
$(Q)$(CFG_PYTHON) "$$<" "$$@" "$$(LLVM_COMPONENTS)" "$$(CFG_ENABLE_LLVM_STATIC_STDCPP)" \
$$(LLVM_CONFIG_$(1))
endef
$(foreach host,$(CFG_HOST_TRIPLES), \
$(foreach host,$(CFG_HOST), \
$(eval $(call DEF_LLVM_RULES,$(host))))
$(foreach host,$(CFG_HOST), \
$(eval LLVM_CONFIGS := $(LLVM_CONFIGS) $(LLVM_CONFIG_$(host))))
# This can't be done in target.mk because it's included before this file.
define LLVM_LINKAGE_DEPS
$$(TLIB$(1)_T_$(2)_H_$(3))/stamp.rustc_llvm: $$(LLVM_LINKAGE_PATH_$(3))
endef
$(foreach source,$(CFG_HOST), \
$(foreach target,$(CFG_TARGET), \
$(eval $(call LLVM_LINKAGE_DEPS,0,$(target),$(source))) \
$(eval $(call LLVM_LINKAGE_DEPS,1,$(target),$(source))) \
$(eval $(call LLVM_LINKAGE_DEPS,2,$(target),$(source))) \
$(eval $(call LLVM_LINKAGE_DEPS,3,$(target),$(source)))))

586
mk/main.mk Normal file
View File

@ -0,0 +1,586 @@
# Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT
# file at the top-level directory of this distribution and at
# http://rust-lang.org/COPYRIGHT.
#
# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
# option. This file may not be copied, modified, or distributed
# except according to those terms.
######################################################################
# Version numbers and strings
######################################################################
# The version number
CFG_RELEASE_NUM=1.0.0
# An optional number to put after the label, e.g. '2' -> '-beta2'
CFG_BETA_CYCLE=
CFG_FILENAME_EXTRA=4e7c5e5c
ifeq ($(CFG_RELEASE_CHANNEL),stable)
# This is the normal semver version string, e.g. "0.12.0", "0.12.0-nightly"
CFG_RELEASE=$(CFG_RELEASE_NUM)
# This is the string used in dist artifact file names, e.g. "0.12.0", "nightly"
CFG_PACKAGE_VERS=$(CFG_RELEASE_NUM)
CFG_DISABLE_UNSTABLE_FEATURES=1
endif
ifeq ($(CFG_RELEASE_CHANNEL),beta)
# The beta channel is temporarily called 'alpha'
CFG_RELEASE=$(CFG_RELEASE_NUM)-alpha$(CFG_BETA_CYCLE)
CFG_PACKAGE_VERS=$(CFG_RELEASE_NUM)-alpha$(CFG_BETA_CYCLE)
CFG_DISABLE_UNSTABLE_FEATURES=1
endif
ifeq ($(CFG_RELEASE_CHANNEL),nightly)
CFG_RELEASE=$(CFG_RELEASE_NUM)-nightly
# When building nightly distributables just reuse the same "nightly" name
# so when we upload we'll always override the previous nighly. This
# doesn't actually impact the version reported by rustc - it's just
# for file naming.
CFG_PACKAGE_VERS=nightly
endif
ifeq ($(CFG_RELEASE_CHANNEL),dev)
CFG_RELEASE=$(CFG_RELEASE_NUM)-dev
CFG_PACKAGE_VERS=$(CFG_RELEASE_NUM)-dev
endif
# The name of the package to use for creating tarballs, installers etc.
CFG_PACKAGE_NAME=rustc-$(CFG_PACKAGE_VERS)
# The version string plus commit information - this is what rustc reports
CFG_VERSION = $(CFG_RELEASE)
CFG_GIT_DIR := $(CFG_SRC_DIR).git
# since $(CFG_GIT) may contain spaces (especially on Windows),
# we need to escape them. (" " to r"\ ")
# Note that $(subst ...) ignores space after `subst`,
# so we use a hack: define $(SPACE) which contains space character.
SPACE :=
SPACE +=
ifneq ($(CFG_GIT),)
ifneq ($(wildcard $(subst $(SPACE),\$(SPACE),$(CFG_GIT_DIR))),)
CFG_VER_DATE = $(shell git --git-dir='$(CFG_GIT_DIR)' log -1 --pretty=format:'%ci')
CFG_VER_HASH = $(shell git --git-dir='$(CFG_GIT_DIR)' rev-parse HEAD)
CFG_SHORT_VER_HASH = $(shell git --git-dir='$(CFG_GIT_DIR)' rev-parse --short=9 HEAD)
CFG_VERSION += ($(CFG_SHORT_VER_HASH) $(CFG_VER_DATE))
endif
endif
# Windows exe's need numeric versions - don't use anything but
# numbers and dots here
CFG_VERSION_WIN = $(CFG_RELEASE_NUM)
######################################################################
# More configuration
######################################################################
# We track all of the object files we might build so that we can find
# and include all of the .d files in one fell swoop.
ALL_OBJ_FILES :=
MKFILE_DEPS := config.stamp $(call rwildcard,$(CFG_SRC_DIR)mk/,*)
MKFILES_FOR_TARBALL:=$(MKFILE_DEPS)
ifneq ($(NO_MKFILE_DEPS),)
MKFILE_DEPS :=
endif
NON_BUILD_HOST = $(filter-out $(CFG_BUILD),$(CFG_HOST))
NON_BUILD_TARGET = $(filter-out $(CFG_BUILD),$(CFG_TARGET))
ifneq ($(MAKE_RESTARTS),)
CFG_INFO := $(info cfg: make restarts: $(MAKE_RESTARTS))
endif
CFG_INFO := $(info cfg: build triple $(CFG_BUILD))
CFG_INFO := $(info cfg: host triples $(CFG_HOST))
CFG_INFO := $(info cfg: target triples $(CFG_TARGET))
ifneq ($(wildcard $(NON_BUILD_HOST)),)
CFG_INFO := $(info cfg: non-build host triples $(NON_BUILD_HOST))
endif
ifneq ($(wildcard $(NON_BUILD_TARGET)),)
CFG_INFO := $(info cfg: non-build target triples $(NON_BUILD_TARGET))
endif
CFG_RUSTC_FLAGS := $(RUSTFLAGS)
CFG_GCCISH_CFLAGS :=
CFG_GCCISH_LINK_FLAGS :=
# Turn off broken quarantine (see jemalloc/jemalloc#161)
CFG_JEMALLOC_FLAGS := --disable-fill
ifdef CFG_DISABLE_OPTIMIZE
$(info cfg: disabling rustc optimization (CFG_DISABLE_OPTIMIZE))
CFG_RUSTC_FLAGS +=
CFG_JEMALLOC_FLAGS += --enable-debug
else
# The rtopt cfg turns off runtime sanity checks
CFG_RUSTC_FLAGS += -O --cfg rtopt
endif
CFG_JEMALLOC_FLAGS += $(JEMALLOC_FLAGS)
ifdef CFG_DISABLE_DEBUG
CFG_RUSTC_FLAGS += --cfg ndebug
else
$(info cfg: enabling more debugging (CFG_ENABLE_DEBUG))
CFG_RUSTC_FLAGS += --cfg debug
endif
ifdef SAVE_TEMPS
CFG_RUSTC_FLAGS += --save-temps
endif
ifdef ASM_COMMENTS
CFG_RUSTC_FLAGS += -Z asm-comments
endif
ifdef TIME_PASSES
CFG_RUSTC_FLAGS += -Z time-passes
endif
ifdef TIME_LLVM_PASSES
CFG_RUSTC_FLAGS += -Z time-llvm-passes
endif
ifdef TRACE
CFG_RUSTC_FLAGS += -Z trace
endif
ifdef CFG_ENABLE_RPATH
CFG_RUSTC_FLAGS += -C rpath
endif
# The executables crated during this compilation process have no need to include
# static copies of libstd and libextra. We also generate dynamic versions of all
# libraries, so in the interest of space, prefer dynamic linking throughout the
# compilation process.
#
# Note though that these flags are omitted for the *bins* in stage2+. This means
# that the snapshot will be generated with a statically linked rustc so we only
# have to worry about the distribution of one file (with its native dynamic
# dependencies)
RUSTFLAGS_STAGE0 += -C prefer-dynamic
RUSTFLAGS_STAGE1 += -C prefer-dynamic
RUST_LIB_FLAGS_ST2 += -C prefer-dynamic
RUST_LIB_FLAGS_ST3 += -C prefer-dynamic
# Landing pads require a lot of codegen. We can get through bootstrapping faster
# by not emitting them.
RUSTFLAGS_STAGE0 += -Z no-landing-pads
# platform-specific auto-configuration
include $(CFG_SRC_DIR)mk/platform.mk
# Run the stage1/2 compilers under valgrind
ifdef VALGRIND_COMPILE
CFG_VALGRIND_COMPILE :=$(CFG_VALGRIND)
else
CFG_VALGRIND_COMPILE :=
endif
ifndef CFG_DISABLE_VALGRIND_RPASS
$(info cfg: enabling valgrind run-pass tests (CFG_ENABLE_VALGRIND_RPASS))
CFG_VALGRIND_RPASS :=$(CFG_VALGRIND)
else
CFG_VALGRIND_RPASS :=
endif
ifdef CFG_ENABLE_VALGRIND
$(info cfg: enabling valgrind (CFG_ENABLE_VALGRIND))
else
CFG_VALGRIND :=
endif
######################################################################
# Target-and-rule "utility variables"
######################################################################
define DEF_FOR_TARGET
X_$(1) := $(CFG_EXE_SUFFIX_$(1))
ifndef CFG_LLVM_TARGET_$(1)
CFG_LLVM_TARGET_$(1) := $(1)
endif
endef
$(foreach target,$(CFG_TARGET), \
$(eval $(call DEF_FOR_TARGET,$(target))))
# "Source" files we generate in builddir along the way.
GENERATED :=
# Delete the built-in rules.
.SUFFIXES:
%:: %,v
%:: RCS/%,v
%:: RCS/%
%:: s.%
%:: SCCS/s.%
######################################################################
# Cleaning out old crates
######################################################################
# $(1) is the path for directory to match against
# $(2) is the glob to use in the match
#
# Note that a common bug is to accidentally construct the glob denoted
# by $(2) with a space character prefix, which invalidates the
# construction $(1)$(2).
define CHECK_FOR_OLD_GLOB_MATCHES
$(Q)MATCHES="$(wildcard $(1))"; if [ -n "$$MATCHES" ] ; then echo "warning: there are previous" \'$(notdir $(2))\' "libraries:" $$MATCHES; fi
endef
# Same interface as above, but deletes rather than just listing the files.
ifdef VERBOSE
define REMOVE_ALL_OLD_GLOB_MATCHES
$(Q)MATCHES="$(wildcard $(1))"; if [ -n "$$MATCHES" ] ; then echo "warning: removing previous" \'$(notdir $(1))\' "libraries:" $$MATCHES; rm $$MATCHES ; fi
endef
else
define REMOVE_ALL_OLD_GLOB_MATCHES
$(Q)MATCHES="$(wildcard $(1))"; if [ -n "$$MATCHES" ] ; then rm $$MATCHES ; fi
endef
endif
# We use a different strategy for LIST_ALL_OLD_GLOB_MATCHES_EXCEPT
# than in the macros above because it needs the result of running the
# `ls` command after other rules in the command list have run; the
# macro-expander for $(wildcard ...) would deliver its results too
# soon. (This is in contrast to the macros above, which are meant to
# be run at the outset of a command list in a rule.)
ifdef VERBOSE
define LIST_ALL_OLD_GLOB_MATCHES
@echo "info: now are following matches for" '$(notdir $(1))' "libraries:"
@( ls $(1) 2>/dev/null || true )
endef
else
define LIST_ALL_OLD_GLOB_MATCHES
endef
endif
######################################################################
# LLVM macros
######################################################################
# FIXME: x86-ism
LLVM_COMPONENTS=x86 arm aarch64 mips ipo bitreader bitwriter linker asmparser mcjit \
interpreter instrumentation
# Only build these LLVM tools
LLVM_TOOLS=bugpoint llc llvm-ar llvm-as llvm-dis llvm-mc opt llvm-extract
define DEF_LLVM_VARS
# The configure script defines these variables with the target triples
# separated by Z. This defines new ones with the expected format.
ifeq ($$(CFG_LLVM_ROOT),)
CFG_LLVM_BUILD_DIR_$(1):=$$(CFG_LLVM_BUILD_DIR_$(subst -,_,$(1)))
CFG_LLVM_INST_DIR_$(1):=$$(CFG_LLVM_INST_DIR_$(subst -,_,$(1)))
else
CFG_LLVM_INST_DIR_$(1):=$$(CFG_LLVM_ROOT)
endif
# Any rules that depend on LLVM should depend on LLVM_CONFIG
LLVM_CONFIG_$(1):=$$(CFG_LLVM_INST_DIR_$(1))/bin/llvm-config$$(X_$(1))
LLVM_MC_$(1):=$$(CFG_LLVM_INST_DIR_$(1))/bin/llvm-mc$$(X_$(1))
LLVM_VERSION_$(1)=$$(shell "$$(LLVM_CONFIG_$(1))" --version)
LLVM_BINDIR_$(1)=$$(shell "$$(LLVM_CONFIG_$(1))" --bindir)
LLVM_INCDIR_$(1)=$$(shell "$$(LLVM_CONFIG_$(1))" --includedir)
LLVM_LIBDIR_$(1)=$$(shell "$$(LLVM_CONFIG_$(1))" --libdir)
LLVM_LIBS_$(1)=$$(shell "$$(LLVM_CONFIG_$(1))" --libs $$(LLVM_COMPONENTS))
LLVM_LDFLAGS_$(1)=$$(shell "$$(LLVM_CONFIG_$(1))" --ldflags)
# On FreeBSD, it may search wrong headers (that are for pre-installed LLVM),
# so we replace -I with -iquote to ensure that it searches bundled LLVM first.
LLVM_CXXFLAGS_$(1)=$$(subst -I, -iquote , $$(shell "$$(LLVM_CONFIG_$(1))" --cxxflags))
LLVM_HOST_TRIPLE_$(1)=$$(shell "$$(LLVM_CONFIG_$(1))" --host-target)
LLVM_AS_$(1)=$$(CFG_LLVM_INST_DIR_$(1))/bin/llvm-as$$(X_$(1))
LLC_$(1)=$$(CFG_LLVM_INST_DIR_$(1))/bin/llc$$(X_$(1))
endef
$(foreach host,$(CFG_HOST), \
$(eval $(call DEF_LLVM_VARS,$(host))))
######################################################################
# Exports for sub-utilities
######################################################################
# Note that any variable that re-configure should pick up needs to be
# exported
export CFG_SRC_DIR
export CFG_BUILD_DIR
ifdef CFG_VER_DATE
export CFG_VER_DATE
endif
ifdef CFG_VER_HASH
export CFG_VER_HASH
endif
export CFG_VERSION
export CFG_VERSION_WIN
export CFG_RELEASE
export CFG_PACKAGE_NAME
export CFG_BUILD
export CFG_RELEASE_CHANNEL
export CFG_LLVM_ROOT
export CFG_PREFIX
export CFG_LIBDIR
export CFG_LIBDIR_RELATIVE
export CFG_DISABLE_INJECT_STD_VERSION
ifdef CFG_DISABLE_UNSTABLE_FEATURES
CFG_INFO := $(info cfg: disabling unstable features (CFG_DISABLE_UNSTABLE_FEATURES))
# Turn on feature-staging
export CFG_DISABLE_UNSTABLE_FEATURES
endif
# Subvert unstable feature lints to do the self-build
export CFG_BOOTSTRAP_KEY
export RUSTC_BOOTSTRAP_KEY:=$(CFG_BOOTSTRAP_KEY)
######################################################################
# Per-stage targets and runner
######################################################################
# Valid setting-strings are 'all', 'none', 'gdb', 'lldb'
# This 'function' will determine which debugger scripts to copy based on a
# target triple. See debuggers.mk for more information.
TRIPLE_TO_DEBUGGER_SCRIPT_SETTING=\
$(if $(findstring windows,$(1)),none,$(if $(findstring darwin,$(1)),lldb,gdb))
STAGES = 0 1 2 3
define SREQ
# $(1) is the stage number
# $(2) is the target triple
# $(3) is the host triple
# Destinations of artifacts for the host compiler
HROOT$(1)_H_$(3) = $(3)/stage$(1)
HBIN$(1)_H_$(3) = $$(HROOT$(1)_H_$(3))/bin
ifeq ($$(CFG_WINDOWSY_$(3)),1)
HLIB$(1)_H_$(3) = $$(HROOT$(1)_H_$(3))/$$(CFG_LIBDIR_RELATIVE)
else
ifeq ($(1),0)
HLIB$(1)_H_$(3) = $$(HROOT$(1)_H_$(3))/lib
else
HLIB$(1)_H_$(3) = $$(HROOT$(1)_H_$(3))/$$(CFG_LIBDIR_RELATIVE)
endif
endif
# Destinations of artifacts for target architectures
TROOT$(1)_T_$(2)_H_$(3) = $$(HLIB$(1)_H_$(3))/rustlib/$(2)
TBIN$(1)_T_$(2)_H_$(3) = $$(TROOT$(1)_T_$(2)_H_$(3))/bin
TLIB$(1)_T_$(2)_H_$(3) = $$(TROOT$(1)_T_$(2)_H_$(3))/lib
# Preqrequisites for using the stageN compiler
ifeq ($(1),0)
HSREQ$(1)_H_$(3) = $$(HBIN$(1)_H_$(3))/rustc$$(X_$(3))
else
HSREQ$(1)_H_$(3) = \
$$(HBIN$(1)_H_$(3))/rustc$$(X_$(3)) \
$$(MKFILE_DEPS) \
tmp/install-debugger-scripts$(1)_H_$(3)-$$(call TRIPLE_TO_DEBUGGER_SCRIPT_SETTING,$(3)).done
endif
# Prerequisites for using the stageN compiler to build target artifacts
TSREQ$(1)_T_$(2)_H_$(3) = \
$$(HSREQ$(1)_H_$(3)) \
$$(TLIB$(1)_T_$(2)_H_$(3))/libmorestack.a \
$$(TLIB$(1)_T_$(2)_H_$(3))/libcompiler-rt.a
# Prerequisites for a working stageN compiler and libraries, for a specific
# target
SREQ$(1)_T_$(2)_H_$(3) = \
$$(TSREQ$(1)_T_$(2)_H_$(3)) \
$$(foreach dep,$$(TARGET_CRATES), \
$$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$$(dep)) \
tmp/install-debugger-scripts$(1)_T_$(2)_H_$(3)-$$(call TRIPLE_TO_DEBUGGER_SCRIPT_SETTING,$(2)).done
# Prerequisites for a working stageN compiler and complete set of target
# libraries
CSREQ$(1)_T_$(2)_H_$(3) = \
$$(TSREQ$(1)_T_$(2)_H_$(3)) \
$$(HBIN$(1)_H_$(3))/rustdoc$$(X_$(3)) \
$$(foreach dep,$$(CRATES),$$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$$(dep))
ifeq ($(1),0)
# Don't run the stage0 compiler under valgrind - that ship has sailed
CFG_VALGRIND_COMPILE$(1) =
else
CFG_VALGRIND_COMPILE$(1) = $$(CFG_VALGRIND_COMPILE)
endif
# Add RUSTFLAGS_STAGEN values to the build command
EXTRAFLAGS_STAGE$(1) = $$(RUSTFLAGS_STAGE$(1))
CFGFLAG$(1)_T_$(2)_H_$(3) = stage$(1)
endef
# Same macro/variables as above, but defined in a separate loop so it can use
# all the variables above for all archs. The RPATH_VAR setup sometimes needs to
# reach across triples to get things in order.
#
# Defines (with the standard $(1)_T_$(2)_H_$(3) suffix):
# * `LD_LIBRARY_PATH_ENV_NAME`: the name for the key to use in the OS
# environment to access or extend the lookup path for dynamic
# libraries. Note on Windows, that key is `$PATH`, and thus not
# only conflates programs with dynamic libraries, but also often
# contains spaces which confuse make.
# * `LD_LIBRARY_PATH_ENV_HOSTDIR`: the entry to add to lookup path for the host
# * `LD_LIBRARY_PATH_ENV_TARGETDIR`: the entry to add to lookup path for target
#
# Below that, HOST_RPATH_VAR and TARGET_RPATH_VAR are defined in terms of the
# above settings.
#
define SREQ_CMDS
ifeq ($$(OSTYPE_$(3)),apple-darwin)
LD_LIBRARY_PATH_ENV_NAME$(1)_T_$(2)_H_$(3) := DYLD_LIBRARY_PATH
else
ifeq ($$(CFG_WINDOWSY_$(3)),1)
LD_LIBRARY_PATH_ENV_NAME$(1)_T_$(2)_H_$(3) := PATH
else
LD_LIBRARY_PATH_ENV_NAME$(1)_T_$(2)_H_$(3) := LD_LIBRARY_PATH
endif
endif
LD_LIBRARY_PATH_ENV_HOSTDIR$(1)_T_$(2)_H_$(3) := \
$$(CURDIR)/$$(HLIB$(1)_H_$(3))
LD_LIBRARY_PATH_ENV_TARGETDIR$(1)_T_$(2)_H_$(3) := \
$$(CURDIR)/$$(TLIB1_T_$(2)_H_$(CFG_BUILD))
HOST_RPATH_VAR$(1)_T_$(2)_H_$(3) := \
$$(LD_LIBRARY_PATH_ENV_NAME$(1)_T_$(2)_H_$(3))=$$(LD_LIBRARY_PATH_ENV_HOSTDIR$(1)_T_$(2)_H_$(3)):$$$$$$(LD_LIBRARY_PATH_ENV_NAME$(1)_T_$(2)_H_$(3))
TARGET_RPATH_VAR$(1)_T_$(2)_H_$(3) := \
$$(LD_LIBRARY_PATH_ENV_NAME$(1)_T_$(2)_H_$(3))=$$(LD_LIBRARY_PATH_ENV_TARGETDIR$(1)_T_$(2)_H_$(3)):$$$$$$(LD_LIBRARY_PATH_ENV_NAME$(1)_T_$(2)_H_$(3))
RPATH_VAR$(1)_T_$(2)_H_$(3) := $$(HOST_RPATH_VAR$(1)_T_$(2)_H_$(3))
# Pass --cfg stage0 only for the build->host part of stage0;
# if you're building a cross config, the host->* parts are
# effectively stage1, since it uses the just-built stage0.
#
# This logic is similar to how the LD_LIBRARY_PATH variable must
# change be slightly different when doing cross compilations.
# The build doesn't copy over all target libraries into
# a new directory, so we need to point the library path at
# the build directory where all the target libraries came
# from (the stage0 build host). Otherwise the relative rpaths
# inside of the rustc binary won't get resolved correctly.
ifeq ($(1),0)
ifneq ($(strip $(CFG_BUILD)),$(strip $(3)))
CFGFLAG$(1)_T_$(2)_H_$(3) = stage1
RPATH_VAR$(1)_T_$(2)_H_$(3) := $$(TARGET_RPATH_VAR$(1)_T_$(2)_H_$(3))
endif
endif
STAGE$(1)_T_$(2)_H_$(3) := \
$$(Q)$$(RPATH_VAR$(1)_T_$(2)_H_$(3)) \
$$(call CFG_RUN_TARG_$(3),$(1), \
$$(CFG_VALGRIND_COMPILE$(1)) \
$$(HBIN$(1)_H_$(3))/rustc$$(X_$(3)) \
--cfg $$(CFGFLAG$(1)_T_$(2)_H_$(3)) \
$$(CFG_RUSTC_FLAGS) $$(EXTRAFLAGS_STAGE$(1)) --target=$(2)) \
$$(RUSTC_FLAGS_$(2))
PERF_STAGE$(1)_T_$(2)_H_$(3) := \
$$(Q)$$(call CFG_RUN_TARG_$(3),$(1), \
$$(CFG_PERF_TOOL) \
$$(HBIN$(1)_H_$(3))/rustc$$(X_$(3)) \
--cfg $$(CFGFLAG$(1)_T_$(2)_H_$(3)) \
$$(CFG_RUSTC_FLAGS) $$(EXTRAFLAGS_STAGE$(1)) --target=$(2)) \
$$(RUSTC_FLAGS_$(2))
endef
$(foreach build,$(CFG_HOST), \
$(eval $(foreach target,$(CFG_TARGET), \
$(eval $(foreach stage,$(STAGES), \
$(eval $(call SREQ,$(stage),$(target),$(build))))))))
$(foreach build,$(CFG_HOST), \
$(eval $(foreach target,$(CFG_TARGET), \
$(eval $(foreach stage,$(STAGES), \
$(eval $(call SREQ_CMDS,$(stage),$(target),$(build))))))))
######################################################################
# rustc-H-targets
#
# Builds a functional Rustc for the given host.
######################################################################
define DEF_RUSTC_STAGE_TARGET
# $(1) == architecture
# $(2) == stage
rustc-stage$(2)-H-$(1): \
$$(foreach target,$$(CFG_TARGET),$$(SREQ$(2)_T_$$(target)_H_$(1)))
endef
$(foreach host,$(CFG_HOST), \
$(eval $(foreach stage,1 2 3, \
$(eval $(call DEF_RUSTC_STAGE_TARGET,$(host),$(stage))))))
rustc-stage1: rustc-stage1-H-$(CFG_BUILD)
rustc-stage2: rustc-stage2-H-$(CFG_BUILD)
rustc-stage3: rustc-stage3-H-$(CFG_BUILD)
define DEF_RUSTC_TARGET
# $(1) == architecture
rustc-H-$(1): rustc-stage2-H-$(1)
endef
$(foreach host,$(CFG_TARGET), \
$(eval $(call DEF_RUSTC_TARGET,$(host))))
rustc-stage1: rustc-stage1-H-$(CFG_BUILD)
rustc-stage2: rustc-stage2-H-$(CFG_BUILD)
rustc-stage3: rustc-stage3-H-$(CFG_BUILD)
rustc: rustc-H-$(CFG_BUILD)
rustc-H-all: $(foreach host,$(CFG_HOST),rustc-H-$(host))
######################################################################
# Entrypoint rule
######################################################################
.DEFAULT_GOAL := all
define ALL_TARGET_N
ifneq ($$(findstring $(1),$$(CFG_HOST)),)
# This is a host
all-target-$(1)-host-$(2): $$(CSREQ2_T_$(1)_H_$(2))
else
# This is a target only
all-target-$(1)-host-$(2): $$(SREQ2_T_$(1)_H_$(2))
endif
endef
$(foreach target,$(CFG_TARGET), \
$(foreach host,$(CFG_HOST), \
$(eval $(call ALL_TARGET_N,$(target),$(host)))))
ALL_TARGET_RULES = $(foreach target,$(CFG_TARGET), \
$(foreach host,$(CFG_HOST), \
all-target-$(target)-host-$(host)))
all: $(ALL_TARGET_RULES) $(GENERATED) docs
######################################################################
# Build system documentation
######################################################################
# $(1) is the name of the doc <section> in Makefile.in
# pick everything between tags | remove first line | remove last line
# | remove extra (?) line | strip leading `#` from lines
SHOW_DOCS = $(Q)awk '/<$(1)>/,/<\/$(1)>/' $(S)/Makefile.in | sed '1d' | sed '$$d' | sed 's/^\# \?//'
help:
$(call SHOW_DOCS,help)
tips:
$(call SHOW_DOCS,tips)
nitty-gritty:
$(call SHOW_DOCS,nitty-gritty)

View File

@ -10,16 +10,16 @@
ifdef CFG_PERF_TOOL
rustc-perf$(X): $(CFG_BUILD_TRIPLE)/stage2/bin/rustc$(X_$(CFG_BUILD_TRIPLE))
rustc-perf$(X): $(CFG_BUILD)/stage2/bin/rustc$(X_$(CFG_BUILD))
@$(call E, perf compile: $@)
$(PERF_STAGE2_T_$(CFG_BUILD_TRIPLE)_H_$(CFG_BUILD_TRIPLE)) \
$(PERF_STAGE2_T_$(CFG_BUILD)_H_$(CFG_BUILD)) \
-o $@ $(COMPILER_CRATE) >rustc-perf.err 2>&1
$(Q)rm -f $(LIBRUSTC_GLOB)
else
rustc-perf$(X): $(CFG_BUILD_TRIPLE)/stage2/bin/rustc$(X_$(CFG_BUILD_TRIPLE))
rustc-perf$(X): $(CFG_BUILD)/stage2/bin/rustc$(X_$(CFG_BUILD))
$(Q)touch $@
endif
perf: check-stage2-perf rustc-perf$(X_$(CFG_BUILD_TRIPLE))
$(Q)find $(CFG_BUILD_TRIPLE)/test/perf -name \*.err | xargs cat
perf: check-stage2-perf rustc-perf$(X_$(CFG_BUILD))
$(Q)find $(CFG_BUILD)/test/perf -name \*.err | xargs cat
$(Q)cat rustc-perf.err

View File

@ -1,4 +1,4 @@
# Copyright 2012 The Rust Project Developers. See the COPYRIGHT
# Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
# file at the top-level directory of this distribution and at
# http://rust-lang.org/COPYRIGHT.
#
@ -16,20 +16,15 @@
define DEF_HOST_VAR
HOST_$(1) = $(subst i686,i386,$(word 1,$(subst -, ,$(1))))
endef
$(foreach t,$(CFG_TARGET_TRIPLES),$(eval $(call DEF_HOST_VAR,$(t))))
$(foreach t,$(CFG_TARGET_TRIPLES),$(info cfg: host for $(t) is $(HOST_$(t))))
$(foreach t,$(CFG_TARGET),$(eval $(call DEF_HOST_VAR,$(t))))
$(foreach t,$(CFG_TARGET),$(info cfg: host for $(t) is $(HOST_$(t))))
# Ditto for OSTYPE
define DEF_OSTYPE_VAR
OSTYPE_$(1) = $(subst $(firstword $(subst -, ,$(1)))-,,$(1))
endef
$(foreach t,$(CFG_TARGET_TRIPLES),$(eval $(call DEF_OSTYPE_VAR,$(t))))
$(foreach t,$(CFG_TARGET_TRIPLES),$(info cfg: os for $(t) is $(OSTYPE_$(t))))
# FIXME: no-omit-frame-pointer is just so that task_start_wrapper
# has a frame pointer and the stack walker can understand it. Turning off
# frame pointers everywhere is overkill
CFG_GCCISH_CFLAGS += -fno-omit-frame-pointer -DUSE_UTF8
$(foreach t,$(CFG_TARGET),$(eval $(call DEF_OSTYPE_VAR,$(t))))
$(foreach t,$(CFG_TARGET),$(info cfg: os for $(t) is $(OSTYPE_$(t))))
# On Darwin, we need to run dsymutil so the debugging information ends
# up in the right place. On other platforms, it automatically gets
@ -37,7 +32,7 @@ CFG_GCCISH_CFLAGS += -fno-omit-frame-pointer -DUSE_UTF8
CFG_DSYMUTIL := true
# Hack: not sure how to test if a file exists in make other than this
OS_SUPP = $(patsubst %,--suppressions=%,\
OS_SUPP = $(patsubst %,--suppressions=%, \
$(wildcard $(CFG_SRC_DIR)src/etc/$(CFG_OSTYPE).supp*))
ifdef CFG_DISABLE_OPTIMIZE_CXX
@ -47,8 +42,11 @@ else
CFG_GCCISH_CFLAGS += -O2
endif
# The soname thing is for supporting a statically linked jemalloc.
# see https://blog.mozilla.org/jseward/2012/06/05/valgrind-now-supports-jemalloc-builds-directly/
ifdef CFG_VALGRIND
CFG_VALGRIND += --error-exitcode=100 \
--soname-synonyms=somalloc=NONE \
--quiet \
--suppressions=$(CFG_SRC_DIR)src/etc/x86.supp \
$(OS_SUPP)
@ -60,6 +58,20 @@ ifdef CFG_VALGRIND
endif
endif
# If we actually want to run Valgrind on a given platform, set this variable
define DEF_GOOD_VALGRIND
ifeq ($(OSTYPE_$(1)),unknown-linux-gnu)
GOOD_VALGRIND_$(1) = 1
endif
ifneq (,$(filter $(OSTYPE_$(1)),darwin freebsd))
ifeq (HOST_$(1),x86_64)
GOOD_VALGRIND_$(1) = 1
endif
endif
endef
$(foreach t,$(CFG_TARGET),$(eval $(call DEF_GOOD_VALGRIND,$(t))))
$(foreach t,$(CFG_TARGET),$(info cfg: good valgrind for $(t) is $(GOOD_VALGRIND_$(t))))
ifneq ($(findstring linux,$(CFG_OSTYPE)),)
ifdef CFG_PERF
ifneq ($(CFG_PERF_WITH_LOGFD),)
@ -69,7 +81,7 @@ ifneq ($(findstring linux,$(CFG_OSTYPE)),)
endif
else
ifdef CFG_VALGRIND
CFG_PERF_TOOL :=\
CFG_PERF_TOOL := \
$(CFG_VALGRIND) --tool=cachegrind --cache-sim=yes --branch-sim=yes
else
CFG_PERF_TOOL := /usr/bin/time --verbose
@ -83,313 +95,39 @@ CFG_DEPEND_FLAGS = -MMD -MP -MT $(1) -MF $(1:%.o=%.d)
AR := ar
CFG_INFO := $(info cfg: using $(CFG_C_COMPILER))
ifeq ($(CFG_C_COMPILER),clang)
ifeq ($(origin CC),default)
CC=clang
define SET_FROM_CFG
ifdef CFG_$(1)
ifeq ($(origin $(1)),undefined)
$$(info cfg: using $(1)=$(CFG_$(1)) (CFG_$(1)))
$(1)=$(CFG_$(1))
endif
ifeq ($(origin $(1)),default)
$$(info cfg: using $(1)=$(CFG_$(1)) (CFG_$(1)))
$(1)=$(CFG_$(1))
endif
endif
ifeq ($(origin CXX),default)
CXX=clang++
endif
ifeq ($(origin CPP),default)
CPP=clang
endif
else
ifeq ($(CFG_C_COMPILER),gcc)
ifeq ($(origin CC),default)
CC=gcc
endif
ifeq ($(origin CXX),default)
CXX=g++
endif
ifeq ($(origin CPP),default)
CPP=gcc
endif
else
ifeq ($(CFG_C_COMPILER),ccache clang)
# The -Qunused-arguments sidesteps spurious warnings from clang
ifeq ($(origin CC),default)
CC=ccache clang -Qunused-arguments
endif
ifeq ($(origin CXX),default)
CXX=ccache clang++ -Qunused-arguments
endif
ifeq ($(origin CPP),default)
CPP=ccache clang -Qunused-arguments
endif
else
ifeq ($(CFG_C_COMPILER),ccache gcc)
ifeq ($(origin CC),default)
CC=ccache gcc
endif
ifeq ($(origin CXX),default)
CXX=ccache g++
endif
ifeq ($(origin CPP),default)
CPP=ccache gcc
endif
else
CFG_ERR := $(error please try on a system with gcc or clang)
endif
endif
endif
endif
endef
$(foreach cvar,CC CXX CPP CFLAGS CXXFLAGS CPPFLAGS, \
$(eval $(call SET_FROM_CFG,$(cvar))))
# x86_64-unknown-linux-gnu configuration
CC_x86_64-unknown-linux-gnu=$(CC)
CXX_x86_64-unknown-linux-gnu=$(CXX)
CPP_x86_64-unknown-linux-gnu=$(CPP)
AR_x86_64-unknown-linux-gnu=$(AR)
CFG_LIB_NAME_x86_64-unknown-linux-gnu=lib$(1).so
CFG_LIB_GLOB_x86_64-unknown-linux-gnu=lib$(1)-*.so
CFG_LIB_DSYM_GLOB_x86_64-unknown-linux-gnu=lib$(1)-*.dylib.dSYM
CFG_GCCISH_CFLAGS_x86_64-unknown-linux-gnu := -Wall -Werror -g -fPIC -m64
CFG_GCCISH_CXXFLAGS_x86_64-unknown-linux-gnu := -fno-rtti
CFG_GCCISH_LINK_FLAGS_x86_64-unknown-linux-gnu := -shared -fPIC -ldl -pthread -lrt -g -m64
CFG_GCCISH_DEF_FLAG_x86_64-unknown-linux-gnu := -Wl,--export-dynamic,--dynamic-list=
CFG_GCCISH_PRE_LIB_FLAGS_x86_64-unknown-linux-gnu := -Wl,-whole-archive
CFG_GCCISH_POST_LIB_FLAGS_x86_64-unknown-linux-gnu := -Wl,-no-whole-archive
CFG_DEF_SUFFIX_x86_64-unknown-linux-gnu := .linux.def
CFG_INSTALL_NAME_x86_64-unknown-linux-gnu =
CFG_LIBUV_LINK_FLAGS_x86_64-unknown-linux-gnu =
CFG_LLVM_BUILD_ENV_x86_64-unknown-linux-gnu="CXXFLAGS=-fno-omit-frame-pointer"
CFG_EXE_SUFFIX_x86_64-unknown-linux-gnu =
CFG_WINDOWSY_x86_64-unknown-linux-gnu :=
CFG_UNIXY_x86_64-unknown-linux-gnu := 1
CFG_PATH_MUNGE_x86_64-unknown-linux-gnu := true
CFG_LDPATH_x86_64-unknown-linux-gnu :=
CFG_RUN_x86_64-unknown-linux-gnu=$(2)
CFG_RUN_TARG_x86_64-unknown-linux-gnu=$(call CFG_RUN_x86_64-unknown-linux-gnu,,$(2))
CFG_RLIB_GLOB=lib$(1)-*.rlib
# i686-unknown-linux-gnu configuration
CC_i686-unknown-linux-gnu=$(CC)
CXX_i686-unknown-linux-gnu=$(CXX)
CPP_i686-unknown-linux-gnu=$(CPP)
AR_i686-unknown-linux-gnu=$(AR)
CFG_LIB_NAME_i686-unknown-linux-gnu=lib$(1).so
CFG_LIB_GLOB_i686-unknown-linux-gnu=lib$(1)-*.so
CFG_LIB_DSYM_GLOB_i686-unknown-linux-gnu=lib$(1)-*.dylib.dSYM
CFG_GCCISH_CFLAGS_i686-unknown-linux-gnu := -Wall -Werror -g -fPIC -m32
CFG_GCCISH_CXXFLAGS_i686-unknown-linux-gnu := -fno-rtti
CFG_GCCISH_LINK_FLAGS_i686-unknown-linux-gnu := -shared -fPIC -ldl -pthread -lrt -g -m32
CFG_GCCISH_DEF_FLAG_i686-unknown-linux-gnu := -Wl,--export-dynamic,--dynamic-list=
CFG_GCCISH_PRE_LIB_FLAGS_i686-unknown-linux-gnu := -Wl,-whole-archive
CFG_GCCISH_POST_LIB_FLAGS_i686-unknown-linux-gnu := -Wl,-no-whole-archive
CFG_DEF_SUFFIX_i686-unknown-linux-gnu := .linux.def
CFG_INSTALL_NAME_i686-unknown-linux-gnu =
CFG_LIBUV_LINK_FLAGS_i686-unknown-linux-gnu =
CFG_LLVM_BUILD_ENV_i686-unknown-linux-gnu="CXXFLAGS=-fno-omit-frame-pointer"
CFG_EXE_SUFFIX_i686-unknown-linux-gnu =
CFG_WINDOWSY_i686-unknown-linux-gnu :=
CFG_UNIXY_i686-unknown-linux-gnu := 1
CFG_PATH_MUNGE_i686-unknown-linux-gnu := true
CFG_LDPATH_i686-unknown-linux-gnu :=
CFG_RUN_i686-unknown-linux-gnu=$(2)
CFG_RUN_TARG_i686-unknown-linux-gnu=$(call CFG_RUN_i686-unknown-linux-gnu,,$(2))
include $(wildcard $(CFG_SRC_DIR)mk/cfg/*.mk)
# x86_64-apple-darwin configuration
CC_x86_64-apple-darwin=$(CC)
CXX_x86_64-apple-darwin=$(CXX)
CPP_x86_64-apple-darwin=$(CPP)
AR_x86_64-apple-darwin=$(AR)
CFG_LIB_NAME_x86_64-apple-darwin=lib$(1).dylib
CFG_LIB_GLOB_x86_64-apple-darwin=lib$(1)-*.dylib
CFG_LIB_DSYM_GLOB_x86_64-apple-darwin=lib$(1)-*.dylib.dSYM
CFG_GCCISH_CFLAGS_x86_64-apple-darwin := -Wall -Werror -g -fPIC -m64 -arch x86_64
CFG_GCCISH_CXXFLAGS_x86_64-apple-darwin := -fno-rtti
CFG_GCCISH_LINK_FLAGS_x86_64-apple-darwin := -dynamiclib -pthread -framework CoreServices -Wl,-no_compact_unwind -m64
CFG_GCCISH_DEF_FLAG_x86_64-apple-darwin := -Wl,-exported_symbols_list,
CFG_GCCISH_PRE_LIB_FLAGS_x86_64-apple-darwin :=
CFG_GCCISH_POST_LIB_FLAGS_x86_64-apple-darwin :=
CFG_DEF_SUFFIX_x86_64-apple-darwin := .darwin.def
CFG_INSTALL_NAME_x86_64-apple-darwin = -Wl,-install_name,@rpath/$(1)
CFG_LIBUV_LINK_FLAGS_x86_64-apple-darwin =
CFG_EXE_SUFFIX_x86_64-apple-darwin :=
CFG_WINDOWSY_x86_64-apple-darwin :=
CFG_UNIXY_x86_64-apple-darwin := 1
CFG_PATH_MUNGE_x86_64-apple-darwin := true
CFG_LDPATH_x86_64-apple-darwin :=
CFG_RUN_x86_64-apple-darwin=$(2)
CFG_RUN_TARG_x86_64-apple-darwin=$(call CFG_RUN_x86_64-apple-darwin,,$(2))
# The -Qunused-arguments sidesteps spurious warnings from clang
define FILTER_FLAGS
ifeq ($$(CFG_USING_CLANG),1)
ifneq ($(findstring clang,$$(shell $(CC_$(1)) -v)),)
CFG_GCCISH_CFLAGS_$(1) += -Qunused-arguments
CFG_GCCISH_CXXFLAGS_$(1) += -Qunused-arguments
endif
endif
endef
# i686-apple-darwin configuration
CC_i686-apple-darwin=$(CC)
CXX_i686-apple-darwin=$(CXX)
CPP_i686-apple-darwin=$(CPP)
AR_i686-apple-darwin=$(AR)
CFG_LIB_NAME_i686-apple-darwin=lib$(1).dylib
CFG_LIB_GLOB_i686-apple-darwin=lib$(1)-*.dylib
CFG_LIB_DSYM_GLOB_i686-apple-darwin=lib$(1)-*.dylib.dSYM
CFG_GCCISH_CFLAGS_i686-apple-darwin := -Wall -Werror -g -fPIC -m32 -arch i386
CFG_GCCISH_CXXFLAGS_i686-apple-darwin := -fno-rtti
CFG_GCCISH_LINK_FLAGS_i686-apple-darwin := -dynamiclib -pthread -framework CoreServices -Wl,-no_compact_unwind -m32
CFG_GCCISH_DEF_FLAG_i686-apple-darwin := -Wl,-exported_symbols_list,
CFG_GCCISH_PRE_LIB_FLAGS_i686-apple-darwin :=
CFG_GCCISH_POST_LIB_FLAGS_i686-apple-darwin :=
CFG_DEF_SUFFIX_i686-apple-darwin := .darwin.def
CFG_INSTALL_NAME_i686-apple-darwin = -Wl,-install_name,@rpath/$(1)
CFG_LIBUV_LINK_FLAGS_i686-apple-darwin =
CFG_EXE_SUFFIX_i686-apple-darwin :=
CFG_WINDOWSY_i686-apple-darwin :=
CFG_UNIXY_i686-apple-darwin := 1
CFG_PATH_MUNGE_i686-apple-darwin := true
CFG_LDPATH_i686-apple-darwin :=
CFG_RUN_i686-apple-darwin=$(2)
CFG_RUN_TARG_i686-apple-darwin=$(call CFG_RUN_i686-apple-darwin,,$(2))
$(foreach target,$(CFG_TARGET), \
$(eval $(call FILTER_FLAGS,$(target))))
# arm-linux-androideabi configuration
CC_arm-linux-androideabi=$(CFG_ANDROID_CROSS_PATH)/bin/arm-linux-androideabi-gcc
CXX_arm-linux-androideabi=$(CFG_ANDROID_CROSS_PATH)/bin/arm-linux-androideabi-g++
CPP_arm-linux-androideabi=$(CFG_ANDROID_CROSS_PATH)/bin/arm-linux-androideabi-gcc
AR_arm-linux-androideabi=$(CFG_ANDROID_CROSS_PATH)/bin/arm-linux-androideabi-ar
CFG_LIB_NAME_arm-linux-androideabi=lib$(1).so
CFG_LIB_GLOB_arm-linux-androideabi=lib$(1)-*.so
CFG_LIB_DSYM_GLOB_arm-linux-androideabi=lib$(1)-*.dylib.dSYM
CFG_GCCISH_CFLAGS_arm-linux-androideabi := -Wall -g -fPIC -D__arm__ -DANDROID -D__ANDROID__
CFG_GCCISH_CXXFLAGS_arm-linux-androideabi := -fno-rtti
CFG_GCCISH_LINK_FLAGS_arm-linux-androideabi := -shared -fPIC -ldl -g -lm -lsupc++ -lgnustl_shared
CFG_GCCISH_DEF_FLAG_arm-linux-androideabi := -Wl,--export-dynamic,--dynamic-list=
CFG_GCCISH_PRE_LIB_FLAGS_arm-linux-androideabi := -Wl,-whole-archive
CFG_GCCISH_POST_LIB_FLAGS_arm-linux-androideabi := -Wl,-no-whole-archive
CFG_DEF_SUFFIX_arm-linux-androideabi := .android.def
CFG_INSTALL_NAME_arm-linux-androideabi =
CFG_LIBUV_LINK_FLAGS_arm-linux-androideabi =
CFG_EXE_SUFFIX_arm-linux-androideabi :=
CFG_WINDOWSY_arm-linux-androideabi :=
CFG_UNIXY_arm-linux-androideabi := 1
CFG_PATH_MUNGE_arm-linux-androideabi := true
CFG_LDPATH_arm-linux-androideabi :=
CFG_RUN_arm-linux-androideabi=
CFG_RUN_TARG_arm-linux-androideabi=
RUSTC_FLAGS_arm-linux-androideabi :=--android-cross-path=$(CFG_ANDROID_CROSS_PATH)
# arm-unknown-linux-gnueabihf configuration
CC_arm-unknown-linux-gnueabihf=arm-linux-gnueabihf-gcc
CXX_arm-unknown-linux-gnueabihf=arm-linux-gnueabihf-g++
CPP_arm-unknown-linux-gnueabihf=arm-linux-gnueabihf-gcc -E
AR_arm-unknown-linux-gnueabihf=arm-linux-gnueabihf-ar
CFG_LIB_NAME_arm-unknown-linux-gnueabihf=lib$(1).so
CFG_LIB_GLOB_arm-unknown-linux-gnueabihf=lib$(1)-*.so
CFG_LIB_DSYM_GLOB_arm-unknown-linux-gnueabihf=lib$(1)-*.dylib.dSYM
CFG_GCCISH_CFLAGS_arm-unknown-linux-gnueabihf := -Wall -g -fPIC
CFG_GCCISH_CXXFLAGS_arm-unknown-linux-gnueabihf := -fno-rtti
CFG_GCCISH_LINK_FLAGS_arm-unknown-linux-gnueabihf := -shared -fPIC -g
CFG_GCCISH_DEF_FLAG_arm-unknown-linux-gnueabihf := -Wl,--export-dynamic,--dynamic-list=
CFG_GCCISH_PRE_LIB_FLAGS_arm-unknown-linux-gnueabihf := -Wl,-whole-archive
CFG_GCCISH_POST_LIB_FLAGS_arm-unknown-linux-gnueabihf := -Wl,-no-whole-archive
CFG_DEF_SUFFIX_arm-unknown-linux-gnueabihf := .linux.def
CFG_INSTALL_NAME_ar,-unknown-linux-gnueabihf =
CFG_LIBUV_LINK_FLAGS_arm-unknown-linux-gnueabihf =
CFG_EXE_SUFFIX_arm-unknown-linux-gnueabihf :=
CFG_WINDOWSY_arm-unknown-linux-gnueabihf :=
CFG_UNIXY_arm-unknown-linux-gnueabihf := 1
CFG_PATH_MUNGE_arm-unknown-linux-gnueabihf := true
CFG_LDPATH_arm-unknown-linux-gnueabihf :=
CFG_RUN_arm-unknown-linux-gnueabihf=
CFG_RUN_TARG_arm-unknown-linux-gnueabihf=
RUSTC_FLAGS_arm-unknown-linux-gnueabihf := --linker=$(CC_arm-unknown-linux-gnueabihf)
# mips-unknown-linux-gnu configuration
CC_mips-unknown-linux-gnu=mips-linux-gnu-gcc
CXX_mips-unknown-linux-gnu=mips-linux-gnu-g++
CPP_mips-unknown-linux-gnu=mips-linux-gnu-gcc -E
AR_mips-unknown-linux-gnu=mips-linux-gnu-ar
CFG_LIB_NAME_mips-unknown-linux-gnu=lib$(1).so
CFG_LIB_GLOB_mips-unknown-linux-gnu=lib$(1)-*.so
CFG_LIB_DSYM_GLOB_mips-unknown-linux-gnu=lib$(1)-*.dylib.dSYM
CFG_GCCISH_CFLAGS_mips-unknown-linux-gnu := -Wall -g -fPIC -mips32r2 -msoft-float -mabi=32 -mno-compact-eh
CFG_GCCISH_CXXFLAGS_mips-unknown-linux-gnu := -fno-rtti
CFG_GCCISH_LINK_FLAGS_mips-unknown-linux-gnu := -shared -fPIC -g -mips32r2 -msoft-float -mabi=32
CFG_GCCISH_DEF_FLAG_mips-unknown-linux-gnu := -Wl,--export-dynamic,--dynamic-list=
CFG_GCCISH_PRE_LIB_FLAGS_mips-unknown-linux-gnu := -Wl,-whole-archive
CFG_GCCISH_POST_LIB_FLAGS_mips-unknown-linux-gnu := -Wl,-no-whole-archive
CFG_DEF_SUFFIX_mips-unknown-linux-gnu := .linux.def
CFG_INSTALL_NAME_mips-unknown-linux-gnu =
CFG_LIBUV_LINK_FLAGS_mips-unknown-linux-gnu =
CFG_EXE_SUFFIX_mips-unknown-linux-gnu :=
CFG_WINDOWSY_mips-unknown-linux-gnu :=
CFG_UNIXY_mips-unknown-linux-gnu := 1
CFG_PATH_MUNGE_mips-unknown-linux-gnu := true
CFG_LDPATH_mips-unknown-linux-gnu :=
CFG_RUN_mips-unknown-linux-gnu=
CFG_RUN_TARG_mips-unknown-linux-gnu=
# i686-pc-mingw32 configuration
CC_i686-pc-mingw32=$(CC)
CXX_i686-pc-mingw32=$(CXX)
CPP_i686-pc-mingw32=$(CPP)
AR_i686-pc-mingw32=$(AR)
CFG_LIB_NAME_i686-pc-mingw32=$(1).dll
CFG_LIB_GLOB_i686-pc-mingw32=$(1)-*.dll
CFG_LIB_DSYM_GLOB_i686-pc-mingw32=$(1)-*.dylib.dSYM
CFG_GCCISH_CFLAGS_i686-pc-mingw32 := -Wall -Werror -g -march=i686
CFG_GCCISH_CXXFLAGS_i686-pc-mingw32 := -fno-rtti
CFG_GCCISH_LINK_FLAGS_i686-pc-mingw32 := -shared -fPIC -g
CFG_GCCISH_DEF_FLAG_i686-pc-mingw32 :=
CFG_GCCISH_PRE_LIB_FLAGS_i686-pc-mingw32 :=
CFG_GCCISH_POST_LIB_FLAGS_i686-pc-mingw32 :=
CFG_DEF_SUFFIX_i686-pc-mingw32 := .mingw32.def
CFG_INSTALL_NAME_i686-pc-mingw32 =
CFG_LIBUV_LINK_FLAGS_i686-pc-mingw32 := -lWs2_32 -lpsapi -liphlpapi
CFG_EXE_SUFFIX_i686-pc-mingw32 := .exe
CFG_WINDOWSY_i686-pc-mingw32 := 1
CFG_UNIXY_i686-pc-mingw32 :=
CFG_PATH_MUNGE_i686-pc-mingw32 :=
CFG_LDPATH_i686-pc-mingw32 :=$(CFG_LDPATH_i686-pc-mingw32):$(PATH)
CFG_RUN_i686-pc-mingw32=PATH="$(CFG_LDPATH_i686-pc-mingw32):$(1)" $(2)
CFG_RUN_TARG_i686-pc-mingw32=$(call CFG_RUN_i686-pc-mingw32,$(HLIB$(1)_H_$(CFG_BUILD_TRIPLE)),$(2))
# i586-mingw32msvc configuration
CC_i586-mingw32msvc=$(CFG_MINGW32_CROSS_PATH)/bin/i586-mingw32msvc-gcc
CXX_i586-mingw32msvc=$(CFG_MINGW32_CROSS_PATH)/bin/i586-mingw32msvc-g++
CPP_i586-mingw32msvc=$(CFG_MINGW32_CROSS_PATH)/bin/i586-mingw32msvc-cpp
AR_i586-mingw32msvc=$(CFG_MINGW32_CROSS_PATH)/bin/i586-mingw32msvc-ar
CFG_LIB_NAME_i586-mingw32msvc=$(1).dll
CFG_LIB_GLOB_i586-mingw32msvc=$(1)-*.dll
CFG_LIB_DSYM_GLOB_i586-mingw32msvc=$(1)-*.dylib.dSYM
CFG_GCCISH_CFLAGS_i586-mingw32msvc := -Wall -Werror -g -march=i586 -m32
CFG_GCCISH_CXXFLAGS_i586-mingw32msvc := -fno-rtti
CFG_GCCISH_LINK_FLAGS_i586-mingw32msvc := -shared -g -m32
CFG_GCCISH_DEF_FLAG_i586-mingw32msvc :=
CFG_GCCISH_PRE_LIB_FLAGS_i586-mingw32msvc :=
CFG_GCCISH_POST_LIB_FLAGS_i586-mingw32msvc :=
CFG_DEF_SUFFIX_i586-mingw32msvc := .mingw32.def
CFG_INSTALL_NAME_i586-mingw32msvc =
CFG_LIBUV_LINK_FLAGS_i586-mingw32msvc := -L$(CFG_MINGW32_CROSS_PATH)/i586-mingw32msvc/lib -lws2_32 -lpsapi -liphlpapi
CFG_EXE_SUFFIX_i586-mingw32msvc := .exe
CFG_WINDOWSY_i586-mingw32msvc := 1
CFG_UNIXY_i586-mingw32msvc :=
CFG_PATH_MUNGE_i586-mingw32msvc := $(strip perl -i.bak -p \
-e 's@\\(\S)@/\1@go;' \
-e 's@^/([a-zA-Z])/@\1:/@o;')
CFG_LDPATH_i586-mingw32msvc :=
CFG_RUN_i586-mingw32msvc=
CFG_RUN_TARG_i586-mingw32msvc=
# x86_64-unknown-freebsd configuration
CC_x86_64-unknown-freebsd=$(CC)
CXX_x86_64-unknown-freebsd=$(CXX)
CPP_x86_64-unknown-freebsd=$(CPP)
AR_x86_64-unknown-freebsd=$(AR)
CFG_LIB_NAME_x86_64-unknown-freebsd=lib$(1).so
CFG_LIB_GLOB_x86_64-unknown-freebsd=lib$(1)-*.so
CFG_LIB_DSYM_GLOB_x86_64-unknown-freebsd=$(1)-*.dylib.dSYM
CFG_GCCISH_CFLAGS_x86_64-unknown-freebsd := -Wall -Werror -g -fPIC -I/usr/local/include
CFG_GCCISH_LINK_FLAGS_x86_64-unknown-freebsd := -shared -fPIC -g -pthread -lrt
CFG_GCCISH_DEF_FLAG_x86_64-unknown-freebsd := -Wl,--export-dynamic,--dynamic-list=
CFG_GCCISH_PRE_LIB_FLAGS_x86_64-unknown-freebsd := -Wl,-whole-archive
CFG_GCCISH_POST_LIB_FLAGS_x86_64-unknown-freebsd := -Wl,-no-whole-archive
CFG_DEF_SUFFIX_x86_64-unknown-freebsd := .bsd.def
CFG_INSTALL_NAME_x86_64-unknown-freebsd =
CFG_LIBUV_LINK_FLAGS_x86_64-unknown-freebsd := -pthread -lkvm
CFG_EXE_SUFFIX_x86_64-unknown-freebsd :=
CFG_WINDOWSY_x86_64-unknown-freebsd :=
CFG_UNIXY_x86_64-unknown-freebsd := 1
CFG_PATH_MUNGE_x86_64-unknown-freebsd :=
CFG_LDPATH_x86_64-unknown-freebsd :=
CFG_RUN_x86_64-unknown-freebsd=$(2)
CFG_RUN_TARG_x86_64-unknown-freebsd=$(call CFG_RUN_x86_64-unknown-freebsd,,$(2))
ifeq ($(CFG_CCACHE_CPP2),1)
CCACHE_CPP2=1
@ -401,49 +139,64 @@ ifdef CFG_CCACHE_BASEDIR
export CCACHE_BASEDIR
endif
FIND_COMPILER = $(word 1,$(1:ccache=))
define CFG_MAKE_TOOLCHAIN
CFG_COMPILE_C_$(1) = $$(CC_$(1)) \
$$(CFG_GCCISH_CFLAGS) \
# Prepend the tools with their prefix if cross compiling
ifneq ($(CFG_BUILD),$(1))
CC_$(1)=$(CROSS_PREFIX_$(1))$(CC_$(1))
CXX_$(1)=$(CROSS_PREFIX_$(1))$(CXX_$(1))
CPP_$(1)=$(CROSS_PREFIX_$(1))$(CPP_$(1))
AR_$(1)=$(CROSS_PREFIX_$(1))$(AR_$(1))
RUSTC_CROSS_FLAGS_$(1)=-C linker=$$(call FIND_COMPILER,$$(CC_$(1))) \
-C ar=$$(call FIND_COMPILER,$$(AR_$(1))) $(RUSTC_CROSS_FLAGS_$(1))
RUSTC_FLAGS_$(1)=$$(RUSTC_CROSS_FLAGS_$(1)) $(RUSTC_FLAGS_$(1))
endif
CFG_COMPILE_C_$(1) = $$(CC_$(1)) \
$$(CFG_GCCISH_CFLAGS) \
$$(CFG_GCCISH_CFLAGS_$(1)) \
$$(CFG_DEPEND_FLAGS) \
$$(CFG_DEPEND_FLAGS) \
-c -o $$(1) $$(2)
CFG_LINK_C_$(1) = $$(CC_$(1)) \
$$(CFG_GCCISH_LINK_FLAGS) -o $$(1) \
$$(CFG_GCCISH_LINK_FLAGS_$(1))) \
$$(CFG_GCCISH_DEF_FLAG_$(1))$$(3) $$(2) \
$$(CFG_GCCISH_LINK_FLAGS) -o $$(1) \
$$(CFG_GCCISH_LINK_FLAGS_$(1)) \
$$(CFG_GCCISH_DEF_FLAG_$(1))$$(3) $$(2) \
$$(call CFG_INSTALL_NAME_$(1),$$(4))
CFG_COMPILE_CXX_$(1) = $$(CXX_$(1)) \
$$(CFG_GCCISH_CFLAGS) \
$$(CFG_GCCISH_CXXFLAGS) \
$$(CFG_GCCISH_CFLAGS) \
$$(CFG_GCCISH_CXXFLAGS) \
$$(CFG_GCCISH_CFLAGS_$(1)) \
$$(CFG_GCCISH_CXXFLAGS_$(1)) \
$$(CFG_DEPEND_FLAGS) \
$$(CFG_GCCISH_CXXFLAGS_$(1)) \
$$(CFG_DEPEND_FLAGS) \
-c -o $$(1) $$(2)
CFG_LINK_CXX_$(1) = $$(CXX_$(1)) \
$$(CFG_GCCISH_LINK_FLAGS) -o $$(1) \
$$(CFG_GCCISH_LINK_FLAGS_$(1)) \
$$(CFG_GCCISH_DEF_FLAG_$(1))$$(3) $$(2) \
$$(CFG_GCCISH_LINK_FLAGS) -o $$(1) \
$$(CFG_GCCISH_LINK_FLAGS_$(1)) \
$$(CFG_GCCISH_DEF_FLAG_$(1))$$(3) $$(2) \
$$(call CFG_INSTALL_NAME_$(1),$$(4))
ifneq ($(1),arm-linux-androideabi)
ifeq ($$(findstring $(HOST_$(1)),arm aarch64 mips mipsel),)
# We're using llvm-mc as our assembler because it supports
# .cfi pseudo-ops on mac
CFG_ASSEMBLE_$(1)=$$(CPP_$(1)) -E $$(CFG_DEPEND_FLAGS) $$(2) | \
$$(LLVM_MC_$$(CFG_BUILD_TRIPLE)) \
$$(LLVM_MC_$$(CFG_BUILD)) \
-assemble \
-filetype=obj \
-triple=$(1) \
-o=$$(1)
else
# For the Android cross, use the Android assembler
# XXX: We should be able to use the LLVM assembler
CFG_ASSEMBLE_$(1)=$$(CPP_$(1)) $$(CFG_DEPEND_FLAGS) $$(2) -c -o $$(1)
# For the ARM, AARCH64 and MIPS crosses, use the toolchain assembler
# FIXME: We should be able to use the LLVM assembler
CFG_ASSEMBLE_$(1)=$$(CC_$(1)) $$(CFG_GCCISH_CFLAGS_$(1)) \
$$(CFG_DEPEND_FLAGS) $$(2) -c -o $$(1)
endif
endef
$(foreach target,$(CFG_TARGET_TRIPLES),\
$(foreach target,$(CFG_TARGET), \
$(eval $(call CFG_MAKE_TOOLCHAIN,$(target))))

View File

@ -1,40 +0,0 @@
# Copyright 2012 The Rust Project Developers. See the COPYRIGHT
# file at the top-level directory of this distribution and at
# http://rust-lang.org/COPYRIGHT.
#
# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
# option. This file may not be copied, modified, or distributed
# except according to those terms.
# Create a way to reformat just some files
ifdef PPFILES
PP_INPUTS_FILTERED := $(wildcard $(PPFILES))
else
PP_INPUTS = $(wildcard $(addprefix $(S)src/libstd/,*.rs */*.rs)) \
$(wildcard $(addprefix $(S)src/libextra/,*.rs */*.rs)) \
$(wildcard $(addprefix $(S)src/rustc/,*.rs */*.rs */*/*.rs)) \
$(wildcard $(S)src/test/*/*.rs \
$(S)src/test/*/*/*.rs) \
$(wildcard $(S)src/rustpkg/*.rs) \
$(wildcard $(S)src/rusti/*.rs) \
$(wildcard $(S)src/rust/*.rs)
PP_INPUTS_FILTERED = $(shell echo $(PP_INPUTS) | xargs grep -L \
"no-reformat\|xfail-pretty\|xfail-test")
endif
reformat: $(SREQ1$(CFG_BUILD_TRIPLE))
@$(call E, reformat [stage1]: $@)
for i in $(PP_INPUTS_FILTERED); \
do $(call CFG_RUN_TARG_$(CFG_BUILD_TRIPLE),1,$(CFG_BUILD_TRIPLE)/stage1/rustc$(X_$(CFG_BUILD_TRIPLE))) \
--pretty normal $$i >$$i.tmp; \
if [ $$? -ne 0 ]; \
then echo failed to print $$i; rm $$i.tmp; \
else if cmp --silent $$i.tmp $$i; \
then echo no changes to $$i; rm $$i.tmp; \
else echo reformated $$i; mv $$i.tmp $$i; \
fi; \
fi; \
done

225
mk/prepare.mk Normal file
View File

@ -0,0 +1,225 @@
# Copyright 2014 The Rust Project Developers. See the COPYRIGHT
# file at the top-level directory of this distribution and at
# http://rust-lang.org/COPYRIGHT.
#
# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
# option. This file may not be copied, modified, or distributed
# except according to those terms.
# Basic support for producing installation images.
#
# The 'prepare' build target copies all release artifacts from the build
# directory to some other location, placing all binaries, libraries, and
# docs in their final locations relative to each other.
#
# It requires the following variables to be set:
#
# PREPARE_HOST - the host triple
# PREPARE_TARGETS - the target triples, space separated
# PREPARE_DEST_DIR - the directory to put the image
PREPARE_STAGE=2
DEFAULT_PREPARE_DIR_CMD = umask 022 && mkdir -p
DEFAULT_PREPARE_BIN_CMD = install -m755
DEFAULT_PREPARE_LIB_CMD = install -m644
DEFAULT_PREPARE_MAN_CMD = install -m644
# Create a directory
# $(1) is the directory
define PREPARE_DIR
@$(Q)$(call E, prepare: $(1))
$(Q)$(PREPARE_DIR_CMD) $(1)
endef
# Copy an executable
# $(1) is the filename/libname-glob
define PREPARE_BIN
@$(call E, prepare: $(PREPARE_DEST_BIN_DIR)/$(1))
$(Q)$(PREPARE_BIN_CMD) $(PREPARE_SOURCE_BIN_DIR)/$(1) $(PREPARE_DEST_BIN_DIR)/$(1)
endef
# Copy a dylib or rlib
# $(1) is the filename/libname-glob
#
# XXX: Don't remove the $(nop) command below!
# Yeah, that's right, it's voodoo. Something in the way this macro is being expanded
# causes it to parse incorrectly. Throwing in that empty command seems to fix the
# problem. I'm sorry, just don't remove the $(nop), alright?
define PREPARE_LIB
$(nop)
@$(call E, prepare: $(PREPARE_WORKING_DEST_LIB_DIR)/$(1))
$(Q)LIB_NAME="$(notdir $(lastword $(wildcard $(PREPARE_WORKING_SOURCE_LIB_DIR)/$(1))))"; \
MATCHES="$(filter-out %$(notdir $(lastword $(wildcard $(PREPARE_WORKING_SOURCE_LIB_DIR)/$(1)))), \
$(wildcard $(PREPARE_WORKING_DEST_LIB_DIR)/$(1)))"; \
if [ -n "$$MATCHES" ]; then \
echo "warning: one or libraries matching Rust library '$(1)'" && \
echo " (other than '$$LIB_NAME' itself) already present" && \
echo " at destination $(PREPARE_WORKING_DEST_LIB_DIR):" && \
echo $$MATCHES ; \
fi
$(Q)$(PREPARE_LIB_CMD) `ls -drt1 $(PREPARE_WORKING_SOURCE_LIB_DIR)/$(1) | tail -1` $(PREPARE_WORKING_DEST_LIB_DIR)/
endef
# Copy a man page
# $(1) - source dir
define PREPARE_MAN
@$(call E, prepare: $(PREPARE_DEST_MAN_DIR)/$(1))
$(Q)$(PREPARE_MAN_CMD) $(PREPARE_SOURCE_MAN_DIR)/$(1) $(PREPARE_DEST_MAN_DIR)/$(1)
endef
PREPARE_TOOLS = $(filter-out compiletest rustbook, $(TOOLS))
# $(1) is tool
# $(2) is stage
# $(3) is host
# $(4) tag
define DEF_PREPARE_HOST_TOOL
prepare-host-tool-$(1)-$(2)-$(3)-$(4): prepare-maybe-clean-$(4) \
$$(foreach dep,$$(TOOL_DEPS_$(1)),prepare-host-lib-$$(dep)-$(2)-$(3)-$(4)) \
$$(HBIN$(2)_H_$(3))/$(1)$$(X_$(3)) \
prepare-host-dirs-$(4)
$$(if $$(findstring $(2), $$(PREPARE_STAGE)), \
$$(if $$(findstring $(3), $$(PREPARE_HOST)), \
$$(call PREPARE_BIN,$(1)$$(X_$$(PREPARE_HOST))),),)
$$(if $$(findstring $(2), $$(PREPARE_STAGE)), \
$$(if $$(findstring $(3), $$(PREPARE_HOST)), \
$$(call PREPARE_MAN,$(1).1),),)
endef
# For host libraries only install dylibs, not rlibs since the host libs are only
# used to support rustc and rustc uses dynamic linking
#
# $(1) is tool
# $(2) is stage
# $(3) is host
# $(4) tag
define DEF_PREPARE_HOST_LIB
prepare-host-lib-$(1)-$(2)-$(3)-$(4): PREPARE_WORKING_SOURCE_LIB_DIR=$$(PREPARE_SOURCE_LIB_DIR)
prepare-host-lib-$(1)-$(2)-$(3)-$(4): PREPARE_WORKING_DEST_LIB_DIR=$$(PREPARE_DEST_LIB_DIR)
prepare-host-lib-$(1)-$(2)-$(3)-$(4): prepare-maybe-clean-$(4) \
$$(foreach dep,$$(RUST_DEPS_$(1)),prepare-host-lib-$$(dep)-$(2)-$(3)-$(4)) \
$$(HLIB$(2)_H_$(3))/stamp.$(1) \
prepare-host-dirs-$(4)
$$(if $$(findstring $(2), $$(PREPARE_STAGE)), \
$$(if $$(findstring $(3), $$(PREPARE_HOST)), \
$$(if $$(findstring 1,$$(ONLY_RLIB_$(1))),, \
$$(call PREPARE_LIB,$$(call CFG_LIB_GLOB_$$(PREPARE_HOST),$(1)))),),)
endef
# $(1) is stage
# $(2) is target
# $(3) is host
# $(4) tag
define DEF_PREPARE_TARGET_N
# Rebind PREPARE_*_LIB_DIR to point to rustlib, then install the libs for the targets
prepare-target-$(2)-host-$(3)-$(1)-$(4): PREPARE_WORKING_SOURCE_LIB_DIR=$$(PREPARE_SOURCE_LIB_DIR)/rustlib/$(2)/lib
prepare-target-$(2)-host-$(3)-$(1)-$(4): PREPARE_WORKING_DEST_LIB_DIR=$$(PREPARE_DEST_LIB_DIR)/rustlib/$(2)/lib
prepare-target-$(2)-host-$(3)-$(1)-$(4): prepare-maybe-clean-$(4) \
$$(foreach crate,$$(TARGET_CRATES), \
$$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$$(crate)) \
$$(if $$(findstring $(2),$$(CFG_HOST)), \
$$(foreach crate,$$(HOST_CRATES), \
$$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$$(crate)),)
# Only install if this host and target combo is being prepared. Also be sure to
# *not* install the rlibs for host crates because there's no need to statically
# link against most of them. They just produce a large amount of extra size
# bloat.
$$(if $$(findstring $(1), $$(PREPARE_STAGE)), \
$$(if $$(findstring $(2), $$(PREPARE_TARGETS)), \
$$(if $$(findstring $(3), $$(PREPARE_HOST)), \
$$(call PREPARE_DIR,$$(PREPARE_WORKING_DEST_LIB_DIR)) \
$$(foreach crate,$$(TARGET_CRATES), \
$$(if $$(findstring 1, $$(ONLY_RLIB_$$(crate))),, \
$$(call PREPARE_LIB,$$(call CFG_LIB_GLOB_$(2),$$(crate)))) \
$$(call PREPARE_LIB,$$(call CFG_RLIB_GLOB,$$(crate)))) \
$$(if $$(findstring $(2),$$(CFG_HOST)), \
$$(foreach crate,$$(HOST_CRATES), \
$$(call PREPARE_LIB,$$(call CFG_LIB_GLOB_$(2),$$(crate)))),) \
$$(call PREPARE_LIB,libmorestack.a) \
$$(call PREPARE_LIB,libcompiler-rt.a),),),)
endef
define INSTALL_GDB_DEBUGGER_SCRIPTS_COMMANDS
$(Q)$(PREPARE_BIN_CMD) $(DEBUGGER_BIN_SCRIPTS_GDB_ABS) $(PREPARE_DEST_BIN_DIR)
$(Q)$(PREPARE_LIB_CMD) $(DEBUGGER_RUSTLIB_ETC_SCRIPTS_GDB_ABS) $(PREPARE_DEST_LIB_DIR)/rustlib/etc
endef
define INSTALL_LLDB_DEBUGGER_SCRIPTS_COMMANDS
$(Q)$(PREPARE_BIN_CMD) $(DEBUGGER_BIN_SCRIPTS_LLDB_ABS) $(PREPARE_DEST_BIN_DIR)
$(Q)$(PREPARE_LIB_CMD) $(DEBUGGER_RUSTLIB_ETC_SCRIPTS_LLDB_ABS) $(PREPARE_DEST_LIB_DIR)/rustlib/etc
endef
define INSTALL_NO_DEBUGGER_SCRIPTS_COMMANDS
$(Q)echo "No debugger scripts will be installed for host $(PREPARE_HOST)"
endef
# $(1) is PREPARE_HOST
INSTALL_DEBUGGER_SCRIPT_COMMANDS=$(if $(findstring windows,$(1)),\
$(INSTALL_NO_DEBUGGER_SCRIPTS_COMMANDS),\
$(if $(findstring darwin,$(1)),\
$(INSTALL_LLDB_DEBUGGER_SCRIPTS_COMMANDS),\
$(INSTALL_GDB_DEBUGGER_SCRIPTS_COMMANDS)))
define DEF_PREPARE
prepare-base-$(1): PREPARE_SOURCE_DIR=$$(PREPARE_HOST)/stage$$(PREPARE_STAGE)
prepare-base-$(1): PREPARE_SOURCE_BIN_DIR=$$(PREPARE_SOURCE_DIR)/bin
prepare-base-$(1): PREPARE_SOURCE_LIB_DIR=$$(PREPARE_SOURCE_DIR)/$$(CFG_LIBDIR_RELATIVE)
prepare-base-$(1): PREPARE_SOURCE_MAN_DIR=$$(S)/man
prepare-base-$(1): PREPARE_DEST_BIN_DIR=$$(PREPARE_DEST_DIR)/bin
prepare-base-$(1): PREPARE_DEST_LIB_DIR=$$(PREPARE_DEST_DIR)/$$(CFG_LIBDIR_RELATIVE)
prepare-base-$(1): PREPARE_DEST_MAN_DIR=$$(PREPARE_DEST_DIR)/share/man/man1
prepare-base-$(1): prepare-everything-$(1)
prepare-everything-$(1): prepare-host-$(1) prepare-targets-$(1) prepare-debugger-scripts-$(1)
prepare-host-$(1): prepare-host-tools-$(1)
prepare-host-tools-$(1): \
$$(foreach tool, $$(PREPARE_TOOLS), \
$$(foreach host,$$(CFG_HOST), \
prepare-host-tool-$$(tool)-$$(PREPARE_STAGE)-$$(host)-$(1)))
prepare-host-dirs-$(1): prepare-maybe-clean-$(1)
$$(call PREPARE_DIR,$$(PREPARE_DEST_BIN_DIR))
$$(call PREPARE_DIR,$$(PREPARE_DEST_LIB_DIR))
$$(call PREPARE_DIR,$$(PREPARE_DEST_LIB_DIR)/rustlib/etc)
$$(call PREPARE_DIR,$$(PREPARE_DEST_MAN_DIR))
prepare-debugger-scripts-$(1): prepare-host-dirs-$(1) \
$$(DEBUGGER_BIN_SCRIPTS_ALL_ABS) \
$$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_ALL_ABS)
$$(call INSTALL_DEBUGGER_SCRIPT_COMMANDS,$$(PREPARE_HOST))
$$(foreach tool,$$(PREPARE_TOOLS), \
$$(foreach host,$$(CFG_HOST), \
$$(eval $$(call DEF_PREPARE_HOST_TOOL,$$(tool),$$(PREPARE_STAGE),$$(host),$(1)))))
$$(foreach lib,$$(CRATES), \
$$(foreach host,$$(CFG_HOST), \
$$(eval $$(call DEF_PREPARE_HOST_LIB,$$(lib),$$(PREPARE_STAGE),$$(host),$(1)))))
prepare-targets-$(1): \
$$(foreach host,$$(CFG_HOST), \
$$(foreach target,$$(CFG_TARGET), \
prepare-target-$$(target)-host-$$(host)-$$(PREPARE_STAGE)-$(1)))
$$(foreach host,$$(CFG_HOST), \
$$(foreach target,$$(CFG_TARGET), \
$$(eval $$(call DEF_PREPARE_TARGET_N,$$(PREPARE_STAGE),$$(target),$$(host),$(1)))))
prepare-maybe-clean-$(1):
$$(if $$(findstring true,$$(PREPARE_CLEAN)), \
@$$(call E, cleaning destination $$(PREPARE_DEST_DIR)),)
$$(if $$(findstring true,$$(PREPARE_CLEAN)), \
$$(Q)rm -rf $$(PREPARE_DEST_DIR),)
endef

37
mk/reconfig.mk Normal file
View File

@ -0,0 +1,37 @@
# Copyright 2014 The Rust Project Developers. See the COPYRIGHT
# file at the top-level directory of this distribution and at
# http://rust-lang.org/COPYRIGHT.
#
# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
# option. This file may not be copied, modified, or distributed
# except according to those terms.
# Recursive wildcard function
# http://blog.jgc.org/2011/07/gnu-make-recursive-wildcard-function.html
rwildcard=$(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2) \
$(filter $(subst *,%,$2),$d))
ifndef CFG_DISABLE_MANAGE_SUBMODULES
# This is a pretty expensive operation but I don't see any way to avoid it
# NB: This only looks for '+' status (wrong commit checked out), not '-' status
# (nothing checked out at all). `./configure --{llvm,jemalloc}-root`
# will explicitly deinitialize the corresponding submodules, and we don't
# want to force constant rebuilds in that case.
NEED_GIT_RECONFIG=$(shell cd "$(CFG_SRC_DIR)" && $(CFG_GIT) submodule status | grep -c '^+')
else
NEED_GIT_RECONFIG=0
endif
ifeq ($(NEED_GIT_RECONFIG),0)
else
# If the submodules have changed then always execute config.mk
.PHONY: config.stamp
endif
Makefile config.mk: config.stamp
config.stamp: $(S)configure $(S)Makefile.in $(S)src/snapshots.txt
@$(call E, cfg: reconfiguring)
$(S)configure $(CFG_CONFIGURE_ARGS)

541
mk/rt.mk
View File

@ -1,272 +1,315 @@
# This is a procedure to define the targets for building
# the runtime.
# Copyright 2014 The Rust Project Developers. See the COPYRIGHT
# file at the top-level directory of this distribution and at
# http://rust-lang.org/COPYRIGHT.
#
# Argument 1 is the target triple.
# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
# option. This file may not be copied, modified, or distributed
# except according to those terms.
################################################################################
# Native libraries built as part of the rust build process
#
# This is not really the right place to explain this, but
# for those of you who are not Makefile gurus, let me briefly
# cover the $ expansion system in use here, because it
# confused me for a while! The variable DEF_RUNTIME_TARGETS
# will be defined once and then expanded with different
# values substituted for $(1) each time it is called.
# That resulting text is then eval'd.
# This portion of the rust build system is meant to keep track of native
# dependencies and how to build them. It is currently required that all native
# dependencies are built as static libraries, as slinging around dynamic
# libraries isn't exactly the most fun thing to do.
#
# For most variables, you could use a single $ sign. The result
# is that the substitution would occur when the CALL occurs,
# I believe. The problem is that the automatic variables $< and $@
# need to be expanded-per-rule. Therefore, for those variables at
# least, you need $$< and $$@ in the variable text. This way, after
# the CALL substitution occurs, you will have $< and $@. This text
# will then be evaluated, and all will work as you like.
# This section should need minimal modification to add new libraries. The
# relevant variables are:
#
# Reader beware, this explanantion could be wrong, but it seems to
# fit the experimental data (i.e., I was able to get the system
# working under these assumptions).
# Hack for passing flags into LIBUV, see below.
LIBUV_FLAGS_i386 = -m32 -fPIC
LIBUV_FLAGS_x86_64 = -m64 -fPIC
ifeq ($(OSTYPE_$(1)), linux-androideabi)
LIBUV_FLAGS_arm = -fPIC -DANDROID -std=gnu99
else
LIBUV_FLAGS_arm = -fPIC -std=gnu99
endif
LIBUV_FLAGS_mips = -fPIC -mips32r2 -msoft-float -mabi=32
# when we're doing a snapshot build, we intentionally degrade as many
# features in libuv and the runtime as possible, to ease portability.
SNAP_DEFINES:=
ifneq ($(strip $(findstring snap,$(MAKECMDGOALS))),)
SNAP_DEFINES=-DRUST_SNAPSHOT
endif
define DEF_RUNTIME_TARGETS
######################################################################
# Runtime (C++) library variables
######################################################################
# NATIVE_LIBS
# This is a list of all native libraries which are built as part of the
# build process. It will build all libraries into RT_OUTPUT_DIR with the
# appropriate name of static library as dictated by the target platform
#
# NATIVE_DEPS_<lib>
# This is a list of files relative to the src/rt directory which are
# needed to build the native library. Each file will be compiled to an
# object file, and then all the object files will be assembled into an
# archive (static library). The list contains files of any extension
#
# If adding a new library, you should update the NATIVE_LIBS list, and then list
# the required files below it. The list of required files is a list of files
# that's per-target so you're allowed to conditionally add files based on the
# target.
################################################################################
NATIVE_LIBS := rust_builtin hoedown morestack miniz \
rustrt_native rust_test_helpers
# $(1) is the target triple
# $(2) is the stage number
define NATIVE_LIBRARIES
RUNTIME_CFLAGS_$(1)_$(2) = -D_RUST_STAGE$(2)
RUNTIME_CXXFLAGS_$(1)_$(2) = -D_RUST_STAGE$(2)
NATIVE_DEPS_hoedown_$(1) := hoedown/src/autolink.c \
hoedown/src/buffer.c \
hoedown/src/document.c \
hoedown/src/escape.c \
hoedown/src/html.c \
hoedown/src/html_blocks.c \
hoedown/src/html_smartypants.c \
hoedown/src/stack.c \
hoedown/src/version.c
NATIVE_DEPS_miniz_$(1) = miniz.c
NATIVE_DEPS_rust_builtin_$(1) := rust_builtin.c \
rust_android_dummy.c
NATIVE_DEPS_rustrt_native_$(1) := \
rust_try.ll \
arch/$$(HOST_$(1))/record_sp.S
NATIVE_DEPS_rust_test_helpers_$(1) := rust_test_helpers.c
NATIVE_DEPS_morestack_$(1) := arch/$$(HOST_$(1))/morestack.S
# XXX: Like with --cfg stage0, pass the defines for stage1 to the stage0
# build of non-build-triple host compilers
ifeq ($(2),0)
ifneq ($(strip $(CFG_BUILD_TRIPLE)),$(strip $(1)))
RUNTIME_CFLAGS_$(1)_$(2) = -D_RUST_STAGE1
RUNTIME_CXXFLAGS_$(1)_$(2) = -D_RUST_STAGE1
endif
endif
RUNTIME_CXXS_$(1)_$(2) := \
rt/sync/timer.cpp \
rt/sync/lock_and_signal.cpp \
rt/sync/rust_thread.cpp \
rt/rust.cpp \
rt/rust_builtin.cpp \
rt/rust_run_program.cpp \
rt/rust_env.cpp \
rt/rust_rng.cpp \
rt/rust_sched_loop.cpp \
rt/rust_sched_launcher.cpp \
rt/rust_sched_driver.cpp \
rt/rust_scheduler.cpp \
rt/rust_sched_reaper.cpp \
rt/rust_task.cpp \
rt/rust_stack.cpp \
rt/rust_upcall.cpp \
rt/rust_uv.cpp \
rt/rust_crate_map.cpp \
rt/rust_log.cpp \
rt/rust_gc_metadata.cpp \
rt/rust_util.cpp \
rt/rust_exchange_alloc.cpp \
rt/isaac/randport.cpp \
rt/miniz.cpp \
rt/rust_kernel.cpp \
rt/rust_abi.cpp \
rt/rust_debug.cpp \
rt/memory_region.cpp \
rt/boxed_region.cpp \
rt/arch/$$(HOST_$(1))/context.cpp \
rt/arch/$$(HOST_$(1))/gpr.cpp \
rt/rust_android_dummy.cpp \
rt/rust_test_helpers.cpp
################################################################################
# You shouldn't find it that necessary to edit anything below this line.
################################################################################
RUNTIME_CS_$(1)_$(2) := rt/linenoise/linenoise.c rt/linenoise/utf8.c
# While we're defining the native libraries for each target, we define some
# common rules used to build files for various targets.
RUNTIME_S_$(1)_$(2) := rt/arch/$$(HOST_$(1))/_context.S \
rt/arch/$$(HOST_$(1))/ccall.S \
rt/arch/$$(HOST_$(1))/record_sp.S
RT_OUTPUT_DIR_$(1) := $(1)/rt
ifeq ($$(CFG_WINDOWSY_$(1)), 1)
LIBUV_OSTYPE_$(1)_$(2) := win
LIBUV_LIB_$(1)_$(2) := rt/$(1)/stage$(2)/libuv/libuv.a
JEMALLOC_LIB_$(1)_$(2) := rt/$(1)/stage$(2)/jemalloc/lib/jemalloc.lib
else ifeq ($(OSTYPE_$(1)), apple-darwin)
LIBUV_OSTYPE_$(1)_$(2) := mac
LIBUV_LIB_$(1)_$(2) := rt/$(1)/stage$(2)/libuv/libuv.a
JEMALLOC_LIB_$(1)_$(2) := rt/$(1)/stage$(2)/jemalloc/lib/libjemalloc_pic.a
else ifeq ($(OSTYPE_$(1)), unknown-freebsd)
LIBUV_OSTYPE_$(1)_$(2) := unix/freebsd
LIBUV_LIB_$(1)_$(2) := rt/$(1)/stage$(2)/libuv/libuv.a
JEMALLOC_LIB_$(1)_$(2) := rt/$(1)/stage$(2)/jemalloc/lib/libjemalloc_pic.a
else ifeq ($(OSTYPE_$(1)), linux-androideabi)
LIBUV_OSTYPE_$(1)_$(2) := unix/android
LIBUV_LIB_$(1)_$(2) := rt/$(1)/stage$(2)/libuv/libuv.a
JEMALLOC_LIB_$(1)_$(2) := rt/$(1)/stage$(2)/jemalloc/lib/libjemalloc_pic.a
else
LIBUV_OSTYPE_$(1)_$(2) := unix/linux
LIBUV_LIB_$(1)_$(2) := rt/$(1)/stage$(2)/libuv/libuv.a
JEMALLOC_LIB_$(1)_$(2) := rt/$(1)/stage$(2)/jemalloc/lib/libjemalloc_pic.a
endif
RUNTIME_DEF_$(1)_$(2) := rt/rustrt$(CFG_DEF_SUFFIX_$(1))
RUNTIME_INCS_$(1)_$(2) := -I $$(S)src/rt -I $$(S)src/rt/isaac -I $$(S)src/rt/uthash \
-I $$(S)src/rt/arch/$$(HOST_$(1)) \
-I $$(S)src/rt/linenoise \
-I $$(S)src/libuv/include
RUNTIME_OBJS_$(1)_$(2) := $$(RUNTIME_CXXS_$(1)_$(2):rt/%.cpp=rt/$(1)/stage$(2)/%.o) \
$$(RUNTIME_CS_$(1)_$(2):rt/%.c=rt/$(1)/stage$(2)/%.o) \
$$(RUNTIME_S_$(1)_$(2):rt/%.S=rt/$(1)/stage$(2)/%.o)
ALL_OBJ_FILES += $$(RUNTIME_OBJS_$(1)_$(2))
MORESTACK_OBJ_$(1)_$(2) := rt/$(1)/stage$(2)/arch/$$(HOST_$(1))/morestack.o
ALL_OBJ_FILES += $$(MORESTACK_OBJS_$(1)_$(2))
rt/$(1)/stage$(2)/%.o: rt/%.cpp $$(MKFILE_DEPS)
$$(RT_OUTPUT_DIR_$(1))/%.o: $(S)src/rt/%.ll $$(MKFILE_DEPS) \
$$(LLVM_CONFIG_$$(CFG_BUILD))
@mkdir -p $$(@D)
@$$(call E, compile: $$@)
$$(Q)$$(call CFG_COMPILE_CXX_$(1), $$@, $$(RUNTIME_INCS_$(1)_$(2)) \
$$(SNAP_DEFINES) $$(RUNTIME_CXXFLAGS_$(1)_$(2))) $$<
$$(Q)$$(LLC_$$(CFG_BUILD)) $$(CFG_LLC_FLAGS_$(1)) \
-filetype=obj -mtriple=$$(CFG_LLVM_TARGET_$(1)) -relocation-model=pic -o $$@ $$<
rt/$(1)/stage$(2)/%.o: rt/%.c $$(MKFILE_DEPS)
$$(RT_OUTPUT_DIR_$(1))/%.o: $(S)src/rt/%.c $$(MKFILE_DEPS)
@mkdir -p $$(@D)
@$$(call E, compile: $$@)
$$(Q)$$(call CFG_COMPILE_C_$(1), $$@, $$(RUNTIME_INCS_$(1)_$(2)) \
$$(SNAP_DEFINES) $$(RUNTIME_CFLAGS_$(1)_$(2))) $$<
$$(Q)$$(call CFG_COMPILE_C_$(1), $$@, \
-I $$(S)src/rt/hoedown/src \
-I $$(S)src/rt \
$$(RUNTIME_CFLAGS_$(1))) $$<
rt/$(1)/stage$(2)/%.o: rt/%.S $$(MKFILE_DEPS) \
$$(LLVM_CONFIG_$$(CFG_BUILD_TRIPLE))
$$(RT_OUTPUT_DIR_$(1))/%.o: $(S)src/rt/%.S $$(MKFILE_DEPS) \
$$(LLVM_CONFIG_$$(CFG_BUILD))
@mkdir -p $$(@D)
@$$(call E, compile: $$@)
$$(Q)$$(call CFG_ASSEMBLE_$(1),$$@,$$<)
endef
rt/$(1)/stage$(2)/arch/$$(HOST_$(1))/libmorestack.a: $$(MORESTACK_OBJ_$(1)_$(2))
$(foreach target,$(CFG_TARGET),$(eval $(call NATIVE_LIBRARIES,$(target))))
# A macro for devining how to build third party libraries listed above (based
# on their dependencies).
#
# $(1) is the target
# $(2) is the lib name
define THIRD_PARTY_LIB
OBJS_$(2)_$(1) := $$(NATIVE_DEPS_$(2)_$(1):%=$$(RT_OUTPUT_DIR_$(1))/%)
OBJS_$(2)_$(1) := $$(OBJS_$(2)_$(1):.c=.o)
OBJS_$(2)_$(1) := $$(OBJS_$(2)_$(1):.cpp=.o)
OBJS_$(2)_$(1) := $$(OBJS_$(2)_$(1):.ll=.o)
OBJS_$(2)_$(1) := $$(OBJS_$(2)_$(1):.S=.o)
NATIVE_$(2)_$(1) := $$(call CFG_STATIC_LIB_NAME_$(1),$(2))
$$(RT_OUTPUT_DIR_$(1))/$$(NATIVE_$(2)_$(1)): $$(OBJS_$(2)_$(1))
@$$(call E, link: $$@)
$$(Q)$(AR_$(1)) rcs $$@ $$<
rt/$(1)/stage$(2)/$(CFG_RUNTIME_$(1)): $$(RUNTIME_OBJS_$(1)_$(2)) $$(MKFILE_DEPS) \
$$(RUNTIME_DEF_$(1)_$(2)) $$(LIBUV_LIB_$(1)_$(2))
@$$(call E, link: $$@)
$$(Q)$$(call CFG_LINK_CXX_$(1),$$@, $$(RUNTIME_OBJS_$(1)_$(2)) \
$$(CFG_GCCISH_POST_LIB_FLAGS_$(1)) $$(LIBUV_LIB_$(1)_$(2)) \
$$(CFG_LIBUV_LINK_FLAGS_$(1)),$$(RUNTIME_DEF_$(1)_$(2)),$$(CFG_RUNTIME_$(1)))
# FIXME: For some reason libuv's makefiles can't figure out the
# correct definition of CC on the mingw I'm using, so we are
# explicitly using gcc. Also, we have to list environment variables
# first on windows... mysterious
ifdef CFG_ENABLE_FAST_MAKE
LIBUV_DEPS := $$(S)/.gitmodules
else
LIBUV_DEPS := $$(wildcard \
$$(S)src/libuv/* \
$$(S)src/libuv/*/* \
$$(S)src/libuv/*/*/* \
$$(S)src/libuv/*/*/*/*)
endif
# XXX: Shouldn't need platform-specific conditions here
ifdef CFG_WINDOWSY_$(1)
$$(LIBUV_LIB_$(1)_$(2)): $$(LIBUV_DEPS)
$$(Q)$$(MAKE) -C $$(S)src/libuv/ \
builddir_name="$$(CFG_BUILD_DIR)/rt/$(1)/stage$(2)/libuv" \
OS=mingw \
V=$$(VERBOSE)
else ifeq ($(OSTYPE_$(1)), linux-androideabi)
$$(LIBUV_LIB_$(1)_$(2)): $$(LIBUV_DEPS)
$$(Q)$$(MAKE) -C $$(S)src/libuv/ \
CFLAGS="$$(CFG_GCCISH_CFLAGS) $$(LIBUV_FLAGS_$$(HOST_$(1))) $$(SNAP_DEFINES)" \
LDFLAGS="$$(CFG_GCCISH_LINK_FLAGS) $$(LIBUV_FLAGS_$$(HOST_$(1)))" \
CC="$$(CC_$(1))" \
CXX="$$(CXX_$(1))" \
AR="$$(AR_$(1))" \
BUILDTYPE=Release \
builddir_name="$$(CFG_BUILD_DIR)/rt/$(1)/stage$(2)/libuv" \
host=android OS=linux \
V=$$(VERBOSE)
else
$$(LIBUV_LIB_$(1)_$(2)): $$(LIBUV_DEPS)
$$(Q)$$(MAKE) -C $$(S)src/libuv/ \
CFLAGS="$$(CFG_GCCISH_CFLAGS) $$(LIBUV_FLAGS_$$(HOST_$(1))) $$(SNAP_DEFINES)" \
LDFLAGS="$$(CFG_GCCISH_LINK_FLAGS) $$(LIBUV_FLAGS_$$(HOST_$(1)))" \
CC="$$(CC_$(1))" \
CXX="$$(CXX_$(1))" \
AR="$$(AR_$(1))" \
builddir_name="$$(CFG_BUILD_DIR)/rt/$(1)/stage$(2)/libuv" \
V=$$(VERBOSE)
endif
ifeq ($(OSTYPE_$(1)), linux-androideabi)
$$(JEMALLOC_LIB_$(1)_$(2)):
cd $$(CFG_BUILD_DIR)/rt/$(1)/stage$(2)/jemalloc; $(S)src/rt/jemalloc/configure \
--disable-experimental --build=$(CFG_BUILD_TRIPLE) --host=$(1) --disable-tls \
EXTRA_CFLAGS="$$(CFG_GCCISH_CFLAGS) $$(LIBUV_FLAGS_$$(HOST_$(1))) $$(SNAP_DEFINES)" \
LDFLAGS="$$(CFG_GCCISH_LINK_FLAGS) $$(LIBUV_FLAGS_$$(HOST_$(1)))" \
CC="$$(CC_$(1))" \
CXX="$$(CXX_$(1))" \
AR="$$(AR_$(1))"
$$(Q)$$(MAKE) -C $$(CFG_BUILD_DIR)/rt/$(1)/stage$(2)/jemalloc
else
$$(JEMALLOC_LIB_$(1)_$(2)):
cd $$(CFG_BUILD_DIR)/rt/$(1)/stage$(2)/jemalloc; $(S)src/rt/jemalloc/configure \
--disable-experimental --build=$(CFG_BUILD_TRIPLE) --host=$(1) \
EXTRA_CFLAGS="$$(CFG_GCCISH_CFLAGS) $$(LIBUV_FLAGS_$$(HOST_$(1))) $$(SNAP_DEFINES)" \
LDFLAGS="$$(CFG_GCCISH_LINK_FLAGS) $$(LIBUV_FLAGS_$$(HOST_$(1)))" \
CC="$$(CC_$(1))" \
CXX="$$(CXX_$(1))" \
AR="$$(AR_$(1))"
$$(Q)$$(MAKE) -C $$(CFG_BUILD_DIR)/rt/$(1)/stage$(2)/jemalloc
endif
# These could go in rt.mk or rustllvm.mk, they're needed for both.
# This regexp has a single $, escaped twice
%.bsd.def: %.def.in $$(MKFILE_DEPS)
@$$(call E, def: $$@)
$$(Q)echo "{" > $$@
$$(Q)sed 's/.$$$$/&;/' $$< >> $$@
$$(Q)echo "};" >> $$@
%.linux.def: %.def.in $$(MKFILE_DEPS)
@$$(call E, def: $$@)
$$(Q)echo "{" > $$@
$$(Q)sed 's/.$$$$/&;/' $$< >> $$@
$$(Q)echo "};" >> $$@
%.darwin.def: %.def.in $$(MKFILE_DEPS)
@$$(call E, def: $$@)
$$(Q)sed 's/^./_&/' $$< > $$@
%.android.def: %.def.in $$(MKFILE_DEPS)
@$$(call E, def: $$@)
$$(Q)echo "{" > $$@
$$(Q)sed 's/.$$$$/&;/' $$< >> $$@
$$(Q)echo "};" >> $$@
%.mingw32.def: %.def.in $$(MKFILE_DEPS)
@$$(call E, def: $$@)
$$(Q)echo LIBRARY $$* > $$@
$$(Q)echo EXPORTS >> $$@
$$(Q)sed 's/^./ &/' $$< >> $$@
$$(Q)$$(AR_$(1)) rcs $$@ $$^
endef
# Instantiate template for all stages
$(foreach stage,$(STAGES), \
$(foreach target,$(CFG_TARGET_TRIPLES), \
$(eval $(call DEF_RUNTIME_TARGETS,$(target),$(stage)))))
$(foreach target,$(CFG_TARGET), \
$(eval $(call RUNTIME_RULES,$(target))))
$(foreach lib,$(NATIVE_LIBS), \
$(foreach target,$(CFG_TARGET), \
$(eval $(call THIRD_PARTY_LIB,$(target),$(lib)))))
################################################################################
# Building third-party targets with external build systems
#
# This location is meant for dependencies which have external build systems. It
# is still assumed that the output of each of these steps is a static library
# in the correct location.
################################################################################
define DEF_THIRD_PARTY_TARGETS
# $(1) is the target triple
ifeq ($$(CFG_WINDOWSY_$(1)), 1)
# This isn't necessarily a desired option, but it's harmless and works around
# what appears to be a mingw-w64 bug.
#
# https://sourceforge.net/p/mingw-w64/bugs/395/
JEMALLOC_ARGS_$(1) := --enable-lazy-lock
else ifeq ($(OSTYPE_$(1)), apple-ios)
JEMALLOC_ARGS_$(1) := --disable-tls
else ifeq ($(OSTYPE_$(1)), linux-androideabi)
JEMALLOC_ARGS_$(1) := --disable-tls
endif
################################################################################
# jemalloc
################################################################################
ifdef CFG_ENABLE_FAST_MAKE
JEMALLOC_DEPS := $(S)/.gitmodules
else
JEMALLOC_DEPS := $(wildcard \
$(S)src/jemalloc/* \
$(S)src/jemalloc/*/* \
$(S)src/jemalloc/*/*/* \
$(S)src/jemalloc/*/*/*/*)
endif
# See #17183 for details, this file is touched during the build process so we
# don't want to consider it as a dependency.
JEMALLOC_DEPS := $(filter-out $(S)src/jemalloc/VERSION,$(JEMALLOC_DEPS))
JEMALLOC_NAME_$(1) := $$(call CFG_STATIC_LIB_NAME_$(1),jemalloc)
ifeq ($$(CFG_WINDOWSY_$(1)),1)
JEMALLOC_REAL_NAME_$(1) := $$(call CFG_STATIC_LIB_NAME_$(1),jemalloc_s)
else
JEMALLOC_REAL_NAME_$(1) := $$(call CFG_STATIC_LIB_NAME_$(1),jemalloc_pic)
endif
JEMALLOC_LIB_$(1) := $$(RT_OUTPUT_DIR_$(1))/$$(JEMALLOC_NAME_$(1))
JEMALLOC_BUILD_DIR_$(1) := $$(RT_OUTPUT_DIR_$(1))/jemalloc
JEMALLOC_LOCAL_$(1) := $$(JEMALLOC_BUILD_DIR_$(1))/lib/$$(JEMALLOC_REAL_NAME_$(1))
$$(JEMALLOC_LOCAL_$(1)): $$(JEMALLOC_DEPS) $$(MKFILE_DEPS)
@$$(call E, make: jemalloc)
cd "$$(JEMALLOC_BUILD_DIR_$(1))"; "$(S)src/jemalloc/configure" \
$$(JEMALLOC_ARGS_$(1)) --with-jemalloc-prefix=je_ $(CFG_JEMALLOC_FLAGS) \
--build=$$(CFG_GNU_TRIPLE_$(CFG_BUILD)) --host=$$(CFG_GNU_TRIPLE_$(1)) \
CC="$$(CC_$(1)) $$(CFG_JEMALLOC_CFLAGS_$(1))" \
AR="$$(AR_$(1))" \
RANLIB="$$(AR_$(1)) s" \
CPPFLAGS="-I $(S)src/rt/" \
EXTRA_CFLAGS="-g1 -ffunction-sections -fdata-sections"
$$(Q)$$(MAKE) -C "$$(JEMALLOC_BUILD_DIR_$(1))" build_lib_static
ifeq ($$(CFG_DISABLE_JEMALLOC),)
RUSTFLAGS_alloc := --cfg jemalloc
ifeq ($(1),$$(CFG_BUILD))
ifneq ($$(CFG_JEMALLOC_ROOT),)
$$(JEMALLOC_LIB_$(1)): $$(CFG_JEMALLOC_ROOT)/libjemalloc_pic.a
@$$(call E, copy: jemalloc)
$$(Q)cp $$< $$@
else
$$(JEMALLOC_LIB_$(1)): $$(JEMALLOC_LOCAL_$(1))
$$(Q)cp $$< $$@
endif
else
$$(JEMALLOC_LIB_$(1)): $$(JEMALLOC_LOCAL_$(1))
$$(Q)cp $$< $$@
endif
else
$$(JEMALLOC_LIB_$(1)): $$(MKFILE_DEPS)
$$(Q)touch $$@
endif
################################################################################
# compiler-rt
################################################################################
ifdef CFG_ENABLE_FAST_MAKE
COMPRT_DEPS := $(S)/.gitmodules
else
COMPRT_DEPS := $(wildcard \
$(S)src/compiler-rt/* \
$(S)src/compiler-rt/*/* \
$(S)src/compiler-rt/*/*/* \
$(S)src/compiler-rt/*/*/*/*)
endif
COMPRT_NAME_$(1) := $$(call CFG_STATIC_LIB_NAME_$(1),compiler-rt)
COMPRT_LIB_$(1) := $$(RT_OUTPUT_DIR_$(1))/$$(COMPRT_NAME_$(1))
COMPRT_BUILD_DIR_$(1) := $$(RT_OUTPUT_DIR_$(1))/compiler-rt
$$(COMPRT_LIB_$(1)): $$(COMPRT_DEPS) $$(MKFILE_DEPS)
@$$(call E, make: compiler-rt)
$$(Q)$$(MAKE) -C "$(S)src/compiler-rt" \
ProjSrcRoot="$(S)src/compiler-rt" \
ProjObjRoot="$$(abspath $$(COMPRT_BUILD_DIR_$(1)))" \
CC="$$(CC_$(1))" \
AR="$$(AR_$(1))" \
RANLIB="$$(AR_$(1)) s" \
CFLAGS="$$(CFG_GCCISH_CFLAGS_$(1))" \
TargetTriple=$(1) \
triple-builtins
$$(Q)cp $$(COMPRT_BUILD_DIR_$(1))/triple/builtins/libcompiler_rt.a $$(COMPRT_LIB_$(1))
################################################################################
# libbacktrace
#
# We use libbacktrace on linux to get symbols in backtraces, but only on linux.
# Elsewhere we use other system utilities, so this library is only built on
# linux.
################################################################################
BACKTRACE_NAME_$(1) := $$(call CFG_STATIC_LIB_NAME_$(1),backtrace)
BACKTRACE_LIB_$(1) := $$(RT_OUTPUT_DIR_$(1))/$$(BACKTRACE_NAME_$(1))
BACKTRACE_BUILD_DIR_$(1) := $$(RT_OUTPUT_DIR_$(1))/libbacktrace
# We don't use this on platforms that aren't linux-based, so just make the file
# available, the compilation of libstd won't actually build it.
ifeq ($$(findstring darwin,$$(OSTYPE_$(1))),darwin)
# See comment above
$$(BACKTRACE_LIB_$(1)):
touch $$@
else
ifeq ($$(findstring ios,$$(OSTYPE_$(1))),ios)
# See comment above
$$(BACKTRACE_LIB_$(1)):
touch $$@
else
ifeq ($$(CFG_WINDOWSY_$(1)),1)
# See comment above
$$(BACKTRACE_LIB_$(1)):
touch $$@
else
ifdef CFG_ENABLE_FAST_MAKE
BACKTRACE_DEPS := $(S)/.gitmodules
else
BACKTRACE_DEPS := $(wildcard $(S)src/libbacktrace/*)
endif
# We need to export CFLAGS because otherwise it doesn't pick up cross compile
# builds. If libbacktrace doesn't realize this, it will attempt to read 64-bit
# elf headers when compiled for a 32-bit system, yielding blank backtraces.
#
# This also removes the -Werror flag specifically to prevent errors during
# configuration.
#
# Down below you'll also see echos into the config.h generated by the
# ./configure script. This is done to force libbacktrace to *not* use the
# atomic/sync functionality because it pulls in unnecessary dependencies and we
# never use it anyway.
$$(BACKTRACE_BUILD_DIR_$(1))/Makefile: $$(BACKTRACE_DEPS) $$(MKFILE_DEPS)
@$$(call E, configure: libbacktrace for $(1))
$$(Q)rm -rf $$(BACKTRACE_BUILD_DIR_$(1))
$$(Q)mkdir -p $$(BACKTRACE_BUILD_DIR_$(1))
$$(Q)(cd $$(BACKTRACE_BUILD_DIR_$(1)) && \
CC="$$(CC_$(1))" \
AR="$$(AR_$(1))" \
RANLIB="$$(AR_$(1)) s" \
CFLAGS="$$(CFG_GCCISH_CFLAGS_$(1):-Werror=) -fno-stack-protector" \
$(S)src/libbacktrace/configure --target=$(1) --host=$(CFG_BUILD))
$$(Q)echo '#undef HAVE_ATOMIC_FUNCTIONS' >> \
$$(BACKTRACE_BUILD_DIR_$(1))/config.h
$$(Q)echo '#undef HAVE_SYNC_FUNCTIONS' >> \
$$(BACKTRACE_BUILD_DIR_$(1))/config.h
$$(BACKTRACE_LIB_$(1)): $$(BACKTRACE_BUILD_DIR_$(1))/Makefile $$(MKFILE_DEPS)
@$$(call E, make: libbacktrace)
$$(Q)$$(MAKE) -C $$(BACKTRACE_BUILD_DIR_$(1)) \
INCDIR=$(S)src/libbacktrace
$$(Q)cp $$(BACKTRACE_BUILD_DIR_$(1))/.libs/libbacktrace.a $$@
endif # endif for windowsy
endif # endif for ios
endif # endif for darwin
endef
# Instantiate template for all stages/targets
$(foreach target,$(CFG_TARGET), \
$(eval $(call DEF_THIRD_PARTY_TARGETS,$(target))))

View File

@ -19,32 +19,30 @@ define DEF_RUSTLLVM_TARGETS
# llvm, but using it straight out of the build directory)
ifdef CFG_WINDOWSY_$(1)
LLVM_EXTRA_INCDIRS_$(1)= -iquote $(S)src/llvm/include \
-iquote llvm/$(1)/include
-iquote $$(CFG_LLVM_BUILD_DIR_$(1))/include
endif
RUSTLLVM_OBJS_CS_$(1) := $$(addprefix rustllvm/, RustWrapper.cpp PassWrapper.cpp)
RUSTLLVM_OBJS_CS_$(1) := $$(addprefix rustllvm/, \
ExecutionEngineWrapper.cpp RustWrapper.cpp PassWrapper.cpp)
RUSTLLVM_DEF_$(1) := rustllvm/rustllvm$(CFG_DEF_SUFFIX_$(1))
RUSTLLVM_DEF_$(1) := $(1)/rustllvm/rustllvm$(CFG_DEF_SUFFIX_$(1))
RUSTLLVM_INCS_$(1) = $$(LLVM_EXTRA_INCDIRS_$(1)) \
-iquote $$(LLVM_INCDIR_$(1)) \
-iquote $$(S)src/rustllvm/include
RUSTLLVM_OBJS_OBJS_$(1) := $$(RUSTLLVM_OBJS_CS_$(1):rustllvm/%.cpp=rustllvm/$(1)/%.o)
RUSTLLVM_OBJS_OBJS_$(1) := $$(RUSTLLVM_OBJS_CS_$(1):rustllvm/%.cpp=$(1)/rustllvm/%.o)
ALL_OBJ_FILES += $$(RUSTLLVM_OBJS_OBJS_$(1))
rustllvm/$(1)/$(CFG_RUSTLLVM_$(1)): $$(RUSTLLVM_OBJS_OBJS_$(1)) \
$$(MKFILE_DEPS) $$(RUSTLLVM_DEF_$(1))
$$(RT_OUTPUT_DIR_$(1))/$$(call CFG_STATIC_LIB_NAME_$(1),rustllvm): \
$$(RUSTLLVM_OBJS_OBJS_$(1))
@$$(call E, link: $$@)
$$(Q)$$(call CFG_LINK_CXX_$(1),$$@,$$(RUSTLLVM_OBJS_OBJS_$(1)) \
$$(CFG_GCCISH_PRE_LIB_FLAGS_$(1)) $$(LLVM_LIBS_$(1)) \
$$(CFG_GCCISH_POST_LIB_FLAGS_$(1)) \
$$(LLVM_LDFLAGS_$(1)),$$(RUSTLLVM_DEF_$(1)),$$(CFG_RUSTLLVM_$(1)))
$$(Q)$$(AR_$(1)) rcs $$@ $$(RUSTLLVM_OBJS_OBJS_$(1))
rustllvm/$(1)/%.o: rustllvm/%.cpp $$(MKFILE_DEPS) $$(LLVM_CONFIG_$(1))
$(1)/rustllvm/%.o: $(S)src/rustllvm/%.cpp $$(MKFILE_DEPS) $$(LLVM_CONFIG_$(1))
@$$(call E, compile: $$@)
$$(Q)$$(call CFG_COMPILE_CXX_$(1), $$@, $$(LLVM_CXXFLAGS_$(1)) $$(RUSTLLVM_INCS_$(1))) $$<
endef
# Instantiate template for all stages
$(foreach host,$(CFG_HOST_TRIPLES), \
$(foreach host,$(CFG_HOST), \
$(eval $(call DEF_RUSTLLVM_TARGETS,$(host))))

View File

@ -12,22 +12,17 @@ define DEF_SNAP_FOR_STAGE_H
# $(1) stage
# $(2) triple
ifdef CFG_INSTALL_SNAP
snap-stage$(1)-H-$(2): $$(HSREQ$(1)_H_$(2))
$(CFG_PYTHON) $(S)src/etc/make-snapshot.py stage$(1) $(2) install
else
snap-stage$(1)-H-$(2): $$(HSREQ$(1)_H_$(2))
$(CFG_PYTHON) $(S)src/etc/make-snapshot.py stage$(1) $(2)
endif
endef
$(foreach host,$(CFG_HOST_TRIPLES), \
$(eval $(foreach stage,1 2 3, \
$(foreach host,$(CFG_HOST), \
$(eval $(foreach stage,1 2 3, \
$(eval $(call DEF_SNAP_FOR_STAGE_H,$(stage),$(host))))))
snap-stage1: snap-stage1-H-$(CFG_BUILD_TRIPLE)
snap-stage1: snap-stage1-H-$(CFG_BUILD)
snap-stage2: snap-stage2-H-$(CFG_BUILD_TRIPLE)
snap-stage2: snap-stage2-H-$(CFG_BUILD)
snap-stage3: snap-stage3-H-$(CFG_BUILD_TRIPLE)
snap-stage3: snap-stage3-H-$(CFG_BUILD)

View File

@ -1,45 +1,28 @@
# Extract the snapshot host compiler
$(HBIN0_H_$(CFG_BUILD))/:
mkdir -p $@
# On windows these two are the same, so cause a redifinition warning
ifneq ($(HBIN0_H_$(CFG_BUILD)),$(HLIB0_H_$(CFG_BUILD)))
$(HLIB0_H_$(CFG_BUILD))/:
mkdir -p $@
endif
$(SNAPSHOT_RUSTC_POST_CLEANUP): \
$(S)src/snapshots.txt \
$(S)src/etc/get-snapshot.py $(MKFILE_DEPS) \
| $(HBIN0_H_$(CFG_BUILD))/
$(HBIN0_H_$(CFG_BUILD_TRIPLE))/rustc$(X_$(CFG_BUILD_TRIPLE)): \
$(S)src/snapshots.txt \
$(S)src/etc/get-snapshot.py $(MKFILE_DEPS)
@$(call E, fetch: $@)
# Note: the variable "SNAPSHOT_FILE" is generally not set, and so
# we generally only pass one argument to this script.
ifdef CFG_ENABLE_LOCAL_RUST
$(Q)$(S)src/etc/local_stage0.sh $(CFG_BUILD_TRIPLE) $(CFG_LOCAL_RUST_ROOT)
$(Q)$(S)src/etc/local_stage0.sh $(CFG_BUILD) $(CFG_LOCAL_RUST_ROOT) rustlib
else
$(Q)$(CFG_PYTHON) $(S)src/etc/get-snapshot.py $(CFG_BUILD_TRIPLE) $(SNAPSHOT_FILE)
ifdef CFG_ENABLE_PAX_FLAGS
@$(call E, apply PaX flags: $@)
@"$(CFG_PAXCTL)" -cm "$@"
$(Q)$(CFG_PYTHON) $(S)src/etc/get-snapshot.py $(CFG_BUILD) $(SNAPSHOT_FILE)
endif
endif
$(Q)touch $@
# Host libs will be extracted by the above rule
$(HLIB0_H_$(CFG_BUILD_TRIPLE))/$(CFG_RUNTIME_$(CFG_BUILD_TRIPLE)): \
$(HBIN0_H_$(CFG_BUILD_TRIPLE))/rustc$(X_$(CFG_BUILD_TRIPLE))
$(Q)touch $@
$(HLIB0_H_$(CFG_BUILD_TRIPLE))/$(CFG_STDLIB_$(CFG_BUILD_TRIPLE)): \
$(HBIN0_H_$(CFG_BUILD_TRIPLE))/rustc$(X_$(CFG_BUILD_TRIPLE))
$(Q)touch $@
$(HLIB0_H_$(CFG_BUILD_TRIPLE))/$(CFG_EXTRALIB_$(CFG_BUILD_TRIPLE)): \
$(HBIN0_H_$(CFG_BUILD_TRIPLE))/rustc$(X_$(CFG_BUILD_TRIPLE))
$(Q)touch $@
$(HLIB0_H_$(CFG_BUILD_TRIPLE))/$(CFG_LIBRUSTC_$(CFG_BUILD_TRIPLE)): \
$(HBIN0_H_$(CFG_BUILD_TRIPLE))/rustc$(X_$(CFG_BUILD_TRIPLE))
$(Q)touch $@
$(HLIB0_H_$(CFG_BUILD_TRIPLE))/$(CFG_RUSTLLVM_$(CFG_BUILD_TRIPLE)): \
$(HBIN0_H_$(CFG_BUILD_TRIPLE))/rustc$(X_$(CFG_BUILD_TRIPLE))
$(Q)touch $@
$(Q)if [ -e "$@" ]; then touch "$@"; else echo "ERROR: snapshot $@ not found"; exit 1; fi
# For other targets, let the host build the target:
@ -48,33 +31,15 @@ define BOOTSTRAP_STAGE0
# $(2) stage to bootstrap from
# $(3) target to bootstrap from
$$(HBIN0_H_$(1))/rustc$$(X_$(1)): \
$$(TBIN$(2)_T_$(1)_H_$(3))/rustc$$(X_$(1))
@$$(call E, cp: $$@)
$$(Q)cp $$< $$@
$(HBIN0_H_$(1))/:
mkdir -p $@
$$(HLIB0_H_$(1))/$(CFG_RUNTIME_$(1)): \
$$(TLIB$(2)_T_$(1)_H_$(3))/$(CFG_RUNTIME_$(1))
@$$(call E, cp: $$@)
$$(Q)cp $$< $$@
$(HLIB0_H_$(1))/:
mkdir -p $@
$$(HLIB0_H_$(1))/$(CFG_STDLIB_$(1)): \
$$(TLIB$(2)_T_$(1)_H_$(3))/$(CFG_STDLIB_$(1))
@$$(call E, cp: $$@)
$$(Q)cp $$(TLIB$(2)_T_$(1)_H_$(3))/$(STDLIB_GLOB_$(1)) $$@
$$(HLIB0_H_$(1))/$(CFG_EXTRALIB_$(1)): \
$$(TLIB$(2)_T_$(1)_H_$(3))/$(CFG_EXTRALIB_$(1))
@$$(call E, cp: $$@)
$$(Q)cp $$(TLIB$(2)_T_$(1)_H_$(3))/$(EXTRALIB_GLOB_$(1)) $$@
$$(HLIB0_H_$(1))/$(CFG_LIBRUSTC_$(1)): \
$$(TLIB$(2)_T_$(1)_H_$(3))/$(CFG_LIBRUSTC_$(1))
@$$(call E, cp: $$@)
$$(Q)cp $$(TLIB$(2)_T_$(1)_H_$(3))/$(LIBRUSTC_GLOB_$(1)) $$@
$$(HLIB0_H_$(1))/$(CFG_RUSTLLVM_$(1)): \
$$(TLIB$(2)_T_$(1)_H_$(3))/$(CFG_RUSTLLVM_$(1))
$$(HBIN0_H_$(1))/rustc$$(X_$(1)): \
$$(TBIN$(2)_T_$(1)_H_$(3))/rustc$$(X_$(1)) \
| $(HBIN0_H_$(1))/
@$$(call E, cp: $$@)
$$(Q)cp $$< $$@
@ -82,5 +47,5 @@ endef
# Use stage1 to build other architectures: then you don't have to wait
# for stage2, but you get the latest updates to the compiler source.
$(foreach t,$(NON_BUILD_HOST_TRIPLES), \
$(eval $(call BOOTSTRAP_STAGE0,$(t),1,$(CFG_BUILD_TRIPLE))))
$(foreach t,$(NON_BUILD_HOST), \
$(eval $(call BOOTSTRAP_STAGE0,$(t),1,$(CFG_BUILD))))

View File

@ -11,107 +11,167 @@
# This is the compile-time target-triple for the compiler. For the compiler at
# runtime, this should be considered the host-triple. More explanation for why
# this exists can be found on issue #2400
export CFG_COMPILER_TRIPLE
export CFG_COMPILER_HOST_TRIPLE
# The standard libraries should be held up to a higher standard than any old
# code, make sure that these common warnings are denied by default. These can
# be overridden during development temporarily. For stage0, we allow all these
# to suppress warnings which may be bugs in stage0 (should be fixed in stage1+)
# NOTE: add "-A warnings" after snapshot to WFLAGS_ST0
WFLAGS_ST0 = -A unrecognized-lint
WFLAGS_ST1 = -D warnings
WFLAGS_ST2 = -D warnings
# be overridden during development temporarily. For stage0, we allow warnings
# which may be bugs in stage0 (should be fixed in stage1+)
RUST_LIB_FLAGS_ST0 += -W warnings
RUST_LIB_FLAGS_ST1 += -D warnings
RUST_LIB_FLAGS_ST2 += -D warnings
# TARGET_STAGE_N template: This defines how target artifacts are built
# for all stage/target architecture combinations. The arguments:
# Macro that generates the full list of dependencies for a crate at a particular
# stage/target/host tuple.
#
# $(1) - stage
# $(2) - target
# $(3) - host
# $(4) crate
define RUST_CRATE_FULLDEPS
CRATE_FULLDEPS_$(1)_T_$(2)_H_$(3)_$(4) := \
$$(CRATEFILE_$(4)) \
$$(RSINPUTS_$(4)) \
$$(foreach dep,$$(RUST_DEPS_$(4)), \
$$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$$(dep)) \
$$(foreach dep,$$(NATIVE_DEPS_$(4)), \
$$(RT_OUTPUT_DIR_$(2))/$$(call CFG_STATIC_LIB_NAME_$(2),$$(dep)))
endef
$(foreach host,$(CFG_HOST), \
$(foreach target,$(CFG_TARGET), \
$(foreach stage,$(STAGES), \
$(foreach crate,$(CRATES), \
$(eval $(call RUST_CRATE_FULLDEPS,$(stage),$(target),$(host),$(crate)))))))
# RUST_TARGET_STAGE_N template: This defines how target artifacts are built
# for all stage/target architecture combinations. This is one giant rule which
# works as follows:
#
# 1. The immediate dependencies are the rust source files
# 2. Each rust crate dependency is listed (based on their stamp files),
# as well as all native dependencies (listed in RT_OUTPUT_DIR)
# 3. The stage (n-1) compiler is required through the TSREQ dependency, along
# with the morestack library
# 4. When actually executing the rule, the first thing we do is to clean out
# old libs and rlibs via the REMOVE_ALL_OLD_GLOB_MATCHES macro
# 5. Finally, we get around to building the actual crate. It's just one
# "small" invocation of the previous stage rustc. We use -L to
# RT_OUTPUT_DIR so all the native dependencies are picked up.
# Additionally, we pass in the llvm dir so rustc can link against it.
# 6. Some cleanup is done (listing what was just built) if verbose is turned
# on.
#
# $(1) is the stage
# $(2) is the target triple
# $(3) is the host triple
# $(4) is the crate name
define RUST_TARGET_STAGE_N
define TARGET_STAGE_N
$$(TLIB$(1)_T_$(2)_H_$(3))/libmorestack.a: \
rt/$(2)/stage$(1)/arch/$$(HOST_$(2))/libmorestack.a \
| $$(TLIB$(1)_T_$(2)_H_$(3))/
@$$(call E, cp: $$@)
$$(Q)cp $$< $$@
$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_RUNTIME_$(2)): \
rt/$(2)/stage$(1)/$(CFG_RUNTIME_$(2)) \
| $$(TLIB$(1)_T_$(2)_H_$(3))/
@$$(call E, cp: $$@)
$$(Q)cp $$< $$@
$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_STDLIB_$(2)): \
$$(STDLIB_CRATE) $$(STDLIB_INPUTS) \
$$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$(4): CFG_COMPILER_HOST_TRIPLE = $(2)
$$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$(4): \
$$(CRATEFILE_$(4)) \
$$(CRATE_FULLDEPS_$(1)_T_$(2)_H_$(3)_$(4)) \
$$(TSREQ$(1)_T_$(2)_H_$(3)) \
| $$(TLIB$(1)_T_$(2)_H_$(3))/
@$$(call E, compile_and_link: $$@)
$$(STAGE$(1)_T_$(2)_H_$(3)) $$(WFLAGS_ST$(1)) -o $$@ $$< && touch $$@
@$$(call E, rustc: $$(@D)/lib$(4))
$$(call REMOVE_ALL_OLD_GLOB_MATCHES, \
$$(dir $$@)$$(call CFG_LIB_GLOB_$(2),$(4)))
$$(call REMOVE_ALL_OLD_GLOB_MATCHES, \
$$(dir $$@)$$(call CFG_RLIB_GLOB,$(4)))
$(Q)CFG_LLVM_LINKAGE_FILE=$$(LLVM_LINKAGE_PATH_$(3)) \
$$(subst @,,$$(STAGE$(1)_T_$(2)_H_$(3))) \
$$(RUST_LIB_FLAGS_ST$(1)) \
-L "$$(RT_OUTPUT_DIR_$(2))" \
-L "$$(LLVM_LIBDIR_$(2))" \
-L "$$(dir $$(LLVM_STDCPP_LOCATION_$(2)))" \
$$(RUSTFLAGS_$(4)) \
--out-dir $$(@D) \
-C extra-filename=-$$(CFG_FILENAME_EXTRA) \
$$<
@touch $$@
$$(call LIST_ALL_OLD_GLOB_MATCHES, \
$$(dir $$@)$$(call CFG_LIB_GLOB_$(2),$(4)))
$$(call LIST_ALL_OLD_GLOB_MATCHES, \
$$(dir $$@)$$(call CFG_RLIB_GLOB,$(4)))
$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_EXTRALIB_$(2)): \
$$(EXTRALIB_CRATE) $$(EXTRALIB_INPUTS) \
$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_STDLIB_$(2)) \
endef
# Macro for building any tool as part of the rust compilation process. Each
# tool is defined in crates.mk with a list of library dependencies as well as
# the source file for the tool. Building each tool will also be passed '--cfg
# <tool>' for usage in driver.rs
#
# This build rule is similar to the one found above, just tweaked for
# locations and things.
#
# $(1) - stage
# $(2) - target triple
# $(3) - host triple
# $(4) - name of the tool being built
define TARGET_TOOL
$$(TBIN$(1)_T_$(2)_H_$(3))/$(4)$$(X_$(2)): \
$$(TOOL_SOURCE_$(4)) \
$$(TOOL_INPUTS_$(4)) \
$$(foreach dep,$$(TOOL_DEPS_$(4)), \
$$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$$(dep)) \
$$(TSREQ$(1)_T_$(2)_H_$(3)) \
| $$(TLIB$(1)_T_$(2)_H_$(3))/
@$$(call E, compile_and_link: $$@)
$$(STAGE$(1)_T_$(2)_H_$(3)) $$(WFLAGS_ST$(1)) -o $$@ $$< && touch $$@
$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBSYNTAX_$(3)): \
$$(LIBSYNTAX_CRATE) $$(LIBSYNTAX_INPUTS) \
$$(TSREQ$(1)_T_$(2)_H_$(3)) \
$$(TSTDLIB_DEFAULT$(1)_T_$(2)_H_$(3)) \
$$(TEXTRALIB_DEFAULT$(1)_T_$(2)_H_$(3)) \
| $$(TLIB$(1)_T_$(2)_H_$(3))/
@$$(call E, compile_and_link: $$@)
$$(STAGE$(1)_T_$(2)_H_$(3)) $(BORROWCK) -o $$@ $$< && touch $$@
# Only build the compiler for host triples
ifneq ($$(findstring $(2),$$(CFG_HOST_TRIPLES)),)
$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_RUSTLLVM_$(3)): \
rustllvm/$(2)/$(CFG_RUSTLLVM_$(3)) \
| $$(TLIB$(1)_T_$(2)_H_$(3))/
@$$(call E, cp: $$@)
$$(Q)cp $$< $$@
$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTC_$(3)): CFG_COMPILER_TRIPLE = $(2)
$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTC_$(3)): \
$$(COMPILER_CRATE) $$(COMPILER_INPUTS) \
$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBSYNTAX_$(3)) \
$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_RUSTLLVM_$(3)) \
| $$(TLIB$(1)_T_$(2)_H_$(3))/
@$$(call E, compile_and_link: $$@)
$$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< && touch $$@
$$(TBIN$(1)_T_$(2)_H_$(3))/rustc$$(X_$(3)): \
$$(DRIVER_CRATE) \
$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTC_$(3)) \
| $$(TBIN$(1)_T_$(2)_H_$(3))/
@$$(call E, compile_and_link: $$@)
$$(STAGE$(1)_T_$(2)_H_$(3)) --cfg rustc -o $$@ $$<
ifdef CFG_ENABLE_PAX_FLAGS
@$$(call E, apply PaX flags: $$@)
@"$(CFG_PAXCTL)" -cm "$$@"
endif
@$$(call E, rustc: $$@)
$$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< --cfg $(4)
endif
endef
# Every recipe in RUST_TARGET_STAGE_N outputs to $$(TLIB$(1)_T_$(2)_H_$(3),
# a directory that can be cleaned out during the middle of a run of
# the get-snapshot.py script. Therefore, every recipe needs to have
# an order-only dependency either on $(SNAPSHOT_RUSTC_POST_CLEANUP) or
# on $$(TSREQ$(1)_T_$(2)_H_$(3)), to ensure that no products will be
# put into the target area until after the get-snapshot.py script has
# had its chance to clean it out; otherwise the other products will be
# inadvertantly included in the clean out.
SNAPSHOT_RUSTC_POST_CLEANUP=$(HBIN0_H_$(CFG_BUILD))/rustc$(X_$(CFG_BUILD))
define TARGET_HOST_RULES
$$(TBIN$(1)_T_$(2)_H_$(3))/:
mkdir -p $$@
ifneq ($(CFG_LIBDIR),bin)
$$(TLIB$(1)_T_$(2)_H_$(3))/:
mkdir -p $$@
endif
$$(TLIB$(1)_T_$(2)_H_$(3))/libcompiler-rt.a: \
$$(RT_OUTPUT_DIR_$(2))/$$(call CFG_STATIC_LIB_NAME_$(2),compiler-rt) \
| $$(TLIB$(1)_T_$(2)_H_$(3))/ $$(SNAPSHOT_RUSTC_POST_CLEANUP)
@$$(call E, cp: $$@)
$$(Q)cp $$< $$@
$$(TLIB$(1)_T_$(2)_H_$(3))/libmorestack.a: \
$$(RT_OUTPUT_DIR_$(2))/$$(call CFG_STATIC_LIB_NAME_$(2),morestack) \
| $$(TLIB$(1)_T_$(2)_H_$(3))/ $$(SNAPSHOT_RUSTC_POST_CLEANUP)
@$$(call E, cp: $$@)
$$(Q)cp $$< $$@
endef
# In principle, each host can build each target:
$(foreach source,$(CFG_HOST_TRIPLES), \
$(foreach target,$(CFG_TARGET_TRIPLES), \
$(eval $(call TARGET_STAGE_N,0,$(target),$(source))) \
$(eval $(call TARGET_STAGE_N,1,$(target),$(source))) \
$(eval $(call TARGET_STAGE_N,2,$(target),$(source))) \
$(eval $(call TARGET_STAGE_N,3,$(target),$(source)))))
$(foreach source,$(CFG_HOST), \
$(foreach target,$(CFG_TARGET), \
$(eval $(call TARGET_HOST_RULES,0,$(target),$(source))) \
$(eval $(call TARGET_HOST_RULES,1,$(target),$(source))) \
$(eval $(call TARGET_HOST_RULES,2,$(target),$(source))) \
$(eval $(call TARGET_HOST_RULES,3,$(target),$(source)))))
# In principle, each host can build each target for both libs and tools
$(foreach crate,$(CRATES), \
$(foreach source,$(CFG_HOST), \
$(foreach target,$(CFG_TARGET), \
$(eval $(call RUST_TARGET_STAGE_N,0,$(target),$(source),$(crate))) \
$(eval $(call RUST_TARGET_STAGE_N,1,$(target),$(source),$(crate))) \
$(eval $(call RUST_TARGET_STAGE_N,2,$(target),$(source),$(crate))) \
$(eval $(call RUST_TARGET_STAGE_N,3,$(target),$(source),$(crate))))))
$(foreach host,$(CFG_HOST), \
$(foreach target,$(CFG_TARGET), \
$(foreach stage,$(STAGES), \
$(foreach tool,$(TOOLS), \
$(eval $(call TARGET_TOOL,$(stage),$(target),$(host),$(tool)))))))

File diff suppressed because it is too large Load Diff

View File

@ -1,200 +0,0 @@
# Copyright 2012 The Rust Project Developers. See the COPYRIGHT
# file at the top-level directory of this distribution and at
# http://rust-lang.org/COPYRIGHT.
#
# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
# option. This file may not be copied, modified, or distributed
# except according to those terms.
# Rules for non-core tools built with the compiler, both for target
# and host architectures
# The test runner that runs the cfail/rfail/rpass and bxench tests
COMPILETEST_CRATE := $(S)src/compiletest/compiletest.rs
COMPILETEST_INPUTS := $(wildcard $(S)src/compiletest/*.rs)
# Rustpkg, the package manager and build system
RUSTPKG_LIB := $(S)src/librustpkg/rustpkg.rs
RUSTPKG_INPUTS := $(wildcard $(S)src/librustpkg/*.rs)
# Rustdoc, the documentation tool
RUSTDOC_LIB := $(S)src/librustdoc/rustdoc.rs
RUSTDOC_INPUTS := $(wildcard $(S)src/librustdoc/*.rs)
# Rusti, the JIT REPL
RUSTI_LIB := $(S)src/librusti/rusti.rs
RUSTI_INPUTS := $(wildcard $(S)src/librusti/*.rs)
# Rust, the convenience tool
RUST_LIB := $(S)src/librust/rust.rs
RUST_INPUTS := $(wildcard $(S)src/librust/*.rs)
# FIXME: These are only built for the host arch. Eventually we'll
# have tools that need to built for other targets.
define TOOLS_STAGE_N_TARGET
$$(TBIN$(1)_T_$(4)_H_$(3))/compiletest$$(X_$(4)): \
$$(COMPILETEST_CRATE) $$(COMPILETEST_INPUTS) \
$$(TSREQ$(1)_T_$(4)_H_$(3)) \
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_STDLIB_$(4)) \
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_EXTRALIB_$(4))
@$$(call E, compile_and_link: $$@)
$$(STAGE$(1)_T_$(4)_H_$(3)) -o $$@ $$<
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTPKG_$(4)): \
$$(RUSTPKG_LIB) $$(RUSTPKG_INPUTS) \
$$(TSREQ$(1)_T_$(4)_H_$(3)) \
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_STDLIB_$(4)) \
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_EXTRALIB_$(4)) \
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTC_$(4))
@$$(call E, compile_and_link: $$@)
$$(STAGE$(1)_T_$(4)_H_$(3)) -o $$@ $$< && touch $$@
$$(TBIN$(1)_T_$(4)_H_$(3))/rustpkg$$(X_$(4)): \
$$(DRIVER_CRATE) \
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTPKG_$(4))
@$$(call E, compile_and_link: $$@)
$$(STAGE$(1)_T_$(4)_H_$(3)) --cfg rustpkg -o $$@ $$<
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTDOC_$(4)): \
$$(RUSTDOC_LIB) $$(RUSTDOC_INPUTS) \
$$(TSREQ$(1)_T_$(4)_H_$(3)) \
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_STDLIB_$(4)) \
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_EXTRALIB_$(4)) \
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTC_$(4))
@$$(call E, compile_and_link: $$@)
$$(STAGE$(1)_T_$(4)_H_$(3)) -o $$@ $$< && touch $$@
$$(TBIN$(1)_T_$(4)_H_$(3))/rustdoc$$(X_$(4)): \
$$(DRIVER_CRATE) \
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTDOC_$(4))
@$$(call E, compile_and_link: $$@)
$$(STAGE$(1)_T_$(4)_H_$(3)) --cfg rustdoc -o $$@ $$<
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTI_$(4)): \
$$(RUSTI_LIB) $$(RUSTI_INPUTS) \
$$(TSREQ$(1)_T_$(4)_H_$(3)) \
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_STDLIB_$(4)) \
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_EXTRALIB_$(4)) \
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTC_$(4))
@$$(call E, compile_and_link: $$@)
$$(STAGE$(1)_T_$(4)_H_$(3)) -o $$@ $$< && touch $$@
$$(TBIN$(1)_T_$(4)_H_$(3))/rusti$$(X_$(4)): \
$$(DRIVER_CRATE) \
$$(TLIB$(1)_T_$(4)_H_$(4))/$(CFG_LIBRUSTI_$(4))
@$$(call E, compile_and_link: $$@)
$$(STAGE$(1)_T_$(4)_H_$(3)) --cfg rusti -o $$@ $$<
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUST_$(4)): \
$$(RUST_LIB) $$(RUST_INPUTS) \
$$(TSREQ$(1)_T_$(4)_H_$(3)) \
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_STDLIB_$(4)) \
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_EXTRALIB_$(4)) \
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTPKG_$(4)) \
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTI_$(4)) \
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTDOC_$(4)) \
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTC_$(4))
@$$(call E, compile_and_link: $$@)
$$(STAGE$(1)_T_$(4)_H_$(3)) -o $$@ $$< && touch $$@
$$(TBIN$(1)_T_$(4)_H_$(3))/rust$$(X_$(4)): \
$$(DRIVER_CRATE) \
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUST_$(4))
@$$(call E, compile_and_link: $$@)
$$(STAGE$(1)_T_$(4)_H_$(3)) --cfg rust -o $$@ $$<
endef
define TOOLS_STAGE_N_HOST
$$(HBIN$(2)_H_$(4))/compiletest$$(X_$(4)): \
$$(TBIN$(1)_T_$(4)_H_$(3))/compiletest$$(X_$(4)) \
$$(HSREQ$(2)_H_$(4))
@$$(call E, cp: $$@)
$$(Q)cp $$< $$@
$$(HLIB$(2)_H_$(4))/$(CFG_LIBRUSTPKG_$(4)): \
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTPKG_$(4)) \
$$(HLIB$(2)_H_$(4))/$(CFG_LIBRUSTC_$(4)) \
$$(HSREQ$(2)_H_$(4))
@$$(call E, cp: $$@)
$$(Q)cp $$< $$@
$$(Q)cp -R $$(TLIB$(1)_T_$(4)_H_$(3))/$(LIBRUSTPKG_GLOB_$(4)) \
$$(wildcard $$(TLIB$(1)_T_$(4)_H_$(3))/$(LIBRUSTPKG_DSYM_GLOB_$(4))) \
$$(HLIB$(2)_H_$(4))
$$(HBIN$(2)_H_$(4))/rustpkg$$(X_$(4)): \
$$(TBIN$(1)_T_$(4)_H_$(3))/rustpkg$$(X_$(4)) \
$$(HLIB$(2)_H_$(4))/$(CFG_LIBRUSTPKG_$(4)) \
$$(HSREQ$(2)_H_$(4))
@$$(call E, cp: $$@)
$$(Q)cp $$< $$@
$$(HLIB$(2)_H_$(4))/$(CFG_LIBRUSTDOC_$(4)): \
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTDOC_$(4)) \
$$(HLIB$(2)_H_$(4))/$(CFG_LIBRUSTC_$(4)) \
$$(HSREQ$(2)_H_$(4))
@$$(call E, cp: $$@)
$$(Q)cp $$< $$@
$$(Q)cp -R $$(TLIB$(1)_T_$(4)_H_$(3))/$(LIBRUSTDOC_GLOB_$(4)) \
$$(wildcard $$(TLIB$(1)_T_$(4)_H_$(3))/$(LIBRUSTDOC_DSYM_GLOB_$(4))) \
$$(HLIB$(2)_H_$(4))
$$(HBIN$(2)_H_$(4))/rustdoc$$(X_$(4)): \
$$(TBIN$(1)_T_$(4)_H_$(3))/rustdoc$$(X_$(4)) \
$$(HLIB$(2)_H_$(4))/$(CFG_LIBRUSTDOC_$(4)) \
$$(HSREQ$(2)_H_$(4))
@$$(call E, cp: $$@)
$$(Q)cp $$< $$@
$$(HLIB$(2)_H_$(4))/$(CFG_LIBRUSTI_$(4)): \
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTI_$(4)) \
$$(HLIB$(2)_H_$(4))/$(CFG_LIBRUSTC_$(4)) \
$$(HSREQ$(2)_H_$(4))
@$$(call E, cp: $$@)
$$(Q)cp $$< $$@
$$(Q)cp -R $$(TLIB$(1)_T_$(4)_H_$(3))/$(LIBRUSTI_GLOB_$(4)) \
$$(wildcard $$(TLIB$(1)_T_$(4)_H_$(3))/$(LIBRUSTI_DSYM_GLOB_$(4))) \
$$(HLIB$(2)_H_$(4))
$$(HBIN$(2)_H_$(4))/rusti$$(X_$(4)): \
$$(TBIN$(1)_T_$(4)_H_$(3))/rusti$$(X_$(4)) \
$$(HLIB$(2)_H_$(4))/$(CFG_LIBRUSTI_$(4)) \
$$(HSREQ$(2)_H_$(4))
@$$(call E, cp: $$@)
$$(Q)cp $$< $$@
$$(HLIB$(2)_H_$(4))/$(CFG_LIBRUST_$(4)): \
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUST_$(4)) \
$$(HLIB$(2)_H_$(4))/$(CFG_LIBRUSTC_$(4)) \
$$(HSREQ$(2)_H_$(4))
@$$(call E, cp: $$@)
$$(Q)cp $$< $$@
$$(Q)cp -R $$(TLIB$(1)_T_$(4)_H_$(3))/$(LIBRUST_GLOB_$(4)) \
$$(wildcard $$(TLIB$(1)_T_$(4)_H_$(3))/$(LIBRUST_DSYM_GLOB)_$(4)) \
$$(HLIB$(2)_H_$(4))
$$(HBIN$(2)_H_$(4))/rust$$(X_$(4)): \
$$(TBIN$(1)_T_$(4)_H_$(3))/rust$$(X_$(4)) \
$$(HLIB$(2)_H_$(4))/$(CFG_LIBRUST_$(4)) \
$$(HSREQ$(2)_H_$(4))
@$$(call E, cp: $$@)
$$(Q)cp $$< $$@
endef
$(foreach host,$(CFG_HOST_TRIPLES), \
$(foreach target,$(CFG_TARGET_TRIPLES), \
$(eval $(call TOOLS_STAGE_N_TARGET,0,1,$(host),$(target))) \
$(eval $(call TOOLS_STAGE_N_TARGET,1,2,$(host),$(target))) \
$(eval $(call TOOLS_STAGE_N_TARGET,2,3,$(host),$(target))) \
$(eval $(call TOOLS_STAGE_N_TARGET,3,bogus,$(host),$(target)))))
$(foreach host,$(CFG_HOST_TRIPLES), \
$(eval $(call TOOLS_STAGE_N_HOST,0,1,$(host),$(host))) \
$(eval $(call TOOLS_STAGE_N_HOST,1,2,$(host),$(host))) \
$(eval $(call TOOLS_STAGE_N_HOST,2,3,$(host),$(host))))

20
mk/util.mk Normal file
View File

@ -0,0 +1,20 @@
# Copyright 2014 The Rust Project Developers. See the COPYRIGHT
# file at the top-level directory of this distribution and at
# http://rust-lang.org/COPYRIGHT.
#
# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
# option. This file may not be copied, modified, or distributed
# except according to those terms.
ifdef VERBOSE
Q :=
E =
else
Q := @
E = echo $(1)
endif
S := $(CFG_SRC_DIR)

View File

@ -1,46 +0,0 @@
This is a preliminary version of the Rust compiler, libraries and tools
Source layout:
librustc/ The self-hosted compiler
libstd/ The standard library (imported and linked by default)
libextra/ The "extras" library (slightly more peripheral code)
libsyntax/ The Rust parser and pretty-printer
rt/ The runtime system
rt/rust_*.cpp - The majority of the runtime services
rt/isaac - The PRNG used for pseudo-random choices in the runtime
rt/bigint - The bigint library used for the 'big' type
rt/uthash - Small hashtable-and-list library for C, used in runtime
rt/sync - Concurrency utils
rt/util - Small utility classes for the runtime.
rt/vg - Valgrind headers
rt/msvc - MSVC support
rt/linenoise - a readline-like line editing library
test/ Testsuite
test/compile-fail - Tests that should fail to compile
test/run-fail - Tests that should compile, run and fail
test/run-pass - Tests that should compile, run and succeed
test/bench - Benchmarks and miscellanea
test/pretty - Pretty-printer tests
test/auxiliary - Dependencies of tests
compiletest/ The test runner
librustpkg/ The package manager and build system
librusti/ The JIT REPL
librustdoc/ The Rust API documentation tool
llvm/ The LLVM submodule
libuv/ The libuv submodule
rustllvm/ LLVM support code
libfuzzer/ A collection of fuzz testers
etc/ Scripts, editor support, misc

View File

@ -0,0 +1,4 @@
{
"project_id" : "compiler-rt",
"conduit_uri" : "http://reviews.llvm.org/"
}

View File

@ -0,0 +1,359 @@
# CMake build for CompilerRT.
#
# This build assumes that CompilerRT is checked out into the
# 'projects/compiler-rt' inside of an LLVM tree.
# Standalone build system for CompilerRT is not yet ready.
#
# An important constraint of the build is that it only produces libraries
# based on the ability of the host toolchain to target various platforms.
# Check if compiler-rt is built as a standalone project.
if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
project(CompilerRT)
set(COMPILER_RT_STANDALONE_BUILD TRUE)
else()
set(COMPILER_RT_STANDALONE_BUILD FALSE)
endif()
# The CompilerRT build system requires CMake version 2.8.8 or higher in order
# to use its support for building convenience "libraries" as a collection of
# .o files. This is particularly useful in producing larger, more complex
# runtime libraries.
if (NOT MSVC)
cmake_minimum_required(VERSION 2.8.8)
else()
# Version 2.8.12.1 is required to build with Visual Studion 2013.
cmake_minimum_required(VERSION 2.8.12.1)
endif()
# FIXME: It may be removed when we use 2.8.12.
if(CMAKE_VERSION VERSION_LESS 2.8.12)
# Invalidate a couple of keywords.
set(cmake_2_8_12_INTERFACE)
set(cmake_2_8_12_PRIVATE)
else()
# Use ${cmake_2_8_12_KEYWORD} intead of KEYWORD in target_link_libraries().
set(cmake_2_8_12_INTERFACE INTERFACE)
set(cmake_2_8_12_PRIVATE PRIVATE)
if(POLICY CMP0022)
cmake_policy(SET CMP0022 NEW) # automatic when 2.8.12 is required
endif()
endif()
# Top level target used to build all compiler-rt libraries.
add_custom_target(compiler-rt ALL)
if (NOT COMPILER_RT_STANDALONE_BUILD)
# Compute the Clang version from the LLVM version.
# FIXME: We should be able to reuse CLANG_VERSION variable calculated
# in Clang cmake files, instead of copying the rules here.
string(REGEX MATCH "[0-9]+\\.[0-9]+(\\.[0-9]+)?" CLANG_VERSION
${PACKAGE_VERSION})
# Setup the paths where compiler-rt runtimes and headers should be stored.
set(COMPILER_RT_OUTPUT_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}/clang/${CLANG_VERSION})
set(COMPILER_RT_EXEC_OUTPUT_DIR ${LLVM_RUNTIME_OUTPUT_INTDIR})
set(COMPILER_RT_INSTALL_PATH lib${LLVM_LIBDIR_SUFFIX}/clang/${CLANG_VERSION})
option(COMPILER_RT_INCLUDE_TESTS "Generate and build compiler-rt unit tests."
${LLVM_INCLUDE_TESTS})
option(COMPILER_RT_ENABLE_WERROR "Fail and stop if warning is triggered"
${LLVM_ENABLE_WERROR})
# Use just-built Clang to compile/link tests.
set(COMPILER_RT_TEST_COMPILER ${LLVM_RUNTIME_OUTPUT_INTDIR}/clang)
else()
# Take output dir and install path from the user.
set(COMPILER_RT_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR} CACHE PATH
"Path where built compiler-rt libraries should be stored.")
set(COMPILER_RT_EXEC_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/bin CACHE PATH
"Path where built compiler-rt executables should be stored.")
set(COMPILER_RT_INSTALL_PATH ${CMAKE_INSTALL_PREFIX} CACHE PATH
"Path where built compiler-rt libraries should be installed.")
option(COMPILER_RT_INCLUDE_TESTS "Generate and build compiler-rt unit tests." OFF)
option(COMPILER_RT_ENABLE_WERROR "Fail and stop if warning is triggered" OFF)
# Use a host compiler to compile/link tests.
set(COMPILER_RT_TEST_COMPILER ${CMAKE_C_COMPILER} CACHE PATH "Compiler to use for testing")
if (NOT LLVM_CONFIG_PATH)
find_program(LLVM_CONFIG_PATH "llvm-config"
DOC "Path to llvm-config binary")
if (NOT LLVM_CONFIG_PATH)
message(FATAL_ERROR "llvm-config not found: specify LLVM_CONFIG_PATH")
endif()
endif()
execute_process(
COMMAND ${LLVM_CONFIG_PATH} "--obj-root" "--bindir" "--libdir" "--src-root"
RESULT_VARIABLE HAD_ERROR
OUTPUT_VARIABLE CONFIG_OUTPUT)
if (HAD_ERROR)
message(FATAL_ERROR "llvm-config failed with status ${HAD_ERROR}")
endif()
string(REGEX REPLACE "[ \t]*[\r\n]+[ \t]*" ";" CONFIG_OUTPUT ${CONFIG_OUTPUT})
list(GET CONFIG_OUTPUT 0 LLVM_BINARY_DIR)
list(GET CONFIG_OUTPUT 1 LLVM_TOOLS_BINARY_DIR)
list(GET CONFIG_OUTPUT 2 LLVM_LIBRARY_DIR)
list(GET CONFIG_OUTPUT 3 LLVM_MAIN_SRC_DIR)
# Make use of LLVM CMake modules.
file(TO_CMAKE_PATH ${LLVM_BINARY_DIR} LLVM_BINARY_DIR_CMAKE_STYLE)
set(LLVM_CMAKE_PATH "${LLVM_BINARY_DIR_CMAKE_STYLE}/share/llvm/cmake")
list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_PATH}")
# Get some LLVM variables from LLVMConfig.
include("${LLVM_CMAKE_PATH}/LLVMConfig.cmake")
set(LLVM_LIBRARY_OUTPUT_INTDIR ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/lib)
# Find Python interpreter.
set(Python_ADDITIONAL_VERSIONS 2.7 2.6 2.5)
include(FindPythonInterp)
if(NOT PYTHONINTERP_FOUND)
message(FATAL_ERROR "
Unable to find Python interpreter required testing. Please install Python
or specify the PYTHON_EXECUTABLE CMake variable.")
endif()
# Define default arguments to lit.
set(LIT_ARGS_DEFAULT "-sv")
if (MSVC OR XCODE)
set(LIT_ARGS_DEFAULT "${LIT_ARGS_DEFAULT} --no-progress-bar")
endif()
set(LLVM_LIT_ARGS "${LIT_ARGS_DEFAULT}" CACHE STRING "Default options for lit")
endif()
if("${COMPILER_RT_TEST_COMPILER}" MATCHES "clang[+]*$")
set(COMPILER_RT_TEST_COMPILER_ID Clang)
else()
set(COMPILER_RT_TEST_COMPILER_ID GNU)
endif()
string(TOLOWER ${CMAKE_SYSTEM_NAME} COMPILER_RT_OS_DIR)
set(COMPILER_RT_LIBRARY_OUTPUT_DIR
${COMPILER_RT_OUTPUT_DIR}/lib/${COMPILER_RT_OS_DIR})
set(COMPILER_RT_LIBRARY_INSTALL_DIR
${COMPILER_RT_INSTALL_PATH}/lib/${COMPILER_RT_OS_DIR})
# Add path for custom compiler-rt modules.
set(CMAKE_MODULE_PATH
"${CMAKE_CURRENT_SOURCE_DIR}/cmake"
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules"
${CMAKE_MODULE_PATH}
)
include(CompilerRTUtils)
set(COMPILER_RT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
set(COMPILER_RT_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
# Setup custom SDK sysroots.
set(COMPILER_RT_DARWIN_SDK_SYSROOT ${COMPILER_RT_SOURCE_DIR}/SDKs/darwin)
set(COMPILER_RT_LINUX_SDK_SYSROOT ${COMPILER_RT_SOURCE_DIR}/SDKs/linux)
set(COMPILER_RT_EXTRA_ANDROID_HEADERS ${COMPILER_RT_SOURCE_DIR}/android/include)
# Detect whether the current target platform is 32-bit or 64-bit, and setup
# the correct commandline flags needed to attempt to target 32-bit and 64-bit.
if (NOT CMAKE_SIZEOF_VOID_P EQUAL 4 AND
NOT CMAKE_SIZEOF_VOID_P EQUAL 8)
message(FATAL_ERROR "Please use architecture with 4 or 8 byte pointers.")
endif()
if (NOT MSVC)
set(TARGET_64_BIT_CFLAGS "-m64")
set(TARGET_32_BIT_CFLAGS "-m32")
else()
set(TARGET_64_BIT_CFLAGS "")
set(TARGET_32_BIT_CFLAGS "")
endif()
# List of architectures we can target.
set(COMPILER_RT_SUPPORTED_ARCH)
function(get_target_flags_for_arch arch out_var)
list(FIND COMPILER_RT_SUPPORTED_ARCH ${arch} ARCH_INDEX)
if(ARCH_INDEX EQUAL -1)
message(FATAL_ERROR "Unsupported architecture: ${arch}")
else()
set(${out_var} ${TARGET_${arch}_CFLAGS} PARENT_SCOPE)
endif()
endfunction()
# Try to compile a very simple source file to ensure we can target the given
# platform. We use the results of these tests to build only the various target
# runtime libraries supported by our current compilers cross-compiling
# abilities.
set(SIMPLE_SOURCE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/simple.cc)
file(WRITE ${SIMPLE_SOURCE} "#include <stdlib.h>\n#include <limits>\nint main() {}\n")
# test_target_arch(<arch> <target flags...>)
# Sets the target flags for a given architecture and determines if this
# architecture is supported by trying to build a simple file.
macro(test_target_arch arch)
set(TARGET_${arch}_CFLAGS ${ARGN})
try_compile(CAN_TARGET_${arch} ${CMAKE_BINARY_DIR} ${SIMPLE_SOURCE}
COMPILE_DEFINITIONS "${TARGET_${arch}_CFLAGS}"
CMAKE_FLAGS "-DCMAKE_EXE_LINKER_FLAGS:STRING=${TARGET_${arch}_CFLAGS}")
if(${CAN_TARGET_${arch}})
list(APPEND COMPILER_RT_SUPPORTED_ARCH ${arch})
endif()
endmacro()
if(ANDROID_COMMON_FLAGS)
test_target_arch(arm_android "${ANDROID_COMMON_FLAGS}")
else()
if("${LLVM_NATIVE_ARCH}" STREQUAL "X86")
if (NOT MSVC)
test_target_arch(x86_64 ${TARGET_64_BIT_CFLAGS})
endif()
test_target_arch(i386 ${TARGET_32_BIT_CFLAGS})
elseif("${LLVM_NATIVE_ARCH}" STREQUAL "PowerPC")
test_target_arch(powerpc64 ${TARGET_64_BIT_CFLAGS})
elseif("${LLVM_NATIVE_ARCH}" STREQUAL "ARM")
test_target_arch(arm "")
endif()
endif()
# We only support running instrumented tests when we're not cross compiling
# and target a unix-like system. We can run tests on Android even when we are
# cross-compiling.
if(("${CMAKE_HOST_SYSTEM}" STREQUAL "${CMAKE_SYSTEM}" AND UNIX) OR ANDROID)
option(COMPILER_RT_CAN_EXECUTE_TESTS "Can we execute instrumented tests" ON)
else()
option(COMPILER_RT_CAN_EXECUTE_TESTS "Can we execute instrumented tests" OFF)
endif()
# Check if compiler-rt is built with libc++.
find_flag_in_string("${CMAKE_CXX_FLAGS}" "-stdlib=libc++"
COMPILER_RT_USES_LIBCXX)
function(filter_available_targets out_var)
set(archs)
foreach(arch ${ARGN})
list(FIND COMPILER_RT_SUPPORTED_ARCH ${arch} ARCH_INDEX)
if(NOT (ARCH_INDEX EQUAL -1) AND CAN_TARGET_${arch})
list(APPEND archs ${arch})
endif()
endforeach()
set(${out_var} ${archs} PARENT_SCOPE)
endfunction()
option(COMPILER_RT_DEBUG "Build runtimes with full debug info" OFF)
# COMPILER_RT_DEBUG_PYBOOL is used by lit.common.configured.in.
pythonize_bool(COMPILER_RT_DEBUG)
option(COMPILER_RT_BUILD_SHARED_ASAN "Build shared version of AddressSanitizer runtime" OFF)
#================================
# Setup Compiler Flags
#================================
include(config-ix)
if(MSVC)
append_string_if(COMPILER_RT_HAS_W3_FLAG /W3 CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
else()
append_string_if(COMPILER_RT_HAS_WALL_FLAG -Wall CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
endif()
if(COMPILER_RT_ENABLE_WERROR)
append_string_if(COMPILER_RT_HAS_WERROR_FLAG -Werror CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
append_string_if(COMPILER_RT_HAS_WX_FLAG /WX CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
endif()
append_string_if(COMPILER_RT_HAS_STD_CXX11_FLAG -std=c++11 CMAKE_CXX_FLAGS)
# Emulate C99 and C++11's __func__ for MSVC prior to 2013 CTP.
if(NOT COMPILER_RT_HAS_FUNC_SYMBOL)
add_definitions(-D__func__=__FUNCTION__)
endif()
# Provide some common commmandline flags for Sanitizer runtimes.
append_if(COMPILER_RT_HAS_FPIC_FLAG -fPIC SANITIZER_COMMON_CFLAGS)
append_if(COMPILER_RT_HAS_FNO_BUILTIN_FLAG -fno-builtin SANITIZER_COMMON_CFLAGS)
append_if(COMPILER_RT_HAS_FNO_EXCEPTIONS_FLAG -fno-exceptions SANITIZER_COMMON_CFLAGS)
append_if(COMPILER_RT_HAS_FOMIT_FRAME_POINTER_FLAG -fomit-frame-pointer SANITIZER_COMMON_CFLAGS)
append_if(COMPILER_RT_HAS_FUNWIND_TABLES_FLAG -funwind-tables SANITIZER_COMMON_CFLAGS)
append_if(COMPILER_RT_HAS_FNO_STACK_PROTECTOR_FLAG -fno-stack-protector SANITIZER_COMMON_CFLAGS)
append_if(COMPILER_RT_HAS_FVISIBILITY_HIDDEN_FLAG -fvisibility=hidden SANITIZER_COMMON_CFLAGS)
append_if(COMPILER_RT_HAS_FNO_FUNCTION_SECTIONS_FLAG -fno-function-sections SANITIZER_COMMON_CFLAGS)
if(MSVC)
# Remove /MD flag so that it doesn't conflict with /MT.
if(COMPILER_RT_HAS_MT_FLAG)
string(REGEX REPLACE "(^| ) */MDd? *( |$)" "\\1 \\2" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
list(APPEND SANITIZER_COMMON_CFLAGS /MT)
endif()
append_if(COMPILER_RT_HAS_Oy_FLAG /Oy- SANITIZER_COMMON_CFLAGS)
append_if(COMPILER_RT_HAS_GS_FLAG /GS- SANITIZER_COMMON_CFLAGS)
endif()
# Build with optimization, unless we're in debug mode. If we're using MSVC,
# always respect the optimization flags set by CMAKE_BUILD_TYPE instead.
if(NOT COMPILER_RT_DEBUG AND NOT MSVC)
list(APPEND SANITIZER_COMMON_CFLAGS -O3)
endif()
# Build sanitizer runtimes with debug info.
if(COMPILER_RT_HAS_GLINE_TABLES_ONLY_FLAG)
list(APPEND SANITIZER_COMMON_CFLAGS -gline-tables-only)
elseif(COMPILER_RT_HAS_G_FLAG)
list(APPEND SANITIZER_COMMON_CFLAGS -g)
elseif(COMPILER_RT_HAS_Zi_FLAG)
list(APPEND SANITIZER_COMMON_CFLAGS /Zi)
endif()
# Turn off several warnings.
append_if(COMPILER_RT_HAS_WNO_GNU_FLAG -Wno-gnu SANITIZER_COMMON_CFLAGS)
append_if(COMPILER_RT_HAS_WNO_VARIADIC_MACROS_FLAG -Wno-variadic-macros SANITIZER_COMMON_CFLAGS)
append_if(COMPILER_RT_HAS_WNO_C99_EXTENSIONS_FLAG -Wno-c99-extensions SANITIZER_COMMON_CFLAGS)
append_if(COMPILER_RT_HAS_WNO_NON_VIRTUAL_DTOR_FLAG -Wno-non-virtual-dtor SANITIZER_COMMON_CFLAGS)
append_if(COMPILER_RT_HAS_WD4722_FLAG /wd4722 SANITIZER_COMMON_CFLAGS)
if(APPLE)
# Obtain the iOS Simulator SDK path from xcodebuild.
execute_process(
COMMAND xcodebuild -version -sdk iphonesimulator Path
OUTPUT_VARIABLE IOSSIM_SDK_DIR
OUTPUT_STRIP_TRAILING_WHITESPACE
)
string(REGEX MATCH "-mmacosx-version-min="
MACOSX_VERSION_MIN_FLAG "${CMAKE_CXX_FLAGS}")
set(SANITIZER_COMMON_SUPPORTED_DARWIN_OS osx)
if (IOSSIM_SDK_DIR AND NOT MACOSX_VERSION_MIN_FLAG)
list(APPEND SANITIZER_COMMON_SUPPORTED_DARWIN_OS iossim)
endif()
if(COMPILER_RT_USES_LIBCXX)
set(SANITIZER_MIN_OSX_VERSION 10.7)
else()
set(SANITIZER_MIN_OSX_VERSION 10.6)
endif()
set(DARWIN_osx_CFLAGS -mmacosx-version-min=${SANITIZER_MIN_OSX_VERSION})
set(DARWIN_iossim_CFLAGS
-mios-simulator-version-min=7.0 -isysroot ${IOSSIM_SDK_DIR})
set(DARWIN_osx_LINKFLAGS)
set(DARWIN_iossim_LINKFLAGS
-Wl,-ios_simulator_version_min,7.0.0
-mios-simulator-version-min=7.0
-isysroot ${IOSSIM_SDK_DIR})
endif()
# Architectures supported by Sanitizer runtimes. Specific sanitizers may
# support only subset of these (e.g. TSan works on x86_64 only).
filter_available_targets(SANITIZER_COMMON_SUPPORTED_ARCH
x86_64 i386 powerpc64 arm)
filter_available_targets(ASAN_SUPPORTED_ARCH x86_64 i386 powerpc64)
filter_available_targets(DFSAN_SUPPORTED_ARCH x86_64)
filter_available_targets(LSAN_SUPPORTED_ARCH x86_64)
filter_available_targets(MSAN_SUPPORTED_ARCH x86_64)
filter_available_targets(PROFILE_SUPPORTED_ARCH x86_64 i386 arm)
filter_available_targets(TSAN_SUPPORTED_ARCH x86_64)
filter_available_targets(UBSAN_SUPPORTED_ARCH x86_64 i386)
add_subdirectory(include)
set(COMPILER_RT_LIBCXX_PATH ${LLVM_MAIN_SRC_DIR}/projects/libcxx)
if(EXISTS ${COMPILER_RT_LIBCXX_PATH}/)
set(COMPILER_RT_HAS_LIBCXX_SOURCES TRUE)
else()
set(COMPILER_RT_HAS_LIBCXX_SOURCES FALSE)
endif()
add_subdirectory(lib)
if(COMPILER_RT_INCLUDE_TESTS)
add_subdirectory(unittests)
endif()
add_subdirectory(test)

View File

@ -0,0 +1,57 @@
This file is a list of the people responsible for ensuring that patches for a
particular part of compiler-rt are reviewed, either by themself or by
someone else. They are also the gatekeepers for their part of compiler-rt, with
the final word on what goes in or not.
The list is sorted by surname and formatted to allow easy grepping and
beautification by scripts. The fields are: name (N), email (E), web-address
(W), PGP key ID and fingerprint (P), description (D), and snail-mail address
(S).
N: Peter Collingbourne
E: peter@pcc.me.uk
D: DataFlowSanitizer
N: Daniel Dunbar
E: daniel@zuster.org
D: Makefile build
N: Timur Iskhodzhanov
E: timurrrr@google.com
D: AddressSanitizer for Windows
N: Howard Hinnant
E: howard.hinnant@gmail.com
D: builtins library
N: Sergey Matveev
E: earthdok@google.com
D: LeakSanitizer
N: Alexander Potapenko
E: glider@google.com
D: MacOS/iOS port of sanitizers
N: Alexey Samsonov
E: samsonov@google.com
D: CMake build, test suite
N: Kostya Serebryany
E: kcc@google.com
D: AddressSanitizer, sanitizer_common, porting sanitizers to another platforms
N: Richard Smith
E: richard-llvm@metafoo.co.uk
D: UndefinedBehaviorSanitizer
N: Evgeniy Stepanov
E: eugenis@google.com
D: MemorySanitizer, Android port of sanitizers
N: Dmitry Vyukov
E: dvyukov@google.com
D: ThreadSanitizer
N: Bill Wendling
E: isanbard@gmail.com
D: Profile runtime library

View File

@ -0,0 +1,32 @@
This file is a partial list of people who have contributed to the LLVM/CompilerRT
project. If you have contributed a patch or made some other contribution to
LLVM/CompilerRT, please submit a patch to this file to add yourself, and it will be
done!
The list is sorted by surname and formatted to allow easy grepping and
beautification by scripts. The fields are: name (N), email (E), web-address
(W), PGP key ID and fingerprint (P), description (D), and snail-mail address
(S).
N: Craig van Vliet
E: cvanvliet@auroraux.org
W: http://www.auroraux.org
D: Code style and Readability fixes.
N: Edward O'Callaghan
E: eocallaghan@auroraux.org
W: http://www.auroraux.org
D: CMake'ify Compiler-RT build system
D: Maintain Solaris & AuroraUX ports of Compiler-RT
N: Howard Hinnant
E: hhinnant@apple.com
D: Architect and primary author of compiler-rt
N: Joerg Sonnenberger
E: joerg@NetBSD.org
D: Maintains NetBSD port.
N: Matt Thomas
E: matt@NetBSD.org
D: ARM improvements.

View File

@ -0,0 +1,91 @@
==============================================================================
compiler_rt License
==============================================================================
The compiler_rt library is dual licensed under both the University of Illinois
"BSD-Like" license and the MIT license. As a user of this code you may choose
to use it under either license. As a contributor, you agree to allow your code
to be used under both.
Full text of the relevant licenses is included below.
==============================================================================
University of Illinois/NCSA
Open Source License
Copyright (c) 2009-2014 by the contributors listed in CREDITS.TXT
All rights reserved.
Developed by:
LLVM Team
University of Illinois at Urbana-Champaign
http://llvm.org
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal with
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimers.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimers in the
documentation and/or other materials provided with the distribution.
* Neither the names of the LLVM Team, University of Illinois at
Urbana-Champaign, nor the names of its contributors may be used to
endorse or promote products derived from this Software without specific
prior written permission.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
SOFTWARE.
==============================================================================
Copyright (c) 2009-2014 by the contributors listed in CREDITS.TXT
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
==============================================================================
Copyrights and Licenses for Third Party Software Distributed with LLVM:
==============================================================================
The LLVM software contains code written by third parties. Such software will
have its own individual LICENSE.TXT file in the directory in which it appears.
This file will describe the copyrights, license, and restrictions which apply
to that code.
The disclaimer of warranty in the University of Illinois Open Source License
applies to all code in the LLVM Distribution, and nothing in any of the
other licenses gives permission to use the names of the LLVM Team or the
University of Illinois to endorse or promote products derived from this
Software.

275
src/compiler-rt/Makefile Normal file
View File

@ -0,0 +1,275 @@
SubDirs := lib
# Set default rule before anything else.
all: help
include make/config.mk
include make/util.mk
# If SRCROOT is defined, assume we are doing an Apple style build. We should be
# able to use RC_XBS for this but that is unused during "make installsrc".
ifdef SRCROOT
include make/AppleBI.mk
endif
# Make sure we don't build with a missing ProjObjRoot.
ifeq ($(ProjObjRoot),)
$(error Refusing to build with empty ProjObjRoot variable)
endif
##############
###
# Rules
###
# Top level targets
# FIXME: Document the available subtargets.
help:
@echo "usage: make [{VARIABLE=VALUE}*] target"
@echo
@echo "User variables:"
@echo " VERBOSE=1: Use to show all commands [default=0]"
@echo
@echo "Available targets:"
@echo " <platform name>: build the libraries for 'platform'"
@echo " clean: clean all configurations"
@echo " test: run unit tests"
@echo
@echo " info-platforms: list available platforms"
@echo " help-devel: print additional help for developers"
@echo
help-devel: help
@echo "Development targets:"
@echo " <platform name>-<config name>:"
@echo " build the libraries for a single platform config"
@echo " <platform name>-<config name>-<arch name>:"
@echo " build the libraries for a single config and arch"
@echo " info-functions: list available compiler-rt functions"
@echo " help-hidden: print help for Makefile debugging"
@echo
help-hidden: help-devel
@echo "Debugging variables:"
@echo " DEBUGMAKE=1: enable some Makefile logging [default=]"
@echo " =2: enable more Makefile logging"
@echo
@echo "Debugging targets:"
@echo " make-print-FOO: print information on the variable 'FOO'"
@echo
info-functions:
@echo "compiler-rt Available Functions"
@echo
@echo "All Functions: $(AvailableFunctions)"
@$(foreach fn,$(AvailableFunctions),\
printf " %-20s - available in (%s)\n" $(fn)\
"$(foreach key,$(AvailableIn.$(fn)),$($(key).Dir))";)
info-platforms:
@echo "compiler-rt Available Platforms"
@echo
@echo "Platforms:"
@$(foreach key,$(PlatformKeys),\
printf " %s - from '%s'\n" $($(key).Name) $($(key).Path);\
printf " %s\n" "$($(key).Description)";\
printf " Configurations: %s\n\n" "$($(key).Configs)";)
# Provide default clean target which is extended by other templates.
.PHONY: clean
clean::
# Test
.PHONY: test
test:
cd test/Unit && ./test
###
# Directory handling magic.
# Create directories as needed, and timestamp their creation.
%/.dir:
$(Summary) " MKDIR: $*"
$(Verb) $(MKDIR) $* > /dev/null
$(Verb) echo 'Created.' > $@
# Remove directories
%/.remove:
$(Verb) $(RM) -r $*
###
# Include child makefile fragments
Dir := .
include make/subdir.mk
include make/lib_info.mk
include make/lib_util.mk
include make/lib_platforms.mk
###
# Define Platform Rules
define PerPlatform_template
$(call Set,Tmp.Key,$(1))
$(call Set,Tmp.Name,$($(Tmp.Key).Name))
$(call Set,Tmp.Configs,$($(Tmp.Key).Configs))
$(call Set,Tmp.ObjPath,$(ProjObjRoot)/$(Tmp.Name))
# Top-Level Platform Target
$(Tmp.Name):: $(Tmp.Configs:%=$(Tmp.Name)-%)
.PHONY: $(Tmp.Name)
clean::
$(Verb) rm -rf $(Tmp.ObjPath)
# Per-Config Libraries
$(foreach config,$(Tmp.Configs),\
$(call PerPlatformConfig_template,$(config)))
endef
define PerPlatformConfig_template
$(call Set,Tmp.Config,$(1))
$(call Set,Tmp.ObjPath,$(ProjObjRoot)/$(Tmp.Name)/$(Tmp.Config))
$(call Set,Tmp.SHARED_LIBRARY,$(strip \
$(call GetCNAVar,SHARED_LIBRARY,$(Tmp.Key),$(Tmp.Config),$(Tmp.Arch))))
$(call Set,Tmp.SHARED_LIBRARY_SUFFIX,$(strip \
$(call GetCNAVar,SHARED_LIBRARY_SUFFIX,$(Tmp.Key),$(Tmp.Config),$(Tmp.Arch))))
# Compute the library suffix.
$(if $(call streq,1,$(Tmp.SHARED_LIBRARY)),
$(call Set,Tmp.LibrarySuffix,$(Tmp.SHARED_LIBRARY_SUFFIX)),
$(call Set,Tmp.LibrarySuffix,a))
# Compute the archs to build, depending on whether this is a universal build or
# not.
$(call Set,Tmp.ArchsToBuild,\
$(if $(call IsDefined,$(Tmp.Key).UniversalArchs),\
$(strip \
$(or $($(Tmp.Key).UniversalArchs.$(Tmp.Config)),\
$($(Tmp.Key).UniversalArchs))),\
$(call VarOrDefault,$(Tmp.Key).Arch.$(Tmp.Config),$($(Tmp.Key).Arch))))
# Copy or lipo to create the per-config library.
$(call Set,Tmp.Inputs,$(Tmp.ArchsToBuild:%=$(Tmp.ObjPath)/%/libcompiler_rt.$(Tmp.LibrarySuffix)))
$(Tmp.ObjPath)/libcompiler_rt.$(Tmp.LibrarySuffix): $(Tmp.Inputs) $(Tmp.ObjPath)/.dir
$(Summary) " FINAL-ARCHIVE: $(Tmp.Name)/$(Tmp.Config): $$@"
-$(Verb) $(RM) $$@
$(if $(call streq,1,$(words $(Tmp.ArchsToBuild))), \
$(Verb) $(CP) $(Tmp.Inputs) $$@, \
$(Verb) $(LIPO) -create -output $$@ $(Tmp.Inputs))
.PRECIOUS: $(Tmp.ObjPath)/.dir
# Per-Config Targets
$(Tmp.Name)-$(Tmp.Config):: $(Tmp.ObjPath)/libcompiler_rt.$(Tmp.LibrarySuffix)
.PHONY: $(Tmp.Name)-$(Tmp.Config)
# Per-Config-Arch Libraries
$(foreach arch,$(Tmp.ArchsToBuild),\
$(call PerPlatformConfigArch_template,$(arch)))
endef
define PerPlatformConfigArch_template
$(call Set,Tmp.Arch,$(1))
$(call Set,Tmp.ObjPath,$(ProjObjRoot)/$(Tmp.Name)/$(Tmp.Config)/$(Tmp.Arch))
$(call Set,Tmp.Functions,$(strip \
$(AlwaysRequiredModules) \
$(call GetCNAVar,FUNCTIONS,$(Tmp.Key),$(Tmp.Config),$(Tmp.Arch))))
$(call Set,Tmp.Optimized,$(strip \
$(call GetCNAVar,OPTIMIZED,$(Tmp.Key),$(Tmp.Config),$(Tmp.Arch))))
$(call Set,Tmp.AR,$(strip \
$(call GetCNAVar,AR,$(Tmp.Key),$(Tmp.Config),$(Tmp.Arch))))
$(call Set,Tmp.ARFLAGS,$(strip \
$(call GetCNAVar,ARFLAGS,$(Tmp.Key),$(Tmp.Config),$(Tmp.Arch))))
$(call Set,Tmp.CC,$(strip \
$(call GetCNAVar,CC,$(Tmp.Key),$(Tmp.Config),$(Tmp.Arch))))
$(call Set,Tmp.LDFLAGS,$(strip \
$(call GetCNAVar,LDFLAGS,$(Tmp.Key),$(Tmp.Config),$(Tmp.Arch))))
$(call Set,Tmp.RANLIB,$(strip \
$(call GetCNAVar,RANLIB,$(Tmp.Key),$(Tmp.Config),$(Tmp.Arch))))
$(call Set,Tmp.RANLIBFLAGS,$(strip \
$(call GetCNAVar,RANLIBFLAGS,$(Tmp.Key),$(Tmp.Config),$(Tmp.Arch))))
$(call Set,Tmp.SHARED_LIBRARY,$(strip \
$(call GetCNAVar,SHARED_LIBRARY,$(Tmp.Key),$(Tmp.Config),$(Tmp.Arch))))
# Compute the library suffix.
$(if $(call streq,1,$(Tmp.SHARED_LIBRARY)),
$(call Set,Tmp.LibrarySuffix,$(Tmp.SHARED_LIBRARY_SUFFIX)),
$(call Set,Tmp.LibrarySuffix,a))
# Compute the object inputs for this library.
$(call Set,Tmp.Inputs,\
$(foreach fn,$(sort $(Tmp.Functions)),\
$(call Set,Tmp.FnDir,\
$(call SelectFunctionDir,$(Tmp.Config),$(Tmp.Arch),$(fn),$(Tmp.Optimized)))\
$(Tmp.ObjPath)/$(Tmp.FnDir)/$(fn).o))
$(Tmp.ObjPath)/libcompiler_rt.a: $(Tmp.Inputs) $(Tmp.ObjPath)/.dir
$(Summary) " ARCHIVE: $(Tmp.Name)/$(Tmp.Config)/$(Tmp.Arch): $$@"
-$(Verb) $(RM) $$@
$(Verb) $(Tmp.AR) $(Tmp.ARFLAGS) $$@ $(Tmp.Inputs)
$(Verb) $(Tmp.RANLIB) $(Tmp.RANLIBFLAGS) $$@
$(Tmp.ObjPath)/libcompiler_rt.dylib: $(Tmp.Inputs) $(Tmp.ObjPath)/.dir
$(Summary) " DYLIB: $(Tmp.Name)/$(Tmp.Config)/$(Tmp.Arch): $$@"
$(Verb) $(Tmp.CC) -arch $(Tmp.Arch) -dynamiclib -o $$@ \
$(Tmp.Inputs) $(Tmp.LDFLAGS)
$(Tmp.ObjPath)/libcompiler_rt.so: $(Tmp.Inputs) $(Tmp.ObjPath)/.dir
$(Summary) " SO: $(Tmp.Name)/$(Tmp.Config)/$(Tmp.Arch): $$@"
$(Verb) $(Tmp.CC) -shared -o $$@ \
$(Tmp.Inputs) $(Tmp.LDFLAGS)
.PRECIOUS: $(Tmp.ObjPath)/.dir
# Per-Config-Arch Targets
$(Tmp.Name)-$(Tmp.Config)-$(Tmp.Arch):: $(Tmp.ObjPath)/libcompiler_rt.$(Tmp.LibrarySuffix)
.PHONY: $(Tmp.Name)-$(Tmp.Config)-$(Tmp.Arch)
# Per-Config-Arch-SubDir Objects
$(foreach key,$(SubDirKeys),\
$(call PerPlatformConfigArchSubDir_template,$(key)))
endef
define PerPlatformConfigArchSubDir_template
$(call Set,Tmp.SubDirKey,$(1))
$(call Set,Tmp.SubDir,$($(Tmp.SubDirKey).Dir))
$(call Set,Tmp.SrcPath,$(ProjSrcRoot)/$(Tmp.SubDir))
$(call Set,Tmp.ObjPath,$(ProjObjRoot)/$(Tmp.Name)/$(Tmp.Config)/$(Tmp.Arch)/$(Tmp.SubDirKey))
$(call Set,Tmp.Dependencies,$($(Tmp.SubDirKey).Dependencies))
$(call Set,Tmp.CC,$(strip \
$(call GetCNAVar,CC,$(Tmp.Key),$(Tmp.Config),$(Tmp.Arch))))
$(call Set,Tmp.KERNEL_USE,$(strip \
$(call GetCNAVar,KERNEL_USE,$(Tmp.Key),$(Tmp.Config),$(Tmp.Arch))))
$(call Set,Tmp.VISIBILITY_HIDDEN,$(strip \
$(call GetCNAVar,VISIBILITY_HIDDEN,$(Tmp.Key),$(Tmp.Config),$(Tmp.Arch))))
$(call Set,Tmp.CFLAGS,$(strip \
$(if $(call IsDefined,$(Tmp.Key).UniversalArchs),-arch $(Tmp.Arch),)\
$(if $(call streq,$(Tmp.VISIBILITY_HIDDEN),1),\
-fvisibility=hidden -DVISIBILITY_HIDDEN,)\
$(if $(call streq,$(Tmp.KERNEL_USE),1),\
-mkernel -DKERNEL_USE,)\
$(call GetCNAVar,CFLAGS,$(Tmp.Key),$(Tmp.Config),$(Tmp.Arch))))
$(Tmp.ObjPath)/%.o: $(Tmp.SrcPath)/%.s $(Tmp.Dependencies) $(Tmp.ObjPath)/.dir
$(Summary) " ASSEMBLE: $(Tmp.Name)/$(Tmp.Config)/$(Tmp.Arch): $$<"
$(Verb) $(Tmp.CC) $(COMMON_ASMFLAGS) $(Tmp.CFLAGS) -c -o $$@ $$<
$(Tmp.ObjPath)/%.o: $(Tmp.SrcPath)/%.S $(Tmp.Dependencies) $(Tmp.ObjPath)/.dir
$(Summary) " ASSEMBLE: $(Tmp.Name)/$(Tmp.Config)/$(Tmp.Arch): $$<"
$(Verb) $(Tmp.CC) $(COMMON_ASMFLAGS) $(Tmp.CFLAGS) -c -o $$@ $$<
$(Tmp.ObjPath)/%.o: $(Tmp.SrcPath)/%.c $(Tmp.Dependencies) $(Tmp.ObjPath)/.dir
$(Summary) " COMPILE: $(Tmp.Name)/$(Tmp.Config)/$(Tmp.Arch): $$<"
$(Verb) $(Tmp.CC) $(COMMON_CFLAGS) $(Tmp.CFLAGS) -c -o $$@ $$<
$(Tmp.ObjPath)/%.o: $(Tmp.SrcPath)/%.cc $(Tmp.Dependencies) $(Tmp.ObjPath)/.dir
$(Summary) " COMPILE: $(Tmp.Name)/$(Tmp.Config)/$(Tmp.Arch): $$<"
$(Verb) $(Tmp.CC) $(COMMON_CXXFLAGS) $(Tmp.CFLAGS) -c -o $$@ $$<
.PRECIOUS: $(Tmp.ObjPath)/.dir
endef
# Run templates.
$(foreach key,$(PlatformKeys),\
$(eval $(call PerPlatform_template,$(key))))
###
ifneq ($(DEBUGMAKE),)
$(info MAKE: Done processing Makefile)
$(info )
endif

343
src/compiler-rt/README.txt Normal file
View File

@ -0,0 +1,343 @@
Compiler-RT
================================
This directory and its subdirectories contain source code for the compiler
support routines.
Compiler-RT is open source software. You may freely distribute it under the
terms of the license agreement found in LICENSE.txt.
================================
This is a replacement library for libgcc. Each function is contained
in its own file. Each function has a corresponding unit test under
test/Unit.
A rudimentary script to test each file is in the file called
test/Unit/test.
Here is the specification for this library:
http://gcc.gnu.org/onlinedocs/gccint/Libgcc.html#Libgcc
Here is a synopsis of the contents of this library:
typedef int si_int;
typedef unsigned su_int;
typedef long long di_int;
typedef unsigned long long du_int;
// Integral bit manipulation
di_int __ashldi3(di_int a, si_int b); // a << b
ti_int __ashlti3(ti_int a, si_int b); // a << b
di_int __ashrdi3(di_int a, si_int b); // a >> b arithmetic (sign fill)
ti_int __ashrti3(ti_int a, si_int b); // a >> b arithmetic (sign fill)
di_int __lshrdi3(di_int a, si_int b); // a >> b logical (zero fill)
ti_int __lshrti3(ti_int a, si_int b); // a >> b logical (zero fill)
si_int __clzsi2(si_int a); // count leading zeros
si_int __clzdi2(di_int a); // count leading zeros
si_int __clzti2(ti_int a); // count leading zeros
si_int __ctzsi2(si_int a); // count trailing zeros
si_int __ctzdi2(di_int a); // count trailing zeros
si_int __ctzti2(ti_int a); // count trailing zeros
si_int __ffsdi2(di_int a); // find least significant 1 bit
si_int __ffsti2(ti_int a); // find least significant 1 bit
si_int __paritysi2(si_int a); // bit parity
si_int __paritydi2(di_int a); // bit parity
si_int __parityti2(ti_int a); // bit parity
si_int __popcountsi2(si_int a); // bit population
si_int __popcountdi2(di_int a); // bit population
si_int __popcountti2(ti_int a); // bit population
uint32_t __bswapsi2(uint32_t a); // a byteswapped, arm only
uint64_t __bswapdi2(uint64_t a); // a byteswapped, arm only
// Integral arithmetic
di_int __negdi2 (di_int a); // -a
ti_int __negti2 (ti_int a); // -a
di_int __muldi3 (di_int a, di_int b); // a * b
ti_int __multi3 (ti_int a, ti_int b); // a * b
si_int __divsi3 (si_int a, si_int b); // a / b signed
di_int __divdi3 (di_int a, di_int b); // a / b signed
ti_int __divti3 (ti_int a, ti_int b); // a / b signed
su_int __udivsi3 (su_int n, su_int d); // a / b unsigned
du_int __udivdi3 (du_int a, du_int b); // a / b unsigned
tu_int __udivti3 (tu_int a, tu_int b); // a / b unsigned
si_int __modsi3 (si_int a, si_int b); // a % b signed
di_int __moddi3 (di_int a, di_int b); // a % b signed
ti_int __modti3 (ti_int a, ti_int b); // a % b signed
su_int __umodsi3 (su_int a, su_int b); // a % b unsigned
du_int __umoddi3 (du_int a, du_int b); // a % b unsigned
tu_int __umodti3 (tu_int a, tu_int b); // a % b unsigned
du_int __udivmoddi4(du_int a, du_int b, du_int* rem); // a / b, *rem = a % b unsigned
tu_int __udivmodti4(tu_int a, tu_int b, tu_int* rem); // a / b, *rem = a % b unsigned
su_int __udivmodsi4(su_int a, su_int b, su_int* rem); // a / b, *rem = a % b unsigned
si_int __divmodsi4(si_int a, si_int b, si_int* rem); // a / b, *rem = a % b signed
// Integral arithmetic with trapping overflow
si_int __absvsi2(si_int a); // abs(a)
di_int __absvdi2(di_int a); // abs(a)
ti_int __absvti2(ti_int a); // abs(a)
si_int __negvsi2(si_int a); // -a
di_int __negvdi2(di_int a); // -a
ti_int __negvti2(ti_int a); // -a
si_int __addvsi3(si_int a, si_int b); // a + b
di_int __addvdi3(di_int a, di_int b); // a + b
ti_int __addvti3(ti_int a, ti_int b); // a + b
si_int __subvsi3(si_int a, si_int b); // a - b
di_int __subvdi3(di_int a, di_int b); // a - b
ti_int __subvti3(ti_int a, ti_int b); // a - b
si_int __mulvsi3(si_int a, si_int b); // a * b
di_int __mulvdi3(di_int a, di_int b); // a * b
ti_int __mulvti3(ti_int a, ti_int b); // a * b
// Integral arithmetic which returns if overflow
si_int __mulosi4(si_int a, si_int b, int* overflow); // a * b, overflow set to one if result not in signed range
di_int __mulodi4(di_int a, di_int b, int* overflow); // a * b, overflow set to one if result not in signed range
ti_int __muloti4(ti_int a, ti_int b, int* overflow); // a * b, overflow set to
one if result not in signed range
// Integral comparison: a < b -> 0
// a == b -> 1
// a > b -> 2
si_int __cmpdi2 (di_int a, di_int b);
si_int __cmpti2 (ti_int a, ti_int b);
si_int __ucmpdi2(du_int a, du_int b);
si_int __ucmpti2(tu_int a, tu_int b);
// Integral / floating point conversion
di_int __fixsfdi( float a);
di_int __fixdfdi( double a);
di_int __fixxfdi(long double a);
ti_int __fixsfti( float a);
ti_int __fixdfti( double a);
ti_int __fixxfti(long double a);
uint64_t __fixtfdi(long double input); // ppc only, doesn't match documentation
su_int __fixunssfsi( float a);
su_int __fixunsdfsi( double a);
su_int __fixunsxfsi(long double a);
du_int __fixunssfdi( float a);
du_int __fixunsdfdi( double a);
du_int __fixunsxfdi(long double a);
tu_int __fixunssfti( float a);
tu_int __fixunsdfti( double a);
tu_int __fixunsxfti(long double a);
uint64_t __fixunstfdi(long double input); // ppc only
float __floatdisf(di_int a);
double __floatdidf(di_int a);
long double __floatdixf(di_int a);
long double __floatditf(int64_t a); // ppc only
float __floattisf(ti_int a);
double __floattidf(ti_int a);
long double __floattixf(ti_int a);
float __floatundisf(du_int a);
double __floatundidf(du_int a);
long double __floatundixf(du_int a);
long double __floatunditf(uint64_t a); // ppc only
float __floatuntisf(tu_int a);
double __floatuntidf(tu_int a);
long double __floatuntixf(tu_int a);
// Floating point raised to integer power
float __powisf2( float a, si_int b); // a ^ b
double __powidf2( double a, si_int b); // a ^ b
long double __powixf2(long double a, si_int b); // a ^ b
long double __powitf2(long double a, si_int b); // ppc only, a ^ b
// Complex arithmetic
// (a + ib) * (c + id)
float _Complex __mulsc3( float a, float b, float c, float d);
double _Complex __muldc3(double a, double b, double c, double d);
long double _Complex __mulxc3(long double a, long double b,
long double c, long double d);
long double _Complex __multc3(long double a, long double b,
long double c, long double d); // ppc only
// (a + ib) / (c + id)
float _Complex __divsc3( float a, float b, float c, float d);
double _Complex __divdc3(double a, double b, double c, double d);
long double _Complex __divxc3(long double a, long double b,
long double c, long double d);
long double _Complex __divtc3(long double a, long double b,
long double c, long double d); // ppc only
// Runtime support
// __clear_cache() is used to tell process that new instructions have been
// written to an address range. Necessary on processors that do not have
// a unified instuction and data cache.
void __clear_cache(void* start, void* end);
// __enable_execute_stack() is used with nested functions when a trampoline
// function is written onto the stack and that page range needs to be made
// executable.
void __enable_execute_stack(void* addr);
// __gcc_personality_v0() is normally only called by the system unwinder.
// C code (as opposed to C++) normally does not need a personality function
// because there are no catch clauses or destructors to be run. But there
// is a C language extension __attribute__((cleanup(func))) which marks local
// variables as needing the cleanup function "func" to be run when the
// variable goes out of scope. That includes when an exception is thrown,
// so a personality handler is needed.
_Unwind_Reason_Code __gcc_personality_v0(int version, _Unwind_Action actions,
uint64_t exceptionClass, struct _Unwind_Exception* exceptionObject,
_Unwind_Context_t context);
// for use with some implementations of assert() in <assert.h>
void __eprintf(const char* format, const char* assertion_expression,
const char* line, const char* file);
// Power PC specific functions
// There is no C interface to the saveFP/restFP functions. They are helper
// functions called by the prolog and epilog of functions that need to save
// a number of non-volatile float point registers.
saveFP
restFP
// PowerPC has a standard template for trampoline functions. This function
// generates a custom trampoline function with the specific realFunc
// and localsPtr values.
void __trampoline_setup(uint32_t* trampOnStack, int trampSizeAllocated,
const void* realFunc, void* localsPtr);
// adds two 128-bit double-double precision values ( x + y )
long double __gcc_qadd(long double x, long double y);
// subtracts two 128-bit double-double precision values ( x - y )
long double __gcc_qsub(long double x, long double y);
// multiples two 128-bit double-double precision values ( x * y )
long double __gcc_qmul(long double x, long double y);
// divides two 128-bit double-double precision values ( x / y )
long double __gcc_qdiv(long double a, long double b);
// ARM specific functions
// There is no C interface to the switch* functions. These helper functions
// are only needed by Thumb1 code for efficient switch table generation.
switch16
switch32
switch8
switchu8
// There is no C interface to the *_vfp_d8_d15_regs functions. There are
// called in the prolog and epilog of Thumb1 functions. When the C++ ABI use
// SJLJ for exceptions, each function with a catch clause or destuctors needs
// to save and restore all registers in it prolog and epliog. But there is
// no way to access vector and high float registers from thumb1 code, so the
// compiler must add call outs to these helper functions in the prolog and
// epilog.
restore_vfp_d8_d15_regs
save_vfp_d8_d15_regs
// Note: long ago ARM processors did not have floating point hardware support.
// Floating point was done in software and floating point parameters were
// passed in integer registers. When hardware support was added for floating
// point, new *vfp functions were added to do the same operations but with
// floating point parameters in floating point registers.
// Undocumented functions
float __addsf3vfp(float a, float b); // Appears to return a + b
double __adddf3vfp(double a, double b); // Appears to return a + b
float __divsf3vfp(float a, float b); // Appears to return a / b
double __divdf3vfp(double a, double b); // Appears to return a / b
int __eqsf2vfp(float a, float b); // Appears to return one
// iff a == b and neither is NaN.
int __eqdf2vfp(double a, double b); // Appears to return one
// iff a == b and neither is NaN.
double __extendsfdf2vfp(float a); // Appears to convert from
// float to double.
int __fixdfsivfp(double a); // Appears to convert from
// double to int.
int __fixsfsivfp(float a); // Appears to convert from
// float to int.
unsigned int __fixunssfsivfp(float a); // Appears to convert from
// float to unsigned int.
unsigned int __fixunsdfsivfp(double a); // Appears to convert from
// double to unsigned int.
double __floatsidfvfp(int a); // Appears to convert from
// int to double.
float __floatsisfvfp(int a); // Appears to convert from
// int to float.
double __floatunssidfvfp(unsigned int a); // Appears to convert from
// unisgned int to double.
float __floatunssisfvfp(unsigned int a); // Appears to convert from
// unisgned int to float.
int __gedf2vfp(double a, double b); // Appears to return __gedf2
// (a >= b)
int __gesf2vfp(float a, float b); // Appears to return __gesf2
// (a >= b)
int __gtdf2vfp(double a, double b); // Appears to return __gtdf2
// (a > b)
int __gtsf2vfp(float a, float b); // Appears to return __gtsf2
// (a > b)
int __ledf2vfp(double a, double b); // Appears to return __ledf2
// (a <= b)
int __lesf2vfp(float a, float b); // Appears to return __lesf2
// (a <= b)
int __ltdf2vfp(double a, double b); // Appears to return __ltdf2
// (a < b)
int __ltsf2vfp(float a, float b); // Appears to return __ltsf2
// (a < b)
double __muldf3vfp(double a, double b); // Appears to return a * b
float __mulsf3vfp(float a, float b); // Appears to return a * b
int __nedf2vfp(double a, double b); // Appears to return __nedf2
// (a != b)
double __negdf2vfp(double a); // Appears to return -a
float __negsf2vfp(float a); // Appears to return -a
float __negsf2vfp(float a); // Appears to return -a
double __subdf3vfp(double a, double b); // Appears to return a - b
float __subsf3vfp(float a, float b); // Appears to return a - b
float __truncdfsf2vfp(double a); // Appears to convert from
// double to float.
int __unorddf2vfp(double a, double b); // Appears to return __unorddf2
int __unordsf2vfp(float a, float b); // Appears to return __unordsf2
Preconditions are listed for each function at the definition when there are any.
Any preconditions reflect the specification at
http://gcc.gnu.org/onlinedocs/gccint/Libgcc.html#Libgcc.
Assumptions are listed in "int_lib.h", and in individual files. Where possible
assumptions are checked at compile time.

View File

@ -0,0 +1,9 @@
It is often convenient to be able to build compiler-rt libraries for a certain
platform without having a full SDK or development environment installed.
This makes it easy for users to build a compiler which can target a number of
different platforms, without having to actively maintain full development
environments for those platforms.
Since compiler-rt's libraries typically have minimal interaction with the
system, we achieve this by stubbing out the SDKs of certain platforms.

View File

@ -0,0 +1,3 @@
The Darwin platforms are all similar enough we roll them into one SDK, and use
preprocessor tricks to get the right definitions for the few things which
diverge between OS X and iOS.

View File

@ -0,0 +1,17 @@
/* ===-- errno.h - stub SDK header for compiler-rt --------------------------===
*
* The LLVM Compiler Infrastructure
*
* This file is dual licensed under the MIT and the University of Illinois Open
* Source Licenses. See LICENSE.TXT for details.
*
* ===-----------------------------------------------------------------------===
*
* This is a stub SDK header file. This file is not part of the interface of
* this library nor an official version of the appropriate SDK header. It is
* intended only to stub the features of this header required by compiler-rt.
*
* ===-----------------------------------------------------------------------===
*/
#include <sys/errno.h>

View File

@ -0,0 +1,17 @@
/* ===-- fcntl.h - stub SDK header for compiler-rt --------------------------===
*
* The LLVM Compiler Infrastructure
*
* This file is dual licensed under the MIT and the University of Illinois Open
* Source Licenses. See LICENSE.TXT for details.
*
* ===-----------------------------------------------------------------------===
*
* This is a stub SDK header file. This file is not part of the interface of
* this library nor an official version of the appropriate SDK header. It is
* intended only to stub the features of this header required by compiler-rt.
*
* ===-----------------------------------------------------------------------===
*/
#include <sys/fcntl.h>

View File

@ -0,0 +1,86 @@
/* ===-- inttypes.h - stub SDK header for compiler-rt -----------------------===
*
* The LLVM Compiler Infrastructure
*
* This file is dual licensed under the MIT and the University of Illinois Open
* Source Licenses. See LICENSE.TXT for details.
*
* ===-----------------------------------------------------------------------===
*
* This is a stub SDK header file. This file is not part of the interface of
* this library nor an official version of the appropriate SDK header. It is
* intended only to stub the features of this header required by compiler-rt.
*
* ===-----------------------------------------------------------------------===
*/
#ifndef __INTTYPES_H__
#define __INTTYPES_H__
#if __WORDSIZE == 64
#define __INTTYPE_PRI64__ "l"
#else
#define __INTTYPE_PRI64__ "ll"
#endif
#define PRId8 "hhd"
#define PRId16 "hd"
#define PRId32 "d"
#define PRId64 __INTTYPE_PRI64__ "d"
#define PRIi8 "hhi"
#define PRIi16 "hi"
#define PRIi32 "i"
#define PRIi64 __INTTYPE_PRI64__ "i"
#define PRIo8 "hho"
#define PRIo16 "ho"
#define PRIo32 "o"
#define PRIo64 __INTTYPE_PRI64__ "o"
#define PRIu8 "hhu"
#define PRIu16 "hu"
#define PRIu32 "u"
#define PRIu64 __INTTYPE_PRI64__ "u"
#define PRIx8 "hhx"
#define PRIx16 "hx"
#define PRIx32 "x"
#define PRIx64 __INTTYPE_PRI64__ "x"
#define PRIX8 "hhX"
#define PRIX16 "hX"
#define PRIX32 "X"
#define PRIX64 __INTTYPE_PRI64__ "X"
#define SCNd8 "hhd"
#define SCNd16 "hd"
#define SCNd32 "d"
#define SCNd64 __INTTYPE_PRI64__ "d"
#define SCNi8 "hhi"
#define SCNi16 "hi"
#define SCNi32 "i"
#define SCNi64 __INTTYPE_PRI64__ "i"
#define SCNo8 "hho"
#define SCNo16 "ho"
#define SCNo32 "o"
#define SCNo64 __INTTYPE_PRI64__ "o"
#define SCNu8 "hhu"
#define SCNu16 "hu"
#define SCNu32 "u"
#define SCNu64 __INTTYPE_PRI64__ "u"
#define SCNx8 "hhx"
#define SCNx16 "hx"
#define SCNx32 "x"
#define SCNx64 __INTTYPE_PRI64__ "x"
#define SCNX8 "hhX"
#define SCNX16 "hX"
#define SCNX32 "X"
#define SCNX64 __INTTYPE_PRI64__ "X"
#endif /* __INTTYPES_H__ */

View File

@ -0,0 +1,23 @@
/* ===-- limits.h - stub SDK header for compiler-rt -------------------------===
*
* The LLVM Compiler Infrastructure
*
* This file is dual licensed under the MIT and the University of Illinois Open
* Source Licenses. See LICENSE.TXT for details.
*
* ===-----------------------------------------------------------------------===
*
* This is a stub SDK header file. This file is not part of the interface of
* this library nor an official version of the appropriate SDK header. It is
* intended only to stub the features of this header required by compiler-rt.
*
* ===-----------------------------------------------------------------------===
*/
#ifndef __LIMITS_H__
#define __LIMITS_H__
/* This is only here as a landing pad for the include_next from the compiler's
built-in limits.h. */
#endif /* __LIMITS_H__ */

View File

@ -0,0 +1,90 @@
/* ===-- stdio.h - stub SDK header for compiler-rt --------------------------===
*
* The LLVM Compiler Infrastructure
*
* This file is dual licensed under the MIT and the University of Illinois Open
* Source Licenses. See LICENSE.TXT for details.
*
* ===-----------------------------------------------------------------------===
*
* This is a stub SDK header file. This file is not part of the interface of
* this library nor an official version of the appropriate SDK header. It is
* intended only to stub the features of this header required by compiler-rt.
*
* ===-----------------------------------------------------------------------===
*/
#ifndef __STDIO_H__
#define __STDIO_H__
#if defined(__cplusplus)
extern "C" {
#endif
typedef struct __sFILE FILE;
typedef __SIZE_TYPE__ size_t;
/* Determine the appropriate fdopen, fopen(), and fwrite() functions. */
#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__)
# if defined(__i386)
# define __FDOPEN_NAME "_fdopen$UNIX2003"
# define __FOPEN_NAME "_fopen$UNIX2003"
# define __FWRITE_NAME "_fwrite$UNIX2003"
# elif defined(__x86_64__)
# define __FDOPEN_NAME "_fdopen"
# define __FOPEN_NAME "_fopen"
# define __FWRITE_NAME "_fwrite"
# elif defined(__arm)
# define __FDOPEN_NAME "_fdopen"
# define __FOPEN_NAME "_fopen"
# define __FWRITE_NAME "_fwrite"
# else
# error "unrecognized architecture for targetting OS X"
# endif
#elif defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__)
# if defined(__i386) || defined (__x86_64)
# define __FDOPEN_NAME "_fdopen"
# define __FOPEN_NAME "_fopen"
# define __FWRITE_NAME "_fwrite"
# elif defined(__arm)
# define __FDOPEN_NAME "_fdopen"
# define __FOPEN_NAME "_fopen"
# define __FWRITE_NAME "_fwrite"
# else
# error "unrecognized architecture for targetting iOS"
# endif
#else
# error "unrecognized architecture for targetting Darwin"
#endif
# define stderr __stderrp
extern FILE *__stderrp;
#ifndef SEEK_SET
#define SEEK_SET 0 /* set file offset to offset */
#endif
#ifndef SEEK_CUR
#define SEEK_CUR 1 /* set file offset to current plus offset */
#endif
#ifndef SEEK_END
#define SEEK_END 2 /* set file offset to EOF plus offset */
#endif
int fclose(FILE *);
int fflush(FILE *);
FILE *fopen(const char * __restrict, const char * __restrict) __asm(__FOPEN_NAME);
FILE *fdopen(int, const char *) __asm(__FDOPEN_NAME);
int fprintf(FILE * __restrict, const char * __restrict, ...);
int fputc(int, FILE *);
size_t fwrite(const void * __restrict, size_t, size_t, FILE * __restrict)
__asm(__FWRITE_NAME);
size_t fread(void * __restrict, size_t, size_t, FILE * __restrict);
long ftell(FILE *);
int fseek(FILE *, long, int);
int snprintf(char * __restrict, size_t, const char * __restrict, ...);
#if defined(__cplusplus)
}
#endif
#endif /* __STDIO_H__ */

View File

@ -0,0 +1,32 @@
/* ===-- stdlib.h - stub SDK header for compiler-rt -------------------------===
*
* The LLVM Compiler Infrastructure
*
* This file is dual licensed under the MIT and the University of Illinois Open
* Source Licenses. See LICENSE.TXT for details.
*
* ===-----------------------------------------------------------------------===
*
* This is a stub SDK header file. This file is not part of the interface of
* this library nor an official version of the appropriate SDK header. It is
* intended only to stub the features of this header required by compiler-rt.
*
* ===-----------------------------------------------------------------------===
*/
#ifndef __STDLIB_H__
#define __STDLIB_H__
#define NULL ((void *)0)
typedef __SIZE_TYPE__ size_t;
void abort(void) __attribute__((__noreturn__));
int atexit(void (*)(void));
int atoi(const char *);
void free(void *);
char *getenv(const char *);
void *malloc(size_t);
void *realloc(void *, size_t);
#endif /* __STDLIB_H__ */

View File

@ -0,0 +1,52 @@
/* ===-- string.h - stub SDK header for compiler-rt -------------------------===
*
* The LLVM Compiler Infrastructure
*
* This file is dual licensed under the MIT and the University of Illinois Open
* Source Licenses. See LICENSE.TXT for details.
*
* ===-----------------------------------------------------------------------===
*
* This is a stub SDK header file. This file is not part of the interface of
* this library nor an official version of the appropriate SDK header. It is
* intended only to stub the features of this header required by compiler-rt.
*
* ===-----------------------------------------------------------------------===
*/
#ifndef __STRING_H__
#define __STRING_H__
typedef __SIZE_TYPE__ size_t;
int memcmp(const void *, const void *, size_t);
void *memcpy(void *, const void *, size_t);
void *memset(void *, int, size_t);
char *strcat(char *, const char *);
char *strcpy(char *, const char *);
char *strdup(const char *);
size_t strlen(const char *);
char *strncpy(char *, const char *, size_t);
/* Determine the appropriate strerror() function. */
#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__)
# if defined(__i386)
# define __STRERROR_NAME "_strerror$UNIX2003"
# elif defined(__x86_64__) || defined(__arm)
# define __STRERROR_NAME "_strerror"
# else
# error "unrecognized architecture for targetting OS X"
# endif
#elif defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__)
# if defined(__i386) || defined (__x86_64) || defined(__arm)
# define __STRERROR_NAME "_strerror"
# else
# error "unrecognized architecture for targetting iOS"
# endif
#else
# error "unrecognized architecture for targetting Darwin"
#endif
char *strerror(int) __asm(__STRERROR_NAME);
#endif /* __STRING_H__ */

View File

@ -0,0 +1,31 @@
/* ===-- errno.h - stub SDK header for compiler-rt --------------------------===
*
* The LLVM Compiler Infrastructure
*
* This file is dual licensed under the MIT and the University of Illinois Open
* Source Licenses. See LICENSE.TXT for details.
*
* ===-----------------------------------------------------------------------===
*
* This is a stub SDK header file. This file is not part of the interface of
* this library nor an official version of the appropriate SDK header. It is
* intended only to stub the features of this header required by compiler-rt.
*
* ===-----------------------------------------------------------------------===
*/
#ifndef _SYS_ERRNO_H_
#define _SYS_ERRNO_H_
#if defined(__cplusplus)
extern "C" {
#endif
extern int *__error(void);
#define errno (*__error())
#if defined(__cplusplus)
}
#endif
#endif

View File

@ -0,0 +1,52 @@
/* ===-- fcntl.h - stub SDK header for compiler-rt --------------------------===
*
* The LLVM Compiler Infrastructure
*
* This file is dual licensed under the MIT and the University of Illinois Open
* Source Licenses. See LICENSE.TXT for details.
*
* ===-----------------------------------------------------------------------===
*
* This is a stub SDK header file. This file is not part of the interface of
* this library nor an official version of the appropriate SDK header. It is
* intended only to stub the features of this header required by compiler-rt.
*
* ===-----------------------------------------------------------------------===
*/
#ifndef _SYS_FCNTL_H_
#define _SYS_FCNTL_H_
/* Determine the appropriate open function. */
#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__)
# if defined(__i386)
# define __OPEN_NAME "_open$UNIX2003"
# elif defined(__x86_64__)
# define __OPEN_NAME "_open"
# elif defined(__arm)
# define __OPEN_NAME "_open"
# else
# error "unrecognized architecture for targetting OS X"
# endif
#elif defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__)
# if defined(__i386) || defined (__x86_64)
# define __OPEN_NAME "_open"
# elif defined(__arm)
# define __OPEN_NAME "_open"
# else
# error "unrecognized architecture for targetting iOS"
# endif
#else
# error "unrecognized architecture for targetting Darwin"
#endif
#define O_RDONLY 0x0000 /* open for reading only */
#define O_WRONLY 0x0001 /* open for writing only */
#define O_RDWR 0x0002 /* open for reading and writing */
#define O_ACCMODE 0x0003 /* mask for above modes */
#define O_CREAT 0x0200 /* create if nonexistant */
int open(const char *, int, ...) __asm(__OPEN_NAME);
#endif /* !_SYS_FCNTL_H_ */

View File

@ -0,0 +1,42 @@
/* ===-- mman.h - stub SDK header for compiler-rt ---------------------------===
*
* The LLVM Compiler Infrastructure
*
* This file is dual licensed under the MIT and the University of Illinois Open
* Source Licenses. See LICENSE.TXT for details.
*
* ===-----------------------------------------------------------------------===
*
* This is a stub SDK header file. This file is not part of the interface of
* this library nor an official version of the appropriate SDK header. It is
* intended only to stub the features of this header required by compiler-rt.
*
* ===-----------------------------------------------------------------------===
*/
#ifndef __SYS_MMAN_H__
#define __SYS_MMAN_H__
typedef __SIZE_TYPE__ size_t;
#define PROT_NONE 0x00
#define PROT_READ 0x01
#define PROT_WRITE 0x02
#define PROT_EXEC 0x04
#define MAP_SHARED 0x0001
#define MAP_PRIVATE 0x0002
#define MAP_FILE 0x0000
#define MAP_ANON 0x1000
#define MS_ASYNC 0x0001
#define MS_INVALIDATE 0x0002
#define MS_SYNC 0x0010
void *mmap(void *addr, size_t len, int prot, int flags, int fd,
long long offset);
int munmap(void *addr, size_t len);
int msync(void *addr, size_t len, int flags);
#endif /* __SYS_MMAN_H__ */

View File

@ -0,0 +1,25 @@
/* ===-- stat.h - stub SDK header for compiler-rt ---------------------------===
*
* The LLVM Compiler Infrastructure
*
* This file is dual licensed under the MIT and the University of Illinois Open
* Source Licenses. See LICENSE.TXT for details.
*
* ===-----------------------------------------------------------------------===
*
* This is a stub SDK header file. This file is not part of the interface of
* this library nor an official version of the appropriate SDK header. It is
* intended only to stub the features of this header required by compiler-rt.
*
* ===-----------------------------------------------------------------------===
*/
#ifndef __SYS_STAT_H__
#define __SYS_STAT_H__
typedef unsigned short uint16_t;
typedef uint16_t mode_t;
int mkdir(const char *, mode_t);
#endif /* __SYS_STAT_H__ */

View File

@ -0,0 +1,20 @@
/* ===-- types.h - stub SDK header for compiler-rt --------------------------===
*
* The LLVM Compiler Infrastructure
*
* This file is dual licensed under the MIT and the University of Illinois Open
* Source Licenses. See LICENSE.TXT for details.
*
* ===-----------------------------------------------------------------------===
*
* This is a stub SDK header file. This file is not part of the interface of
* this library nor an official version of the appropriate SDK header. It is
* intended only to stub the features of this header required by compiler-rt.
*
* ===-----------------------------------------------------------------------===
*/
#ifndef __SYS_TYPES_H__
#define __SYS_TYPES_H__
#endif /* __SYS_TYPES_H__ */

View File

@ -0,0 +1,2 @@
This is a stub SDK for Linux. Currently, this has only been tested on i386 and
x86_64 using the Clang compiler.

View File

@ -0,0 +1,29 @@
/* ===-- endian.h - stub SDK header for compiler-rt -------------------------===
*
* The LLVM Compiler Infrastructure
*
* This file is dual licensed under the MIT and the University of Illinois Open
* Source Licenses. See LICENSE.TXT for details.
*
* ===-----------------------------------------------------------------------===
*
* This is a stub SDK header file. This file is not part of the interface of
* this library nor an official version of the appropriate SDK header. It is
* intended only to stub the features of this header required by compiler-rt.
*
* ===-----------------------------------------------------------------------===
*/
#ifndef __ENDIAN_H__
#define __ENDIAN_H__
#define __LITTLE_ENDIAN 1234
#define __BIG_ENDIAN 4321
#if defined(__LITTLE_ENDIAN__) || defined(__ORDER_LITTLE_ENDIAN__)
#define __BYTE_ORDER __LITTLE_ENDIAN
#else
#define __BYTE_ORDER __BIG_ENDIAN
#endif
#endif /* __ENDIAN_H__ */

View File

@ -0,0 +1,17 @@
/* ===-- fcntl.h - stub SDK header for compiler-rt --------------------------===
*
* The LLVM Compiler Infrastructure
*
* This file is dual licensed under the MIT and the University of Illinois Open
* Source Licenses. See LICENSE.TXT for details.
*
* ===-----------------------------------------------------------------------===
*
* This is a stub SDK header file. This file is not part of the interface of
* this library nor an official version of the appropriate SDK header. It is
* intended only to stub the features of this header required by compiler-rt.
*
* ===-----------------------------------------------------------------------===
*/
#include <sys/fcntl.h>

View File

@ -0,0 +1,23 @@
/* ===-- limits.h - stub SDK header for compiler-rt -------------------------===
*
* The LLVM Compiler Infrastructure
*
* This file is dual licensed under the MIT and the University of Illinois Open
* Source Licenses. See LICENSE.TXT for details.
*
* ===-----------------------------------------------------------------------===
*
* This is a stub SDK header file. This file is not part of the interface of
* this library nor an official version of the appropriate SDK header. It is
* intended only to stub the features of this header required by compiler-rt.
*
* ===-----------------------------------------------------------------------===
*/
#ifndef __LIMITS_H__
#define __LIMITS_H__
/* This is only here as a landing pad for the include_next from the compiler's
built-in limits.h. */
#endif /* __LIMITS_H__ */

View File

@ -0,0 +1,44 @@
/* ===-- stdio.h - stub SDK header for compiler-rt --------------------------===
*
* The LLVM Compiler Infrastructure
*
* This file is dual licensed under the MIT and the University of Illinois Open
* Source Licenses. See LICENSE.TXT for details.
*
* ===-----------------------------------------------------------------------===
*
* This is a stub SDK header file. This file is not part of the interface of
* this library nor an official version of the appropriate SDK header. It is
* intended only to stub the features of this header required by compiler-rt.
*
* ===-----------------------------------------------------------------------===
*/
#ifndef __STDIO_H__
#define __STDIO_H__
typedef __SIZE_TYPE__ size_t;
struct _IO_FILE;
typedef struct _IO_FILE FILE;
extern struct _IO_FILE *stdin;
extern struct _IO_FILE *stdout;
extern struct _IO_FILE *stderr;
#define SEEK_SET 0 /* set file offset to offset */
#define SEEK_CUR 1 /* set file offset to current plus offset */
#define SEEK_END 2 /* set file offset to EOF plus offset */
extern int fclose(FILE *);
extern int fflush(FILE *);
extern FILE *fopen(const char * restrict, const char * restrict);
extern FILE *fdopen(int, const char * restrict);
extern int fprintf(FILE * restrict, const char * restrict, ...);
extern int fputc(int, FILE *);
extern size_t fwrite(const void * restrict, size_t, size_t, FILE * restrict);
extern size_t fread(void * restrict, size_t, size_t, FILE * restrict);
extern long ftell(FILE *);
extern int fseek(FILE *, long, int);
#endif /* __STDIO_H__ */

View File

@ -0,0 +1,36 @@
/* ===-- stdlib.h - stub SDK header for compiler-rt -------------------------===
*
* The LLVM Compiler Infrastructure
*
* This file is dual licensed under the MIT and the University of Illinois Open
* Source Licenses. See LICENSE.TXT for details.
*
* ===-----------------------------------------------------------------------===
*
* This is a stub SDK header file. This file is not part of the interface of
* this library nor an official version of the appropriate SDK header. It is
* intended only to stub the features of this header required by compiler-rt.
*
* ===-----------------------------------------------------------------------===
*/
#ifndef __STDLIB_H__
#define __STDLIB_H__
#define NULL ((void *)0)
typedef __SIZE_TYPE__ size_t;
void abort(void) __attribute__((__nothrow__)) __attribute__((__noreturn__));
int atexit(void (*)(void)) __attribute__((__nothrow__));
int atoi(const char *) __attribute__((__nothrow__));
void free(void *) __attribute__((__nothrow__));
char *getenv(const char *) __attribute__((__nothrow__))
__attribute__((__nonnull__(1)));
__attribute__((__warn_unused_result__));
void *malloc(size_t) __attribute__((__nothrow__)) __attribute((__malloc__))
__attribute__((__warn_unused_result__));
void *realloc(void *, size_t) __attribute__((__nothrow__)) __attribute((__malloc__))
__attribute__((__warn_unused_result__));
#endif /* __STDLIB_H__ */

View File

@ -0,0 +1,31 @@
/* ===-- string.h - stub SDK header for compiler-rt -------------------------===
*
* The LLVM Compiler Infrastructure
*
* This file is dual licensed under the MIT and the University of Illinois Open
* Source Licenses. See LICENSE.TXT for details.
*
* ===-----------------------------------------------------------------------===
*
* This is a stub SDK header file. This file is not part of the interface of
* this library nor an official version of the appropriate SDK header. It is
* intended only to stub the features of this header required by compiler-rt.
*
* ===-----------------------------------------------------------------------===
*/
#ifndef __STRING_H__
#define __STRING_H__
typedef __SIZE_TYPE__ size_t;
int memcmp(const void *, const void *, size_t);
void *memcpy(void *, const void *, size_t);
void *memset(void *, int, size_t);
char *strcat(char *, const char *);
char *strcpy(char *, const char *);
char *strdup(const char *);
size_t strlen(const char *);
char *strncpy(char *, const char *, size_t);
#endif /* __STRING_H__ */

View File

@ -0,0 +1,29 @@
/* ===-- fcntl.h - stub SDK header for compiler-rt --------------------------===
*
* The LLVM Compiler Infrastructure
*
* This file is dual licensed under the MIT and the University of Illinois Open
* Source Licenses. See LICENSE.TXT for details.
*
* ===-----------------------------------------------------------------------===
*
* This is a stub SDK header file. This file is not part of the interface of
* this library nor an official version of the appropriate SDK header. It is
* intended only to stub the features of this header required by compiler-rt.
*
* ===-----------------------------------------------------------------------===
*/
#ifndef _SYS_FCNTL_H_
#define _SYS_FCNTL_H_
#define O_RDONLY 0x0000
#define O_WRONLY 0x0001
#define O_RDWR 0x0002
#define O_ACCMODE 0x0003
#define O_CREAT 0x0200
int open(const char *, int, ...);
#endif /* _SYS_FCNTL_H_ */

View File

@ -0,0 +1,47 @@
/* ===-- limits.h - stub SDK header for compiler-rt -------------------------===
*
* The LLVM Compiler Infrastructure
*
* This file is dual licensed under the MIT and the University of Illinois Open
* Source Licenses. See LICENSE.TXT for details.
*
* ===-----------------------------------------------------------------------===
*
* This is a stub SDK header file. This file is not part of the interface of
* this library nor an official version of the appropriate SDK header. It is
* intended only to stub the features of this header required by compiler-rt.
*
* ===-----------------------------------------------------------------------===
*/
#ifndef __SYS_MMAN_H__
#define __SYS_MMAN_H__
typedef __SIZE_TYPE__ size_t;
#define PROT_NONE 0x00
#define PROT_READ 0x01
#define PROT_WRITE 0x02
#define PROT_EXEC 0x04
#define MAP_SHARED 0x0001
#define MAP_PRIVATE 0x0002
#define MAP_FILE 0x0000
#define MAP_ANON 0x1000
#define MS_ASYNC 0x0001
#define MS_INVALIDATE 0x0002
#define MS_SYNC 0x0010
extern void *mmap(void *addr, size_t len, int prot, int flags, int fd,
long long offset)
__attribute__((__nothrow__));
extern int munmap(void *addr, size_t len)
__attribute__((__nothrow__));
extern int msync(void *addr, size_t len, int flags)
__attribute__((__nothrow__));
extern int mprotect (void *__addr, size_t __len, int __prot)
__attribute__((__nothrow__));
#endif /* __SYS_MMAN_H__ */

View File

@ -0,0 +1,24 @@
/* ===-- stat.h - stub SDK header for compiler-rt ---------------------------===
*
* The LLVM Compiler Infrastructure
*
* This file is dual licensed under the MIT and the University of Illinois Open
* Source Licenses. See LICENSE.TXT for details.
*
* ===-----------------------------------------------------------------------===
*
* This is a stub SDK header file. This file is not part of the interface of
* this library nor an official version of the appropriate SDK header. It is
* intended only to stub the features of this header required by compiler-rt.
*
* ===-----------------------------------------------------------------------===
*/
#ifndef __SYS_STAT_H__
#define __SYS_STAT_H__
typedef unsigned int mode_t;
int mkdir(const char *, mode_t);
#endif /* __SYS_STAT_H__ */

View File

@ -0,0 +1,20 @@
/* ===-- stat.h - stub SDK header for compiler-rt ---------------------------===
*
* The LLVM Compiler Infrastructure
*
* This file is dual licensed under the MIT and the University of Illinois Open
* Source Licenses. See LICENSE.TXT for details.
*
* ===-----------------------------------------------------------------------===
*
* This is a stub SDK header file. This file is not part of the interface of
* this library nor an official version of the appropriate SDK header. It is
* intended only to stub the features of this header required by compiler-rt.
*
* ===-----------------------------------------------------------------------===
*/
#ifndef __SYS_TYPES_H__
#define __SYS_TYPES_H__
#endif /* __SYS_TYPES_H__ */

View File

@ -0,0 +1,26 @@
/* ===-- unistd.h - stub SDK header for compiler-rt -------------------------===
*
* The LLVM Compiler Infrastructure
*
* This file is dual licensed under the MIT and the University of Illinois Open
* Source Licenses. See LICENSE.TXT for details.
*
* ===-----------------------------------------------------------------------===
*
* This is a stub SDK header file. This file is not part of the interface of
* this library nor an official version of the appropriate SDK header. It is
* intended only to stub the features of this header required by compiler-rt.
*
* ===-----------------------------------------------------------------------===
*/
#ifndef __UNISTD_H__
#define __UNISTD_H__
enum {
_SC_PAGESIZE = 30
};
extern long int sysconf (int __name) __attribute__ ((__nothrow__));
#endif /* __UNISTD_H__ */

Some files were not shown because too many files have changed in this diff Show More