diff options
author | Igor Pashev <pashev.igor@gmail.com> | 2012-08-26 19:24:46 +0400 |
---|---|---|
committer | Igor Pashev <pashev.igor@gmail.com> | 2012-08-26 19:24:46 +0400 |
commit | e46c9ea201b4bad8f4c6d19ee6dfb3537bc9facd (patch) | |
tree | 26ae9736985be2ef61032e7808b9fb0e2155c71f /tests | |
download | make.old-upstream.tar.gz |
Imported GNU Make 3.81upstream/3.82upstream
Diffstat (limited to 'tests')
114 files changed, 12111 insertions, 0 deletions
diff --git a/tests/COPYING b/tests/COPYING new file mode 100644 index 0000000..94a9ed0 --- /dev/null +++ b/tests/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + <program> Copyright (C) <year> <name of author> + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +<http://www.gnu.org/licenses/>. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +<http://www.gnu.org/philosophy/why-not-lgpl.html>. diff --git a/tests/ChangeLog b/tests/ChangeLog new file mode 100644 index 0000000..d036568 --- /dev/null +++ b/tests/ChangeLog @@ -0,0 +1,1079 @@ +2010-07-28 Paul Smith <psmith@gnu.org> + + * scripts/targets/POSIX: Compatibility issues with Solaris (and + Tru64?); "false" returns different exit codes, and set -x shows + output with extra whitespace. Run the commands by hand first to + find out what the real shell would do, then compare what make does. + * scripts/variables/SHELL: Ditto. + +2010-07-12 Paul Smith <psmith@gnu.org> + + * test_driver.pl: Add a new $perl_name containing the path to Perl. + * run_make_tests.pl (run_make_test): Replace the special string + #PERL# in a makefile etc. with the path the Perl executable so + makefiles can use it. + + * scripts/targets/ONESHELL: Add a new set of regression tests for + the .ONESHELL feature. + +2010-07-06 Paul Smith <psmith@gnu.org> + + * scripts/variables/SHELL: Test the new .SHELLFLAGS variable. + + * scripts/targets/POSIX: New file. Test the .POSIX special target. + Verify that enabling .POSIX changes the shell flags to set -e. + +2010-07-01 Paul Smith <psmith@gnu.org> + + * scripts/features/recursion: Add a space to separate command-line + args. Fixes Savannah bug #29968. + +2009-11-12 Boris Kolpackov <boris@codesynthesis.com> + + * scripts/features/vpath3: Test for the new library search + behavior. + +2009-10-06 Boris Kolpackov <boris@codesynthesis.com> + + * scripts/features/se_explicit: Enable the test for now fixed + Savannah bug 25780. + +2009-10-06 Boris Kolpackov <boris@codesynthesis.com> + + * scripts/variables/undefine: Tests for the new undefine feature. + +2009-10-03 Paul Smith <psmith@gnu.org> + + * scripts/features/parallelism: Test for open Savannah bug #26846. + + * scripts/variables/MAKE: Rewrite for new run_make_test() format. + + * scripts/variables/MAKEFLAGS: Created. + Add test for Savannah bug #2216 (still open). + + * scripts/features/include: Test for Savannah bug #102 (still open). + +2009-09-30 Boris Kolpackov <boris@codesynthesis.com> + + * scripts/features/include: Add diagnostics issuing tests for + cases where targets have been updated and failed with the + dontcare flag. Savannah bugs #15110, #25493, #12686, #17740. + +2009-09-28 Paul Smith <psmith@gnu.org> + + * scripts/functions/shell: Add regression test for Savannah bug + #20513 (still open). + + * scripts/features/se_explicit: Add regression tests for Savannah + bug #25780 (still open). + + * run_make_tests.pl (valid_option): Add a new flag, -all([-_]?tests)? + that runs tests we know will fail. This allows us to add + regression tests to the test suite for bugs that haven't been + fixed yet. + +2009-09-28 Boris Kolpackov <boris@codesynthesis.com> + + * scripts/features/patspecific_vars: Add a test for the shortest + stem first order. + + * scripts/features/patternrules: Add a test for the shortest stem + first order. + +2009-09-24 Paul Smith <psmith@gnu.org> + + * scripts/features/se_implicit: Add a test for order-only + secondary expansion prerequisites. + +2009-09-23 Paul Smith <psmith@gnu.org> + + * scripts/features/patternrules: Test that we can remove pattern + rules, both single and multiple prerequisites. Savannah bug #18622. + + * scripts/features/echoing: Rework for run_make_test(). + +2009-06-14 Paul Smith <psmith@gnu.org> + + * scripts/features/vpath: Verify we don't get bogus circular + dependency warnings if we choose a different file via vpath during + update. Savannah bug #13529. + +2009-06-13 Paul Smith <psmith@gnu.org> + + * scripts/variables/MAKEFILES: Verify that MAKEFILES included + files (and files included by them) don't set the default goal. + Savannah bug #13401. + + * scripts/functions/wildcard: Test that wildcards with + non-existent glob matchers return empty. + +2009-06-09 Paul Smith <psmith@gnu.org> + + * scripts/options/dash-B: Test the $? works correctly with -B. + Savannah bug #17825. + + * scripts/features/patternrules: Test that dependencies of + "also_make" targets are created properly. Savannah bug #19108. + + * test_driver.pl (compare_output): Create a "run" file for failed + tests containing the command that was run. + (get_runfile): New function. + + * run_make_tests.pl (valid_option): Enhanced support for valgrind: + allow memcheck and massif tools. + + * scripts/features/patternrules: Have to comment out a line in the + first test due to backing out a change that broke the implicit + rule search algorithm. Savannah bug #17752. + * scripts/misc/general4: Remove a test that is redundant with + patternrules. + + * scripts/features/parallelism: Add a test for re-exec with + jobserver master override. Savannah bug #18124. + +2009-06-08 Paul Smith <psmith@gnu.org> + + * scripts/features/targetvars: Add a test for continued target + vars after a semicolon. Savannah bug #17521. + +2009-06-07 Paul Smith <psmith@gnu.org> + + * scripts/features/se_explicit: Make sure we catch defining + prereqs during snap_deps(). Savannah bug #24622. + + * scripts/variables/automatic: Check prereq ordering when the + target with the recipe has no prereqs. Savannah bug #21198. + + * scripts/variables/LIBPATTERNS: Add a new set of test for + $(.LIBPATTERNS) (previously untested!) + +2009-06-04 Paul Smith <psmith@gnu.org> + + * scripts/variables/SHELL: The export target-specific SHELL test + has an incorrect known-good-value. + + * scripts/misc/general4: Check for whitespace (ffeed, vtab, etc.) + + * scripts/features/se_explicit: Add tests for Savannah bug #24588. + +2009-05-31 Paul Smith <psmith@gnu.org> + + * scripts/variables/DEFAULT_GOAL: Add tests for Savannah bug #25697. + + * scripts/features/targetvars: Add tests of overrides for Savannah + bug #26207. + * scripts/features/patspecific_vars: Ditto. + + * scripts/features/patternrules: Add a test for Savannah bug #26593. + +2009-05-30 Paul Smith <psmith@gnu.org> + + * scripts/variables/flavors: Update with new variable flavor tests. + * scripts/variables/define: Create a new set of tests for + define/endef and move those aspects of the flavors suite here. + +2009-05-25 Paul Smith <psmith@gnu.org> + + * scripts/features/targetvars: Ditto. + + * scripts/features/export: Test new variable parsing abilities. + +2009-02-23 Ramon Garcia <ramon.garcia.f@gmail.com> + + * scripts/variables/private: Create a new suite of tests for 'private'. + +2007-11-04 Paul Smith <psmith@gnu.org> + + * scripts/functions/eval: Update error message for command -> recipe. + + * test_driver.pl (compare_output): Allow the answer to be a regex, + if surrounded by '/'. + * scripts/misc/close_stdout: Use a regex for the answer, since + sometimes the error will have a description and sometimes it won't. + +2007-09-10 Paul Smith <psmith@gnu.org> + + * scripts/variables/special: Add tests for .RECIPEPREFIX variable. + +2007-08-15 Paul Smith <psmith@gnu.org> + + These test cases were contributed by + Icarus Sparry <savannah@icarus.freeuk.com> and J. David Bryan for + Savannah bugs #3330 and #15919. + + * scripts/targets/SECONDARY: Add tests for Savannah bugs 3330 and + 15919. + + * scripts/features/parallelism: Add tests for wrong answer/hang + combining INTERMEDIATE, order-only prereqs, and parallelism. + See Savannah bugs 3330 and 15919. + +2007-07-13 Paul Smith <psmith@gnu.org> + + Install a timeout so tests can never loop infinitely. + Original idea and patch for a single-test version provided by + Icarus Sparry <savannah@icarus.freeuk.com> + + * test_driver.pl (_run_command): New function: this is called by + other functions to actually run a command. Before we run it, + install a SIGALRM handler and set up a timer to go off in the + future (default is 5s; this can be overridden by individual tests). + (run_command): Call it. + (run_command_with_output): Call it. + + * run_make_tests.pl (run_make_with_options): Override the default + timeout if the caller requests it. + (run_make_test): Pass any timeout override to run_make_with_options. + + * scripts/features/parallelism: Increase the timeout for long tests. + * scripts/options/dash-l: Ditto. + +2006-10-01 Paul Smith <psmith@paulandlesley.org> + + * run_make_tests.pl (set_more_defaults): Remove setting of LANG in + ENV here. This doesn't always work. + * test_driver.pl (toplevel): Set LC_ALL to 'C' in the make + environment. Fixes Savannah bug #16698. + +2006-09-30 Paul Smith <psmith@paulandlesley.org> + + * scripts/variables/automatic: Add back the test for bug #8154. + +2006-04-01 Paul D. Smith <psmith@gnu.org> + + * scripts/functions/realpath: Don't run tests with multiple + initial slashes on Windows: those paths mean something different. + +2006-03-19 Paul D. Smith <psmith@gnu.org> + + * scripts/features/parallelism: Test that the jobserver is + properly managed when we have to re-exec the master instance of + make. + +2006-03-17 Boris Kolpackov <boris@kolpackov.net> + + * scripts/features/statipattrules: Add tests for bug #16053. + +2006-03-09 Paul Smith <psmith@gnu.org> + + * scripts/features/escape: Use "pre:" not "p:" to avoid conflicts + with DOS drive letters. Fixes Savannah bug #15947. + + * test_driver.pl (run_each_test): Set the status properly even + when a test fails to execute. Fixes Savannah bug #15942. + + * scripts/functions/foreach: Use a different environment variable + other than PATH to avoid differences with Windows platforms. + Fixes Savannah bug #15938. + +2006-03-05 Paul D. Smith <psmith@gnu.org> + + * run_make_tests.pl (set_more_defaults): Add CYGWIN_NT as a port + type W32. Fixed Savannah bug #15937. + + * scripts/features/default_names: Don't call error() when the test + fails. Fixes Savannah bug #15941. + +2006-02-17 Paul D. Smith <psmith@gnu.org> + + * scripts/features/targetvars: Test a complex construction which + guarantees that we have to merge variable lists of different + sizes. Tests for Savannah bug #15757. + +2006-02-15 Paul D. Smith <psmith@gnu.org> + + * scripts/functions/error: Make sure filename/lineno information + is related to where the error is expanded, not where it's set. + * scripts/functions/warning: Ditto. + * scripts/functions/foreach: Check for different error conditions. + * scripts/functions/word: Ditto. + * scripts/variables/negative: Test some variable reference failure + conditions. + * scripts/options/warn-undefined-variables: Test the + --warn-undefined-variables flag. + +2006-02-09 Paul D. Smith <psmith@gnu.org> + + * run_make_tests.pl (set_more_defaults): Update valgrind support + for newer versions. + * test_driver.pl (toplevel): Skip all hidden files/directories (ones + beginning with "."). + + * scripts/functions/andor: Tests for $(and ..) and $(or ...) + functions. + +2006-02-08 Boris Kolpackov <boris@kolpackov.net> + + * scripts/features/parallelism: Add a test for bug #15641. + +2006-02-06 Paul D. Smith <psmith@gnu.org> + + * scripts/options/dash-W: Add a test for bug #15341. + +2006-01-03 Paul D. Smith <psmith@gnu.org> + + * scripts/variables/automatic: Add a test for bug #8154. + + * README: Update to reflect the current state of the test suite. + +2005-12-12 Paul D. Smith <psmith@gnu.org> + + * scripts/features/parallelism, scripts/functions/wildcard, + scripts/targets/FORCE, scripts/targets/PHONY, + scripts/targets/SILENT: Use the default setting for + $delete_command. Fixes bug #15085. + + * run_make_tests.pl (get_this_pwd) [VMS]: Use -no_ask with delete_file. + +2005-12-11 Paul D. Smith <psmith@gnu.org> + + * scripts/misc/general4: Test implicit rules with '$' in the + prereq list & prereq patterns. + * scripts/features/se_implicit: Add in .SECONDEXPANSION settings. + +2005-12-09 Boris Kolpackov <boris@kolpackov.net> + + * scripts/features/patternrules: Add a test for bug #13022. + +2005-12-07 Boris Kolpackov <boris@kolpackov.net> + + * scripts/features/double_colon: Add a test for bug #14334. + +2005-11-17 Boris Kolpackov <boris@kolpackov.net> + + * scripts/functions/flavor: Add a test for the flavor function. + +2005-11-14 Boris Kolpackov <boris@kolpackov.net> + + * scripts/variables/INCLUDE_DIRS: Add a test for the .INCLUDE_DIRS + special variable. + +2005-10-24 Paul D. Smith <psmith@gnu.org> + + * scripts/misc/general4: Test '$$' in prerequisites list. + * scripts/features/statipattrules: Rewrite to use run_make_test(). + Add various static pattern info. + * scripts/features/se_statpat: Enable .SECONDEXPANSION target. + * scripts/features/se_explicit: Add tests for handling '$$' in + prerequisite lists with and without setting .SECONDEXPANSION. + * scripts/features/order_only: Convert to run_make_test(). + * run_make_tests.pl (set_more_defaults): If we can't get the value + of $(MAKE) from make, then fatal immediately. + +2005-08-31 Paul D. Smith <psmith@gnu.org> + + * run_make_tests.pl (get_this_pwd): Require the POSIX module (in + an eval to trap errors) and if it exists, use POSIX::getcwd to + find the working directory. If it doesn't exist, go back to the + previous methods. This tries to be more accurate on Windows + systems. + +2005-08-29 Paul D. Smith <psmith@gnu.org> + + * scripts/functions/abspath: Add some text to the error messages + to get a better idea of what's wrong. Make warnings instead of + errors. + + * scripts/features/patspecific_vars: Don't use "test", which is + UNIX specific. Print the values and let the test script match + them. + +2005-08-25 Paul Smith <psmith@gnu.org> + + * scripts/variables/SHELL: Use a /./ prefix instead of //: the + former works better with non-UNIX environments. Fixes Savannah + bug #14129. + +2005-08-13 Boris Kolpackov <boris@kolpackov.net> + + * scripts/functions/wildcard: Wrap calls to $(wildcard ) with + $(sort) so that the resulting order is no longer filesystem- + dependant. + +2005-08-10 Boris Kolpackov <boris@kolpackov.net> + + * scripts/features/statipattrules: Add a test for Savannah bug #13881. + +2005-08-07 Paul D. Smith <psmith@gnu.org> + + * scripts/features/parallelism: Add a test for a bug reported by + Michael Matz (matz@suse.de) in which make exits without waiting + for all its children in some situations during parallel builds. + +2005-07-08 Paul D. Smith <psmith@gnu.org> + + * test_driver.pl: Reset the environment to a clean value every + time before we invoke make. I'm suspicious that the environment + isn't handled the same way in Windows as it is in UNIX, and some + variables are leaking out beyond the tests they are intended for. + Create an %extraENV hash tests can set to add more env. vars. + * tests/scripts/features/export: Change to use %extraENV. + * tests/scripts/functions/eval: Ditto. + * tests/scripts/functions/origin: Ditto. + * tests/scripts/options/dash-e: Ditto. + * tests/scripts/variables/SHELL: Ditto. + +2005-06-27 Paul D. Smith <psmith@gnu.org> + + * scripts/options/dash-W: Use 'echo >>' instead of touch to update + files. + * scripts/features/reinvoke: Rewrite to be safer on systems with + subsecond timestamps. + * scripts/features/patternrules: False exits with different error + codes on different systems (for example, Linux => 1, Solaris => 255). + + * scripts/options/dash-W: Set the timestamp to foo.x in the future, + to be sure it will be considered updated when it's remade. + +2005-06-26 Paul D. Smith <psmith@gnu.org> + + * scripts/functions/shell: New test suite for the shell function. + +2005-06-25 Paul D. Smith <psmith@gnu.org> + + * scripts/features/include: Test include/-include/sinclude with no + arguments. Tests fix for Savannah bug #1761. + + * scripts/misc/general3: Implement comprehensive testing of + backslash-newline behavior in command scripts: various types of + quoting, fast path / slow path, etc. + Tests fix for Savannah bug #1332. + + * scripts/options/symlinks: Test symlinks to non-existent files. + Tests fix for Savannah bug #13280. + + * scripts/misc/general3: Test semicolons in variable references. + Tests fix for Savannah bug #1454. + + * scripts/variables/MAKE_RESTARTS: New file: test the + MAKE_RESTARTS variable. + * scripts/options/dash-B: Test re-exec doesn't loop infinitely. + Tests fix for Savannah bug #7566. + * scripts/options/dash-W: New file: test the -W flag, including + re-exec infinite looping. + +2005-06-12 Paul D. Smith <psmith@gnu.org> + + * scripts/misc/close_stdout: Add a test for Savannah bug #1328. + This test only works on systems that have /dev/full (e.g., Linux). + +2005-06-09 Paul D. Smith <psmith@gnu.org> + + * scripts/functions/foreach: Add a test for Savannah bug #11913. + +2005-05-31 Boris Kolpackov <boris@kolpackov.net> + + * scripts/features/include: Add a test for Savannah bug #13216. + * scripts/features/patternrules: Add a test for Savannah bug #13218. + +2005-05-13 Paul D. Smith <psmith@gnu.org> + + * scripts/features/conditionals: Add tests for the new if... else + if... endif syntax. + +2005-05-03 Paul D. Smith <psmith@gnu.org> + + * scripts/variables/DEFAULT_GOAL: Rename DEFAULT_TARGET to + DEFAULT_GOAL. + +2005-05-02 Paul D. Smith <psmith@gnu.org> + + * scripts/features/parallelism: Add a test for exporting recursive + variables containing $(shell ) calls. Rewrite this script to use + run_make_test() everywhere. + +2005-04-07 Paul D. Smith <psmith@gnu.org> + + * scripts/targets/SECONDARY: Add a test for Savannah bug #12331. + +2005-03-15 Boris Kolpackov <boris@kolpackov.net> + + * scripts/variables/automatic: Add a test for Savannah bug #12320. + +2005-03-10 Boris Kolpackov <boris@kolpackov.net> + + * scripts/features/patternrules: Add a test for Savannah bug #12267. + +2005-03-09 Boris Kolpackov <boris@kolpackov.net> + + * scripts/variables/DEFAULT_TARGET: Add a test for Savannah + bug #12266. + +2005-03-04 Boris Kolpackov <boris@kolpackov.net> + + * scripts/features/patternrules: Add a test for Savannah bug #12202. + +2005-03-03 Boris Kolpackov <boris@kolpackov.net> + + * scripts/features/se_implicit: Add a test for stem + termination bug. Add a test for stem triple-expansion bug. + + * scripts/features/se_statpat: Add a test for stem + triple-expansion bug. + + * scripts/features/statipattrules: Change test #4 to reflect + new way empty prerequisite list is handled. + + +2005-03-01 Boris Kolpackov <boris@kolpackov.net> + + * scripts/features/statipattrules: Add a test for + Savannah bug #12180. + +2005-02-28 Paul D. Smith <psmith@gnu.org> + + * scripts/options/dash-q: Add a test for Savannah bug # 7144. + + * scripts/options/symlinks: New file to test checking of symlink + timestamps. Can't use filename dash-L because it conflicts with + dash-l on case-insensitive filesystems. + + * scripts/variables/MAKEFILE_LIST, scripts/variables/MFILE_LIST: + Rename MAKEFILE_LIST test to MFILE_LIST, for systems that need 8.3 + unique filenames. + +2005-02-28 Boris Kolpackov <boris@kolpackov.net> + + * scripts/variables/DEFAULT_TARGET: Test the .DEFAULT_TARGET + special variable. + +2005-02-27 Boris Kolpackov <boris@kolpackov.net> + + * scripts/features/se_explicit: Test the second expansion in + explicit rules. + * scripts/features/se_implicit: Test the second expansion in + implicit rules. + * scripts/features/se_statpat: Test the second expansion in + static pattern rules. + * scripts/variables/automatic: Fix to work with the second + expansion. + + * scripts/misc/general4: Add a test for bug #12091. + +2005-02-27 Paul D. Smith <psmith@gnu.org> + + * scripts/functions/eval: Check that eval of targets within + command scripts fails. See Savannah bug # 12124. + +2005-02-26 Paul D. Smith <psmith@gnu.org> + + * test_driver.pl (compare_output): If a basic comparison of the + log and answer doesn't match, try harder: change all backslashes + to slashes and all CRLF to LF. This helps on DOS/Windows systems. + +2005-02-09 Paul D. Smith <psmith@gnu.org> + + * scripts/features/recursion: Test command line variable settings: + only one instance of a given variable should be provided. + +2004-11-30 Boris Kolpackov <boris@kolpackov.net> + + * tests/scripts/functions/abspath: New file: test `abspath' + built-in function. + + * tests/scripts/functions/realpath: New file: test `realpath' + built-in function. + +2004-11-28 Paul D. Smith <psmith@gnu.org> + + * scripts/options/dash-C [WINDOWS32]: Add a test for bug #10252; + this doesn't really test anything useful in UNIX but... + + * scripts/variables/SHELL: New file: test proper handling of SHELL + according to POSIX rules. Fixes bug #1276. + +2004-10-21 Boris Kolpackov <boris@kolpackov.net> + + * scripts/functions/word: Test $(firstword ) and $(lastword ). + +2004-10-05 Boris Kolpackov <boris@kolpackov.net> + + * scripts/features/patspecific_vars: Test simple/recursive + variable expansion. + +2004-09-28 Boris Kolpackov <boris@kolpackov.net> + + * scripts/features/include: Test dontcare flag inheritance + when rebuilding makefiles. + +2004-09-27 Boris Kolpackov <boris@kolpackov.net> + + * scripts/features/patspecific_vars: Test exported variables. + +2004-09-22 Paul D. Smith <psmith@gnu.org> + + * run_make_tests.pl (run_make_test): Don't add newlines to the + makestring or answer if they are completely empty. + + * scripts/features/patternrules: Rename from implicit_prereq_eval. + + * scripts/test_template: Rework the template. + +2004-09-21 Boris Kolpackov <boris@kolpackov.net> + + * run_make_tests.pl: Change `#!/usr/local/bin/perl' to be + `#!/usr/bin/env perl'. + + * scripts/features/implicit_prereq_eval: Test implicit rule + prerequisite evaluation code. + +2004-09-21 Paul D. Smith <psmith@gnu.org> + + * run_make_tests.pl (run_make_test): Enhance to allow the make + string to be undef: in that case it reuses the previous make + string. Allows multiple tests on the same makefile. + + * scripts/variables/flavors: Add some tests for prefix characters + interacting with define/endef variables. + +2004-09-20 Paul D. Smith <psmith@gnu.org> + + * scripts/functions/substitution: Rewrite to use run_make_test() + interface, and add test for substitution failures reported by + Markus Mauhart <qwe123@chello.at>. + +2004-03-22 Paul D. Smith <psmith@gnu.org> + + * test_driver.pl (run_each_test, toplevel, compare_output): Change + to track both the testing categories _AND_ the number of + individual tests, and report both sets of numbers. + +2004-02-21 Paul D. Smith <psmith@gnu.org> + + * scripts/functions/origin: Set our own environment variable + rather than relying on $HOME. + +2004-01-21 Paul D. Smith <psmith@gnu.org> + + * scripts/features/conditionals: Test arguments to ifn?def which + contain whitespace (such as a function that is evaluated). Bug + #7257. + +2004-01-07 Paul D. Smith <psmith@gnu.org> + + * scripts/features/order_only: Test order-only prerequisites in + pattern rules (patch #2349). + +2003-11-02 Paul D. Smith <psmith@gnu.org> + + * scripts/functions/if: Test if on conditionals with trailing + whitespace--bug #5798. + + * scripts/functions/eval: Test eval in a non-file context--bug #6195. + +2003-04-19 Paul D. Smith <psmith@gnu.org> + + * scripts/features/patspecific_vars: Test multiple patterns + matching the same target--Bug #1405. + +2003-04-09 Paul D. Smith <psmith@gnu.org> + + * run_make_tests.pl (set_more_defaults): A new $port_type of + 'OS/2' for (surprise!) OS/2. Also choose a wait time of 2 seconds + for OS/2. + +2003-03-28 Paul D. Smith <psmith@gnu.org> + + * scripts/targets/SECONDARY: Test the "global" .SECONDARY (with + not prerequisites)--Bug #2515. + +2003-01-30 Paul D. Smith <psmith@gnu.org> + + * scripts/features/targetvars: Test very long target-specific + variable definition lines (longer than the default make buffer + length). Tests patch # 1022. + + * scripts/functions/eval: Test very recursive $(eval ...) calls + with simple variable expansion (bug #2238). + + * scripts/functions/word: Test error handling for word and + wordlist functions (bug #2407). + +2003-01-22 Paul D. Smith <psmith@gnu.org> + + * scripts/functions/call: Test recursive argument masking (bug + #1744). + +2002-10-25 Paul D. Smith <psmith@gnu.org> + + * scripts/functions/eval: Test using $(eval ...) inside + conditionals (Bug #1516). + +2002-10-14 Paul D. Smith <psmith@gnu.org> + + * scripts/options/dash-t: Add a test for handling -t on targets + with no commands (Bug #1418). + +2002-10-13 Paul D. Smith <psmith@gnu.org> + + * scripts/features/targetvars: Add a test for exporting + target-specific vars (Bug #1391). + +2002-10-05 Paul D. Smith <psmith@gnu.org> + + * scripts/variables/automatic: Add tests for $$(@), $${@}, $${@D}, + and $${@F}. + +2002-09-23 Paul D. Smith <psmith@gnu.org> + + * scripts/features/escape: Test handling of escaped comment + characters in targets and prerequisites. + +2002-09-18 Paul D. Smith <psmith@gnu.org> + + * scripts/features/export: Test export/unexport of multiple + variables in a single command. + +2002-09-17 Paul D. Smith <psmith@gnu.org> + + * scripts/features/targetvars: Tests for Bug #940: test + target-specific and pattern-specific variables in conjunction with + double-colon targets. + +2002-09-10 Paul D. Smith <psmith@gnu.org> + + * test_driver.pl (compare_output): Match the new format for time + skew error messages. + + * scripts/features/export: Created. Add tests for export/unexport + capabilities, including exporting/unexporting expanded variables. + + * scripts/features/conditionals: Add a test for expanded variables + in ifdef conditionals. + +2002-09-04 Paul D. Smith <psmith@gnu.org> + + * scripts/features/reinvoke: Change touch/sleep combos to utouch + invocations. + * scripts/features/vpathgpath: Ditto. + * scripts/features/vpathplus: Ditto. + * scripts/options/dash-n: Ditto. + * scripts/targets/INTERMEDIATE: Ditto. + * scripts/targets/SECONDARY: Ditto. + + * scripts/options/dash-t: Added a test for the -t bug fixed by + Henning Makholm. This test was also contributed by Henning. + + * scripts/misc/general4: Add a test suite for obscure algorithmic + features of make. First test: make sure creation subdirectories + as prerequisites of targets works properly. + + * scripts/misc/version: Remove this bogus test. + +2002-08-07 Paul D. Smith <psmith@gnu.org> + + * scripts/misc/general3: Add a test for makefiles that don't end + in newlines. + + * scripts/variables/special: Create tests for the special + variables (.VARIABLES and .TARGETS). Comment out .TARGETS test + for now as it's not yet supported. + +2002-08-01 Paul D. Smith <psmith@gnu.org> + + * scripts/options/dash-B: Add a test for the new -B option. + +2002-07-11 Paul D. Smith <psmith@gnu.org> + + * run_make_tests.pl (valid_option): Add support for Valgrind. Use + -valgrind option to the test suite. + (set_more_defaults): Set up the file descriptor to capture + Valgrind output. We have to unset its close-on-exec flag; we + hardcode the value for F_SETFD (2) rather than load it; hopefully + this will help us avoid breaking the Windows/DOS test suite. + +2002-07-10 Paul D. Smith <psmith@gnu.org> + + * scripts/variables/automatic: Add some tests for $$@, $$(@D), and + $$(@F). + + * test_driver.pl (utouch): Create a new function that creates a + file with a specific timestamp offset. Use of this function will + let us avoid lots of annoying sleep() invocations in the tests + just to get proper timestamping, which will make the tests run a + lot faster. So far it's only used in the automatic test suite. + +2002-07-09 Paul D. Smith <psmith@gnu.org> + + * scripts/variables/automatic: Create a test for automatic variables. + +2002-07-08 Paul D. Smith <psmith@gnu.org> + + * scripts/features/order_only: Test new order-only prerequisites. + +2002-07-07 Paul D. Smith <psmith@gnu.org> + + * scripts/functions/eval: Test new function. + * scripts/functions/value: Test new function. + * scripts/variables/MAKEFILE_LIST: Test new variable. + +2002-04-28 Paul D. Smith <psmith@gnu.org> + + * scripts/functions/call: New test: transitive closure + implementation using $(call ...) to test variable recursion. + +2002-04-21 Paul D. Smith <psmith@gnu.org> + + * test_driver.pl (compare_dir_tree): Ignore CVS and RCS + directories in the script directories. + +2001-05-02 Paul D. Smith <psmith@gnu.org> + + * scripts/variables/flavors: Test define/endef scripts where only + one of the command lines is quiet. + +2000-06-22 Paul D. Smith <psmith@gnu.org> + + * scripts/options/dash-q: New file; test the -q option. Includes + a test for PR/1780. + +2000-06-21 Paul D. Smith <psmith@gnu.org> + + * scripts/features/targetvars: Added a test for PR/1709: allowing + semicolons in target-specific variable values. + +2000-06-19 Paul D. Smith <psmith@gnu.org> + + * scripts/functions/addsuffix: Test for an empty final argument. + Actually this bug might have happened for any function, but this + one was handy. + +2000-06-17 Eli Zaretskii <eliz@is.elta.co.il> + + * scripts/options/general: If parallel jobs are not supported, + expect a warning message from Make. + +2000-06-15 Eli Zaretskii <eliz@is.elta.co.il> + + * scripts/options/general: Don't try -jN with N != 1 if parallel + jobs are not supported. + +2000-05-24 Paul D. Smith <psmith@gnu.org> + + * scripts/options/general: Test general option processing (PR/1716). + +2000-04-11 Paul D. Smith <psmith@gnu.org> + + * scripts/functions/strip: Test empty value to strip (PR/1689). + +2000-04-08 Eli Zaretskii <eliz@is.elta.co.il> + + * scripts/features/reinvoke: Sleep before updating the target + files in the first test, to ensure its time stamp really gets + newer; otherwise Make might re-exec more than once. + +2000-04-07 Eli Zaretskii <eliz@is.elta.co.il> + + * scripts/features/double_colon: Don't run the parallel tests if + parallel jobs aren't supported. + +2000-04-04 Paul D. Smith <psmith@gnu.org> + + * scripts/functions/word: wordlist doesn't swap arguments anymore. + +2000-03-27 Paul D. Smith <psmith@gnu.org> + + * scripts/features/statipattrules: Test that static pattern rules + whose prerequisite patterns resolve to empty strings throw an + error (instead of dumping core). Fixes PR/1670. + + * scripts/features/reinvoke: Make more robust by touching "b" + first, to ensure it's not newer than "a". + Reported by Marco Franzen <Marco.Franzen@Thyron.com>. + * scripts/options/dash-n: Ditto. + + * scripts/functions/call: Whoops. The fix to PR/1527 caused + recursive invocations of $(call ...) to break. I can't come up + with any way to get both working at the same time, so I backed out + the fix to 1527 and added a test case for recursive calls. This + also tests the fix for PR/1610. + + * scripts/features/double_colon: Test that circular dependencies + in double-colon rule sets are detected correctly (PR/1671). + +2000-03-26 Paul D. Smith <psmith@gnu.org> + + * scripts/targets/INTERMEDIATE: Test that make doesn't remove + .INTERMEDIATE files when given on the command line (PR/1669). + +2000-03-08 Paul D. Smith <psmith@gnu.org> + + * scripts/options/dash-k: Add a test for error detection by + multiple targets depending on the same prerequisite with -k. + For PR/1634. + +2000-02-07 Paul D. Smith <psmith@gnu.org> + + * scripts/features/escape: Add a test for backslash-escaped spaces + in a target name (PR/1586). + +2000-02-04 Paul D. Smith <psmith@gnu.org> + + * scripts/features/patspecific_vars: Add a test for pattern-specific + target variables inherited from the parent target (PR/1407). + +2000-02-02 Paul D. Smith <psmith@gnu.org> + + * run_make_tests.pl (set_more_defaults): Hard-code the LANG to C + to make sure sorting order, etc. is predictable. + Reported by Andreas Jaeger <aj@suse.de>. + + * run_make_tests.pl (set_more_defaults): Set the $wtime variable + depending on the OS. Eli Zaretskii <eliz@is.elta.co.il> reports + this seems to need to be *4* on DOS/Windows, not just 2. Keep it + 1 for other systems. + * scripts/features/vpathplus (touchfiles): Use the $wtime value + instead of hardcoding 2. + * scripts/targets/SECONDARY: Ditto. + * scripts/targets/INTERMEDIATE: Ditto. + +2000-01-27 Paul D. Smith <psmith@gnu.org> + + * test_driver.pl (toplevel): Don't try to run test scripts which + are really directories. + +2000-01-23 Paul D. Smith <psmith@gnu.org> + + * scripts/features/include: Remove a check; the fix caused more + problems than the error, so I removed it and removed the test for + it. + +2000-01-11 Paul D. Smith <psmith@gnu.org> + + * scripts/functions/call: Add a test for PR/1517 and PR/1527: make + sure $(call ...) doesn't eval its arguments and that you can + invoke foreach from it without looping forever. + +1999-12-15 Paul D. Smith <psmith@gnu.org> + + * scripts/targets/INTERMEDIATE: Add a test for PR/1423: make sure + .INTERMEDIATE settings on files don't disable them as implicit + intermediate possibilities. + +1999-12-01 Paul D. Smith <psmith@gnu.org> + + * scripts/features/double_colon: Add a test for PR/1476: Try + double-colon rules as non-goal targets and during parallel builds + to make sure they're handled serially. + +1999-11-17 Paul D. Smith <psmith@gnu.org> + + * scripts/functions/if: Add a test for PR/1429: put some text + after an if-statement to make sure it works. + + * scripts/features/targetvars: Add a test for PR/1380: handling += + in target-specific variable definitions correctly. + +1999-10-15 Paul D. Smith <psmith@gnu.org> + + * scripts/variables/MAKEFILES: This was really broken: it didn't + test anything at all, really. Rewrote it, plus added a test for + PR/1394. + +1999-10-13 Paul D. Smith <psmith@gnu.org> + + * scripts/options/dash-n: Add a test for PR/1379: "-n doesn't + behave properly when used with recursive targets". + +1999-10-08 Paul D. Smith <psmith@gnu.org> + + * scripts/features/targetvars: Add a check for PR/1378: + "Target-specific vars don't inherit correctly" + +1999-09-29 Paul D. Smith <psmith@gnu.org> + + * test_driver.pl (get_osname): Change $fancy_file_names to + $short_filenames and reverse the logic. + (run_each_test): Change test of non-existent $port_host to use + $short_filenames--problem reported by Eli Zaretskii. + +1999-09-23 Paul D. Smith <psmith@gnu.org> + + * scripts/features/parallelism: Add a check to ensure that the + jobserver works when we re-invoke. Also cleaned up the tests a + little, reducing the number of rules we use so the test won't need + as many "sleep" commands. + +1999-09-16 Paul D. Smith <psmith@gnu.org> + + * scripts/features/reinvoke: Remove invocations of "touch" in + makefiles. See the comments on the touch function rewrite below. + Note that UNIX touch behaves the same way if the file already + exists: it sets the time to the _local_ time. We don't want + this. This is probably a good tip for makefile writers in + general, actually... where practical. + * scripts/options/dash-l: Ditto. + * scripts/options/dash-n: Ditto. + + * test_driver.pl (run_each_test): In retrospect, I don't like the + .lN/.bN/.dN postfix required by DOS. So, for non-DOS systems I + changed it back to use .log, .base, and .diff. + + * run_make_tests.pl (set_more_defaults): Move the check for the + make pathname to here from set_defaults (that's too early since it + happens before the command line processing). + Create a new variable $port_type, calculated from $osname, to + specify what kind of system we're running on. We should integrate + the VOS stuff here, too. + (valid_option): Comment out the workdir/-work stuff so people + won't be fooled into thinking it works... someone needs to fix + this, though! + + * scripts/functions/origin: Use $port_type instead of $osname. + * scripts/functions/foreach: Ditto. + * scripts/features/default_names: Ditto. + +1999-09-15 Paul D. Smith <psmith@gnu.org> + + * test_driver.pl (touch): Rewrite this function. Previously it + used to use utime() to hard-set the time based on the current + local clock, or, if the file didn't exist, it merely created it. + This mirrors exactly what real UNIX touch does, but it fails badly + on networked filesystems where the FS server clock is skewed from + the local clock: normally modifying a file causes it to get a mod + time based on the _server's_ clock. Hard-setting it based on the + _local_ clock causes gratuitous errors and makes the tests + unreliable except on local filesystems. The new function will + simply modify the file, allowing the filesystem to set the mod + time as it sees fit. + + * scripts/features/parallelism: The second test output could + change depending on how fast some scripts completed; use "sleep" + to force the order we want. + + * test_driver.pl (toplevel): A bug in Perl 5.000 to Perl 5.004 + means that "%ENV = ();" doesn't do the right thing. This worked + in Perl 4 and was fixed in Perl 5.004_01, but use a loop to delete + the environment rather than require specific versions. + + * run_make_tests.pl (set_more_defaults): Don't use Perl 5 s/// + modifier "s", so the tests will run with Perl 4. + (set_more_defaults): Set $pure_log to empty if there's no -logfile + option in PURIFYOPTIONS. + (setup_for_test): Don't remove any logs unless $pure_log is set. + +1999-09-15 Eli Zaretskii <eliz@is.elta.co.il> + + * scripts/features/reinvoke: Put the SHELL definition in the right + test makefile. + +1999-09-15 Paul D. Smith <psmith@gnu.org> + + ChangeLog file for the test suite created. + + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. +This file is part of GNU Make. + +GNU Make is free software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the Free Software +Foundation; either version 3 of the License, or (at your option) any later +version. + +GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/tests/NEWS b/tests/NEWS new file mode 100644 index 0000000..43971ec --- /dev/null +++ b/tests/NEWS @@ -0,0 +1,179 @@ +Changes from 0.4.9 to 3.78 (Sep 6, 1999): + + Lots of new tests. Renamed to follow the GNU make scheme. Also + added some support for using Purify with make. + + Rob Tulloh contributed some changes to get the test suite running on + NT; I tweaked them a bit (hopefully I didn't break anything!) Note + that NT doesn't grok the self-exec funkiness that Unix shells use, + so instead I broke that out into a separate shell script + "run_make_tests" that invokes perl with the (renamed) script + run_make_tests.pl. + + Eli Zaretski contributed changes to get the test suite running on + DOS with DJGPP. I also meddled in these somewhat. + + If you're on DOS or NT you should run "perl.exe run_make_tests.pl ..." + If you're on Unix, you can continue to run "./run_make_tests ..." as + before. + +Changes from 0.4.8 to 0.4.9 (May 14, 1998): + + Release by Paul D. Smith <psmith@baynetworks.com>; I'm the one to + blame for problems in this version :). + + Add some perl to test_driver.pl to strip out GNU make clock skew + warning messages from the output before comparing it to the + known-good output. + + A new test for escaped :'s in filenames (someone on VMS found this + didn't work anymore in 3.77): scripts/features/escape. + +Changes from 0.4.7 to 0.4.8 (May 14, 1998): + + Release by Paul D. Smith <psmith@baynetworks.com>; I'm the one to + blame for problems in this version :). + + New tests for features to be included in GNU make 3.77. + +Changes from 0.4.6 to 0.4.7 (August 18, 1997): + + Release by Paul D. Smith <psmith@baynetworks.com>; I'm the one to + blame for problems in this version :). + + Reworked some tests to make sure they all work with both perl4 and perl5. + + Work around a bug in perl 5.004 which doesn't clean the environment + correctly in all cases (fixed in at least 5.004_02). + + Updated functions/strip to test for newline stripping. + + Keep a $PURIFYOPTIONS env variable if present. + +Changes from 0.4.5 to 0.4.6 (April 07, 1997): + + Release by Paul D. Smith <psmith@baynetworks.com>; I'm the one to + blame for problems in this version :). + + Updated to work with GNU make 3.76 (and pretests). + + Added new tests and updated existing ones. Note that the new tests + weren't tested with perl 4, however I think they should work. + + Ignore any tests whose filenames end in "~", so that Emacs backup + files aren't run. + +Changes from 0.4.4 to 0.4.5 (April 29, 1995): + + Updated to be compatible with perl 5.001 as well as 4.036. + + Note: the test suite still won't work on 14-char filesystems + (sorry, Kaveh), but I will get to it. + + Also, some tests and stuff still haven't made it in because I + haven't had time to write the test scripts for them. But they, + too, will get in eventually. Contributions of scripts (ie, tests + that I can just drop in) are particularly welcome and will be + incorporated immediately. + +Changes from 0.4.3 to 0.4.4 (March 1995): + + Updated for changes in make 3.72.12, and to ignore CVS directories + (thanks go to Jim Meyering for the patches for this). + + Fixed uname call to not make a mess on BSD/OS 2.0 (whose uname -a + is very verbose). Let me know if this doesn't work correctly on + your system. + + Changed to display test name while it is running, not just when it + finishes. + + Note: the test suite still won't work on 14-char filesystems + (sorry, Kaveh), but I will get to it. + + Also, some tests and stuff still haven't made it in because I + haven't had time to write the test scripts for them. But they, + too, will get in eventually. + +Changes from 0.4 to 0.4.3 (October 1994): + + Fixed bugs (like dependencies on environment variables). + + Caught up with changes in make. + + The load_limit test should now silently ignore a failure due to + make not being able to read /dev/kmem. + + Reorganized tests into subdirs and renamed lots of things so that + those poor souls who still have to deal with 14-char filename + limits won't hate me any more. Thanks very much to Kaveh R. Ghazi + <ghazi@noc.rutgers.edu> for helping me with the implementation and + testing of these changes, and for putting up with all my whining + about it... + + Added a $| = 1 so that systems that don't seem to automatically + flush their output for some reason will still print all the + output. I'd hate for someone to miss out on the smiley that + you're supposed to get when all the tests pass... :-) + +Changes from 0.3 to 0.4 (August 1993): + + Lost in the mists of time (and my hurry to get it out before I + left my job). + +Changes from 0.2 to 0.3 (9-30-92): + + Several tests fixed to match the fact that MAKELEVEL > 0 or -C now + imply -w. + + parallel_execution test fixed to not use double colon rules any + more since their behavior has changed. + + errors_in_commands test fixed to handle different error messages + and return codes from rm. + + Several tests fixed to handle -make_path with a relative path + and/or a name other than "make" for make. + + dash-e-option test fixed to use $PATH instead of $USER (since the + latter does not exist on some System V systems). This also + removes the dependency on getlogin (which fails under certain + weird conditions). + + test_driver_core changed so that you can give a test name like + scripts/errors_in_commands and it will be handled correctly (handy + if you have a shell with filename completion). + +Changes from 0.1 to 0.2 (5-4-92): + + README corrected to require perl 4.019, not 4.010. + + -make_path replaces -old. + + errors_in_commands test updated for change in format introduced in + make 3.62.6. + + test_driver_core now uses a better way of figuring what OS it is + running on (thanks to meyering@cs.utexas.edu (Jim Meyering) for + suggesting this, as well as discovering the hard way that the old + way (testing for /mnt) fails on his machine). + + Some new tests were added. + + +------------------------------------------------------------------------------- +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. +This file is part of GNU Make. + +GNU Make is free software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the Free Software +Foundation; either version 3 of the License, or (at your option) any later +version. + +GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/tests/README b/tests/README new file mode 100644 index 0000000..3860bdb --- /dev/null +++ b/tests/README @@ -0,0 +1,103 @@ +The test suite was originally written by Steve McGee and Chris Arthur. +It is covered by the GNU General Public License (Version 2), described +in the file COPYING. It has been maintained as part of GNU make proper +since GNU make 3.78. + +This entire test suite, including all test files, are copyright and +distributed under the following terms: + + ----------------------------------------------------------------------------- + Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, + 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. + This file is part of GNU Make. + + GNU Make is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3 of the License, or (at your option) any later + version. + + GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + this program. If not, see <http://www.gnu.org/licenses/>. + ----------------------------------------------------------------------------- + +The test suite requires Perl. These days, you should have at least Perl +5.004 (available from ftp.gnu.org, and portable to many machines). It +used to work with Perl 4.036 but official support for Perl 4.x was +abandoned a long time ago, due to lack of testbeds, as well as interest. + +The test suite assumes that the first "diff" it finds on your PATH is +GNU diff, but that only matters if a test fails. + +To run the test suite on a UNIX system, use "perl ./run_make_tests" +(or just "./run_make_tests" if you have a perl on your PATH). + +To run the test suite on Windows NT or DOS systems, use +"perl.exe ./run_make-tests.pl". + +By default, the test engine picks up the first executable called "make" +that it finds in your path. You may use the -make_path option (ie, +"perl run_make_tests -make_path /usr/local/src/make-3.78/make") if +you want to run a particular copy. This now works correctly with +relative paths and when make is called something other than "make" (like +"gmake"). + +Tests cannot end with a "~" character, as the test suite will ignore any +that do (I was tired of having it run my Emacs backup files as tests :)) + +Also, sometimes the tests may behave strangely on networked +filesystems. You can use mkshadow to create a copy of the test suite in +/tmp or similar, and try again. If the error disappears, it's an issue +with your network or file server, not GNU make (I believe). This +shouldn't happen very often anymore: I've done a lot of work on the +tests to reduce the impacts of this situation. + +The options/dash-l test will not really test anything if the copy of +make you are using can't obtain the system load. Some systems require +make to be setgid sys or kmem for this; if you don't want to install +make just to test it, make it setgid to kmem or whatever group /dev/kmem +is (ie, "chgrp kmem make;chmod g+s make" as root). In any case, the +options/dash-l test should no longer *fail* because make can't read +/dev/kmem. + +A directory named "work" will be created when the tests are run which +will contain any makefiles and "diff" files of tests that fail so that +you may look at them afterward to see the output of make and the +expected result. + +There is a -help option which will give you more information about the +other possible options for the test suite. + + +Open Issues +----------- + +The test suite has a number of problems which should be addressed. One +VERY serious one is that there is no real documentation. You just have +to see the existing tests. Use the newer tests: many of the tests +haven't been updated to use the latest/greatest test methods. See the +ChangeLog in the tests directory for pointers. + +The second serious problem is that it's not parallelizable: it scribbles +all over its installation directory and so can only test one make at a +time. The third serious problem is that it's not relocatable: the only +way it works when you build out of the source tree is to create +symlinks, which doesn't work on every system and is bogus to boot. The +fourth serious problem is that it doesn't create its own sandbox when +running tests, so that if a test forgets to clean up after itself that +can impact future tests. + + +Bugs +---- + +Any complaints/suggestions/bugs/etc. for the test suite itself (as +opposed to problems in make that the suite finds) should be handled the +same way as normal GNU make bugs/problems (see the README for GNU make). + + + Paul D. Smith + Chris Arthur diff --git a/tests/mkshadow b/tests/mkshadow new file mode 100755 index 0000000..d41b40e --- /dev/null +++ b/tests/mkshadow @@ -0,0 +1,59 @@ +#!/bin/sh +# +# Simple script to make a "shadow" test directory, using symbolic links. +# Typically you'd put the shadow in /tmp or another local disk +# +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, +# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software +# Foundation, Inc. +# This file is part of GNU Make. +# +# GNU Make is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 3 of the License, or (at your option) any later +# version. +# +# GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +# details. +# +# You should have received a copy of the GNU General Public License along with +# this program. If not, see <http://www.gnu.org/licenses/>. + +case "$1" in + "") echo 'Usage: mkshadow <destdir>'; exit 1 ;; +esac + +dest="$1" + +if [ ! -d "$dest" ]; then + echo "Destination directory \`$dest' must exist!" + exit 1 +fi + +if [ ! -f run_make_tests ]; then + echo "The current directory doesn't appear to contain the test suite!" + exit 1 +fi + +suite=`pwd | sed 's%^/tmp_mnt%%'` +name=`basename "$suite"` + +files=`echo *` + +set -e + +mkdir "$dest/$name" +cd "$dest/$name" + +ln -s "$suite" .testdir + +for f in $files; do + ln -s .testdir/$f . +done + +rm -rf work + +echo "Shadow test suite created in \`$dest/$name'." +exit 0 diff --git a/tests/run_make_tests b/tests/run_make_tests new file mode 100755 index 0000000..b68b784 --- /dev/null +++ b/tests/run_make_tests @@ -0,0 +1,2 @@ +#!/bin/sh +exec perl $0.pl ${1+"$@"} diff --git a/tests/run_make_tests.pl b/tests/run_make_tests.pl new file mode 100755 index 0000000..2c8c08b --- /dev/null +++ b/tests/run_make_tests.pl @@ -0,0 +1,402 @@ +#!/usr/bin/env perl +# -*-perl-*- + +# Test driver for the Make test suite + +# Usage: run_make_tests [testname] +# [-debug] +# [-help] +# [-verbose] +# [-keep] +# [-make <make prog>] +# (and others) + +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, +# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software +# Foundation, Inc. +# This file is part of GNU Make. +# +# GNU Make is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 3 of the License, or (at your option) any later +# version. +# +# GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +# details. +# +# You should have received a copy of the GNU General Public License along with +# this program. If not, see <http://www.gnu.org/licenses/>. + + +$valgrind = 0; # invoke make with valgrind +$valgrind_args = ''; +$memcheck_args = '--num-callers=15 --tool=memcheck --leak-check=full'; +$massif_args = '--num-callers=15 --tool=massif --alloc-fn=xmalloc --alloc-fn=xcalloc --alloc-fn=xrealloc --alloc-fn=xstrdup --alloc-fn=xstrndup'; +$pure_log = undef; + +$command_string = ''; + +$all_tests = 0; + +require "test_driver.pl"; + +# Some target systems might not have the POSIX module... +$has_POSIX = eval { require "POSIX.pm" }; + +#$SIG{INT} = sub { print STDERR "Caught a signal!\n"; die @_; }; + +sub valid_option +{ + local($option) = @_; + + if ($option =~ /^-make([-_]?path)?$/i) { + $make_path = shift @argv; + if (!-f $make_path) { + print "$option $make_path: Not found.\n"; + exit 0; + } + return 1; + } + + if ($option =~ /^-all([-_]?tests)?$/i) { + $all_tests = 1; + return 1; + } + + if ($option =~ /^-(valgrind|memcheck)$/i) { + $valgrind = 1; + $valgrind_args = $memcheck_args; + return 1; + } + + if ($option =~ /^-massif$/i) { + $valgrind = 1; + $valgrind_args = $massif_args; + return 1; + } + +# This doesn't work--it _should_! Someone badly needs to fix this. +# +# elsif ($option =~ /^-work([-_]?dir)?$/) +# { +# $workdir = shift @argv; +# return 1; +# } + + return 0; +} + + +# This is an "all-in-one" function. Arguments are as follows: +# +# [0] (string): The makefile to be tested. undef means use the last one. +# [1] (string): Arguments to pass to make. +# [2] (string): Answer we should get back. +# [3] (integer): Exit code we expect. A missing code means 0 (success) + +$old_makefile = undef; + +sub run_make_test +{ + local ($makestring, $options, $answer, $err_code, $timeout) = @_; + + # If the user specified a makefile string, create a new makefile to contain + # it. If the first value is not defined, use the last one (if there is + # one). + + if (! defined $makestring) { + defined $old_makefile + || die "run_make_test(undef) invoked before run_make_test('...')\n"; + $makefile = $old_makefile; + } else { + if (! defined($makefile)) { + $makefile = &get_tmpfile(); + } + + # Make sure it ends in a newline. + $makestring && $makestring !~ /\n$/s and $makestring .= "\n"; + + # Replace @MAKEFILE@ with the makefile name and @MAKE@ with the path to + # make + $makestring =~ s/#MAKEFILE#/$makefile/g; + $makestring =~ s/#MAKEPATH#/$mkpath/g; + $makestring =~ s/#MAKE#/$make_name/g; + $makestring =~ s/#PERL#/$perl_name/g; + $makestring =~ s/#PWD#/$pwd/g; + + # Populate the makefile! + open(MAKEFILE, "> $makefile") || die "Failed to open $makefile: $!\n"; + print MAKEFILE $makestring; + close(MAKEFILE) || die "Failed to write $makefile: $!\n"; + } + + # Do the same processing on $answer as we did on $makestring. + + $answer && $answer !~ /\n$/s and $answer .= "\n"; + $answer =~ s/#MAKEFILE#/$makefile/g; + $answer =~ s/#MAKEPATH#/$mkpath/g; + $answer =~ s/#MAKE#/$make_name/g; + $answer =~ s/#PERL#/$perl_name/g; + $answer =~ s/#PWD#/$pwd/g; + + run_make_with_options($makefile, $options, &get_logfile(0), + $err_code, $timeout); + &compare_output($answer, &get_logfile(1)); + + $old_makefile = $makefile; + $makefile = undef; +} + +# The old-fashioned way... +sub run_make_with_options { + local ($filename,$options,$logname,$expected_code,$timeout) = @_; + local($code); + local($command) = $make_path; + + $expected_code = 0 unless defined($expected_code); + + # Reset to reflect this one test. + $test_passed = 1; + + if ($filename) { + $command .= " -f $filename"; + } + + if ($options) { + $command .= " $options"; + } + + $command_string = "$command\n"; + + if ($valgrind) { + print VALGRIND "\n\nExecuting: $command\n"; + } + + + { + my $old_timeout = $test_timeout; + $timeout and $test_timeout = $timeout; + + # If valgrind is enabled, turn off the timeout check + $valgrind and $test_timeout = 0; + + $code = &run_command_with_output($logname,$command); + + $test_timeout = $old_timeout; + } + + # Check to see if we have Purify errors. If so, keep the logfile. + # For this to work you need to build with the Purify flag -exit-status=yes + + if ($pure_log && -f $pure_log) { + if ($code & 0x7000) { + $code &= ~0x7000; + + # If we have a purify log, save it + $tn = $pure_testname . ($num_of_logfiles ? ".$num_of_logfiles" : ""); + print("Renaming purify log file to $tn\n") if $debug; + rename($pure_log, "$tn") + || die "Can't rename $log to $tn: $!\n"; + ++$purify_errors; + } else { + unlink($pure_log); + } + } + + if ($code != $expected_code) { + print "Error running $make_path (expected $expected_code; got $code): $command\n"; + $test_passed = 0; + $runf = &get_runfile; + &create_file (&get_runfile, $command_string); + # If it's a SIGINT, stop here + if ($code & 127) { + print STDERR "\nCaught signal ".($code & 127)."!\n"; + ($code & 127) == 2 and exit($code); + } + return 0; + } + + if ($profile & $vos) { + system "add_profile $make_path"; + } + + return 1; +} + +sub print_usage +{ + &print_standard_usage ("run_make_tests", + "[-make_path make_pathname] [-memcheck] [-massif]",); +} + +sub print_help +{ + &print_standard_help ( + "-make_path", + "\tYou may specify the pathname of the copy of make to run.", + "-valgrind", + "-memcheck", + "\tRun the test suite under valgrind's memcheck tool.", + "\tChange the default valgrind args with the VALGRIND_ARGS env var.", + "-massif", + "\tRun the test suite under valgrind's massif toool.", + "\tChange the default valgrind args with the VALGRIND_ARGS env var." + ); +} + +sub get_this_pwd { + $delete_command = 'rm -f'; + if ($has_POSIX) { + $__pwd = POSIX::getcwd(); + } elsif ($vos) { + $delete_command = "delete_file -no_ask"; + $__pwd = `++(current_dir)`; + } else { + # No idea... just try using pwd as a last resort. + chop ($__pwd = `pwd`); + } + + return $__pwd; +} + +sub set_defaults +{ + # $profile = 1; + $testee = "GNU make"; + $make_path = "make"; + $tmpfilesuffix = "mk"; + $pwd = &get_this_pwd; +} + +sub set_more_defaults +{ + local($string); + local($index); + + # find the type of the port. We do this up front to have a single + # point of change if it needs to be tweaked. + # + # This is probably not specific enough. + # + if ($osname =~ /Windows/i || $osname =~ /MINGW32/i || $osname =~ /CYGWIN_NT/i) { + $port_type = 'W32'; + } + # Bleah, the osname is so variable on DOS. This kind of bites. + # Well, as far as I can tell if we check for some text at the + # beginning of the line with either no spaces or a single space, then + # a D, then either "OS", "os", or "ev" and a space. That should + # match and be pretty specific. + elsif ($osname =~ /^([^ ]*|[^ ]* [^ ]*)D(OS|os|ev) /) { + $port_type = 'DOS'; + } + # Check for OS/2 + elsif ($osname =~ m%OS/2%) { + $port_type = 'OS/2'; + } + # Everything else, right now, is UNIX. Note that we should integrate + # the VOS support into this as well and get rid of $vos; we'll do + # that next time. + else { + $port_type = 'UNIX'; + } + + # On DOS/Windows system the filesystem apparently can't track + # timestamps with second granularity (!!). Change the sleep time + # needed to force a file to be considered "old". + $wtime = $port_type eq 'UNIX' ? 1 : $port_type eq 'OS/2' ? 2 : 4; + + print "Port type: $port_type\n" if $debug; + print "Make path: $make_path\n" if $debug; + + # Find the full pathname of Make. For DOS systems this is more + # complicated, so we ask make itself. + my $mk = `sh -c 'echo "all:;\@echo \\\$(MAKE)" | $make_path -f-'`; + chop $mk; + $mk or die "FATAL ERROR: Cannot determine the value of \$(MAKE):\n +'echo \"all:;\@echo \\\$(MAKE)\" | $make_path -f-' failed!\n"; + $make_path = $mk; + print "Make\t= `$make_path'\n" if $debug; + + $string = `$make_path -v -f /dev/null 2> /dev/null`; + + $string =~ /^(GNU Make [^,\n]*)/; + $testee_version = "$1\n"; + + $string = `sh -c "$make_path -f /dev/null 2>&1"`; + if ($string =~ /(.*): \*\*\* No targets\. Stop\./) { + $make_name = $1; + } + else { + if ($make_path =~ /$pathsep([^\n$pathsep]*)$/) { + $make_name = $1; + } + else { + $make_name = $make_path; + } + } + + # prepend pwd if this is a relative path (ie, does not + # start with a slash, but contains one). Thanks for the + # clue, Roland. + + if (index ($make_path, ":") != 1 && index ($make_path, "/") > 0) + { + $mkpath = "$pwd$pathsep$make_path"; + } + else + { + $mkpath = $make_path; + } + + # Get Purify log info--if any. + + if (exists $ENV{PURIFYOPTIONS} + && $ENV{PURIFYOPTIONS} =~ /.*-logfile=([^ ]+)/) { + $pure_log = $1 || ''; + $pure_log =~ s/%v/$make_name/; + $purify_errors = 0; + } + + $string = `sh -c "$make_path -j 2 -f /dev/null 2>&1"`; + if ($string =~ /not supported/) { + $parallel_jobs = 0; + } + else { + $parallel_jobs = 1; + } + + # Set up for valgrind, if requested. + + if ($valgrind) { + my $args = $valgrind_args; + open(VALGRIND, "> valgrind.out") + || die "Cannot open valgrind.out: $!\n"; + # -q --leak-check=yes + exists $ENV{VALGRIND_ARGS} and $args = $ENV{VALGRIND_ARGS}; + $make_path = "valgrind --log-fd=".fileno(VALGRIND)." $args $make_path"; + # F_SETFD is 2 + fcntl(VALGRIND, 2, 0) or die "fcntl(setfd) failed: $!\n"; + system("echo Starting on `date` 1>&".fileno(VALGRIND)); + print "Enabled valgrind support.\n"; + } +} + +sub setup_for_test +{ + $makefile = &get_tmpfile; + if (-f $makefile) { + unlink $makefile; + } + + # Get rid of any Purify logs. + if ($pure_log) { + ($pure_testname = $testname) =~ tr,/,_,; + $pure_testname = "$pure_log.$pure_testname"; + system("rm -f $pure_testname*"); + print("Purify testfiles are: $pure_testname*\n") if $debug; + } +} + +exit !&toplevel; diff --git a/tests/scripts/features/comments b/tests/scripts/features/comments new file mode 100644 index 0000000..9257955 --- /dev/null +++ b/tests/scripts/features/comments @@ -0,0 +1,35 @@ +$description = "The following test creates a makefile to test comments\n" + ."and comment continuation to the next line using a \n" + ."backslash within makefiles."; + +$details = "To test comments within a makefile, a semi-colon was placed \n" + ."after a comment was started. This should not be reported as\n" + ."an error since it is within a comment. We then continue the \n" + ."comment to the next line using a backslash. To test whether\n" + ."the comment really continued, we place an echo command with some\n" + ."text on the line which should never execute since it should be \n" + ."within a comment\n"; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE <<\EOF; +# Test comment vs semicolon parsing and line continuation +target: # this ; is just a comment \ + @echo This is within a comment. + @echo There should be no errors for this makefile. +EOF + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&run_make_with_options($makefile,"",&get_logfile); + +# Create the answer to what should be produced by this Makefile +$answer = "There should be no errors for this makefile.\n"; + +# COMPARE RESULTS + +&compare_output($answer,&get_logfile(1)) diff --git a/tests/scripts/features/conditionals b/tests/scripts/features/conditionals new file mode 100644 index 0000000..2ece60b --- /dev/null +++ b/tests/scripts/features/conditionals @@ -0,0 +1,146 @@ +# -*-perl-*- +$description = "Check GNU make conditionals."; + +$details = "Attempt various different flavors of GNU make conditionals."; + +run_make_test(' +arg1 = first +arg2 = second +arg3 = third +arg4 = cc +arg5 = second + +all: +ifeq ($(arg1),$(arg2)) + @echo arg1 equals arg2 +else + @echo arg1 NOT equal arg2 +endif + +ifeq \'$(arg2)\' "$(arg5)" + @echo arg2 equals arg5 +else + @echo arg2 NOT equal arg5 +endif + +ifneq \'$(arg3)\' \'$(arg4)\' + @echo arg3 NOT equal arg4 +else + @echo arg3 equal arg4 +endif + +ifndef undefined + @echo variable is undefined +else + @echo variable undefined is defined +endif +ifdef arg4 + @echo arg4 is defined +else + @echo arg4 is NOT defined +endif', + '', + 'arg1 NOT equal arg2 +arg2 equals arg5 +arg3 NOT equal arg4 +variable is undefined +arg4 is defined'); + + +# Test expansion of variables inside ifdef. + +run_make_test(' +foo = 1 + +FOO = foo +F = f + +DEF = no +DEF2 = no + +ifdef $(FOO) +DEF = yes +endif + +ifdef $(F)oo +DEF2 = yes +endif + + +DEF3 = no +FUNC = $1 +ifdef $(call FUNC,DEF)3 + DEF3 = yes +endif + +all:; @echo DEF=$(DEF) DEF2=$(DEF2) DEF3=$(DEF3)', + '', + 'DEF=yes DEF2=yes DEF3=yes'); + + +# Test all the different "else if..." constructs + +run_make_test(' +arg1 = first +arg2 = second +arg3 = third +arg4 = cc +arg5 = fifth + +result = + +ifeq ($(arg1),$(arg2)) + result += arg1 equals arg2 +else ifeq \'$(arg2)\' "$(arg5)" + result += arg2 equals arg5 +else ifneq \'$(arg3)\' \'$(arg3)\' + result += arg3 NOT equal arg4 +else ifndef arg5 + result += variable is undefined +else ifdef undefined + result += arg4 is defined +else + result += success +endif + + +all: ; @echo $(result)', + '', + 'success'); + + +# Test some random "else if..." construct nesting + +run_make_test(' +arg1 = first +arg2 = second +arg3 = third +arg4 = cc +arg5 = second + +ifeq ($(arg1),$(arg2)) + $(info failed 1) +else ifeq \'$(arg2)\' "$(arg2)" + ifdef undefined + $(info failed 2) + else + $(info success) + endif +else ifneq \'$(arg3)\' \'$(arg3)\' + $(info failed 3) +else ifdef arg5 + $(info failed 4) +else ifdef undefined + $(info failed 5) +else + $(info failed 6) +endif + +.PHONY: all +all: ; @:', + '', + 'success'); + + +# This tells the test driver that the perl test script executed properly. +1; diff --git a/tests/scripts/features/default_names b/tests/scripts/features/default_names new file mode 100644 index 0000000..e53127e --- /dev/null +++ b/tests/scripts/features/default_names @@ -0,0 +1,41 @@ +# -*-perl-*- + +$description = "This script tests to make sure that Make looks for +default makefiles in the correct order (GNUmakefile,makefile,Makefile)"; + +# Create a makefile called "GNUmakefile" +$makefile = "GNUmakefile"; + +open(MAKEFILE,"> $makefile"); +print MAKEFILE "FIRST: ; \@echo It chose GNUmakefile\n"; +close(MAKEFILE); + +# DOS/WIN32 platforms preserve case, but Makefile is the same file as makefile. +# Just test what we can here (avoid Makefile versus makefile test). + +if ($port_type eq 'UNIX') { + # Create another makefile called "makefile" + open(MAKEFILE,"> makefile"); + print MAKEFILE "SECOND: ; \@echo It chose makefile\n"; + close(MAKEFILE); +} + +# Create another makefile called "Makefile" +open(MAKEFILE,"> Makefile"); +print MAKEFILE "THIRD: ; \@echo It chose Makefile\n"; +close(MAKEFILE); + + +&run_make_with_options("","",&get_logfile); +&compare_output("It chose GNUmakefile\n",&get_logfile(1)); +unlink $makefile; + +if ($port_type eq 'UNIX') { + &run_make_with_options("","",&get_logfile); + &compare_output("It chose makefile\n",&get_logfile(1)); + unlink "makefile"; +} + +&run_make_with_options("","",&get_logfile); +&compare_output("It chose Makefile\n",&get_logfile(1)); +unlink "Makefile"; diff --git a/tests/scripts/features/double_colon b/tests/scripts/features/double_colon new file mode 100644 index 0000000..cad605d --- /dev/null +++ b/tests/scripts/features/double_colon @@ -0,0 +1,155 @@ +# -*-perl-*- +$description = "Test handling of double-colon rules."; + +$details = "\ +We test these features: + + - Multiple commands for the same (double-colon) target + - Different prerequisites for targets: only out-of-date + ones are rebuilt. + - Double-colon targets that aren't the goal target. + +Then we do the same thing for parallel builds: double-colon +targets should always be built serially."; + +# The Contents of the MAKEFILE ... + +open(MAKEFILE,"> $makefile"); + +print MAKEFILE <<'EOF'; + +all: baz + +foo:: f1.h ; @echo foo FIRST +foo:: f2.h ; @echo foo SECOND + +bar:: ; @echo aaa; sleep 1; echo aaa done +bar:: ; @echo bbb + +baz:: ; @echo aaa +baz:: ; @echo bbb + +biz:: ; @echo aaa +biz:: two ; @echo bbb + +two: ; @echo two + +f1.h f2.h: ; @echo $@ + +d :: ; @echo ok +d :: d ; @echo oops + +EOF + +close(MAKEFILE); + +# TEST 0: A simple double-colon rule that isn't the goal target. + +&run_make_with_options($makefile, "all", &get_logfile, 0); +$answer = "aaa\nbbb\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST 1: As above, in parallel + +if ($parallel_jobs) { + &run_make_with_options($makefile, "-j10 all", &get_logfile, 0); + $answer = "aaa\nbbb\n"; + &compare_output($answer, &get_logfile(1)); +} + +# TEST 2: A simple double-colon rule that is the goal target + +&run_make_with_options($makefile, "bar", &get_logfile, 0); +$answer = "aaa\naaa done\nbbb\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST 3: As above, in parallel + +if ($parallel_jobs) { + &run_make_with_options($makefile, "-j10 bar", &get_logfile, 0); + $answer = "aaa\naaa done\nbbb\n"; + &compare_output($answer, &get_logfile(1)); +} + +# TEST 4: Each double-colon rule is supposed to be run individually + +&utouch(-5, 'f2.h'); +&touch('foo'); + +&run_make_with_options($makefile, "foo", &get_logfile, 0); +$answer = "f1.h\nfoo FIRST\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST 5: Again, in parallel. + +if ($parallel_jobs) { + &run_make_with_options($makefile, "-j10 foo", &get_logfile, 0); + $answer = "f1.h\nfoo FIRST\n"; + &compare_output($answer, &get_logfile(1)); +} + +# TEST 6: Each double-colon rule is supposed to be run individually + +&utouch(-5, 'f1.h'); +unlink('f2.h'); +&touch('foo'); + +&run_make_with_options($makefile, "foo", &get_logfile, 0); +$answer = "f2.h\nfoo SECOND\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST 7: Again, in parallel. + +if ($parallel_jobs) { + &run_make_with_options($makefile, "-j10 foo", &get_logfile, 0); + $answer = "f2.h\nfoo SECOND\n"; + &compare_output($answer, &get_logfile(1)); +} + +# TEST 8: Test circular dependency check; PR/1671 + +&run_make_with_options($makefile, "d", &get_logfile, 0); +$answer = "ok\n$make_name: Circular d <- d dependency dropped.\noops\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST 8: I don't grok why this is different than the above, but it is... +# +# Hmm... further testing indicates this might be timing-dependent? +# +#if ($parallel_jobs) { +# &run_make_with_options($makefile, "-j10 biz", &get_logfile, 0); +# $answer = "aaa\ntwo\nbbb\n"; +# &compare_output($answer, &get_logfile(1)); +#} + +unlink('foo','f1.h','f2.h'); + + +# TEST 9: make sure all rules in s double colon family get executed +# (Savannah bug #14334). +# + +&touch('one'); +&touch('two'); + +run_make_test(' +.PHONY: all +all: result + +result:: one + @echo $^ >>$@ + @echo $^ + +result:: two + @echo $^ >>$@ + @echo $^ + +', +'', +'one +two'); + +unlink('result','one','two'); + +# This tells the test driver that the perl test script executed properly. +1; diff --git a/tests/scripts/features/echoing b/tests/scripts/features/echoing new file mode 100644 index 0000000..40debf5 --- /dev/null +++ b/tests/scripts/features/echoing @@ -0,0 +1,64 @@ +# -*-perl-*- +$description = "The following test creates a makefile to test command +echoing. It tests that when a command line starts with +a '\@', the echoing of that line is suppressed. It also +tests the -n option which tells make to ONLY echo the +commands and no execution happens. In this case, even +the commands with '\@' are printed. Lastly, it tests the +-s flag which tells make to prevent all echoing, as if +all commands started with a '\@'."; + +$details = "This test is similar to the 'clean' test except that a '\@' has +been placed in front of the delete command line. Four tests +are run here. First, make is run normally and the first echo +command should be executed. In this case there is no '\@' so +we should expect make to display the command AND display the +echoed message. Secondly, make is run with the clean target, +but since there is a '\@' at the beginning of the command, we +expect no output; just the deletion of a file which we check +for. Third, we give the clean target again except this time +we give make the -n option. We now expect the command to be +displayed but not to be executed. In this case we need only +to check the output since an error message would be displayed +if it actually tried to run the delete command again and the +file didn't exist. Lastly, we run the first test again with +the -s option and check that make did not echo the echo +command before printing the message.\n"; + +$example = "EXAMPLE_FILE"; + +touch($example); + +# TEST #1 +# ------- + +run_make_test(" +all: +\techo This makefile did not clean the dir... good +clean: +\t\@$delete_command $example\n", + '', 'echo This makefile did not clean the dir... good +This makefile did not clean the dir... good'); + +# TEST #2 +# ------- + +run_make_test(undef, 'clean', ''); +if (-f $example) { + $test_passed = 0; + unlink($example); +} + +# TEST #3 +# ------- + +run_make_test(undef, '-n clean', "$delete_command $example\n"); + + +# TEST #4 +# ------- + +run_make_test(undef, '-s', "This makefile did not clean the dir... good\n"); + + +1; diff --git a/tests/scripts/features/errors b/tests/scripts/features/errors new file mode 100644 index 0000000..e372fe0 --- /dev/null +++ b/tests/scripts/features/errors @@ -0,0 +1,92 @@ +# -*-perl-*- + +$description = "The following tests the -i option and the '-' in front of \n" + ."commands to test that make ignores errors in these commands\n" + ."and continues processing."; + +$details = "This test runs two makes. The first runs on a target with a \n" + ."command that has a '-' in front of it (and a command that is \n" + ."intended to fail) and then a delete command after that is \n" + ."intended to succeed. If make ignores the failure of the first\n" + ."command as it is supposed to, then the second command should \n" + ."delete a file and this is what we check for. The second make\n" + ."that is run in this test is identical except that the make \n" + ."command is given with the -i option instead of the '-' in \n" + ."front of the command. They should run the same. "; + +if ($vos) +{ + $rm_command = "delete_file"; +} +else +{ + $rm_command = "rm"; +} + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "clean:\n" + ."\t-$rm_command cleanit\n" + ."\t$rm_command foo\n" + ."clean2: \n" + ."\t$rm_command cleanit\n" + ."\t$rm_command foo\n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&touch("foo"); + +unlink("cleanit"); +$cleanit_error = `sh -c "$rm_command cleanit 2>&1"`; +$delete_error_code = $? >> 8; + +# TEST #1 +# ------- + +$answer = "$rm_command cleanit\n" + . $cleanit_error + ."$make_name: [clean] Error $delete_error_code (ignored)\n" + ."$rm_command foo\n"; + +&run_make_with_options($makefile,"",&get_logfile); + +# If make acted as planned, it should ignore the error from the first +# command in the target and execute the second which deletes the file "foo" +# This file, therefore, should not exist if the test PASSES. +if (-f "foo") { + $test_passed = 0; +} + +# The output for this on VOS is too hard to replicate, so we only check it +# on unix. +if (!$vos) +{ + &compare_output($answer,&get_logfile(1)); +} + + +&touch("foo"); + +# TEST #2 +# ------- + +$answer = "$rm_command cleanit\n" + . $cleanit_error + ."$make_name: [clean2] Error $delete_error_code (ignored)\n" + ."$rm_command foo\n"; + +&run_make_with_options($makefile,"clean2 -i",&get_logfile); + +if (-f "foo") { + $test_passed = 0; +} + +if (!$vos) { + &compare_output($answer,&get_logfile(1)); +} + +1; diff --git a/tests/scripts/features/escape b/tests/scripts/features/escape new file mode 100644 index 0000000..97a2994 --- /dev/null +++ b/tests/scripts/features/escape @@ -0,0 +1,58 @@ +# -*-perl-*- +$description = "Test various types of escaping in makefiles."; + +$details = "\ +Make sure that escaping of `:' works in target names. +Make sure escaping of whitespace works in target names. +Make sure that escaping of '#' works."; + + +close(MAKEFILE); + + +# TEST 1 + +run_make_test(' +$(path)foo : ; @echo "touch ($@)" + +foo\ bar: ; @echo "touch ($@)" + +sharp: foo\#bar.ext +foo\#bar.ext: ; @echo "foo#bar.ext = ($@)"', + '', + 'touch (foo)'); + +# TEST 2: This one should fail, since the ":" is unquoted. + +run_make_test(undef, + 'path=pre:', + "#MAKEFILE#:2: *** target pattern contains no `%'. Stop.", + 512); + +# TEST 3: This one should work, since we escape the ":". + +run_make_test(undef, + "'path=pre\\:'", + 'touch (pre:foo)'); + +# TEST 4: This one should fail, since the escape char is escaped. + +run_make_test(undef, + "'path=pre\\\\:'", + "#MAKEFILE#:2: *** target pattern contains no `%'. Stop.", + 512); + +# TEST 5: This one should work + +run_make_test(undef, + "'foo bar'", + 'touch (foo bar)'); + +# TEST 6: Test escaped comments + +run_make_test(undef, + 'sharp', + 'foo#bar.ext = (foo#bar.ext)'); + +# This tells the test driver that the perl test script executed properly. +1; diff --git a/tests/scripts/features/export b/tests/scripts/features/export new file mode 100644 index 0000000..81bff0c --- /dev/null +++ b/tests/scripts/features/export @@ -0,0 +1,186 @@ +# -*-perl-*- +$description = "Check GNU make export/unexport commands."; + +$details = ""; + +# The test driver cleans out our environment for us so we don't have to worry +# about that here. + +&run_make_test(' +FOO = foo +BAR = bar +BOZ = boz + +export BAZ = baz +export BOZ + +BITZ = bitz +BOTZ = botz + +export BITZ BOTZ +unexport BOTZ + +ifdef EXPORT_ALL +export +endif + +ifdef UNEXPORT_ALL +unexport +endif + +ifdef EXPORT_ALL_PSEUDO +.EXPORT_ALL_VARIABLES: +endif + +all: + @echo "FOO=$(FOO) BAR=$(BAR) BAZ=$(BAZ) BOZ=$(BOZ) BITZ=$(BITZ) BOTZ=$(BOTZ)" + @echo "FOO=$$FOO BAR=$$BAR BAZ=$$BAZ BOZ=$$BOZ BITZ=$$BITZ BOTZ=$$BOTZ" +', + '', "FOO=foo BAR=bar BAZ=baz BOZ=boz BITZ=bitz BOTZ=botz +FOO= BAR= BAZ=baz BOZ=boz BITZ=bitz BOTZ=\n"); + +# TEST 1: make sure vars inherited from the parent are exported + +$extraENV{FOO} = 1; + +&run_make_test(undef, '', "FOO=foo BAR=bar BAZ=baz BOZ=boz BITZ=bitz BOTZ=botz +FOO=foo BAR= BAZ=baz BOZ=boz BITZ=bitz BOTZ=\n"); + +# TEST 2: global export. Explicit unexport takes precedence. + +run_make_test(undef, "EXPORT_ALL=1" , + "FOO=foo BAR=bar BAZ=baz BOZ=boz BITZ=bitz BOTZ=botz +FOO=foo BAR=bar BAZ=baz BOZ=boz BITZ=bitz BOTZ=\n"); + +# TEST 3: global unexport. Explicit export takes precedence. + +&run_make_test(undef, "UNEXPORT_ALL=1", + "FOO=foo BAR=bar BAZ=baz BOZ=boz BITZ=bitz BOTZ=botz +FOO= BAR= BAZ=baz BOZ=boz BITZ=bitz BOTZ=\n"); + +# TEST 4: both: in the above makefile the unexport comes last so that rules. + +&run_make_test(undef, "EXPORT_ALL=1 UNEXPORT_ALL=1", + "FOO=foo BAR=bar BAZ=baz BOZ=boz BITZ=bitz BOTZ=botz +FOO= BAR= BAZ=baz BOZ=boz BITZ=bitz BOTZ=\n"); + +# TEST 5: test the pseudo target. + +&run_make_test(undef, "EXPORT_ALL_PSEUDO=1", + "FOO=foo BAR=bar BAZ=baz BOZ=boz BITZ=bitz BOTZ=botz +FOO=foo BAR=bar BAZ=baz BOZ=boz BITZ=bitz BOTZ=\n"); + +# TEST 6: Test the expansion of variables inside export + +&run_make_test(' +foo = f-ok +bar = b-ok + +FOO = foo +F = f + +BAR = bar +B = b + +export $(FOO) +export $(B)ar + +all: + @echo foo=$(foo) bar=$(bar) + @echo foo=$$foo bar=$$bar +', + "", "foo=f-ok bar=b-ok\nfoo=f-ok bar=b-ok\n"); + +# TEST 7: Test the expansion of variables inside unexport + +&run_make_test(' +foo = f-ok +bar = b-ok + +FOO = foo +F = f + +BAR = bar +B = b + +export foo bar + +unexport $(FOO) +unexport $(B)ar + +all: + @echo foo=$(foo) bar=$(bar) + @echo foo=$$foo bar=$$bar +', + '', "foo=f-ok bar=b-ok\nfoo= bar=\n"); + +# TEST 7: Test exporting multiple variables on the same line + +&run_make_test(' +A = a +B = b +C = c +D = d +E = e +F = f +G = g +H = h +I = i +J = j + +SOME = A B C + +export F G H I J + +export D E $(SOME) + +all: ; @echo A=$$A B=$$B C=$$C D=$$D E=$$E F=$$F G=$$G H=$$H I=$$I J=$$J +', + '', "A=a B=b C=c D=d E=e F=f G=g H=h I=i J=j\n"); + +# TEST 8: Test unexporting multiple variables on the same line + +@extraENV{qw(A B C D E F G H I J)} = qw(1 2 3 4 5 6 7 8 9 10); + +&run_make_test(' +A = a +B = b +C = c +D = d +E = e +F = f +G = g +H = h +I = i +J = j + +SOME = A B C + +unexport F G H I J + +unexport D E $(SOME) + +all: ; @echo A=$$A B=$$B C=$$C D=$$D E=$$E F=$$F G=$$G H=$$H I=$$I J=$$J +', + '', "A= B= C= D= E= F= G= H= I= J=\n"); + +# TEST 9: Check setting a variable named "export" + +&run_make_test(' +export = 123 +export export +export export = 456 +a: ; @echo "\$$(export)=$(export) / \$$export=$$export" +', + '', "\$(export)=456 / \$export=456\n"); + +# TEST 9: Check "export" as a target + +&run_make_test(' +a: export +export: ; @echo "$@" +', + '', "export\n"); + +# This tells the test driver that the perl test script executed properly. +1; diff --git a/tests/scripts/features/include b/tests/scripts/features/include new file mode 100644 index 0000000..ba8908c --- /dev/null +++ b/tests/scripts/features/include @@ -0,0 +1,179 @@ +# -*-mode: perl; rm-trailing-spaces: nil-*- + +$description = "Test various forms of the GNU make `include' command."; + +$details = "\ +Test include, -include, sinclude and various regressions involving them. +Test extra whitespace at the end of the include, multiple -includes and +sincludes (should not give an error) and make sure that errors are reported +for targets that were also -included."; + +$makefile2 = &get_tmpfile; + +open(MAKEFILE,"> $makefile"); + +# The contents of the Makefile ... + +print MAKEFILE <<EOF; +\#Extra space at the end of the following file name +include $makefile2 +all: ; \@echo There should be no errors for this makefile. + +-include nonexistent.mk +-include nonexistent.mk +sinclude nonexistent.mk +sinclude nonexistent-2.mk +-include makeit.mk +sinclude makeit.mk + +error: makeit.mk +EOF + +close(MAKEFILE); + + +open(MAKEFILE,"> $makefile2"); + +print MAKEFILE "ANOTHER: ; \@echo This is another included makefile\n"; + +close(MAKEFILE); + +# Create the answer to what should be produced by this Makefile +&run_make_with_options($makefile, "all", &get_logfile); +$answer = "There should be no errors for this makefile.\n"; +&compare_output($answer, &get_logfile(1)); + +&run_make_with_options($makefile, "ANOTHER", &get_logfile); +$answer = "This is another included makefile\n"; +&compare_output($answer, &get_logfile(1)); + +$makefile = undef; + +# Try to build the "error" target; this will fail since we don't know +# how to create makeit.mk, but we should also get a message (even though +# the -include suppressed it during the makefile read phase, we should +# see one during the makefile run phase). + +run_make_test + (' +-include foo.mk +error: foo.mk ; @echo $@ +', + '', + "#MAKE#: *** No rule to make target `foo.mk', needed by `error'. Stop.\n", + 512 + ); + +# Make sure that target-specific variables don't impact things. This could +# happen because a file record is created when a target-specific variable is +# set. + +run_make_test + (' +bar.mk: foo := baz +-include bar.mk +hello: ; @echo hello +', + '', + "hello\n" + ); + + +# Test inheritance of dontcare flag when rebuilding makefiles. +# +run_make_test(' +.PHONY: all +all: ; @: + +-include foo + +foo: bar; @: +', '', ''); + + +# Make sure that we don't die when the command fails but we dontcare. +# (Savannah bug #13216). +# +run_make_test(' +.PHONY: all +all:; @: + +-include foo + +foo: bar; @: + +bar:; @exit 1 +', '', ''); + +# Check include, sinclude, -include with no filenames. +# (Savannah bug #1761). + +run_make_test(' +.PHONY: all +all:; @: +include +-include +sinclude', '', ''); + + +# Test that the diagnostics is issued even if the target has been +# tried before with the dontcare flag (direct dependency case). +# +run_make_test(' +-include foo + +all: bar + +foo: baz +bar: baz +', +'', +"#MAKE#: *** No rule to make target `baz', needed by `bar'. Stop.\n", +512); + +# Test that the diagnostics is issued even if the target has been +# tried before with the dontcare flag (indirect dependency case). +# +run_make_test(' +-include foo + +all: bar + +foo: baz +bar: baz +baz: end +', +'', +"#MAKE#: *** No rule to make target `end', needed by `baz'. Stop.\n", +512); + +# Test that the diagnostics is issued even if the target has been +# tried before with the dontcare flag (include/-include case). +# +run_make_test(' +include bar +-include foo + +all: + +foo: baz +bar: baz +baz: end +', +'', +"#MAKEFILE#:2: bar: No such file or directory +#MAKE#: *** No rule to make target `end', needed by `baz'. Stop.\n", +512); + +if ($all_tests) { + # Test that include of a rebuild-able file doesn't show a warning + # Savannah bug #102 + run_make_test(q! +include foo +foo: ; @echo foo = bar > $@ +!, + '', "#MAKE#: `foo' is up to date.\n"); + rmfiles('foo'); +} + +1; diff --git a/tests/scripts/features/mult_rules b/tests/scripts/features/mult_rules new file mode 100644 index 0000000..6f120f1 --- /dev/null +++ b/tests/scripts/features/mult_rules @@ -0,0 +1,78 @@ +$description = "\ +The following test creates a makefile to test the presence +of multiple rules for one target. One file can be the +target of several rules if at most one rule has commands; +the other rules can only have dependencies."; + +$details = "\ +The makefile created in this test contains two hardcoded rules +for foo.o and bar.o. It then gives another multiple target rule +with the same names as above but adding more dependencies. +Additionally, another variable extradeps is listed as a +dependency but is defined to be null. It can however be defined +on the make command line as extradeps=extra.h which adds yet +another dependency to the targets."; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE <<EOF; +objects = foo.o bar.o +foo.o : defs.h +bar.o : defs.h test.h +extradeps = +\$(objects) : config.h \$(extradeps) +\t\@echo EXTRA EXTRA +EOF + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&touch("defs.h","test.h","config.h"); + +if ($vos) +{ + $error_code = 3307; +} +else +{ + $error_code = 512; +} + +&run_make_with_options($makefile, + "extradeps=extra.h", + &get_logfile, + $error_code); + +# Create the answer to what should be produced by this Makefile +$answer = "$make_name: *** No rule to make target `extra.h', needed by `foo.o'. Stop.\n"; + +&compare_output($answer,&get_logfile(1)); + + +# TEST #2 +# ------- + +&touch("extra.h"); + +&run_make_with_options($makefile, + "extradeps=extra.h", + &get_logfile, + 0); + +# Create the answer to what should be produced by this Makefile +$answer = "EXTRA EXTRA\n"; + +&compare_output($answer,&get_logfile(1)); + +unlink("defs.h","test.h","config.h","extra.h"); + +1; + + + + + + diff --git a/tests/scripts/features/mult_targets b/tests/scripts/features/mult_targets new file mode 100644 index 0000000..c8ff418 --- /dev/null +++ b/tests/scripts/features/mult_targets @@ -0,0 +1,46 @@ +$description = "The following test creates a makefile to test that a \n " + ."rule with multiple targets is equivalent to writing \n" + ."many rules, each with one target, and all identical aside\n" + ."from that."; + +$details = "A makefile is created with one rule and two targets. Make \n" + ."is called twice, once for each target, and the output which \n" + ."contains the target name with \$@ is looked at for the changes.\n" + ."This test also tests the substitute function by replacing \n" + ."the word output with nothing in the target name giving either\n" + ."an output of \"I am little\" or \"I am big\""; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "bigoutput littleoutput: test.h\n"; +print MAKEFILE "\t\@echo I am \$(subst output,,\$@)\n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&touch("test.h"); + +&run_make_with_options($makefile,"bigoutput",&get_logfile); + + +# Create the answer to what should be produced by this Makefile +$answer = "I am big\n"; + +&compare_output($answer,&get_logfile(1)); + +&run_make_with_options($makefile,"littleoutput",&get_logfile); +$answer = "I am little\n"; +&compare_output($answer,&get_logfile(1)); + +unlink "test.h"; + +1; + + + + + + diff --git a/tests/scripts/features/order_only b/tests/scripts/features/order_only new file mode 100644 index 0000000..4ebdc2b --- /dev/null +++ b/tests/scripts/features/order_only @@ -0,0 +1,118 @@ +# -*-perl-*- +$description = "Test order-only prerequisites."; + +$details = "\ +Create makefiles with various combinations of normal and order-only +prerequisites and ensure they behave properly. Test the \$| variable."; + +# TEST #0 -- Basics + +run_make_test(' +%r: | baz ; @echo $< $^ $| +bar: foo +foo:;@: +baz:;@:', + '', "foo foo baz\n"); + +# TEST #1 -- First try: the order-only prereqs need to be built. + +run_make_test(q! +foo: bar | baz + @echo '$$^ = $^' + @echo '$$| = $|' + touch $@ + +.PHONY: baz + +bar baz: + touch $@!, + '', "touch bar\ntouch baz\n\$^ = bar\n\$| = baz\ntouch foo\n"); + + +# TEST #2 -- now we do it again: baz is PHONY but foo should _NOT_ be updated + +run_make_test(undef, '', "touch baz\n"); + +unlink(qw(foo bar baz)); + +# TEST #3 -- Make sure the order-only prereq was promoted to normal. + +run_make_test(q! +foo: bar | baz + @echo '$$^ = $^' + @echo '$$| = $|' + touch $@ + +foo: baz + +.PHONY: baz + +bar baz: + touch $@!, + '', "touch bar\ntouch baz\n\$^ = bar baz\n\$| = \ntouch foo\n"); + + +# TEST #4 -- now we do it again + +run_make_test(undef, '', "touch baz\n\$^ = bar baz\n\$| = \ntouch foo\n"); + +unlink(qw(foo bar baz)); + +# Test empty normal prereqs + +# TEST #5 -- make sure the parser was correct. + +run_make_test(q! +foo:| baz + @echo '$$^ = $^' + @echo '$$| = $|' + touch $@ + +.PHONY: baz + +baz: + touch $@!, + '', "touch baz\n\$^ = \n\$| = baz\ntouch foo\n"); + +# TEST #6 -- now we do it again: this time foo won't be built + +run_make_test(undef, '', "touch baz\n"); + +unlink(qw(foo baz)); + +# Test order-only in pattern rules + +# TEST #7 -- make sure the parser was correct. + +run_make_test(q! +%.w : %.x | baz + @echo '$$^ = $^' + @echo '$$| = $|' + touch $@ + +all: foo.w + +.PHONY: baz +foo.x baz: + touch $@!, + '', + "touch foo.x\ntouch baz\n\$^ = foo.x\n\$| = baz\ntouch foo.w\n"); + +# TEST #8 -- now we do it again: this time foo.w won't be built + +run_make_test(undef, '', "touch baz\n"); + +unlink(qw(foo.w foo.x baz)); + +# TEST #9 -- make sure that $< is set correctly in the face of order-only +# prerequisites in pattern rules. + +run_make_test(' +%r: | baz ; @echo $< $^ $| +bar: foo +foo:;@: +baz:;@:', + '', "foo foo baz\n"); + + +1; diff --git a/tests/scripts/features/override b/tests/scripts/features/override new file mode 100644 index 0000000..fff6c4e --- /dev/null +++ b/tests/scripts/features/override @@ -0,0 +1,45 @@ +# -*-perl-*- + +$description = "Test the override directive on variable assignments."; + +$details = ""; + +# TEST 0: Basic override + +run_make_test(' +X = start +override recur = $(X) +override simple := $(X) +X = end +all: ; @echo "$(recur) $(simple)" +', + 'recur=I simple=J', "end start\n"); + +# TEST 1: Override with append + +run_make_test(' +X += X1 +override X += X2 +override Y += Y1 +Y += Y2 +all: ; @echo "$(X) $(Y)" +', + '', "X1 X2 Y1\n"); + +# TEST 2: Override with append to the command line + +run_make_test(undef, 'X=C Y=C', "C X2 C Y1\n"); + +# Test override of define/endef + +run_make_test(' +override define foo +@echo First comes the definition. +@echo Then comes the override. +endef +all: ; $(foo) +', + 'foo=Hello', "First comes the definition.\nThen comes the override.\n"); + + +1; diff --git a/tests/scripts/features/parallelism b/tests/scripts/features/parallelism new file mode 100644 index 0000000..cc0f84f --- /dev/null +++ b/tests/scripts/features/parallelism @@ -0,0 +1,254 @@ +# -*-perl-*- + +$description = "Test parallelism (-j) option."; + + +$details = "This test creates a makefile with two double-colon default +rules. The first rule has a series of sleep and echo commands +intended to run in series. The second and third have just an +echo statement. When make is called in this test, it is given +the -j option with a value of 4. This tells make that it may +start up to four jobs simultaneously. In this case, since the +first command is a sleep command, the output of the second +and third commands will appear before the first if indeed +make is running all of these commands in parallel."; + +if (!$parallel_jobs) { + return -1; +} + +if ($vos) { + $sleep_command = "sleep -seconds"; +} +else { + $sleep_command = "sleep"; +} + + +run_make_test(" +all : def_1 def_2 def_3 +def_1 : ; \@echo ONE; $sleep_command 3 ; echo TWO +def_2 : ; \@$sleep_command 2 ; echo THREE +def_3 : ; \@$sleep_command 1 ; echo FOUR", + '-j4', "ONE\nFOUR\nTHREE\nTWO"); + +# Test parallelism with included files. Here we sleep/echo while +# building the included files, to test that they are being built in +# parallel. +run_make_test(" +all: 1 2; \@echo success +-include 1.inc 2.inc +1.inc: ; \@echo ONE.inc; $sleep_command 2; echo TWO.inc; echo '1: ; \@echo ONE; $sleep_command 2; echo TWO' > \$\@ +2.inc: ; \@$sleep_command 1; echo THREE.inc; echo '2: ; \@$sleep_command 1; echo THREE' > \$\@", + "-j4", + "ONE.inc\nTHREE.inc\nTWO.inc\nONE\nTHREE\nTWO\nsuccess\n"); + +rmfiles(qw(1.inc 2.inc)); + + +# Test parallelism with included files--this time recurse first and make +# sure the jobserver works. +run_make_test(" +recurse: ; \@\$(MAKE) --no-print-directory -f #MAKEFILE# INC=yes all +all: 1 2; \@echo success + +INC = no +ifeq (\$(INC),yes) +-include 1.inc 2.inc +endif + +1.inc: ; \@echo ONE.inc; $sleep_command 2; echo TWO.inc; echo '1: ; \@echo ONE; $sleep_command 2; echo TWO' > \$\@ +2.inc: ; \@$sleep_command 1; echo THREE.inc; echo '2: ; \@$sleep_command 1; echo THREE' > \$\@", + "-j4", + "ONE.inc\nTHREE.inc\nTWO.inc\nONE\nTHREE\nTWO\nsuccess\n"); + +rmfiles(qw(1.inc 2.inc)); + +# Grant Taylor reports a problem where tokens can be lost (not written back +# to the pipe when they should be): this happened when there is a $(shell ...) +# function in an exported recursive variable. I added some code to check +# for this situation and print a message if it occurred. This test used +# to trigger this code when I added it but no longer does after the fix. +# We have to increase the timeout from the default (5s) on this test. + +run_make_test(" +export HI = \$(shell \$(\$\@.CMD)) +first.CMD = echo hi +second.CMD = $sleep_command 4; echo hi + +.PHONY: all first second +all: first second + +first second: ; \@echo \$\@; $sleep_command 1; echo \$\@", + '-j2', "first\nfirst\nsecond\nsecond", 0, 7); + +# Michael Matz <matz@suse.de> reported a bug where if make is running in +# parallel without -k and two jobs die in a row, but not too close to each +# other, then make will quit without waiting for the rest of the jobs to die. + +run_make_test(" +.PHONY: all fail.1 fail.2 fail.3 ok +all: fail.1 ok fail.2 fail.3 + +fail.1 fail.2 fail.3: + \@sleep \$(patsubst fail.%,%,\$\@) + \@echo Fail + \@exit 1 + +ok: + \@sleep 4 + \@echo Ok done", + '-rR -j5', 'Fail +#MAKE#: *** [fail.1] Error 1 +#MAKE#: *** Waiting for unfinished jobs.... +Fail +#MAKE#: *** [fail.2] Error 1 +Fail +#MAKE#: *** [fail.3] Error 1 +Ok done', + 512); + + +# Test for Savannah bug #15641. +# +run_make_test(' +.PHONY: all +all:; @: + +-include foo.d + +foo.d: comp + @echo building $@ + +comp: mod_a.o mod_b.o; @: + +mod_a.o mod_b.o: + @exit 1 +', '-j2', ''); + + +# TEST #9 -- Savannah bugs 3330 and 15919 +# In earlier versions of make this will either give the wrong answer, or hang. + +utouch(-10, 'target'); +run_make_test('target: intermed ; touch $@ + +.INTERMEDIATE: intermed +intermed: | phony ; touch $@ + +.PHONY: phony +phony: ; : phony', '-rR -j', ': phony'); +rmfiles('target'); + +# TEST #10: Don't put --jobserver-fds into a re-exec'd MAKEFLAGS. +# We can't test this directly because there's no way a makefile can +# show the value of MAKEFLAGS we were re-exec'd with. We can intuit it +# by looking for "disabling jobserver mode" warnings; we should only +# get one from the original invocation and none from the re-exec. +# See Savannah bug #18124 + +run_make_test(q! +-include inc.mk +recur: +# @echo 'MAKEFLAGS = $(MAKEFLAGS)' + @rm -f inc.mk + @$(MAKE) -j2 -f #MAKEFILE# all +all: +# @echo 'MAKEFLAGS = $(MAKEFLAGS)' + @echo $@ +inc.mk: +# @echo 'MAKEFLAGS = $(MAKEFLAGS)' + @echo 'FOO = bar' > $@ +!, + '--no-print-directory -j2', "#MAKE#[1]: warning: -jN forced in submake: disabling jobserver mode.\nall\n"); + +rmfiles('inc.mk'); + +if ($all_tests) { + # Implicit files aren't properly recreated during parallel builds + # Savannah bug #26864 + + # The first run works fine + run_make_test(q! +%.bar: %.x foo.y ; cat $^ > $@ +%.x: ; touch $@ +foo.y: foo.y.in ; cp $< $@ +foo.y.in: ; touch $@ +!, + '-j2 main.bar', + "touch foo.y.in +touch main.x +cp foo.y.in foo.y +cat main.x foo.y > main.bar +rm main.x"); + + # Now we touch the .in file and make sure it still works + touch('foo.y.in'); + + run_make_test(undef, '-j2 main.bar', "cp foo.y.in foo.y +touch main.x +cat main.x foo.y > main.bar +rm main.x"); + + # Clean up + rmfiles(qw(foo.y foo.y.in main.bar)); +} + +if ($all_tests) { + # Jobserver FD handling is messed up in some way. + # Savannah bug #28189 + # It doesn't look like that bug anymore but this is the code it runs + + run_make_test(q! +ifdef EXTRA +vpath %.dst / +xxx.dst: ; true +yyy.dst: ; true +endif + +M := $(MAKE) +xx: ; $M --no-print-directory -j2 -f $(MAKEFILE_LIST) xxx.dst yyy.dst EXTRA=1 +!, + '-j2', + '#MAKE#[1]: warning: -jN forced in submake: disabling jobserver mode. +true +true +'); +} + +# Make sure that all jobserver FDs are closed if we need to re-exec the +# master copy. +# +# First, find the "default" file descriptors we normally use +# Then make sure they're still used. +# +# Right now we don't have a way to run a makefile and capture the output +# without checking it, so we can't really write this test. + +# run_make_test(' +# submake: ; @$(MAKE) --no-print-directory -f #MAKEFILE# fdprint 5>output + +# dependfile: ; @echo FOO=bar > $@ + +# INCL := true + +# FOO=foo +# ifeq ($(INCL),true) +# -include dependfile +# endif + +# fdprint: ; @echo $(filter --jobserver%,$(MAKEFLAGS)) + +# recurse: ; @$(MAKE) --no-print-directory -f #MAKEFILE# submake INCL=true', +# '-j2 INCL=false fdprint', +# 'bar'); + +# rmfiles(qw(dependfile output)); + + +# # Do it again, this time where the include is done by the non-master make. +# run_make_test(undef, '-j2 recurse INCL=false', 'bar'); + +# rmfiles(qw(dependfile output)); + +1; diff --git a/tests/scripts/features/patspecific_vars b/tests/scripts/features/patspecific_vars new file mode 100644 index 0000000..8ca228d --- /dev/null +++ b/tests/scripts/features/patspecific_vars @@ -0,0 +1,148 @@ +# -*-perl-*- +$description = "Test pattern-specific variable settings."; + +$details = "\ +Create a makefile containing various flavors of pattern-specific variable +settings, override and non-override, and using various variable expansion +rules, semicolon interference, etc."; + +open(MAKEFILE,"> $makefile"); + +print MAKEFILE <<'EOF'; +all: one.x two.x three.x +FOO = foo +BAR = bar +BAZ = baz +one.x: override FOO = one +%.x: BAR = two +t%.x: BAR = four +thr% : override BAZ = three +one.x two.x three.x: ; @echo $@: $(FOO) $(BAR) $(BAZ) +four.x: baz ; @echo $@: $(FOO) $(BAR) $(BAZ) +baz: ; @echo $@: $(FOO) $(BAR) $(BAZ) + +# test matching multiple patterns +a%: AAA = aaa +%b: BBB = ccc +a%: BBB += ddd +%b: AAA ?= xxx +%b: AAA += bbb +.PHONY: ab +ab: ; @echo $(AAA); echo $(BBB) +EOF + +close(MAKEFILE); + + +# TEST #1 -- basics + +&run_make_with_options($makefile, "", &get_logfile); +$answer = "one.x: one two baz\ntwo.x: foo four baz\nthree.x: foo four three\n"; +&compare_output($answer,&get_logfile(1)); + + +# TEST #2 -- try the override feature + +&run_make_with_options($makefile, "BAZ=five", &get_logfile); +$answer = "one.x: one two five\ntwo.x: foo four five\nthree.x: foo four three\n"; +&compare_output($answer,&get_logfile(1)); + + +# TEST #3 -- make sure patterns are inherited properly + +&run_make_with_options($makefile, "four.x", &get_logfile); +$answer = "baz: foo two baz\nfour.x: foo two baz\n"; +&compare_output($answer,&get_logfile(1)); + + +# TEST #4 -- test multiple patterns matching the same target + +&run_make_with_options($makefile, "ab", &get_logfile); +$answer = "aaa bbb\nccc ddd\n"; +&compare_output($answer,&get_logfile(1)); + +# TEST #5 -- test pattern-specific exported variables +# +run_make_test(' +/%: export foo := foo + +/bar: + @echo $(foo) $$foo +', '', 'foo foo'); + + +# TEST #6 -- test expansion of pattern-specific simple variables +# +run_make_test(' +.PHONY: all + +all: inherit := good $$t +all: bar baz + +b%: pattern := good $$t + +global := orginal $$t + + +# normal target +# +ifdef rec +bar: a = global: $(global) pattern: $(pattern) inherit: $(inherit) +else +bar: a := global: $(global) pattern: $(pattern) inherit: $(inherit) +endif + +bar: ; @echo \'normal: $a;\' + + +# pattern target +# +ifdef rec +%z: a = global: $(global) pattern: $(pattern) inherit: $(inherit) +else +%z: a := global: $(global) pattern: $(pattern) inherit: $(inherit) +endif + +%z: ; @echo \'pattrn: $a;\' + + +global := new $$t +', +'', +'normal: global: orginal $t pattern: inherit: ; +pattrn: global: orginal $t pattern: inherit: ;'); + + +# TEST #7 -- test expansion of pattern-specific recursive variables +# +run_make_test(undef, # reuse previous makefile +'rec=1', +'normal: global: new $t pattern: good $t inherit: good $t; +pattrn: global: new $t pattern: good $t inherit: good $t;'); + +# TEST #8: override in pattern-specific variables + +run_make_test(' +a%: override FOO += f1 +a%: FOO += f2 +ab: ; @echo "$(FOO)" +', + '', "f1\n"); + +run_make_test(undef, 'FOO=C', "C f1\n"); + +# TEST #9: Test shortest stem selection in pattern-specific variables. + +run_make_test(' +%-mt.x: x := two +%.x: x := one + +all: foo.x foo-mt.x + +foo.x: ;@echo $x +foo-mt.x: ;@echo $x +', +'', +"one\ntwo"); + +1; diff --git a/tests/scripts/features/patternrules b/tests/scripts/features/patternrules new file mode 100644 index 0000000..eebe7c0 --- /dev/null +++ b/tests/scripts/features/patternrules @@ -0,0 +1,224 @@ +# -*-perl-*- + +$description = "Test pattern rules."; + +$details = ""; + +use Cwd; + +$dir = cwd; +$dir =~ s,.*/([^/]+)$,../$1,; + + +# TEST #0: Make sure that multiple patterns where the same target +# can be built are searched even if the first one fails +# to match properly. +# + +run_make_test(q! +.PHONY: all + +all: case.1 case.2 case.3 + +# We can't have this, due to "Implicit Rule Search Algorithm" step 5c +#xxx: void + +# 1 - existing file +%.1: void + @exit 1 +%.1: #MAKEFILE# + @exit 0 + +# 2 - phony +%.2: void + @exit 1 +%.2: 2.phony + @exit 0 +.PHONY: 2.phony + +# 3 - implicit-phony +%.3: void + @exit 1 +%.3: 3.implicit-phony + @exit 0 + +3.implicit-phony: +!, '', ''); + +# TEST #1: make sure files that are built via implicit rules are marked +# as targets (Savannah bug #12202). +# +run_make_test(' +TARGETS := foo foo.out + +.PHONY: all foo.in + +all: $(TARGETS) + +%: %.in + @echo $@ + +%.out: % + @echo $@ + +foo.in: ; @: + +', +'', +'foo +foo.out'); + + +# TEST #2: make sure intermediate files that also happened to be +# prerequisites are not removed (Savannah bug #12267). +# +run_make_test(' +$(dir)/foo.o: + +$(dir)/foo.y: + @echo $@ + +%.c: %.y + touch $@ + +%.o: %.c + @echo $@ + +.PHONY: install +install: $(dir)/foo.c + +', +"dir=$dir", +"$dir/foo.y +touch $dir/foo.c +$dir/foo.o"); + +unlink("$dir/foo.c"); + + +# TEST #3: make sure precious flag is set properly for targets +# that are built via implicit rules (Savannah bug #13218). +# +run_make_test(' +.DELETE_ON_ERROR: + +.PRECIOUS: %.bar + +%.bar:; @touch $@ && exit 1 + +$(dir)/foo.bar: + +', +"dir=$dir", +"#MAKE#: *** [$dir/foo.bar] Error 1", +512); + +unlink("$dir/foo.bar"); + + +# TEST #4: make sure targets of a matched implicit pattern rule are +# never considered intermediate (Savannah bug #13022). +# +run_make_test(' +.PHONY: all +all: foo.c foo.o + +%.h %.c: %.in + touch $*.h + touch $*.c + +%.o: %.c %.h + echo $+ >$@ + +%.o: %.c + @echo wrong rule + +foo.in: + touch $@ + +', +'', +'touch foo.in +touch foo.h +touch foo.c +echo foo.c foo.h >foo.o'); + +unlink('foo.in', 'foo.h', 'foo.c', 'foo.o'); + +# TEST #5: make sure both prefix and suffix patterns work with multiple +# target patterns (Savannah bug #26593). +# +run_make_test(' +all: foo.s1 foo.s2 p1.foo p2.foo + +p1.% p2.%: %.orig + @echo $@ +%.s1 %.s2: %.orig + @echo $@ + +.PHONY: foo.orig +', + '', "foo.s1\np1.foo\n"); + +# TEST 6: Make sure that non-target files are still eligible to be created +# as part of implicit rule chaining. Savannah bug #17752. + +run_make_test(q! +BIN = xyz +COPY = $(BIN).cp +SRC = $(BIN).c +allbroken: $(COPY) $(BIN) ; @echo ok +$(SRC): ; @echo 'main(){}' > $@ +%.cp: % ; @cp $< $@ +% : %.c ; @cp $< $@ +clean: ; @rm -rf $(SRC) $(COPY) $(BIN) +!, + '', "ok\n"); + +unlink(qw(xyz xyz.cp xyz.c)); + +# TEST 7: Make sure that all prereqs of all "also_make" targets get created +# before any of the things that depend on any of them. Savannah bug #19108. + +run_make_test(q! +final: x ; @echo $@ +x: x.t1 x.t2 ; @echo $@ +x.t2: dep +dep: ; @echo $@ +%.t1 %.t2: ; @echo $*.t1 ; echo $*.t2 +!, + '', "dep\nx.t1\nx.t2\nx\nfinal\n"); + + +# TEST 8: Verify we can remove pattern rules. Savannah bug #18622. + +my @f = (qw(foo.w foo.ch)); +touch(@f); + +run_make_test(q! +CWEAVE := : + +# Disable builtin rules +%.tex : %.w +%.tex : %.w %.ch +!, + 'foo.tex', + "#MAKE#: *** No rule to make target `foo.tex'. Stop.", 512); + +unlink(@f); + +# TEST #9: Test shortest stem selection in pattern rules. + +run_make_test(' +%.x: ;@echo one +%-mt.x: ;@echo two + +all: foo.x foo-mt.x +', +'', +"one\ntwo"); + +1; + +# This tells the test driver that the perl test script executed properly. +1; diff --git a/tests/scripts/features/quoting b/tests/scripts/features/quoting new file mode 100644 index 0000000..916681c --- /dev/null +++ b/tests/scripts/features/quoting @@ -0,0 +1,32 @@ +# -*-perl-*- + +$description = "The following test creates a makefile to test using \n" . + "quotes within makefiles."; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE <<'EOM'; +SHELL = /bin/sh +TEXFONTS = NICEFONT +DEFINES = -DDEFAULT_TFM_PATH=\".:$(TEXFONTS)\" +test: ; @"echo" 'DEFINES = $(DEFINES)' +EOM + +# END of Contents of MAKEFILE + +close(MAKEFILE); + + +&run_make_with_options($makefile,"",&get_logfile); + + +# Create the answer to what should be produced by this Makefile +$answer = 'DEFINES = -DDEFAULT_TFM_PATH=\".:NICEFONT\"' . "\n"; + +# COMPARE RESULTS + +&compare_output($answer,&get_logfile(1)); + +1; diff --git a/tests/scripts/features/recursion b/tests/scripts/features/recursion new file mode 100644 index 0000000..a6b8f90 --- /dev/null +++ b/tests/scripts/features/recursion @@ -0,0 +1,55 @@ +# -*-perl-*- +$description = "Test recursion."; + +$details = "DETAILS"; + +# Test some basic recursion. +run_make_test(' +all: + $(MAKE) -f #MAKEFILE# foo +foo: + @echo $(MAKE) + @echo MAKELEVEL = $(MAKELEVEL) + $(MAKE) -f #MAKEFILE# last +last: + @echo $(MAKE) + @echo MAKELEVEL = $(MAKELEVEL) + @echo THE END +', + ('CFLAGS=-O -w' . ($parallel_jobs ? ' -j 2' : '')), + ($vos + ? "#MAKE#: Entering directory `#PWD#' +make 'CFLAGS=-O' -f #MAKEFILE# foo +make CFLAGS=-O +MAKELEVEL = 0 +make 'CFLAGS=-O' -f #MAKEFILE# last +make CFLAGS=-O +MAKELEVEL = 0 +THE END +#MAKE#: Leaving directory `#PWD#'" + : "#MAKE#: Entering directory `#PWD#' +#MAKEPATH# -f #MAKEFILE# foo +#MAKE#[1]: Entering directory `#PWD#' +#MAKEPATH# +MAKELEVEL = 1 +#MAKEPATH# -f #MAKEFILE# last +#MAKE#[2]: Entering directory `#PWD#' +#MAKEPATH# +MAKELEVEL = 2 +THE END +#MAKE#[2]: Leaving directory `#PWD#' +#MAKE#[1]: Leaving directory `#PWD#' +#MAKE#: Leaving directory `#PWD#'")); + + +# Test command line overrides. +run_make_test(' +recur: all ; @$(MAKE) --no-print-directory -f #MAKEFILE# a=AA all +all: ; @echo "MAKEOVERRIDES = $(MAKEOVERRIDES)" +', + 'a=ZZ', + 'MAKEOVERRIDES = a=ZZ +MAKEOVERRIDES = a=AA +'); + +1; diff --git a/tests/scripts/features/reinvoke b/tests/scripts/features/reinvoke new file mode 100644 index 0000000..9952ced --- /dev/null +++ b/tests/scripts/features/reinvoke @@ -0,0 +1,65 @@ +# -*-mode: perl-*- + +$description = "Test GNU make's auto-reinvocation feature."; + +$details = "\ +If the makefile or one it includes can be rebuilt then it is, and make +is reinvoked. We create a rule to rebuild the makefile from a temp +file, then touch the temp file to make it newer than the makefile."; + +$omkfile = $makefile; + +&utouch(-600, 'incl.mk'); +# For some reason if we don't do this then the test fails for systems +# with sub-second timestamps, maybe + NFS? Not sure. +&utouch(-1, 'incl-1.mk'); + +run_make_test(' +all: ; @echo running rules. + +#MAKEFILE# incl.mk: incl-1.mk + @echo rebuilding $@ + @echo >> $@ + +include incl.mk', + '', "rebuilding incl.mk\nrunning rules.\n"); + +# Make sure updating the makefile itself also works + +&utouch(-600, $omkfile); + +run_make_test(undef, '', "rebuilding #MAKEFILE#\nrunning rules.\n"); + +&rmfiles('incl.mk', 'incl-1.mk'); + + +# In this test we create an included file that's out-of-date, but then +# the rule doesn't update it. Make shouldn't re-exec. + +&utouch(-600, 'b','a'); +#&utouch(-10, 'a'); +&touch('c'); + +run_make_test(' +SHELL = /bin/sh + +all: ; @echo hello + +a : b ; echo >> $@ + +b : c ; [ -f $@ ] || echo >> $@ + +c: ; echo >> $@ + +include $(F)', + 'F=a', "[ -f b ] || echo >> b\nhello\n"); + +# Now try with the file we're not updating being the actual file we're +# including: this and the previous one test different parts of the code. + +run_make_test(undef, "F=b", "[ -f b ] || echo >> b\nhello\n") + +&rmfiles('a','b','c'); + +# This tells the test driver that the perl test script executed properly. +1; diff --git a/tests/scripts/features/se_explicit b/tests/scripts/features/se_explicit new file mode 100644 index 0000000..79e0a36 --- /dev/null +++ b/tests/scripts/features/se_explicit @@ -0,0 +1,156 @@ +# -*-perl-*- +$description = "Test second expansion in ordinary rules."; + +$details = ""; + +# TEST #0: Test handing of '$' in prerequisites with and without second +# expansion. + +run_make_test(q! +ifdef SE + .SECONDEXPANSION: +endif +foo$$bar: bar$$baz bar$$biz ; @echo '$@ : $^' +PRE = one two +bar$$baz: $$(PRE) +baraz: $$(PRE) +PRE = three four +.DEFAULT: ; @echo '$@' +!, + '', + "\$\nbar\$biz\nfoo\$bar : bar\$baz bar\$biz"); + +run_make_test(undef, 'SE=1', "three\nfour\nbariz\nfoo\$bar : baraz bariz"); + +# TEST #1: automatic variables. +# +run_make_test(q! +.SECONDEXPANSION: +.DEFAULT: ; @echo '$@' + +foo: bar baz + +foo: biz | buz + +foo: $$@.1 \ + $$<.2 \ + $$(addsuffix .3,$$^) \ + $$(addsuffix .4,$$+) \ + $$|.5 \ + $$*.6 + +!, +'', +'bar +baz +biz +buz +foo.1 +bar.2 +bar.3 +baz.3 +biz.3 +bar.4 +baz.4 +biz.4 +buz.5 +.6 +'); + + +# Test #2: target/pattern -specific variables. +# +run_make_test(q! +.SECONDEXPANSION: +.DEFAULT: ; @echo '$@' + +foo.x: $$a $$b + +foo.x: a := bar + +%.x: b := baz +!, +'', +'bar +baz +'); + + +# Test #3: order of prerequisites. +# +run_make_test(q! +.SECONDEXPANSION: +.DEFAULT: ; @echo '$@' + +all: foo bar baz + +# Subtest #1 +foo: foo.1; @: +foo: foo.2 +foo: foo.3 + +# Subtest #2 +bar: bar.2 +bar: bar.1; @: +bar: bar.3 + +# Subtest #3 +baz: baz.1 +baz: baz.2 +baz: ; @: +!, +'', +'foo.1 +foo.2 +foo.3 +bar.1 +bar.2 +bar.3 +baz.1 +baz.2 +'); + +# TEST #4: eval in a context where there is no reading_file +run_make_test(q! +.SECONDEXPANSION: +all : $$(eval $$(info test)) +!, + '', "test\n#MAKE#: Nothing to be done for `all'.\n"); + +# TEST #5: (NEGATIVE) catch eval in a prereq list trying to create new +# target/prereq relationships. + +run_make_test(q! +.SECONDEXPANSION: +proj1.exe : proj1.o $$(eval $$(test)) +define test +proj1.o : proj1.c +proj1.c: proj1.h +endef +!, + '', "#MAKE#: *** prerequisites cannot be defined in recipes. Stop.\n", 512); + + +# Automatic $$+ variable expansion issue. Savannah bug #25780 +run_make_test(q! +all : foo foo +.SECONDEXPANSION: +all : $$+ ; @echo '$+' +foo : ; +!, + '', "foo foo foo foo\n"); + + +# Automatic $$+ variable expansion issue. Savannah bug #25780 +run_make_test(q! +all : bar bar +bar : ; +q%x : ; +.SECONDEXPANSION: +a%l: q1x $$+ q2x ; @echo '$+' +!, + '', "q1x bar bar q2x bar bar\n"); + + +# This tells the test driver that the perl test script executed properly. +1; diff --git a/tests/scripts/features/se_implicit b/tests/scripts/features/se_implicit new file mode 100644 index 0000000..e9acb2f --- /dev/null +++ b/tests/scripts/features/se_implicit @@ -0,0 +1,226 @@ +# -*-perl-*- +$description = "Test second expansion in ordinary rules."; + +$details = ""; + +use Cwd; + +$dir = cwd; +$dir =~ s,.*/([^/]+)$,../$1,; + + +# Test #1: automatic variables. +# +run_make_test(q! +.SECONDEXPANSION: +.DEFAULT: ; @echo '$@' + +foo.a: bar baz + +foo.a: biz | buz + +foo.%: 1.$$@ \ + 2.$$< \ + $$(addprefix 3.,$$^) \ + $$(addprefix 4.,$$+) \ + 5.$$| \ + 6.$$* + @: + +1.foo.a \ +2.bar \ +3.bar \ +3.baz \ +3.biz \ +4.bar \ +4.baz \ +4.biz \ +5.buz \ +6.a: + @echo '$@' + +!, +'', +'1.foo.a +2.bar +3.bar +3.baz +3.biz +4.bar +4.baz +4.biz +5.buz +6.a +bar +baz +biz +buz +'); + + +# Test #2: target/pattern -specific variables. +# +run_make_test(q! +.SECONDEXPANSION: +foo.x: + +foo.%: $$(%_a) $$(%_b) bar + @: + +foo.x: x_a := bar + +%.x: x_b := baz + +bar baz: ; @echo '$@' +!, + '', "bar\nbaz\n"); + + +# Test #3: order of prerequisites. +# +run_make_test(q! +.SECONDEXPANSION: +.DEFAULT: ; @echo '$@' + +all: foo bar baz + + +# Subtest #1 +# +%oo: %oo.1; @: + +foo: foo.2 + +foo: foo.3 + +foo.1: ; @echo '$@' + + +# Subtest #2 +# +bar: bar.2 + +%ar: %ar.1; @: + +bar: bar.3 + +bar.1: ; @echo '$@' + + +# Subtest #3 +# +baz: baz.1 + +baz: baz.2 + +%az: ; @: +!, + '', +'foo.1 +foo.2 +foo.3 +bar.1 +bar.2 +bar.3 +baz.1 +baz.2 +'); + + +# Test #4: stem splitting logic. +# +run_make_test(q! +.SECONDEXPANSION: +$(dir)/tmp/bar.o: + +$(dir)/tmp/foo/bar.c: ; @echo '$@' +$(dir)/tmp/bar/bar.c: ; @echo '$@' +foo.h: ; @echo '$@' + +%.o: $$(addsuffix /%.c,foo bar) foo.h + @echo '$@: {$<} $^' +!, + "dir=$dir", "$dir/tmp/foo/bar.c +$dir/tmp/bar/bar.c +foo.h +$dir/tmp/bar.o: {$dir/tmp/foo/bar.c} $dir/tmp/foo/bar.c $dir/tmp/bar/bar.c foo.h +"); + + +# Test #5: stem splitting logic and order-only prerequisites. +# +run_make_test(q! +.SECONDEXPANSION: +$(dir)/tmp/foo.o: $(dir)/tmp/foo.c +$(dir)/tmp/foo.c: ; @echo '$@' +bar.h: ; @echo '$@' + +%.o: %.c|bar.h + @echo '$@: {$<} {$|} $^' + +!, + "dir=$dir", "$dir/tmp/foo.c +bar.h +$dir/tmp/foo.o: {$dir/tmp/foo.c} {bar.h} $dir/tmp/foo.c +"); + + +# Test #6: lack of implicit prerequisites. +# +run_make_test(q! +.SECONDEXPANSION: +foo.o: foo.c +foo.c: ; @echo '$@' + +%.o: + @echo '$@: {$<} $^' +!, + '', "foo.c\nfoo.o: {foo.c} foo.c\n"); + + +# Test #7: Test stem from the middle of the name. +# +run_make_test(q! +.SECONDEXPANSION: +foobarbaz: + +foo%baz: % $$*.1 + @echo '$*' + +bar bar.1: + @echo '$@' +!, + '', "bar\nbar.1\nbar\n"); + + +# Test #8: Make sure stem triple-expansion does not happen. +# +run_make_test(q! +.SECONDEXPANSION: +foo$$bar: + +f%r: % $$*.1 + @echo '$*' + +oo$$ba oo$$ba.1: + @echo '$@' +!, + '', 'oo$ba +oo$ba.1 +oo$ba +'); + +# Test #9: Check the value of $^ +run_make_test(q! +.SECONDEXPANSION: + +%.so: | $$(extra) ; @echo $^ + +foo.so: extra := foo.o +foo.so: +foo.o: +!, + '', "\n"); + +# This tells the test driver that the perl test script executed properly. +1; diff --git a/tests/scripts/features/se_statpat b/tests/scripts/features/se_statpat new file mode 100644 index 0000000..b1e59e1 --- /dev/null +++ b/tests/scripts/features/se_statpat @@ -0,0 +1,107 @@ +# -*-perl-*- +$description = "Test second expansion in static pattern rules."; + +$details = ""; + +# Test #1: automatic variables. +# +run_make_test(q! +.SECONDEXPANSION: +.DEFAULT: ; @echo '$@' + +foo.a foo.b: foo.%: bar.% baz.% +foo.a foo.b: foo.%: biz.% | buz.% + +foo.a foo.b: foo.%: $$@.1 \ + $$<.2 \ + $$(addsuffix .3,$$^) \ + $$(addsuffix .4,$$+) \ + $$|.5 \ + $$*.6 +!, + '', 'bar.a +baz.a +biz.a +buz.a +foo.a.1 +bar.a.2 +bar.a.3 +baz.a.3 +biz.a.3 +bar.a.4 +baz.a.4 +biz.a.4 +buz.a.5 +a.6 +'); + + +# Test #2: target/pattern -specific variables. +# +run_make_test(q! +.SECONDEXPANSION: +.DEFAULT: ; @echo '$@' + +foo.x foo.y: foo.%: $$(%_a) $$($$*_b) + +foo.x: x_a := bar + +%.x: x_b := baz +!, + '', "bar\nbaz\n"); + + +# Test #3: order of prerequisites. +# +run_make_test(q! +.SECONDEXPANSION: +.DEFAULT: ; @echo '$@' + +all: foo.a bar.a baz.a + +# Subtest #1 +foo.a foo.b: foo.%: foo.%.1; @: +foo.a foo.b: foo.%: foo.%.2 +foo.a foo.b: foo.%: foo.%.3 + + +# Subtest #2 +bar.a bar.b: bar.%: bar.%.2 +bar.a bar.b: bar.%: bar.%.1; @: +bar.a bar.b: bar.%: bar.%.3 + + +# Subtest #3 +baz.a baz.b: baz.%: baz.%.1 +baz.a baz.b: baz.%: baz.%.2 +baz.a baz.b: ; @: +!, + '', 'foo.a.1 +foo.a.2 +foo.a.3 +bar.a.1 +bar.a.2 +bar.a.3 +baz.a.1 +baz.a.2 +'); + + +# Test #4: Make sure stem triple-expansion does not happen. +# +run_make_test(q! +.SECONDEXPANSION: +foo$$bar: f%r: % $$*.1 + @echo '$*' + +oo$$ba oo$$ba.1: + @echo '$@' +!, + '', 'oo$ba +oo$ba.1 +oo$ba +'); + + +# This tells the test driver that the perl test script executed properly. +1; diff --git a/tests/scripts/features/statipattrules b/tests/scripts/features/statipattrules new file mode 100644 index 0000000..3f363de --- /dev/null +++ b/tests/scripts/features/statipattrules @@ -0,0 +1,111 @@ +# -*-perl-*- +$description = "Test handling of static pattern rules."; + +$details = "\ +The makefile created in this test has three targets. The +filter command is used to get those target names ending in +.o and statically creates a compile command with the target +name and the target name with .c. It also does the same thing +for another target filtered with .elc and creates a command +to emacs a .el file"; + +&touch('bar.c', 'lose.c'); + +# TEST #0 +# ------- + +run_make_test(' +files = foo.elc bar.o lose.o + +$(filter %.o,$(files)): %.o: %.c ; @echo CC -c $(CFLAGS) $< -o $@ + +$(filter %.elc,$(files)): %.elc: %.el ; @echo emacs $< +', + '', + 'CC -c bar.c -o bar.o'); + +# TEST #1 +# ------- + +run_make_test(undef, 'lose.o', 'CC -c lose.c -o lose.o'); + + +# TEST #2 +# ------- +&touch("foo.el"); + +run_make_test(undef, 'foo.elc', 'emacs foo.el'); + +# Clean up after the first tests. +unlink('foo.el', 'bar.c', 'lose.c'); + + +# TEST #3 -- PR/1670: don't core dump on invalid static pattern rules +# ------- + +run_make_test(' +.DEFAULT: ; @echo $@ +foo: foo%: % %.x % % % y.% % ; @echo $@ +', + '', ".x\ny.\nfoo"); + + +# TEST #4 -- bug #12180: core dump on a stat pattern rule with an empty +# prerequisite list. +run_make_test(' +foo.x bar.x: %.x : ; @echo $@ + +', + '', 'foo.x'); + + +# TEST #5 -- bug #13881: double colon static pattern rule does not +# substitute %. +run_make_test(' +foo.bar:: %.bar: %.baz +foo.baz: ;@: +', + '', ''); + + +# TEST #6: make sure the second stem does not overwrite the first +# perprerequisite's stem (Savannah bug #16053). +# +run_make_test(' +all.foo.bar: %.foo.bar: %.one + +all.foo.bar: %.bar: %.two + +all.foo.bar: + @echo $* + @echo $^ + +.DEFAULT:;@: +', +'', +'all.foo +all.one all.foo.two'); + + +# TEST #7: make sure the second stem does not overwrite the first +# perprerequisite's stem when second expansion is enabled +# (Savannah bug #16053). +# +run_make_test(' +.SECONDEXPANSION: + +all.foo.bar: %.foo.bar: %.one $$*-one + +all.foo.bar: %.bar: %.two $$*-two + +all.foo.bar: + @echo $* + @echo $^ + +.DEFAULT:;@: +', +'', +'all.foo +all.one all-one all.foo.two all.foo-two'); + +1; diff --git a/tests/scripts/features/targetvars b/tests/scripts/features/targetvars new file mode 100644 index 0000000..ddd6c1f --- /dev/null +++ b/tests/scripts/features/targetvars @@ -0,0 +1,263 @@ +# -*-perl-*- +$description = "Test target-specific variable settings."; + +$details = "\ +Create a makefile containing various flavors of target-specific variable +values, override and non-override, and using various variable expansion +rules, semicolon interference, etc."; + +run_make_test(' +SHELL = /bin/sh +export FOO = foo +export BAR = bar +one: override FOO = one +one two: ; @echo $(FOO) $(BAR) +two: BAR = two +three: ; BAR=1000 + @echo $(FOO) $(BAR) +# Some things that shouldn not be target vars +funk : override +funk : override adelic +adelic override : ; echo $@ +# Test per-target recursive variables +four:FOO=x +four:VAR$(FOO)=ok +four: ; @echo "$(FOO) $(VAR$(FOO)) $(VAR) $(VARx)" +five:FOO=x +five six : VAR$(FOO)=good +five six: ;@echo "$(FOO) $(VAR$(FOO)) $(VAR) $(VARx) $(VARfoo)" +# Test per-target variable inheritance +seven: eight +seven eight: ; @echo $@: $(FOO) $(BAR) +seven: BAR = seven +seven: FOO = seven +eight: BAR = eight +# Test the export keyword with per-target variables +nine: ; @echo $(FOO) $(BAR) $$FOO $$BAR +nine: FOO = wallace +nine-a: export BAZ = baz +nine-a: ; @echo $$BAZ +# Test = escaping +EQ = = +ten: one$(EQ)two +ten: one $(EQ) two +ten one$(EQ)two $(EQ):;@echo $@ +.PHONY: one two three four five six seven eight nine ten $(EQ) one$(EQ)two +# Test target-specific vars with pattern/suffix rules +QVAR = qvar +RVAR = = +%.q : ; @echo $(QVAR) $(RVAR) +foo.q : RVAR += rvar +# Target-specific vars with multiple LHS pattern rules +%.r %.s %.t: ; @echo $(QVAR) $(RVAR) $(SVAR) $(TVAR) +foo.r : RVAR += rvar +foo.t : TVAR := $(QVAR) +', + "one two three", "one bar\nfoo two\nBAR=1000\nfoo bar\n"); + +# TEST #2 + +run_make_test(undef, "one two FOO=1 BAR=2", "one 2\n1 2\n"); + +# TEST #3 + +run_make_test(undef, "four", "x ok ok\n"); + +# TEST #4 + +run_make_test(undef, "seven", "eight: seven eight\nseven: seven seven\n"); + +# TEST #5 + +run_make_test(undef, "nine", "wallace bar wallace bar\n"); + +# TEST #5-a + +run_make_test(undef, "nine-a", "baz\n"); + +# TEST #6 + +run_make_test(undef, "ten", "one=two\none bar\n=\nfoo two\nten\n"); + +# TEST #6 + +run_make_test(undef, "foo.q bar.q", "qvar = rvar\nqvar =\n"); + +# TEST #7 + +run_make_test(undef, "foo.t bar.s", "qvar = qvar\nqvar =\n"); + + +# TEST #8 +# For PR/1378: Target-specific vars don't inherit correctly + +run_make_test(' +foo: FOO = foo +bar: BAR = bar +foo: bar +bar: baz +baz: ; @echo $(FOO) $(BAR) +', "", "foo bar\n"); + +# TEST #9 +# For PR/1380: Using += assignment in target-specific variables sometimes fails +# Also PR/1831 + +run_make_test(' +.PHONY: all one +all: FOO += baz +all: one; @echo $(FOO) + +FOO = bar + +one: FOO += biz +one: FOO += boz +one: ; @echo $(FOO) +', + '', "bar baz biz boz\nbar baz\n"); + +# Test #10 + +run_make_test(undef, 'one', "bar biz boz\n"); + +# Test #11 +# PR/1709: Test semicolons in target-specific variable values + +run_make_test(' +foo : FOO = ; ok +foo : ; @echo "$(FOO)" +', + '', "; ok\n"); + +# Test #12 +# PR/2020: More hassles with += target-specific vars. I _really_ think +# I nailed it this time :-/. + +run_make_test(' +.PHONY: a + +BLAH := foo +COMMAND = echo $(BLAH) + +a: ; @$(COMMAND) + +a: BLAH := bar +a: COMMAND += snafu $(BLAH) +', + '', "bar snafu bar\n"); + +# Test #13 +# Test double-colon rules with target-specific variable values + +run_make_test(' +W = bad +X = bad +foo: W = ok +foo:: ; @echo $(W) $(X) $(Y) $(Z) +foo:: ; @echo $(W) $(X) $(Y) $(Z) +foo: X = ok + +Y = foo +bar: foo +bar: Y = bar + +Z = nopat +ifdef PATTERN + fo% : Z = pat +endif +', + 'foo', "ok ok foo nopat\nok ok foo nopat\n"); + +# Test #14 +# Test double-colon rules with target-specific variable values and +# inheritance + +run_make_test(undef, 'bar', "ok ok bar nopat\nok ok bar nopat\n"); + +# Test #15 +# Test double-colon rules with pattern-specific variable values + +run_make_test(undef, 'foo PATTERN=yes', "ok ok foo pat\nok ok foo pat\n"); + +# Test #16 +# Test target-specific variables with very long command line +# (> make default buffer length) + +run_make_test(' +base_metals_fmd_reports.sun5 base_metals_fmd_reports CreateRealPositions CreateMarginFunds deals_changed_since : BUILD_OBJ=$(shell if [ -f "build_information.generate" ]; then echo "$(OBJ_DIR)/build_information.o"; else echo "no build information"; fi ) + +deals_changed_since: ; @echo $(BUILD_OBJ) +', + '', "no build information\n"); + +# TEST #17 + +# Test a merge of set_lists for files, where one list is much longer +# than the other. See Savannah bug #15757. + +mkdir('t1', 0777); +touch('t1/rules.mk'); + +run_make_test(' +VPATH = t1 +include rules.mk +.PHONY: all +all: foo.x +foo.x : rules.mk ; @echo MYVAR=$(MYVAR) FOOVAR=$(FOOVAR) ALLVAR=$(ALLVAR) +all: ALLVAR = xxx +foo.x: FOOVAR = bar +rules.mk : MYVAR = foo +.INTERMEDIATE: foo.x rules.mk +', + '-I t1', 'MYVAR= FOOVAR=bar ALLVAR=xxx'); + +rmfiles('t1/rules.mk'); +rmdir('t1'); + +# TEST #18 + +# Test appending to a simple variable containing a "$": avoid a +# double-expansion. See Savannah bug #15913. + +run_make_test(' +VAR := $$FOO +foo: VAR += BAR +foo: ; @echo '."'".'$(VAR)'."'".' +', + '', '$FOO BAR'); + +# TEST #19: Override with append variables + +run_make_test(' +a: override FOO += f1 +a: FOO += f2 +a: ; @echo "$(FOO)" +', + '', "f1\n"); + +run_make_test(undef, 'FOO=C', "C f1\n"); + +# TEST #20: Check for continuation after semicolons + +run_make_test(q! +a: A = 'hello; \ +world' +a: ; @echo $(A) +!, + '', "hello; world\n"); + +# TEST #19: Test define/endef variables as target-specific vars + +# run_make_test(' +# define b +# @echo global +# endef +# a: define b +# @echo local +# endef + +# a: ; $(b) +# ', +# '', "local\n"); + +1; diff --git a/tests/scripts/features/varnesting b/tests/scripts/features/varnesting new file mode 100644 index 0000000..15d5071 --- /dev/null +++ b/tests/scripts/features/varnesting @@ -0,0 +1,34 @@ +$description = "The following test creates a makefile to ..."; + +$details = ""; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "x = variable1\n" + ."variable2 := Hello\n" + ."y = \$(subst 1,2,\$(x))\n" + ."z = y\n" + ."a := \$(\$(\$(z)))\n" + ."all: \n" + ."\t\@echo \$(a)\n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&run_make_with_options($makefile,"",&get_logfile); + +# Create the answer to what should be produced by this Makefile +$answer = "Hello\n"; + +&compare_output($answer,&get_logfile(1)); + +1; + + + + + + diff --git a/tests/scripts/features/vpath b/tests/scripts/features/vpath new file mode 100644 index 0000000..a3aebd9 --- /dev/null +++ b/tests/scripts/features/vpath @@ -0,0 +1,81 @@ +# -*-perl-*- + +$description = "The following test creates a makefile to test the \n" + ."vpath directive which allows you to specify a search \n" + ."path for a particular class of filenames, those that\n" + ."match a particular pattern."; + +$details = "This tests the vpath directive by specifying search directories\n" + ."for one class of filenames with the form: vpath pattern directories" + ."\nIn this test, we specify the working directory for all files\n" + ."that end in c or h. We also test the variables $@ (which gives\n" + ."target name) and $^ (which is a list of all dependencies \n" + ."including the directories in which they were found). It also\n" + ."uses the function firstword used to extract just the first\n" + ."dependency from the entire list."; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "vpath %.c foo\n"; +print MAKEFILE "vpath %.c $workdir\n"; +print MAKEFILE "vpath %.h $workdir\n"; +print MAKEFILE "objects = main.o kbd.o commands.o display.o insert.o\n"; +print MAKEFILE "edit: \$(objects)\n"; +print MAKEFILE "\t\@echo cc -o \$@ \$^\n"; +print MAKEFILE "main.o : main.c defs.h\n"; +print MAKEFILE "\t\@echo cc -c \$(firstword \$^)\n"; +print MAKEFILE "kbd.o : kbd.c defs.h command.h\n"; +print MAKEFILE "\t\@echo cc -c kbd.c\n"; +print MAKEFILE "commands.o : command.c defs.h command.h\n"; +print MAKEFILE "\t\@echo cc -c commands.c\n"; +print MAKEFILE "display.o : display.c defs.h buffer.h\n"; +print MAKEFILE "\t\@echo cc -c display.c\n"; +print MAKEFILE "insert.o : insert.c defs.h buffer.h\n"; +print MAKEFILE "\t\@echo cc -c insert.c\n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + + +@files_to_touch = ("$workdir${pathsep}main.c","$workdir${pathsep}defs.h", + "$workdir${pathsep}kbd.c","$workdir${pathsep}command.h", + "$workdir${pathsep}commands.c","$workdir${pathsep}display.c", + "$workdir${pathsep}buffer.h","$workdir${pathsep}insert.c", + "$workdir${pathsep}command.c"); + +&touch(@files_to_touch); + +&run_make_with_options($makefile,"",&get_logfile); + +# Create the answer to what should be produced by this Makefile +$answer = "cc -c $workdir${pathsep}main.c\ncc -c kbd.c\ncc -c commands.c\n" + ."cc -c display.c\n" + ."cc -c insert.c\ncc -o edit main.o kbd.o commands.o display.o " + ."insert.o\n"; + +if (&compare_output($answer,&get_logfile(1))) +{ + unlink @files_to_touch; +} + +# TEST 2: after vpath lookup ensure we don't get incorrect circular dependency +# warnings due to change of struct file ptr. Savannah bug #13529. + +mkdir('vpath-d', 0777); + +run_make_test(q! +vpath %.te vpath-d/ +.SECONDARY: +default: vpath-d/a vpath-d/b +vpath-d/a: fail.te +vpath-d/b : fail.te +vpath-d/fail.te: +!, + '', "#MAKE#: Nothing to be done for `default'.\n"); + +rmdir('vpath-d'); + +1; diff --git a/tests/scripts/features/vpath2 b/tests/scripts/features/vpath2 new file mode 100644 index 0000000..7e970a7 --- /dev/null +++ b/tests/scripts/features/vpath2 @@ -0,0 +1,45 @@ +$description = "This is part 2 in a series to test the vpath directive\n" + ."It tests the three forms of the directive:\n" + ." vpath pattern directive\n" + ." vpath pattern (clears path associated with pattern)\n" + ." vpath (clears all paths specified with vpath)\n"; + +$details = "This test simply adds many search paths using various vpath\n" + ."directive forms and clears them afterwards. It has a simple\n" + ."rule to print a message at the end to confirm that the makefile\n" + ."ran with no errors.\n"; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "VPATH = $workdir:$sourcedir\n"; +print MAKEFILE "vpath %.c foo\n"; +print MAKEFILE "vpath %.c $workdir\n"; +print MAKEFILE "vpath %.c $sourcedir\n"; +print MAKEFILE "vpath %.h $workdir\n"; +print MAKEFILE "vpath %.c\n"; +print MAKEFILE "vpath\n"; +print MAKEFILE "all:\n"; +print MAKEFILE "\t\@echo ALL IS WELL\n"; +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&run_make_with_options($makefile,"",&get_logfile); + +# Create the answer to what should be produced by this Makefile +$answer = "ALL IS WELL\n"; + +&compare_output($answer,&get_logfile(1)); + +1; + + + + + + + + + diff --git a/tests/scripts/features/vpath3 b/tests/scripts/features/vpath3 new file mode 100644 index 0000000..978c5ee --- /dev/null +++ b/tests/scripts/features/vpath3 @@ -0,0 +1,50 @@ +# -*-perl-*- + +$description = "Test the interaction of the -lfoo feature and vpath"; +$details = ""; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "vpath %.a a1\n"; +print MAKEFILE "vpath %.so b1\n"; +print MAKEFILE "vpath % a2 b2\n"; +print MAKEFILE "vpath % b3\n"; +print MAKEFILE "all: -l1 -l2 -l3; \@echo \$^\n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +mkdir("a1", 0777); +mkdir("b1", 0777); +mkdir("a2", 0777); +mkdir("b2", 0777); +mkdir("b3", 0777); + +@files_to_touch = ("a1${pathsep}lib1.a", + "b1${pathsep}lib1.so", + "a2${pathsep}lib2.a", + "b2${pathsep}lib2.so", + "lib3.a", + "b3${pathsep}lib3.so"); + +&touch(@files_to_touch); + +&run_make_with_options($makefile,"",&get_logfile); + +# Create the answer to what should be produced by this Makefile +$answer = "a1${pathsep}lib1.a a2${pathsep}lib2.a lib3.a\n"; + +if (&compare_output($answer,&get_logfile(1))) +{ + unlink @files_to_touch; + rmdir("a1"); + rmdir("b1"); + rmdir("a2"); + rmdir("b2"); + rmdir("b3"); +} + +1; diff --git a/tests/scripts/features/vpathgpath b/tests/scripts/features/vpathgpath new file mode 100644 index 0000000..f7683f5 --- /dev/null +++ b/tests/scripts/features/vpathgpath @@ -0,0 +1,66 @@ +# -*-perl-*- +$description = "Tests VPATH+/GPATH functionality."; + +$details = ""; + +$VP = "$workdir$pathsep"; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "VPATH = $VP\n"; + +print MAKEFILE <<'EOMAKE'; + +GPATH = $(VPATH) + +.SUFFIXES: .a .b .c .d +.PHONY: general rename notarget intermediate + +%.a: +%.b: +%.c: +%.d: + +%.a : %.b ; cat $^ > $@ +%.b : %.c ; cat $^ > $@ +%.c :: %.d ; cat $^ > $@ + +# General testing info: + +general: foo.b +foo.b: foo.c bar.c + +EOMAKE + +close(MAKEFILE); + +@touchedfiles = (); + +$off = -500; + +sub touchfiles { + foreach (@_) { + ($f = $_) =~ s,VP/,$VP,g; + &utouch($off, $f); + $off += 10; + push(@touchedfiles, $f); + } +} + +# Run the general-case test + +&touchfiles("VP/foo.d", "VP/bar.d", "VP/foo.c", "VP/bar.c", "foo.b", "bar.d"); + +&run_make_with_options($makefile,"general",&get_logfile()); + +push(@touchedfiles, "bar.c"); + +$answer = "$make_name: Nothing to be done for `general'.\n"; + +&compare_output($answer,&get_logfile(1)); + +unlink(@touchedfiles) unless $keep; + +1; diff --git a/tests/scripts/features/vpathplus b/tests/scripts/features/vpathplus new file mode 100644 index 0000000..a37fbed --- /dev/null +++ b/tests/scripts/features/vpathplus @@ -0,0 +1,128 @@ +# -*-perl-*- +$description = "Tests the new VPATH+ functionality added in 3.76."; + +$details = ""; + +$VP = "$workdir$pathsep"; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "VPATH = $VP\n"; + +print MAKEFILE <<'EOMAKE'; + +SHELL = /bin/sh + +.SUFFIXES: .a .b .c .d +.PHONY: general rename notarget intermediate + +%.a: +%.b: +%.c: +%.d: + +%.a : %.b + cat $^ > $@ +%.b : %.c + cat $^ > $@ 2>/dev/null || exit 1 +%.c :: %.d + cat $^ > $@ + +# General testing info: + +general: foo.b +foo.b: foo.c bar.c + +# Rename testing info: + +rename: $(VPATH)/foo.c foo.d + +# Target not made testing info: + +notarget: notarget.b +notarget.c: notarget.d + -@echo "not creating $@ from $^" + +# Intermediate files: + +intermediate: inter.a + +EOMAKE + +close(MAKEFILE); + +@touchedfiles = (); + +$off = -500; + +sub touchfiles { + foreach (@_) { + &utouch($off, $_); + $off += 10; + push(@touchedfiles, $_); + } +} + +# Run the general-case test + +&touchfiles("$VP/foo.d", "$VP/bar.d", "$VP/foo.c", "$VP/bar.c", "foo.b", "bar.d"); + +&run_make_with_options($makefile,"general",&get_logfile); + +push(@touchedfiles, "bar.c"); + +$answer = "cat bar.d > bar.c +cat ${VP}foo.c bar.c > foo.b 2>/dev/null || exit 1 +"; +&compare_output($answer,&get_logfile(1)); + +# Test rules that don't make the target correctly + +&touchfiles("$VP/notarget.c", "notarget.b", "notarget.d"); + +&run_make_with_options($makefile,"notarget",&get_logfile,512); + +$answer = "not creating notarget.c from notarget.d +cat notarget.c > notarget.b 2>/dev/null || exit 1 +$make_name: *** [notarget.b] Error 1 +"; + +&compare_output($answer,&get_logfile(1)); + +# Test intermediate file handling (part 1) + +&touchfiles("$VP/inter.d"); + +&run_make_with_options($makefile,"intermediate",&get_logfile); + +push(@touchedfiles, "inter.a", "inter.b"); + +$answer = "cat ${VP}inter.d > inter.c +cat inter.c > inter.b 2>/dev/null || exit 1 +cat inter.b > inter.a +rm inter.b inter.c +"; +&compare_output($answer,&get_logfile(1)); + +# Test intermediate file handling (part 2) + +&utouch(-20, "inter.a"); +&utouch(-10, "$VP/inter.b"); +&touch("$VP/inter.d"); + +push(@touchedfiles, "$VP/inter.b", "$VP/inter.d"); + +&run_make_with_options($makefile,"intermediate",&get_logfile); + +$answer = "cat ${VP}inter.d > inter.c +cat inter.c > inter.b 2>/dev/null || exit 1 +cat inter.b > inter.a +rm inter.c +"; +&compare_output($answer,&get_logfile(1)); + +unlink @touchedfiles unless $keep; + +1; diff --git a/tests/scripts/functions/abspath b/tests/scripts/functions/abspath new file mode 100644 index 0000000..84c30ab --- /dev/null +++ b/tests/scripts/functions/abspath @@ -0,0 +1,81 @@ +# -*-perl-*- +$description = "Test the abspath functions."; + +$details = ""; + +run_make_test(' +ifneq ($(realpath $(abspath .)),$(CURDIR)) + $(warning .: abs="$(abspath .)" real="$(realpath $(abspath .))" curdir="$(CURDIR)") +endif + +ifneq ($(realpath $(abspath ./)),$(CURDIR)) + $(warning ./: abs="$(abspath ./)" real="$(realpath $(abspath ./))" curdir="$(CURDIR)") +endif + +ifneq ($(realpath $(abspath .///)),$(CURDIR)) + $(warning .///: abs="$(abspath .///)" real="$(realpath $(abspath .///))" curdir="$(CURDIR)") +endif + +ifneq ($(abspath /),/) + $(warning /: abspath="$(abspath /)") +endif + +ifneq ($(abspath ///),/) + $(warning ///: abspath="$(abspath ///)") +endif + +ifneq ($(abspath /.),/) + $(warning /.: abspath="$(abspath /.)") +endif + +ifneq ($(abspath ///.),/) + $(warning ///.: abspath="$(abspath ///.)") +endif + +ifneq ($(abspath /./),/) + $(warning /./: abspath="$(abspath /./)") +endif + +ifneq ($(abspath /.///),/) + $(warning /.///: abspath="$(abspath /.///)") +endif + +ifneq ($(abspath /..),/) + $(warning /..: abspath="$(abspath /..)") +endif + +ifneq ($(abspath ///..),/) + $(warning ///..: abspath="$(abspath ///..)") +endif + +ifneq ($(abspath /../),/) + $(warning /../: abspath="$(abspath /../)") +endif + +ifneq ($(abspath /..///),/) + $(warning /..///: abspath="$(abspath /..///)") +endif + + +ifneq ($(abspath /foo/bar/..),/foo) + $(warning /foo/bar/..: abspath="$(abspath /foo/bar/..)") +endif + +ifneq ($(abspath /foo/bar/../../../baz),/baz) + $(warning /foo/bar/../../../baz: abspath="$(abspath /foo/bar/../../../baz)") +endif + +ifneq ($(abspath /foo/bar/../ /..),/foo /) + $(warning /foo/bar/../ /..: abspath="$(abspath /foo/bar/../ /..)") +endif + + +.PHONY: all +all: ; @: +', +'', +''); + + +# This tells the test driver that the perl test script executed properly. +1; diff --git a/tests/scripts/functions/addprefix b/tests/scripts/functions/addprefix new file mode 100644 index 0000000..1845552 --- /dev/null +++ b/tests/scripts/functions/addprefix @@ -0,0 +1,44 @@ +$description = "The following test creates a makefile to test the addprefix " + ."function."; + +$details = ""; + +# IF YOU NEED >1 MAKEFILE FOR THIS TEST, USE &get_tmpfile; TO GET +# THE NAME OF THE MAKEFILE. THIS INSURES CONSISTENCY AND KEEPS TRACK OF +# HOW MANY MAKEFILES EXIST FOR EASY DELETION AT THE END. +# EXAMPLE: $makefile2 = &get_tmpfile; + + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "string := \$(addprefix src${pathsep},a.b.z.foo hacks) \n" + ."all: \n" + ."\t\@echo \$(string) \n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&run_make_with_options($makefile,"",&get_logfile,0); + +# Create the answer to what should be produced by this Makefile +$answer = "src${pathsep}a.b.z.foo src${pathsep}hacks\n"; + +# COMPARE RESULTS + +# In this call to compare output, you should use the call &get_logfile(1) +# to send the name of the last logfile created. You may also use +# the special call &get_logfile(1) which returns the same as &get_logfile(1). + +&compare_output($answer,&get_logfile(1)); + +# This tells the test driver that the perl test script executed properly. +1; + + + + + + diff --git a/tests/scripts/functions/addsuffix b/tests/scripts/functions/addsuffix new file mode 100644 index 0000000..da4fbb7 --- /dev/null +++ b/tests/scripts/functions/addsuffix @@ -0,0 +1,36 @@ +# -*-perl-*- +$description = "Test the addsuffix function."; + +$details = ""; + + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE <<EOMAKE; +string := \$(addsuffix .c,src${pathsep}a.b.z.foo hacks) +one: ; \@echo \$(string) + +two: ; \@echo \$(addsuffix foo,) +EOMAKE + +close(MAKEFILE); + + +# TEST 0 + +&run_make_with_options($makefile, "", &get_logfile); +$answer = "src${pathsep}a.b.z.foo.c hacks.c\n"; +&compare_output($answer,&get_logfile(1)); + + +# TEST 1 + +&run_make_with_options($makefile, "two", &get_logfile); +$answer = "\n"; +&compare_output($answer,&get_logfile(1)); + + +# This tells the test driver that the perl test script executed properly. +1; diff --git a/tests/scripts/functions/andor b/tests/scripts/functions/andor new file mode 100644 index 0000000..62e0c2e --- /dev/null +++ b/tests/scripts/functions/andor @@ -0,0 +1,50 @@ +# -*-perl-*- +$description = "Test the and & or functions.\n"; + +$details = "Try various uses of and & or to ensure they all give the correct +results.\n"; + +# TEST #0 +# For $(and ...), it will either be empty or the last value +run_make_test(' +NEQ = $(subst $1,,$2) +f = +t = true + +all: + @echo 1 $(and ,$t) + @echo 2 $(and $t) + @echo 3 $(and $t,) + @echo 4 $(and z,true,$f,false) + @echo 5 $(and $t,$f,$(info bad short-circuit)) + @echo 6 $(and $(call NEQ,a,b),true) + @echo 7 $(and $(call NEQ,a,a),true) + @echo 8 $(and z,true,fal,se) hi + @echo 9 $(and ,true,fal,se)there + @echo 10 $(and $(e) ,$t)', + '', + "1\n2 true\n3\n4\n5\n6 true\n7\n8 se hi\n9 there\n10\n"); + +# TEST #1 +# For $(or ...), it will either be empty or the first true value +run_make_test(' +NEQ = $(subst $1,,$2) +f = +t = true + +all: + @echo 1 $(or , ) + @echo 2 $(or $t) + @echo 3 $(or ,$t) + @echo 4 $(or z,true,$f,false) + @echo 5 $(or $t,$(info bad short-circuit)) + @echo 6 $(or $(info short-circuit),$t) + @echo 7 $(or $(call NEQ,a,b),true) + @echo 8 $(or $(call NEQ,a,a),true) + @echo 9 $(or z,true,fal,se) hi + @echo 10 $(or ,true,fal,se)there + @echo 11 $(or $(e) ,$f)', + '', + "short-circuit\n1\n2 true\n3 true\n4 z\n5 true\n6 true\n7 b\n8 true\n9 z hi\n10 truethere\n11\n"); + +1; diff --git a/tests/scripts/functions/basename b/tests/scripts/functions/basename new file mode 100644 index 0000000..08f2ea5 --- /dev/null +++ b/tests/scripts/functions/basename @@ -0,0 +1,44 @@ +$description = "The following test creates a makefile to test the suffix " + ."function."; + +$details = ""; + +# IF YOU NEED >1 MAKEFILE FOR THIS TEST, USE &get_tmpfile; TO GET +# THE NAME OF THE MAKEFILE. THIS INSURES CONSISTENCY AND KEEPS TRACK OF +# HOW MANY MAKEFILES EXIST FOR EASY DELETION AT THE END. +# EXAMPLE: $makefile2 = &get_tmpfile; + + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "string := \$(basename src${pathsep}a.b.z.foo.c src${pathsep}hacks src.bar${pathsep}a.b.z.foo.c src.bar${pathsep}hacks hacks) \n" + ."all: \n" + ."\t\@echo \$(string) \n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&run_make_with_options($makefile,"",&get_logfile,0); + +# Create the answer to what should be produced by this Makefile +$answer = "src${pathsep}a.b.z.foo src${pathsep}hacks src.bar${pathsep}a.b.z.foo src.bar${pathsep}hacks hacks\n"; + +# COMPARE RESULTS + +# In this call to compare output, you should use the call &get_logfile(1) +# to send the name of the last logfile created. You may also use +# the special call &get_logfile(1) which returns the same as &get_logfile(1). + +&compare_output($answer,&get_logfile(1)); + +# This tells the test driver that the perl test script executed properly. +1; + + + + + + diff --git a/tests/scripts/functions/call b/tests/scripts/functions/call new file mode 100644 index 0000000..f3c5470 --- /dev/null +++ b/tests/scripts/functions/call @@ -0,0 +1,99 @@ +# -*-perl-*- +$description = "Test the call function.\n"; + +$details = "Try various uses of call and ensure they all give the correct +results.\n"; + +open(MAKEFILE, "> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE <<'EOMAKE'; +# Simple, just reverse two things +# +reverse = $2 $1 + +# A complex `map' function, using recursive `call'. +# +map = $(foreach a,$2,$(call $1,$a)) + +# Test using a builtin; this is silly as it's simpler to do without call +# +my-notdir = $(call notdir,$(1)) + +# Test using non-expanded builtins +# +my-foreach = $(foreach $(1),$(2),$(3)) +my-if = $(if $(1),$(2),$(3)) + +# Test recursive invocations of call with different arguments +# +one = $(1) $(2) $(3) +two = $(call one,$(1),foo,$(2)) + +# Test recursion on the user-defined function. As a special case make +# won't error due to this. +# Implement transitive closure using $(call ...) +# +DEP_foo = bar baz quux +DEP_baz = quux blarp +rest = $(wordlist 2,$(words ${1}),${1}) +tclose = $(if $1,$(firstword $1) \ + $(call tclose,$(sort ${DEP_$(firstword $1)} $(call rest,$1)))) + +all: ; @echo '$(call reverse,bar,foo)'; \ + echo '$(call map,origin,MAKE reverse map)'; \ + echo '$(call my-notdir,a/b c/d e/f)'; \ + echo '$(call my-foreach)'; \ + echo '$(call my-foreach,a,,,)'; \ + echo '$(call my-if,a,b,c)'; \ + echo '$(call two,bar,baz)'; \ + echo '$(call tclose,foo)' + + + +EOMAKE + +# These won't work until/unless PR/1527 is resolved. +# echo '$(call my-foreach,a,x y z,$(a)$(a))'; \ +# echo '$(call my-if,,$(warning don't print this),ok)' +# +# $answer = "xx yy zz\nok\n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&run_make_with_options($makefile, "", &get_logfile); +$answer = "foo bar\ndefault file file\nb d f\n\n\nb\nbar foo baz\nfoo bar baz blarp quux \n"; +&compare_output($answer, &get_logfile(1)); + + +# TEST eclipsing of arguments when invoking sub-calls + +$makefile2 = &get_tmpfile; + +open(MAKEFILE,"> $makefile2"); + +print MAKEFILE <<'EOF'; + +all = $1 $2 $3 $4 $5 $6 $7 $8 $9 + +level1 = $(call all,$1,$2,$3,$4,$5) +level2 = $(call level1,$1,$2,$3) +level3 = $(call level2,$1,$2,$3,$4,$5) + +all: + @echo $(call all,1,2,3,4,5,6,7,8,9,10,11) + @echo $(call level1,1,2,3,4,5,6,7,8) + @echo $(call level2,1,2,3,4,5,6,7,8) + @echo $(call level3,1,2,3,4,5,6,7,8) +EOF + +close(MAKEFILE); + +&run_make_with_options($makefile2, "", &get_logfile); +$answer = "1 2 3 4 5 6 7 8 9\n1 2 3 4 5\n1 2 3\n1 2 3\n"; +&compare_output($answer,&get_logfile(1)); + +1; diff --git a/tests/scripts/functions/dir b/tests/scripts/functions/dir new file mode 100644 index 0000000..f48fb8c --- /dev/null +++ b/tests/scripts/functions/dir @@ -0,0 +1,44 @@ +$description = "The following test creates a makefile to test the dir " + ."function."; + +$details = ""; + +# IF YOU NEED >1 MAKEFILE FOR THIS TEST, USE &get_tmpfile; TO GET +# THE NAME OF THE MAKEFILE. THIS INSURES CONSISTENCY AND KEEPS TRACK OF +# HOW MANY MAKEFILES EXIST FOR EASY DELETION AT THE END. +# EXAMPLE: $makefile2 = &get_tmpfile; + + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "string := \$(dir src${pathsep}foo.c hacks) \n" + ."all: \n" + ."\t\@echo \$(string) \n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&run_make_with_options($makefile,"",&get_logfile,0); + +# Create the answer to what should be produced by this Makefile +$answer = "src${pathsep} .${pathsep}\n"; + +# COMPARE RESULTS + +# In this call to compare output, you should use the call &get_logfile(1) +# to send the name of the last logfile created. You may also use +# the special call &get_logfile(1) which returns the same as &get_logfile(1). + +&compare_output($answer,&get_logfile(1)); + +# This tells the test driver that the perl test script executed properly. +1; + + + + + + diff --git a/tests/scripts/functions/error b/tests/scripts/functions/error new file mode 100644 index 0000000..0d61177 --- /dev/null +++ b/tests/scripts/functions/error @@ -0,0 +1,73 @@ +# -*-Perl-*- + +$description = "\ +The following test creates a makefile to test the error function."; + +$details = ""; + +open(MAKEFILE,"> $makefile"); + +print MAKEFILE 'err = $(error Error found!) + +ifdef ERROR1 +$(error error is $(ERROR1)) +endif + +ifdef ERROR2 +$(error error is $(ERROR2)) +endif + +ifdef ERROR3 +all: some; @echo $(error error is $(ERROR3)) +endif + +ifdef ERROR4 +all: some; @echo error is $(ERROR4) + @echo $(error error is $(ERROR4)) +endif + +some: ; @echo Some stuff + +testvar: ; @: $(err) +'; + +close(MAKEFILE); + +# Test #1 + +&run_make_with_options($makefile, "ERROR1=yes", &get_logfile, 512); +$answer = "$makefile:4: *** error is yes. Stop.\n"; +&compare_output($answer,&get_logfile(1)); + +# Test #2 + +&run_make_with_options($makefile, "ERROR2=no", &get_logfile, 512); +$answer = "$makefile:8: *** error is no. Stop.\n"; +&compare_output($answer,&get_logfile(1)); + +# Test #3 + +&run_make_with_options($makefile, "ERROR3=maybe", &get_logfile, 512); +$answer = "Some stuff\n$makefile:12: *** error is maybe. Stop.\n"; +&compare_output($answer,&get_logfile(1)); + +# Test #4 + +&run_make_with_options($makefile, "ERROR4=definitely", &get_logfile, 512); +$answer = "Some stuff\n$makefile:16: *** error is definitely. Stop.\n"; +&compare_output($answer,&get_logfile(1)); + +# Test #5 + +&run_make_with_options($makefile, "testvar", &get_logfile, 512); +$answer = "$makefile:22: *** Error found!. Stop.\n"; +&compare_output($answer,&get_logfile(1)); + +# This tells the test driver that the perl test script executed properly. +1; + + + + + + diff --git a/tests/scripts/functions/eval b/tests/scripts/functions/eval new file mode 100644 index 0000000..90513bd --- /dev/null +++ b/tests/scripts/functions/eval @@ -0,0 +1,169 @@ +# -*-perl-*- + +$description = "Test the eval function."; + +$details = "This is a test of the eval function in GNU make. +This function will evaluate inline makefile syntax and incorporate the +results into its internal database.\n"; + +open(MAKEFILE,"> $makefile"); + +print MAKEFILE <<'EOF'; +define Y + all:: ; @echo $AA + A = B +endef + +X = $(eval $(value Y)) + +$(eval $(shell echo A = A)) +$(eval $(Y)) +$(eval A = C) +$(eval $(X)) +EOF + +close(MAKEFILE); + +&run_make_with_options($makefile, "", &get_logfile); + +# Create the answer to what should be produced by this Makefile +$answer = "AA\nBA\n"; + +&compare_output($answer,&get_logfile(1)); + +# Test to make sure defining variables when we have extra scope pushed works +# as expected. + +$makefile2 = &get_tmpfile; + +open(MAKEFILE,"> $makefile2"); + +print MAKEFILE <<'EOF'; +VARS = A B + +VARSET = $(1) = $(2) + +$(foreach v,$(VARS),$(eval $(call VARSET,$v,$v))) + +all: ; @echo A = $(A) B = $(B) +EOF + +close(MAKEFILE); + +&run_make_with_options($makefile2, "", &get_logfile); + +# Create the answer to what should be produced by this Makefile +$answer = "A = A B = B\n"; + +&compare_output($answer,&get_logfile(1)); + +# Test to make sure eval'ing inside conditionals works properly + +$makefile3 = &get_tmpfile; + +open(MAKEFILE,"> $makefile3"); + +print MAKEFILE <<'EOF'; +FOO = foo + +all:: ; @echo it + +define Y + all:: ; @echo worked +endef + +ifdef BAR +$(eval $(Y)) +endif + +EOF + +close(MAKEFILE); + +&run_make_with_options($makefile3, "", &get_logfile); +$answer = "it\n"; +&compare_output($answer,&get_logfile(1)); + +&run_make_with_options($makefile3, "BAR=1", &get_logfile); +$answer = "it\nworked\n"; +&compare_output($answer,&get_logfile(1)); + + +# TEST very recursive invocation of eval + +$makefile3 = &get_tmpfile; + +open(MAKEFILE,"> $makefile3"); + +print MAKEFILE <<'EOF'; +..9 := 0 1 2 3 4 5 6 7 8 9 +rev=$(eval res:=)$(foreach word,$1,$(eval res:=${word} ${res}))${res} +a:=$(call rev,${..9}) +all: ; @echo '[$(a)]' + +EOF + +close(MAKEFILE); + +&run_make_with_options($makefile3, "", &get_logfile); +$answer = "[ 9 8 7 6 5 4 3 2 1 0 ]\n"; +&compare_output($answer,&get_logfile(1)); + + +# TEST eval with no filename context. +# The trick here is that because EVAR is taken from the environment, it must +# be evaluated before every command is invoked. Make sure that works, when +# we have no file context for reading_file (bug # 6195) + +$makefile4 = &get_tmpfile; + +open(MAKEFILE,"> $makefile4"); + +print MAKEFILE <<'EOF'; +EVAR = $(eval FOBAR = 1) +all: ; @echo "OK" + +EOF + +close(MAKEFILE); + +$extraENV{EVAR} = '1'; +&run_make_with_options($makefile4, "", &get_logfile); +$answer = "OK\n"; +&compare_output($answer,&get_logfile(1)); + + +# Clean out previous information to allow new run_make_test() interface. +# If we ever convert all the above to run_make_test() we can remove this line. +$makefile = undef; + +# Test handling of backslashes in strings to be evaled. + +run_make_test(' +define FOO +all: ; @echo hello \ +world +endef +$(eval $(FOO)) +', '', 'hello world'); + +run_make_test(' +define FOO +all: ; @echo '."'".'he\llo'."'".' + @echo world +endef +$(eval $(FOO)) +', '', 'he\llo +world'); + + +# We don't allow new target/prerequisite relationships to be defined within a +# command script, because these are evaluated after snap_deps() and that +# causes lots of problems (like core dumps!) +# See Savannah bug # 12124. + +run_make_test('deps: ; $(eval deps: foo)', '', + '#MAKEFILE#:1: *** prerequisites cannot be defined in recipes. Stop.', + 512); + +1; diff --git a/tests/scripts/functions/filter-out b/tests/scripts/functions/filter-out new file mode 100644 index 0000000..6c8b27a --- /dev/null +++ b/tests/scripts/functions/filter-out @@ -0,0 +1,28 @@ +# -*-perl-*- + +$description = "Test the filter-out function."; + +$details = "The makefile created in this test has two variables. The +filter-out function is first used to discard names ending in +.o with a single simple pattern. The second filter-out function +augments the simple pattern with three literal names, which are +also added to the text argument. This tests an internal hash table +which is only used if there are multiple literals present in both +the pattern and text arguments. The result of both filter-out +functions is the same single .elc name.\n"; + +open(MAKEFILE,"> $makefile"); + +print MAKEFILE <<'EOF'; +files1 := $(filter-out %.o, foo.elc bar.o lose.o) +files2 := $(filter-out foo.i bar.i lose.i %.o, foo.i bar.i lose.i foo.elc bar.o lose.o) +all: ; @echo $(files1) $(files2) +EOF + +close(MAKEFILE); + +&run_make_with_options($makefile, "", &get_logfile, 0); +$answer = "foo.elc foo.elc\n"; +&compare_output($answer,&get_logfile(1)); + +1; diff --git a/tests/scripts/functions/findstring b/tests/scripts/functions/findstring new file mode 100644 index 0000000..48abede --- /dev/null +++ b/tests/scripts/functions/findstring @@ -0,0 +1,47 @@ +$description = "The following test creates a makefile to test the findstring " + ."function."; + +$details = ""; + +# IF YOU NEED >1 MAKEFILE FOR THIS TEST, USE &get_tmpfile; TO GET +# THE NAME OF THE MAKEFILE. THIS INSURES CONSISTENCY AND KEEPS TRACK OF +# HOW MANY MAKEFILES EXIST FOR EASY DELETION AT THE END. +# EXAMPLE: $makefile2 = &get_tmpfile; + + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "string := \$(findstring port, reporter)\n" + ."all: \n" + ."\t\@echo \$(string) \n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&run_make_with_options($makefile, + "", + &get_logfile, + 0); + +# Create the answer to what should be produced by this Makefile +$answer = "port\n"; + +# COMPARE RESULTS + +# In this call to compare output, you should use the call &get_logfile(1) +# to send the name of the last logfile created. You may also use +# the special call &get_logfile(1) which returns the same as &get_logfile(1). + +&compare_output($answer,&get_logfile(1)); + +# This tells the test driver that the perl test script executed properly. +1; + + + + + + diff --git a/tests/scripts/functions/flavor b/tests/scripts/functions/flavor new file mode 100644 index 0000000..80d6be7 --- /dev/null +++ b/tests/scripts/functions/flavor @@ -0,0 +1,44 @@ +# -*-perl-*- +$description = "Test the flavor function."; + +$details = ""; + + +# Test #1: Test general logic. +# +run_make_test(' +s := s +r = r + +$(info u $(flavor u)) +$(info s $(flavor s)) +$(info r $(flavor r)) + +ra += ra +rc ?= rc + +$(info ra $(flavor ra)) +$(info rc $(flavor rc)) + +s += s +r += r + +$(info s $(flavor s)) +$(info r $(flavor r)) + + +.PHONY: all +all:;@: +', +'', +'u undefined +s simple +r recursive +ra recursive +rc recursive +s simple +r recursive'); + + +# This tells the test driver that the perl test script executed properly. +1; diff --git a/tests/scripts/functions/foreach b/tests/scripts/functions/foreach new file mode 100644 index 0000000..82e99d7 --- /dev/null +++ b/tests/scripts/functions/foreach @@ -0,0 +1,77 @@ +# -*-perl-*- +# $Id: foreach,v 1.5 2006/03/10 02:20:46 psmith Exp $ + +$description = "Test the foreach function."; + +$details = "This is a test of the foreach function in gnu make. +This function starts with a space separated list of +names and a variable. Each name in the list is subsituted +into the variable and the given text evaluated. The general +form of the command is $(foreach var,$list,$text). Several +types of foreach loops are tested\n"; + + +# TEST 0 + +# Set an environment variable that we can test in the makefile. +$extraENV{FOOFOO} = 'foo foo'; + +run_make_test("space = ' '".' +null := +auto_var = udef space CC null FOOFOO MAKE foo CFLAGS WHITE @ < +foo = bletch null @ garf +av = $(foreach var, $(auto_var), $(origin $(var)) ) +override WHITE := BLACK +for_var = $(addsuffix .c,foo $(null) $(foo) $(space) $(av) ) +fe = $(foreach var2, $(for_var),$(subst .c,.o, $(var2) ) ) +all: auto for2 +auto : ; @echo $(av) +for2: ; @echo $(fe)', + '-e WHITE=WHITE CFLAGS=', + "undefined file default file environment default file command line override automatic automatic +foo.o bletch.o null.o @.o garf.o .o .o undefined.o file.o default.o file.o environment.o default.o file.o command.o line.o override.o automatic.o automatic.o"); + +delete $extraENV{FOOFOO}; + +# TEST 1: Test that foreach variables take precedence over global +# variables in a global scope (like inside an eval). Tests bug #11913 + +run_make_test(' +.PHONY: all target +all: target + +x := BAD + +define mktarget +target: x := $(x) +target: ; @echo "$(x)" +endef + +x := GLOBAL + +$(foreach x,FOREACH,$(eval $(value mktarget)))', + '', + 'FOREACH'); + + +# TEST 2: Check some error conditions. + +run_make_test(' +x = $(foreach ) +y = $x + +all: ; @echo $y', + '', + "#MAKEFILE#:2: *** insufficient number of arguments (1) to function `foreach'. Stop.", + 512); + +run_make_test(' +x = $(foreach ) +y := $x + +all: ; @echo $y', + '', + "#MAKEFILE#:2: *** insufficient number of arguments (1) to function `foreach'. Stop.", + 512); + +1; diff --git a/tests/scripts/functions/if b/tests/scripts/functions/if new file mode 100644 index 0000000..8604e4f --- /dev/null +++ b/tests/scripts/functions/if @@ -0,0 +1,33 @@ +# -*-perl-*- +$description = "Test the if function.\n"; + +$details = "Try various uses of if and ensure they all give the correct +results.\n"; + +open(MAKEFILE, "> $makefile"); + +print MAKEFILE <<EOMAKE; +NEQ = \$(subst \$1,,\$2) +e = + +all: +\t\@echo 1 \$(if ,true,false) +\t\@echo 2 \$(if ,true,) +\t\@echo 3 \$(if ,true) +\t\@echo 4 \$(if z,true,false) +\t\@echo 5 \$(if z,true,\$(shell echo hi)) +\t\@echo 6 \$(if ,\$(shell echo hi),false) +\t\@echo 7 \$(if \$(call NEQ,a,b),true,false) +\t\@echo 8 \$(if \$(call NEQ,a,a),true,false) +\t\@echo 9 \$(if z,true,fal,se) hi +\t\@echo 10 \$(if ,true,fal,se)there +\t\@echo 11 \$(if \$(e) ,true,false) +EOMAKE + +close(MAKEFILE); + +&run_make_with_options($makefile, "", &get_logfile); +$answer = "1 false\n2\n3\n4 true\n5 true\n6 false\n7 true\n8 false\n9 true hi\n10 fal,sethere\n11 false\n"; +&compare_output($answer, &get_logfile(1)); + +1; diff --git a/tests/scripts/functions/join b/tests/scripts/functions/join new file mode 100644 index 0000000..302c307 --- /dev/null +++ b/tests/scripts/functions/join @@ -0,0 +1,44 @@ +$description = "The following test creates a makefile to test the join " + ."function."; + +$details = ""; + +# IF YOU NEED >1 MAKEFILE FOR THIS TEST, USE &get_tmpfile; TO GET +# THE NAME OF THE MAKEFILE. THIS INSURES CONSISTENCY AND KEEPS TRACK OF +# HOW MANY MAKEFILES EXIST FOR EASY DELETION AT THE END. +# EXAMPLE: $makefile2 = &get_tmpfile; + + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "string := \$(join a b c,foo hacks .pl1) \n" + ."all: \n" + ."\t\@echo \$(string) \n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&run_make_with_options($makefile,"",&get_logfile,0); + +# Create the answer to what should be produced by this Makefile +$answer = "afoo bhacks c.pl1\n"; + +# COMPARE RESULTS + +# In this call to compare output, you should use the call &get_logfile(1) +# to send the name of the last logfile created. You may also use +# the special call &get_logfile(1) which returns the same as &get_logfile(1). + +&compare_output($answer,&get_logfile(1)); + +# This tells the test driver that the perl test script executed properly. +1; + + + + + + diff --git a/tests/scripts/functions/notdir b/tests/scripts/functions/notdir new file mode 100644 index 0000000..4ed8f9c --- /dev/null +++ b/tests/scripts/functions/notdir @@ -0,0 +1,44 @@ +$description = "The following test creates a makefile to test the notdir " + ."function."; + +$details = ""; + +# IF YOU NEED >1 MAKEFILE FOR THIS TEST, USE &get_tmpfile; TO GET +# THE NAME OF THE MAKEFILE. THIS INSURES CONSISTENCY AND KEEPS TRACK OF +# HOW MANY MAKEFILES EXIST FOR EASY DELETION AT THE END. +# EXAMPLE: $makefile2 = &get_tmpfile; + + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "string := \$(notdir ${pathsep}src${pathsep}foo.c hacks) \n" + ."all: \n" + ."\t\@echo \$(string) \n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&run_make_with_options($makefile,"",&get_logfile,0); + +# Create the answer to what should be produced by this Makefile +$answer = "foo.c hacks\n"; + +# COMPARE RESULTS + +# In this call to compare output, you should use the call &get_logfile(1) +# to send the name of the last logfile created. You may also use +# the special call &get_logfile(1) which returns the same as &get_logfile(1). + +&compare_output($answer,&get_logfile(1)); + +# This tells the test driver that the perl test script executed properly. +1; + + + + + + diff --git a/tests/scripts/functions/origin b/tests/scripts/functions/origin new file mode 100644 index 0000000..f7b7eb8 --- /dev/null +++ b/tests/scripts/functions/origin @@ -0,0 +1,51 @@ +# -*-perl-*- + +$description = "Test the origin function."; + +$details = "This is a test of the origin function in gnu make. +This function will report on where a variable was +defined per the following list: + +'undefined' never defined +'default' default definition +'environment' environment var without -e +'environment override' environment var with -e +'file' defined in makefile +'command line' defined on the command line +'override' defined by override in makefile +'automatic' Automatic variable\n"; + +# Set an environment variable +$extraENV{MAKETEST} = 1; + +run_make_test(' +foo := bletch garf +auto_var = undefined CC MAKETEST MAKE foo CFLAGS WHITE @ +av = $(foreach var, $(auto_var), $(origin $(var)) ) +override WHITE := BLACK +all: auto + @echo $(origin undefined) + @echo $(origin CC) + @echo $(origin MAKETEST) + @echo $(origin MAKE) + @echo $(origin foo) + @echo $(origin CFLAGS) + @echo $(origin WHITE) + @echo $(origin @) +auto : + @echo $(av)', + '-e WHITE=WHITE CFLAGS=', + 'undefined default environment default file command line override automatic +undefined +default +environment +default +file +command line +override +automatic'); + +# Reset an environment variable +delete $extraENV{MAKETEST}; + +1; diff --git a/tests/scripts/functions/realpath b/tests/scripts/functions/realpath new file mode 100644 index 0000000..9b503b4 --- /dev/null +++ b/tests/scripts/functions/realpath @@ -0,0 +1,82 @@ +# -*-perl-*- +$description = "Test the realpath functions."; + +$details = ""; + +run_make_test(' +ifneq ($(realpath .),$(CURDIR)) + $(error ) +endif + +ifneq ($(realpath ./),$(CURDIR)) + $(error ) +endif + +ifneq ($(realpath .///),$(CURDIR)) + $(error ) +endif + +ifneq ($(realpath /),/) + $(error ) +endif + +ifneq ($(realpath /.),/) + $(error ) +endif + +ifneq ($(realpath /./),/) + $(error ) +endif + +ifneq ($(realpath /.///),/) + $(error ) +endif + +ifneq ($(realpath /..),/) + $(error ) +endif + +ifneq ($(realpath /../),/) + $(error ) +endif + +ifneq ($(realpath /..///),/) + $(error ) +endif + +ifneq ($(realpath . /..),$(CURDIR) /) + $(error ) +endif + +.PHONY: all +all: ; @: +', + '', + ''); + +# On Windows platforms, "//" means something special. So, don't do these +# tests there. + +if ($port_type ne 'W32') { + run_make_test(' +ifneq ($(realpath ///),/) + $(error ) +endif + +ifneq ($(realpath ///.),/) + $(error ) +endif + +ifneq ($(realpath ///..),/) + $(error ) +endif + +.PHONY: all +all: ; @:', + '', + ''); +} + + +# This tells the test driver that the perl test script executed properly. +1; diff --git a/tests/scripts/functions/shell b/tests/scripts/functions/shell new file mode 100644 index 0000000..723cd0e --- /dev/null +++ b/tests/scripts/functions/shell @@ -0,0 +1,32 @@ +# -*-perl-*- + +$description = 'Test the $(shell ...) function.'; + +$details = ''; + + +# Test shells inside rules. +run_make_test('.PHONY: all +all: ; @echo $(shell echo hi) +','','hi'); + + +# Test unescaped comment characters in shells. Savannah bug #20513 +if ($all_tests) { + run_make_test(q! +FOO := $(shell echo '#') +foo: ; echo '$(FOO)' +!, + '', "#\n"); +} + +# Test shells inside exported environment variables. +# This is the test that fails if we try to put make exported variables into +# the environment for a $(shell ...) call. +run_make_test(' +export HI = $(shell echo hi) +.PHONY: all +all: ; @echo $$HI +','','hi'); + +1; diff --git a/tests/scripts/functions/sort b/tests/scripts/functions/sort new file mode 100644 index 0000000..d472102 --- /dev/null +++ b/tests/scripts/functions/sort @@ -0,0 +1,55 @@ +$description = "The following test creates a makefile to verify\n" + ."the ability of make to sort lists of object. Sort\n" + ."will also remove any duplicate entries. This will also\n" + ."be tested."; + +$details = "The make file is built with a list of object in a random order\n" + ."and includes some duplicates. Make should sort all of the elements\n" + ."remove all duplicates\n"; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "foo := moon_light days \n" + ."foo1:= jazz\n" + ."bar := captured \n" + ."bar2 = boy end, has rise A midnight \n" + ."bar3:= \$(foo)\n" + ."s1 := _by\n" + ."s2 := _and_a\n" + ."t1 := \$(addsuffix \$(s1), \$(bar) )\n" + ."t2 := \$(addsuffix \$(s2), \$(foo1) )\n" + ."t3 := \$(t2) \$(t2) \$(t2) \$(t2) \$(t2) \$(t2) \$(t2) \$(t2) \$(t2) \$(t2) \n" + ."t4 := \$(t3) \$(t3) \$(t3) \$(t3) \$(t3) \$(t3) \$(t3) \$(t3) \$(t3) \$(t3) \n" + ."t5 := \$(t4) \$(t4) \$(t4) \$(t4) \$(t4) \$(t4) \$(t4) \$(t4) \$(t4) \$(t4) \n" + ."t6 := \$(t5) \$(t5) \$(t5) \$(t5) \$(t5) \$(t5) \$(t5) \$(t5) \$(t5) \$(t5) \n" + ."t7 := \$(t6) \$(t6) \$(t6) \n" + ."p1 := \$(addprefix \$(foo1), \$(s2) )\n" + ."blank:= \n" + ."all:\n" + ."\t\@echo \$(sort \$(bar2) \$(foo) \$(addsuffix \$(s1), \$(bar) ) \$(t2) \$(bar2) \$(bar3))\n" + ."\t\@echo \$(sort \$(blank) \$(foo) \$(bar2) \$(t1) \$(p1) )\n" + ."\t\@echo \$(sort \$(foo) \$(bar2) \$(t1) \$(t4) \$(t5) \$(t7) \$(t6) )\n"; + + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&run_make_with_options($makefile,"",&get_logfile); + +# Create the answer to what should be produced by this Makefile +$answer = "A boy captured_by days end, has jazz_and_a midnight moon_light rise\n" + ."A boy captured_by days end, has jazz_and_a midnight moon_light rise\n" + ."A boy captured_by days end, has jazz_and_a midnight moon_light rise\n"; + +&compare_output($answer,&get_logfile(1)); + +1; + + + + + + diff --git a/tests/scripts/functions/strip b/tests/scripts/functions/strip new file mode 100644 index 0000000..8222433 --- /dev/null +++ b/tests/scripts/functions/strip @@ -0,0 +1,57 @@ +# -*-perl-*- +$description = "The following test creates a makefile to verify +the ability of make to strip white space from lists of object.\n"; + + +$details = "The make file is built with a list of objects that contain white space +These are then run through the strip command to remove it. This is then +verified by echoing the result.\n"; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE <<'EOMAKE'; +TEST1 := "Is this TERMINAL fun? What makes you believe is this terminal fun? JAPAN is a WONDERFUL planet -- I wonder if we will ever reach their level of COMPARATIVE SHOPPING..." +E := +TEST2 := $E try this and this $E + +define TEST3 + +and these test out + + +some +blank lines + + + +endef + +.PHONY: all +all: + @echo '$(strip $(TEST1) )' + @echo '$(strip $(TEST2) )' + @echo '$(strip $(TEST3) )' + +space: ; @echo '$(strip ) $(strip )' + +EOMAKE + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&run_make_with_options($makefile,"",&get_logfile); +$answer = "\"Is this TERMINAL fun? What makes you believe is this terminal fun? JAPAN is a WONDERFUL planet -- I wonder if we will ever reach their level of COMPARATIVE SHOPPING...\" +try this and this +and these test out some blank lines +"; +&compare_output($answer,&get_logfile(1)); + + +&run_make_with_options($makefile,"space",&get_logfile); +$answer = " \n"; +&compare_output($answer,&get_logfile(1)); + +1; diff --git a/tests/scripts/functions/substitution b/tests/scripts/functions/substitution new file mode 100644 index 0000000..0d2f6a2 --- /dev/null +++ b/tests/scripts/functions/substitution @@ -0,0 +1,38 @@ +# -*-perl-*- + +$description = "Test the subst and patsubst functions"; + +$details = ""; + +# Generic patsubst test: test both the function and variable form. + +run_make_test(' +foo := a.o b.o c.o +bar := $(foo:.o=.c) +bar2:= $(foo:%.o=%.c) +bar3:= $(patsubst %.c,%.o,x.c.c bar.c) +all:;@echo $(bar); echo $(bar2); echo $(bar3)', +'', +'a.c b.c c.c +a.c b.c c.c +x.c.o bar.o'); + +# Patsubst without '%'--shouldn't match because the whole word has to match +# in patsubst. Based on a bug report by Markus Mauhart <qwe123@chello.at> + +run_make_test('all:;@echo $(patsubst Foo,Repl,FooFoo)', '', 'FooFoo'); + +# Variable subst where a pattern matches multiple times in a single word. +# Based on a bug report by Markus Mauhart <qwe123@chello.at> + +run_make_test(' +A := fooBARfooBARfoo +all:;@echo $(A:fooBARfoo=REPL)', '', 'fooBARREPL'); + +1; + + + + + + diff --git a/tests/scripts/functions/suffix b/tests/scripts/functions/suffix new file mode 100644 index 0000000..0c4f919 --- /dev/null +++ b/tests/scripts/functions/suffix @@ -0,0 +1,57 @@ +$description = "The following test creates a makefile to test the suffix\n" + ."function. \n"; + +$details = "The suffix function will return the string following the last _._\n" + ."the list provided. It will provide all of the unique suffixes found\n" + ."in the list. The long strings are sorted to remove duplicates.\n"; + +# IF YOU NEED >1 MAKEFILE FOR THIS TEST, USE &get_tmpfile; TO GET +# THE NAME OF THE MAKEFILE. THIS INSURES CONSISTENCY AND KEEPS TRACK OF +# HOW MANY MAKEFILES EXIST FOR EASY DELETION AT THE END. +# EXAMPLE: $makefile2 = &get_tmpfile; + + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "string := word.pl general_test2.pl1 FORCE.pl word.pl3 generic_test.perl /tmp.c/bar foo.baz/bar.c MAKEFILES_variable.c\n" + ."string2 := \$(string) \$(string) \$(string) \$(string) \$(string) \$(string) \$(string)\n" + ."string3 := \$(string2) \$(string2) \$(string2) \$(string2) \$(string2) \$(string2) \$(string2)\n" + ."string4 := \$(string3) \$(string3) \$(string3) \$(string3) \$(string3) \$(string3) \$(string3)\n" + ."all: \n" + ."\t\@echo \$(suffix \$(string)) \n" + ."\t\@echo \$(sort \$(suffix \$(string4))) \n" + ."\t\@echo \$(suffix \$(string) a.out) \n" + ."\t\@echo \$(sort \$(suffix \$(string3))) \n"; + + + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&run_make_with_options($makefile,"",&get_logfile,0); + +# Create the answer to what should be produced by this Makefile + +# COMPARE RESULTS +$answer = ".pl .pl1 .pl .pl3 .perl .c .c\n" + .".c .perl .pl .pl1 .pl3\n" + .".pl .pl1 .pl .pl3 .perl .c .c .out\n" + .".c .perl .pl .pl1 .pl3\n"; + +# In this call to compare output, you should use the call &get_logfile(1) +# to send the name of the last logfile created. You may also use +# the special call &get_logfile(1) which returns the same as &get_logfile(1). + +&compare_output($answer,&get_logfile(1)); + +# This tells the test driver that the perl test script executed properly. +1; + + + + + + diff --git a/tests/scripts/functions/value b/tests/scripts/functions/value new file mode 100644 index 0000000..8e1a6f0 --- /dev/null +++ b/tests/scripts/functions/value @@ -0,0 +1,30 @@ +# -*-perl-*- + +$description = "Test the value function."; + +$details = "This is a test of the value function in GNU make. +This function will evaluate to the value of the named variable with no +further expansion performed on it.\n"; + +open(MAKEFILE,"> $makefile"); + +print MAKEFILE <<'EOF'; +export FOO = foo + +recurse = FOO = $FOO +static := FOO = $(value FOO) + +all: ; @echo $(recurse) $(value recurse) $(static) $(value static) +EOF + +close(MAKEFILE); + +&run_make_with_options($makefile, "", &get_logfile); + +# Create the answer to what should be produced by this Makefile +$answer = "FOO = OO FOO = foo FOO = foo FOO = foo\n"; + + +&compare_output($answer,&get_logfile(1)); + +1; diff --git a/tests/scripts/functions/warning b/tests/scripts/functions/warning new file mode 100644 index 0000000..cd452d4 --- /dev/null +++ b/tests/scripts/functions/warning @@ -0,0 +1,65 @@ +# -*-Perl-*- + +$description = "\ +The following test creates a makefile to test the warning function."; + +$details = ""; + +open(MAKEFILE,"> $makefile"); + +print MAKEFILE <<'EOF'; +ifdef WARNING1 +$(warning warning is $(WARNING1)) +endif + +ifdef WARNING2 +$(warning warning is $(WARNING2)) +endif + +ifdef WARNING3 +all: some; @echo hi $(warning warning is $(WARNING3)) +endif + +ifdef WARNING4 +all: some; @echo hi + @echo there $(warning warning is $(WARNING4)) +endif + +some: ; @echo Some stuff + +EOF + +close(MAKEFILE); + +# Test #1 + +&run_make_with_options($makefile, "WARNING1=yes", &get_logfile, 0); +$answer = "$makefile:2: warning is yes\nSome stuff\n"; +&compare_output($answer,&get_logfile(1)); + +# Test #2 + +&run_make_with_options($makefile, "WARNING2=no", &get_logfile, 0); +$answer = "$makefile:6: warning is no\nSome stuff\n"; +&compare_output($answer,&get_logfile(1)); + +# Test #3 + +&run_make_with_options($makefile, "WARNING3=maybe", &get_logfile, 0); +$answer = "Some stuff\n$makefile:10: warning is maybe\nhi\n"; +&compare_output($answer,&get_logfile(1)); + +# Test #4 + +&run_make_with_options($makefile, "WARNING4=definitely", &get_logfile, 0); +$answer = "Some stuff\n$makefile:14: warning is definitely\nhi\nthere\n"; +&compare_output($answer,&get_logfile(1)); + +# This tells the test driver that the perl test script executed properly. +1; + + + + + + diff --git a/tests/scripts/functions/wildcard b/tests/scripts/functions/wildcard new file mode 100644 index 0000000..2841f5d --- /dev/null +++ b/tests/scripts/functions/wildcard @@ -0,0 +1,91 @@ +# -*-perl-*- + +$description = "The following test creates a makefile to test wildcard +expansions and the ability to put a command on the same +line as the target name separated by a semi-colon."; + +$details = "\ +This test creates 4 files by the names of 1.example, +two.example and 3.example. We execute three tests. The first +executes the print1 target which tests the '*' wildcard by +echoing all filenames by the name of '*.example'. The second +test echo's all files which match '?.example' and +[a-z0-9].example. Lastly we clean up all of the files using +the '*' wildcard as in the first test"; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE <<EOM; +.PHONY: print1 print2 clean +print1: ;\@echo \$(sort \$(wildcard example.*)) +print2: +\t\@echo \$(sort \$(wildcard example.?)) +\t\@echo \$(sort \$(wildcard example.[a-z0-9])) +\t\@echo \$(sort \$(wildcard example.[!A-Za-z_\\!])) +clean: +\t$delete_command \$(sort \$(wildcard example.*)) +EOM + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&touch("example.1"); +&touch("example.two"); +&touch("example.3"); +&touch("example.for"); +&touch("example._"); + +# TEST #1 +# ------- + +$answer = "example.1 example.3 example._ example.for example.two\n"; + +&run_make_with_options($makefile,"print1",&get_logfile); + +&compare_output($answer,&get_logfile(1)); + + +# TEST #2 +# ------- + +$answer = "example.1 example.3 example._\n" + ."example.1 example.3\n" + ."example.1 example.3\n"; + +&run_make_with_options($makefile,"print2",&get_logfile); + +&compare_output($answer,&get_logfile(1)); + + +# TEST #3 +# ------- + +$answer = "$delete_command example.1 example.3 example._ example.for example.two"; +if ($vos) +{ + $answer .= " \n"; +} +else +{ + $answer .= "\n"; +} + +&run_make_with_options($makefile,"clean",&get_logfile); + +if ((-f "example.1")||(-f "example.two")||(-f "example.3")||(-f "example.for")) { + $test_passed = 0; +} + +&compare_output($answer,&get_logfile(1)); + +# TEST #4: Verify that failed wildcards don't return the pattern + +run_make_test(q! +all: ; @echo $(wildcard xz--y*.7) +!, + '', "\n"); + +1; diff --git a/tests/scripts/functions/word b/tests/scripts/functions/word new file mode 100644 index 0000000..34527ea --- /dev/null +++ b/tests/scripts/functions/word @@ -0,0 +1,167 @@ +# -*-perl-*- +$description = "\ +Test the word, words, wordlist, firstword, and lastword functions.\n"; + +$details = "\ +Produce a variable with a large number of words in it, +determine the number of words, and then read each one back.\n"; + +open(MAKEFILE,"> $makefile"); +print MAKEFILE <<'EOF'; +string := word.pl general_test2.pl FORCE.pl word.pl generic_test.perl MAKEFILES_variable.pl +string2 := $(string) $(string) $(string) $(string) $(string) $(string) $(string) +string3 := $(string2) $(string2) $(string2) $(string2) $(string2) $(string2) $(string2) +string4 := $(string3) $(string3) $(string3) $(string3) $(string3) $(string3) $(string3) +all: + @echo $(words $(string)) + @echo $(words $(string4)) + @echo $(word 1, $(string)) + @echo $(word 100, $(string)) + @echo $(word 1, $(string)) + @echo $(word 1000, $(string3)) + @echo $(wordlist 3, 4, $(string)) + @echo $(wordlist 4, 3, $(string)) + @echo $(wordlist 1, 6, $(string)) + @echo $(wordlist 5, 7, $(string)) + @echo $(wordlist 100, 110, $(string)) + @echo $(wordlist 7, 10, $(string2)) +EOF +close(MAKEFILE); + +&run_make_with_options($makefile, "", &get_logfile); +$answer = "6\n" + ."2058\n" + ."word.pl\n" + ."\n" + ."word.pl\n" + ."\n" + ."FORCE.pl word.pl\n" + ."\n" + ."word.pl general_test2.pl FORCE.pl word.pl generic_test.perl MAKEFILES_variable.pl\n" + ."generic_test.perl MAKEFILES_variable.pl\n" + ."\n" + ."word.pl general_test2.pl FORCE.pl word.pl\n"; +&compare_output($answer, &get_logfile(1)); + + +# Test error conditions + +run_make_test('FOO = foo bar biz baz + +word-e1: ; @echo $(word ,$(FOO)) +word-e2: ; @echo $(word abc ,$(FOO)) +word-e3: ; @echo $(word 1a,$(FOO)) + +wordlist-e1: ; @echo $(wordlist ,,$(FOO)) +wordlist-e2: ; @echo $(wordlist abc ,,$(FOO)) +wordlist-e3: ; @echo $(wordlist 1, 12a ,$(FOO))', + 'word-e1', + "#MAKEFILE#:3: *** non-numeric first argument to `word' function: ''. Stop.", + 512); + +run_make_test(undef, + 'word-e2', + "#MAKEFILE#:4: *** non-numeric first argument to `word' function: 'abc '. Stop.", + 512); + +run_make_test(undef, + 'word-e3', + "#MAKEFILE#:5: *** non-numeric first argument to `word' function: '1a'. Stop.", + 512); + +run_make_test(undef, + 'wordlist-e1', + "#MAKEFILE#:7: *** non-numeric first argument to `wordlist' function: ''. Stop.", + 512); + +run_make_test(undef, + 'wordlist-e2', + "#MAKEFILE#:8: *** non-numeric first argument to `wordlist' function: 'abc '. Stop.", + 512); + +run_make_test(undef, + 'wordlist-e3', + "#MAKEFILE#:9: *** non-numeric second argument to `wordlist' function: ' 12a '. Stop.", + 512); + +# Test error conditions again, but this time in a variable reference + +run_make_test('FOO = foo bar biz baz + +W = $(word $x,$(FOO)) +WL = $(wordlist $s,$e,$(FOO)) + +word-e: ; @echo $(W) +wordlist-e: ; @echo $(WL)', + 'word-e x=', + "#MAKEFILE#:3: *** non-numeric first argument to `word' function: ''. Stop.", + 512); + +run_make_test(undef, + 'word-e x=abc', + "#MAKEFILE#:3: *** non-numeric first argument to `word' function: 'abc'. Stop.", + 512); + +run_make_test(undef, + 'word-e x=0', + "#MAKEFILE#:3: *** first argument to `word' function must be greater than 0. Stop.", + 512); + +run_make_test(undef, + 'wordlist-e s= e=', + "#MAKEFILE#:4: *** non-numeric first argument to `wordlist' function: ''. Stop.", + 512); + +run_make_test(undef, + 'wordlist-e s=abc e=', + "#MAKEFILE#:4: *** non-numeric first argument to `wordlist' function: 'abc'. Stop.", + 512); + +run_make_test(undef, + 'wordlist-e s=4 e=12a', + "#MAKEFILE#:4: *** non-numeric second argument to `wordlist' function: '12a'. Stop.", + 512); + +run_make_test(undef, + 'wordlist-e s=0 e=12', + "#MAKEFILE#:4: *** invalid first argument to `wordlist' function: `0'. Stop.", + 512); + + +# TEST #8 -- test $(firstword ) +# +run_make_test(' +void := +list := $(void) foo bar baz # + +a := $(word 1,$(list)) +b := $(firstword $(list)) + +.PHONY: all + +all: + @test "$a" = "$b" && echo $a +', +'', +'foo'); + + +# TEST #9 -- test $(lastword ) +# +run_make_test(' +void := +list := $(void) foo bar baz # + +a := $(word $(words $(list)),$(list)) +b := $(lastword $(list)) + +.PHONY: all + +all: + @test "$a" = "$b" && echo $a +', +'', +'baz'); + +# This tells the test driver that the perl test script executed properly. +1; diff --git a/tests/scripts/misc/close_stdout b/tests/scripts/misc/close_stdout new file mode 100644 index 0000000..18606c3 --- /dev/null +++ b/tests/scripts/misc/close_stdout @@ -0,0 +1,9 @@ +# -*-perl-*- + +$description = "Make sure make exits with an error if stdout is full."; + +if (-e '/dev/full') { + run_make_test('', '-v > /dev/full', '/^#MAKE#: write error/', 256); +} + +1; diff --git a/tests/scripts/misc/general1 b/tests/scripts/misc/general1 new file mode 100644 index 0000000..352fc6a --- /dev/null +++ b/tests/scripts/misc/general1 @@ -0,0 +1,51 @@ +# -*-perl-*- + +$description = "The following test creates a makefile to test the +simple functionality of make. It mimics the +rebuilding of a product with dependencies. +It also tests the simple definition of VPATH."; + +open(MAKEFILE,"> $makefile"); + +print MAKEFILE <<EOF; +VPATH = $workdir +edit: main.o kbd.o commands.o display.o \\ + insert.o +\t\@echo cc -o edit main.o kbd.o commands.o display.o \\ + insert.o +main.o : main.c defs.h +\t\@echo cc -c main.c +kbd.o : kbd.c defs.h command.h +\t\@echo cc -c kbd.c +commands.o : command.c defs.h command.h +\t\@echo cc -c commands.c +display.o : display.c defs.h buffer.h +\t\@echo cc -c display.c +insert.o : insert.c defs.h buffer.h +\t\@echo cc -c insert.c +EOF + +close(MAKEFILE); + + +@files_to_touch = ("$workdir${pathsep}main.c","$workdir${pathsep}defs.h", + "$workdir${pathsep}kbd.c","$workdir${pathsep}command.h", + "$workdir${pathsep}commands.c","$workdir${pathsep}display.c", + "$workdir${pathsep}buffer.h","$workdir${pathsep}insert.c", + "$workdir${pathsep}command.c"); + +&touch(@files_to_touch); + +&run_make_with_options($makefile,"",&get_logfile); + +# Create the answer to what should be produced by this Makefile +$answer = "cc -c main.c\ncc -c kbd.c\ncc -c commands.c\ncc -c display.c +cc -c insert.c\ncc -o edit main.o kbd.o commands.o display.o insert.o\n"; + +# COMPARE RESULTS + +if (&compare_output($answer,&get_logfile(1))) { + unlink @files_to_touch; +} + +1; diff --git a/tests/scripts/misc/general2 b/tests/scripts/misc/general2 new file mode 100644 index 0000000..fb5c3aa --- /dev/null +++ b/tests/scripts/misc/general2 @@ -0,0 +1,50 @@ +# -*-perl-*- + +$description = "The following test creates a makefile to test the +simple functionality of make. It is the same as +general_test1 except that this one tests the +definition of a variable to hold the object filenames."; + +open(MAKEFILE,"> $makefile"); + +# The contents of the Makefile ... + +print MAKEFILE <<EOF; +VPATH = $workdir +objects = main.o kbd.o commands.o display.o insert.o +edit: \$(objects) +\t\@echo cc -o edit \$(objects) +main.o : main.c defs.h +\t\@echo cc -c main.c +kbd.o : kbd.c defs.h command.h +\t\@echo cc -c kbd.c +commands.o : command.c defs.h command.h +\t\@echo cc -c commands.c +display.o : display.c defs.h buffer.h +\t\@echo cc -c display.c +insert.o : insert.c defs.h buffer.h +\t\@echo cc -c insert.c +EOF + +close(MAKEFILE); + + +@files_to_touch = ("$workdir${pathsep}main.c","$workdir${pathsep}defs.h", + "$workdir${pathsep}kbd.c","$workdir${pathsep}command.h", + "$workdir${pathsep}commands.c","$workdir${pathsep}display.c", + "$workdir${pathsep}buffer.h","$workdir${pathsep}insert.c", + "$workdir${pathsep}command.c"); + +&touch(@files_to_touch); + +&run_make_with_options($makefile,"",&get_logfile); + +# Create the answer to what should be produced by this Makefile +$answer = "cc -c main.c\ncc -c kbd.c\ncc -c commands.c\ncc -c display.c +cc -c insert.c\ncc -o edit main.o kbd.o commands.o display.o insert.o\n"; + +if (&compare_output($answer,&get_logfile(1))) { + unlink @files_to_touch; +} + +1; diff --git a/tests/scripts/misc/general3 b/tests/scripts/misc/general3 new file mode 100644 index 0000000..b3142c2 --- /dev/null +++ b/tests/scripts/misc/general3 @@ -0,0 +1,313 @@ +# -*-perl-*- + +$description = "\ +This tests random features of the parser that need to be supported, and +which have either broken at some point in the past or seem likely to +break."; + +run_make_test(" +# We want to allow both empty commands _and_ commands that resolve to empty. +EMPTY = + +.PHONY: all a1 a2 a3 a4 +all: a1 a2 a3 a4 + +a1:; +a2: +\t +a3:;\$(EMPTY) +a4: +\t\$(EMPTY) + +\# Non-empty lines that expand to nothing should also be ignored. +STR = \# Some spaces +TAB = \t \# A TAB and some spaces + +\$(STR) + +\$(STR) \$(TAB)", + '', "#MAKE#: Nothing to be done for `all'."); + +# TEST 2 + +# Make sure files without trailing newlines are handled properly. +# Have to use the old style invocation to test this. + +$makefile2 = &get_tmpfile; + +open(MAKEFILE, "> $makefile2"); +print MAKEFILE "all:;\@echo FOO = \$(FOO)\nFOO = foo"; +close(MAKEFILE); + +&run_make_with_options($makefile2,"",&get_logfile); +$answer = "FOO = foo\n"; +&compare_output($answer,&get_logfile(1)); + +# TEST 3 + +# Check semicolons in variable references + +run_make_test(' +$(if true,$(info true; true)) +all: ; @: +', + '', 'true; true'); + +# TEST 4 + +# Check that backslashes in command scripts are handled according to POSIX. +# Checks Savannah bug # 1332. + +# Test the fastpath / no quotes +run_make_test(' +all: + @echo foo\ +bar + @echo foo\ + bar + @echo foo\ + bar + @echo foo\ + bar + @echo foo \ +bar + @echo foo \ + bar + @echo foo \ + bar + @echo foo \ + bar +', + '', 'foobar +foobar +foo bar +foo bar +foo bar +foo bar +foo bar +foo bar'); + +# Test the fastpath / single quotes +run_make_test(" +all: + \@echo 'foo\\ +bar' + \@echo 'foo\\ + bar' + \@echo 'foo\\ + bar' + \@echo 'foo\\ + bar' + \@echo 'foo \\ +bar' + \@echo 'foo \\ + bar' + \@echo 'foo \\ + bar' + \@echo 'foo \\ + bar' +", + '', 'foo\ +bar +foo\ +bar +foo\ + bar +foo\ + bar +foo \ +bar +foo \ +bar +foo \ + bar +foo \ + bar'); + +# Test the fastpath / double quotes +run_make_test(' +all: + @echo "foo\ +bar" + @echo "foo\ + bar" + @echo "foo\ + bar" + @echo "foo\ + bar" + @echo "foo \ +bar" + @echo "foo \ + bar" + @echo "foo \ + bar" + @echo "foo \ + bar" +', + '', 'foobar +foobar +foo bar +foo bar +foo bar +foo bar +foo bar +foo bar'); + +# Test the slow path / no quotes +run_make_test(' +all: + @echo hi; echo foo\ +bar + @echo hi; echo foo\ + bar + @echo hi; echo foo\ + bar + @echo hi; echo foo\ + bar + @echo hi; echo foo \ +bar + @echo hi; echo foo \ + bar + @echo hi; echo foo \ + bar + @echo hi; echo foo \ + bar +', + '', 'hi +foobar +hi +foobar +hi +foo bar +hi +foo bar +hi +foo bar +hi +foo bar +hi +foo bar +hi +foo bar'); + +# Test the slow path / no quotes. This time we put the slow path +# determination _after_ the backslash-newline handling. +run_make_test(' +all: + @echo foo\ +bar; echo hi + @echo foo\ + bar; echo hi + @echo foo\ + bar; echo hi + @echo foo\ + bar; echo hi + @echo foo \ +bar; echo hi + @echo foo \ + bar; echo hi + @echo foo \ + bar; echo hi + @echo foo \ + bar; echo hi +', + '', 'foobar +hi +foobar +hi +foo bar +hi +foo bar +hi +foo bar +hi +foo bar +hi +foo bar +hi +foo bar +hi'); + +# Test the slow path / single quotes +run_make_test(" +all: + \@echo hi; echo 'foo\\ +bar' + \@echo hi; echo 'foo\\ + bar' + \@echo hi; echo 'foo\\ + bar' + \@echo hi; echo 'foo\\ + bar' + \@echo hi; echo 'foo \\ +bar' + \@echo hi; echo 'foo \\ + bar' + \@echo hi; echo 'foo \\ + bar' + \@echo hi; echo 'foo \\ + bar' +", + '', 'hi +foo\ +bar +hi +foo\ +bar +hi +foo\ + bar +hi +foo\ + bar +hi +foo \ +bar +hi +foo \ +bar +hi +foo \ + bar +hi +foo \ + bar'); + +# Test the slow path / double quotes +run_make_test(' +all: + @echo hi; echo "foo\ +bar" + @echo hi; echo "foo\ + bar" + @echo hi; echo "foo\ + bar" + @echo hi; echo "foo\ + bar" + @echo hi; echo "foo \ +bar" + @echo hi; echo "foo \ + bar" + @echo hi; echo "foo \ + bar" + @echo hi; echo "foo \ + bar" +', + '', 'hi +foobar +hi +foobar +hi +foo bar +hi +foo bar +hi +foo bar +hi +foo bar +hi +foo bar +hi +foo bar'); + +1; diff --git a/tests/scripts/misc/general4 b/tests/scripts/misc/general4 new file mode 100644 index 0000000..6d42a16 --- /dev/null +++ b/tests/scripts/misc/general4 @@ -0,0 +1,82 @@ +# -*-perl-*- + +$description = "\ +This tests random features of make's algorithms, often somewhat obscure, +which have either broken at some point in the past or seem likely to +break."; + +run_make_test(' +# Make sure that subdirectories built as prerequisites are actually handled +# properly. + +all: dir/subdir/file.a + +dir/subdir: ; @echo mkdir -p dir/subdir + +dir/subdir/file.b: dir/subdir ; @echo touch dir/subdir/file.b + +dir/subdir/%.a: dir/subdir/%.b ; @echo cp $< $@', + '', "mkdir -p dir/subdir\ntouch dir/subdir/file.b\ncp dir/subdir/file.b dir/subdir/file.a\n"); + +# Test implicit rules + +&touch('foo.c'); +run_make_test('foo: foo.o', + 'CC="@echo cc" OUTPUT_OPTION=', + 'cc -c foo.c +cc foo.o -o foo'); +unlink('foo.c'); + + +# Test implicit rules with '$' in the name (see se_implicit) + +run_make_test(q! +%.foo : baz$$bar ; @echo 'done $<' +%.foo : bar$$baz ; @echo 'done $<' +test.foo: +baz$$bar bar$$baz: ; @echo '$@' +!, + '', + "baz\$bar\ndone baz\$bar"); + + +# Test implicit rules with '$' in the name (see se_implicit) +# Use the '$' in the pattern. + +run_make_test(q! +%.foo : %$$bar ; @echo 'done $<' +test.foo: +test$$bar: ; @echo '$@' +!, + '', + "test\$bar\ndone test\$bar"); + +# Make sure that subdirectories built as prerequisites are actually handled +# properly... this time with '$' + +run_make_test(q! + +all: dir/subdir/file.$$a + +dir/subdir: ; @echo mkdir -p '$@' + +dir/subdir/file.$$b: dir/subdir ; @echo touch '$@' + +dir/subdir/%.$$a: dir/subdir/%.$$b ; @echo 'cp $< $@' +!, + '', "mkdir -p dir/subdir\ntouch dir/subdir/file.\$b\ncp dir/subdir/file.\$b dir/subdir/file.\$a\n"); + +# Test odd whitespace at the beginning of a line + +run_make_test(" +all: + \f + + \\ + \f \\ + \013 \\ +all: ; \@echo hi +", + '', "hi\n"); + +1; diff --git a/tests/scripts/options/dash-B b/tests/scripts/options/dash-B new file mode 100644 index 0000000..e36842e --- /dev/null +++ b/tests/scripts/options/dash-B @@ -0,0 +1,85 @@ +# -*-perl-*- + +$description = "Test make -B (always remake) option.\n"; + +$details = "\ +Construct a simple makefile that builds a target. +Invoke make once, so it builds everything. Invoke it again and verify +that nothing is built. Then invoke it with -B and verify that everything +is built again."; + +&touch('bar.x'); + +run_make_test(' +.SUFFIXES: + +.PHONY: all +all: foo + +foo: bar.x + @echo cp $< $@ + @echo "" > $@ +', + '', 'cp bar.x foo'); + +run_make_test(undef, '', "#MAKE#: Nothing to be done for `all'."); +run_make_test(undef, '-B', 'cp bar.x foo'); + +# Put the timestamp for foo into the future; it should still be remade. + +utouch(1000, 'foo'); +run_make_test(undef, '', "#MAKE#: Nothing to be done for `all'."); +run_make_test(undef, '-B', 'cp bar.x foo'); + +# Clean up + +rmfiles('bar.x', 'foo'); + +# Test -B with the re-exec feature: we don't want to re-exec forever +# Savannah bug # 7566 + +run_make_test(' +all: ; @: +$(info MAKE_RESTARTS=$(MAKE_RESTARTS)) +include foo.x +foo.x: ; @touch $@ +', + '-B', 'MAKE_RESTARTS= +#MAKEFILE#:4: foo.x: No such file or directory +MAKE_RESTARTS=1'); + +rmfiles('foo.x'); + +# Test -B with the re-exec feature: we DO want -B in the "normal" part of the +# makefile. + +&touch('blah.x'); + +run_make_test(' +all: blah.x ; @echo $@ +$(info MAKE_RESTARTS=$(MAKE_RESTARTS)) +include foo.x +foo.x: ; @touch $@ +blah.x: ; @echo $@ +', + '-B', 'MAKE_RESTARTS= +#MAKEFILE#:4: foo.x: No such file or directory +MAKE_RESTARTS=1 +blah.x +all'); + +rmfiles('foo.x', 'blah.x'); + +# Test that $? is set properly with -B; all prerequisites will be newer! + +utouch(-10, 'x.b'); +touch('x.a'); + +run_make_test(q! +x.a: x.b ; @echo $? +!, + '-B', "x.b\n"); + +unlink(qw(x.a x.b)); + +1; diff --git a/tests/scripts/options/dash-C b/tests/scripts/options/dash-C new file mode 100644 index 0000000..5864ffd --- /dev/null +++ b/tests/scripts/options/dash-C @@ -0,0 +1,71 @@ +# -*-perl-*- + +$description = "Test the -C option to GNU make."; + +$details = "\ +This test is similar to the clean test except that this test creates the file +to delete in the work directory instead of the current directory. Make is +called from another directory using the -C workdir option so that it can both +find the makefile and the file to delete in the work directory."; + +$example = $workdir . $pathsep . "EXAMPLE"; + +open(MAKEFILE,"> $makefile"); +print MAKEFILE <<EOF; +all: ; \@echo This makefile did not clean the dir ... good +clean: ; $delete_command EXAMPLE\$(ext) +EOF +close(MAKEFILE); + +# TEST #1 +# ------- +&touch($example); + +&run_make_with_options("${testname}.mk", + "-C $workdir clean", + &get_logfile); + +chdir $workdir; +$wpath = &get_this_pwd; +chdir $pwd; + +if (-f $example) { + $test_passed = 0; +} + +# Create the answer to what should be produced by this Makefile +$answer = "$make_name: Entering directory `$wpath'\n" + . "$delete_command EXAMPLE\n" + . "$make_name: Leaving directory `$wpath'\n"; + +&compare_output($answer,&get_logfile(1)); + + +# TEST #2 +# ------- +# Do it again with trailing "/"; this should work the same + +$example .= "slash"; + +&touch($example); + +&run_make_with_options("${testname}.mk", + "-C $workdir/ clean ext=slash", + &get_logfile); + +chdir $workdir; +$wpath = &get_this_pwd; +chdir $pwd; + +if (-f $example) { + $test_passed = 0; +} + +# Create the answer to what should be produced by this Makefile +$answer = "$make_name: Entering directory `$wpath'\n" + . "$delete_command EXAMPLEslash\n" + . "$make_name: Leaving directory `$wpath'\n"; + +&compare_output($answer,&get_logfile(1)); + +1; diff --git a/tests/scripts/options/dash-I b/tests/scripts/options/dash-I new file mode 100644 index 0000000..8dc5d9b --- /dev/null +++ b/tests/scripts/options/dash-I @@ -0,0 +1,59 @@ +# -*-perl-*- + +$description ="The following test creates a makefile to test the -I option."; + +$details = "\ +This test tests the -I option by including a filename in +another directory and giving make that directory name +under -I in the command line. Without this option, the make +would fail to find the included file. It also checks to make +sure that the -I option gets passed to recursive makes."; + +$makefile2 = &get_tmpfile; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +$mf2 = substr ($makefile2, index ($makefile2, $pathsep) + 1); +print MAKEFILE <<EOF; +include $mf2 +all: +\t\@echo There should be no errors for this makefile. +EOF + +# END of Contents of MAKEFILE + +close(MAKEFILE); + + +open(MAKEFILE,"> $makefile2"); + +print MAKEFILE <<EOF; +ANOTHER: +\t\@echo This is another included makefile +recurse: +\t\$(MAKE) ANOTHER -f $makefile +EOF + +close(MAKEFILE); + +&run_make_with_options($makefile,"-I $workdir all",&get_logfile); + +# Create the answer to what should be produced by this Makefile +$answer = "There should be no errors for this makefile.\n"; +&compare_output($answer,&get_logfile(1)); + + +$answer = "This is another included makefile\n"; +&run_make_with_options($makefile,"-I $workdir ANOTHER",&get_logfile); +&compare_output($answer,&get_logfile(1)); + + +$answer = "$mkpath ANOTHER -f $makefile +${make_name}[1]: Entering directory `$pwd' +This is another included makefile +${make_name}[1]: Leaving directory `$pwd'\n"; + +&run_make_with_options($makefile,"-I $workdir recurse",&get_logfile); +&compare_output($answer,&get_logfile(1)); diff --git a/tests/scripts/options/dash-W b/tests/scripts/options/dash-W new file mode 100644 index 0000000..d3fde87 --- /dev/null +++ b/tests/scripts/options/dash-W @@ -0,0 +1,88 @@ +# -*-perl-*- + +$description = "Test make -W (what if) option.\n"; + +# Basic build + +run_make_test(' +a.x: b.x +a.x b.x: ; echo >> $@ +', + '', "echo >> b.x\necho >> a.x"); + +# Run it again: nothing should happen + +run_make_test(undef, '', "#MAKE#: `a.x' is up to date."); + +# Now run it with -W b.x: should rebuild a.x + +run_make_test(undef, '-W b.x', 'echo >> a.x'); + +# Put the timestamp for a.x into the future; it should still be remade. + +utouch(1000, 'a.x'); +run_make_test(undef, '', "#MAKE#: `a.x' is up to date."); +run_make_test(undef, '-W b.x', 'echo >> a.x'); + +# Clean up + +rmfiles('a.x', 'b.x'); + +# Test -W with the re-exec feature: we don't want to re-exec forever +# Savannah bug # 7566 + +# First set it up with a normal build + +run_make_test(' +all: baz.x ; @: +include foo.x +foo.x: bar.x + @echo "\$$(info restarts=\$$(MAKE_RESTARTS))" > $@ + @echo "touch $@" +bar.x: ; echo >> $@ +baz.x: bar.x ; @echo "touch $@" +', + '', '#MAKEFILE#:3: foo.x: No such file or directory +echo >> bar.x +touch foo.x +restarts=1 +touch baz.x'); + +# Now run with -W bar.x + +# Tweak foo.x's timestamp so the update will change it. +&utouch(1000, 'foo.x'); + +run_make_test(undef, '-W bar.x', "restarts=\ntouch foo.x\nrestarts=1\ntouch baz.x"); + +rmfiles('foo.x', 'bar.x'); + +# Test -W on vpath-found files: it should take effect. +# Savannah bug # 15341 + +mkdir('x-dir', 0777); +utouch(-20, 'x-dir/x'); +touch('y'); + +run_make_test(' +y: x ; @echo cp $< $@ +', + '-W x-dir/x VPATH=x-dir', + 'cp x-dir/x y'); + +# Make sure ./ stripping doesn't interfere with the match. + +run_make_test(' +y: x ; @echo cp $< $@ +', + '-W ./x-dir/x VPATH=x-dir', + 'cp x-dir/x y'); + +run_make_test(undef, + '-W x-dir/x VPATH=./x-dir', + 'cp ./x-dir/x y'); + +unlink(qw(y x-dir/x)); +rmdir('x-dir'); + +1; diff --git a/tests/scripts/options/dash-e b/tests/scripts/options/dash-e new file mode 100644 index 0000000..17c3fc8 --- /dev/null +++ b/tests/scripts/options/dash-e @@ -0,0 +1,24 @@ +# -*-perl-*- + +$description = "The following test creates a makefile to ..."; + +$details = ""; + +$extraENV{GOOGLE} = 'boggle'; + +open(MAKEFILE,"> $makefile"); + +print MAKEFILE <<'EOF'; +GOOGLE = bazzle +all:; @echo "$(GOOGLE)" +EOF + +close(MAKEFILE); + +&run_make_with_options($makefile, '-e' ,&get_logfile); + +$answer = "boggle\n"; + +&compare_output($answer,&get_logfile(1)); + +1; diff --git a/tests/scripts/options/dash-f b/tests/scripts/options/dash-f new file mode 100644 index 0000000..3aa4746 --- /dev/null +++ b/tests/scripts/options/dash-f @@ -0,0 +1,85 @@ +$description = "The following test tests that if you specify greater \n" + ."than one '-f makefilename' on the command line, \n" + ."that make concatenates them. This test creates three \n" + ."makefiles and specifies all of them with the -f option \n" + ."on the command line. To make sure they were concatenated, \n" + ."we then call make with the rules from the concatenated \n" + ."makefiles one at a time. Finally, it calls all three \n" + ."rules in one call to make and checks that the output\n" + ."is in the correct order."; + +$makefile2 = &get_tmpfile; +$makefile3 = &get_tmpfile; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "all: \n"; +print MAKEFILE "\t\@echo This is the output from the original makefile\n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +# Create a second makefile +open(MAKEFILE,"> $makefile2"); +print MAKEFILE "TWO: \n"; +print MAKEFILE "\t\@echo This is the output from makefile 2\n"; +close(MAKEFILE); + +# Create a third makefile +open(MAKEFILE,"> $makefile3"); +print MAKEFILE "THREE: \n"; +print MAKEFILE "\t\@echo This is the output from makefile 3\n"; +close(MAKEFILE); + + +# Create the answer to what should be produced by this Makefile +$answer = "This is the output from the original makefile\n"; + +# Run make to catch the default rule +&run_make_with_options($makefile,"-f $makefile2 -f $makefile3",&get_logfile,0); + +&compare_output($answer,&get_logfile(1)); + + +# Run Make again with the rule from the second makefile: TWO +$answer = "This is the output from makefile 2\n"; + +&run_make_with_options($makefile,"-f $makefile2 -f $makefile3 TWO",&get_logfile,0); + +&compare_output($answer,&get_logfile(1)); + + +# Run Make again with the rule from the third makefile: THREE + +$answer = "This is the output from makefile 3\n"; +&run_make_with_options($makefile, + "-f $makefile2 -f $makefile3 THREE", + &get_logfile, + 0); +&compare_output($answer,&get_logfile(1)); + + +# Run Make again with ALL three rules in the order 2 1 3 to make sure +# that all rules are executed in the proper order + +$answer = "This is the output from makefile 2\n"; +$answer .= "This is the output from the original makefile\n"; +$answer .= "This is the output from makefile 3\n"; +&run_make_with_options($makefile, + "-f $makefile2 -f $makefile3 TWO all THREE", + &get_logfile, + 0); +&compare_output($answer,&get_logfile(1)); + + + + + + + + + + diff --git a/tests/scripts/options/dash-k b/tests/scripts/options/dash-k new file mode 100644 index 0000000..d87a786 --- /dev/null +++ b/tests/scripts/options/dash-k @@ -0,0 +1,114 @@ +# -*-perl-*- + +$description = "Test the make -k (don't stop on error) option.\n"; + +$details = "\ +The makefile created in this test is a simulation of building +a small product. However, the trick to this one is that one +of the dependencies of the main target does not exist. +Without the -k option, make would fail immediately and not +build any part of the target. What we are looking for here, +is that make builds the rest of the dependencies even though +it knows that at the end it will fail to rebuild the main target."; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE <<EOF; +VPATH = $workdir +edit: main.o kbd.o commands.o display.o +\t\@echo cc -o edit main.o kbd.o commands.o display.o + +main.o : main.c defs.h +\t\@echo cc -c main.c + +kbd.o : kbd.c defs.h command.h +\t\@echo cc -c kbd.c + +commands.o : command.c defs.h command.h +\t\@echo cc -c commands.c + +display.o : display.c defs.h buffer.h +\t\@echo cc -c display.c +EOF + +# END of Contents of MAKEFILE + +close(MAKEFILE); + + +@files_to_touch = ("$workdir${pathsep}main.c","$workdir${pathsep}defs.h", + "$workdir${pathsep}command.h", + "$workdir${pathsep}commands.c","$workdir${pathsep}display.c", + "$workdir${pathsep}buffer.h", + "$workdir${pathsep}command.c"); + +&touch(@files_to_touch); + +if ($vos) { + $error_code = 3307; +} +else { + $error_code = 512; +} + +&run_make_with_options($makefile, "-k", &get_logfile, $error_code); + +# Create the answer to what should be produced by this Makefile +$answer = "cc -c main.c +$make_name: *** No rule to make target `kbd.c', needed by `kbd.o'. +cc -c commands.c +cc -c display.c +$make_name: Target `edit' not remade because of errors.\n"; + +# COMPARE RESULTS + +&compare_output($answer, &get_logfile(1)); + +unlink(@files_to_touch) unless $keep; + + +# TEST 1: Make sure that top-level targets that depend on targets that +# previously failed to build, aren't attempted. Regression for PR/1634. + +$makefile2 = &get_tmpfile; + +open(MAKEFILE, "> $makefile2"); +print MAKEFILE <<'EOF'; +.SUFFIXES: + +all: exe1 exe2; @echo making $@ + +exe1 exe2: lib; @echo cp $^ $@ + +lib: foo.o; @echo cp $^ $@ + +foo.o: ; exit 1 +EOF + +close(MAKEFILE); + +&run_make_with_options($makefile2, "-k", &get_logfile, $error_code); + +$answer = "exit 1 +$make_name: *** [foo.o] Error 1 +$make_name: Target `all' not remade because of errors.\n"; + +&compare_output($answer, &get_logfile(1)); + +# TEST -- make sure we keep the error code if we can't create an included +# makefile. + +run_make_test('all: ; @echo hi +include ifile +ifile: no-such-file; @false +', + '-k', + "#MAKEFILE#:2: ifile: No such file or directory +#MAKE#: *** No rule to make target `no-such-file', needed by `ifile'. +#MAKE#: Failed to remake makefile `ifile'. +hi\n", + 512); + +1; diff --git a/tests/scripts/options/dash-l b/tests/scripts/options/dash-l new file mode 100644 index 0000000..0b0f196 --- /dev/null +++ b/tests/scripts/options/dash-l @@ -0,0 +1,56 @@ +# -*-perl-*- +# Date: Tue, 11 Aug 1992 09:34:26 -0400 +# From: pds@lemming.webo.dg.com (Paul D. Smith) + +$description = "Test load balancing (-l) option."; + +$details = "\ +This test creates a makefile where all depends on three rules +which contain the same body. Each rule checks for the existence +of a temporary file; if it exists an error is generated. If it +doesn't exist then it is created, the rule sleeps, then deletes +the temp file again. Thus if any of the rules are run in +parallel the test will fail. When make is called in this test, +it is given the -l option with a value of 0.0001. This ensures +that the load will be above this number and make will therefore +decide that it cannot run more than one job even though -j 4 was +also specified on the command line."; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE <<'EOF'; +SHELL = /bin/sh + +define test +if [ ! -f test-file ]; then \ + echo >> test-file; sleep 2; rm -f test-file; \ +else \ + echo $@ FAILED; \ +fi +endef + +all : ONE TWO THREE +ONE : ; @$(test) +TWO : ; @$(test) +THREE : ; @$(test) +EOF + + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +$mkoptions = "-l 0.0001"; +$mkoptions .= " -j 4" if ($parallel_jobs); + +# We have to wait longer than the default (5s). +&run_make_with_options($makefile, $mkoptions, &get_logfile, 0, 8); + +$slurp = &read_file_into_string (&get_logfile(1)); +if ($slurp !~ /cannot enforce load limit/) { + &compare_output("", &get_logfile(1)); +} + +1; diff --git a/tests/scripts/options/dash-n b/tests/scripts/options/dash-n new file mode 100644 index 0000000..de19f42 --- /dev/null +++ b/tests/scripts/options/dash-n @@ -0,0 +1,70 @@ +# -*-perl-*- +$description = "Test the -n option.\n"; + +$details = "Try various uses of -n and ensure they all give the correct results.\n"; + +open(MAKEFILE, "> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE <<'EOMAKE'; + +final: intermediate ; echo >> $@ +intermediate: orig ; echo >> $@ + +EOMAKE + +close(MAKEFILE); + +&touch('orig'); + +# TEST 0 + +&run_make_with_options($makefile, "", &get_logfile); +$answer = "echo >> intermediate\necho >> final\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST 1 + +&run_make_with_options($makefile, "-Worig -n", &get_logfile); +$answer = "echo >> intermediate\necho >> final\n"; +&compare_output($answer, &get_logfile(1)); + +unlink('orig', 'intermediate', 'final'); + +# We consider the actual updated timestamp of targets with all +# recursive commands, even with -n. + +$makefile2 = &get_tmpfile; + +open(MAKEFILE, "> $makefile2"); + +print MAKEFILE <<'EOF'; +.SUFFIXES: +BAR = # nothing +FOO = +$(BAR) +a: b; echo > $@ +b: c; $(FOO) +EOF + +close(MAKEFILE); + +&utouch(-20, 'b'); +&utouch(-10, 'a'); +&touch('c'); + +# TEST 2 + +&run_make_with_options($makefile2, "", &get_logfile); +$answer = "$make_name: `a' is up to date.\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST 3 + +&run_make_with_options($makefile2, "-n", &get_logfile); +$answer = "$make_name: `a' is up to date.\n"; +&compare_output($answer, &get_logfile(1)); + +unlink('a', 'b', 'c'); + +1; diff --git a/tests/scripts/options/dash-q b/tests/scripts/options/dash-q new file mode 100644 index 0000000..56f04a1 --- /dev/null +++ b/tests/scripts/options/dash-q @@ -0,0 +1,57 @@ +# -*-perl-*- +$description = "Test the -q option.\n"; + +$details = "Try various uses of -q and ensure they all give the correct results.\n"; + +# TEST 0 + +run_make_test(' +one: +two: ; +three: ; : +four: ; $(.XY) +five: ; \ + $(.XY) +six: ; \ + $(.XY) + $(.XY) +seven: ; \ + $(.XY) + : foo + $(.XY) +', + '-q one', ''); + +# TEST 1 + +run_make_test(undef, '-q two', ''); + +# TEST 2 + +run_make_test(undef, '-q three', '', 256); + +# TEST 3 + +run_make_test(undef, '-q four', ''); + +# TEST 4 + +run_make_test(undef, '-q five', ''); + +# TEST 5 + +run_make_test(undef, '-q six', ''); + +# TEST 6 + +run_make_test(undef, '-q seven', '', 256); + +# TEST 7 : Savannah bug # 7144 + +run_make_test(' +one:: ; @echo one +one:: ; @echo two +', + '-q', '', 256); + +1; diff --git a/tests/scripts/options/dash-t b/tests/scripts/options/dash-t new file mode 100644 index 0000000..ec27d7a --- /dev/null +++ b/tests/scripts/options/dash-t @@ -0,0 +1,58 @@ +# -*-perl-*- + +$description = "Test the -t option.\n"; + +$details = "Look out for regressions of prior bugs related to -t.\n"; +# That means, nobody has even tried to make the tests below comprehensive + +# TEST 0 +# bug reported by Henning Makholm <henning@makholm.net> on 2001-11-03: +# make 3.79.1 touches only interm-[ab] but reports final-[a] as +# 'up to date' without touching them. +# The 'obvious' fix didn't work for double-colon rules, so pay special +# attention to them. + +open(MAKEFILE, "> $makefile"); +print MAKEFILE <<'EOMAKE'; +final-a: interm-a ; echo >> $@ +final-b: interm-b ; echo >> $@ +interm-a:: orig1-a ; echo >> $@ +interm-a:: orig2-a ; echo >> $@ +interm-b:: orig1-b ; echo >> $@ +interm-b:: orig2-b ; echo >> $@ +EOMAKE +close(MAKEFILE); + +&utouch(-30, 'orig1-a','orig2-b'); +&utouch(-20, 'interm-a','interm-b'); +&utouch(-10, 'final-a','final-b'); +&touch('orig2-a','orig1-b'); + +&run_make_with_options($makefile, "-t final-a final-b", &get_logfile); +$answer = "touch interm-a\ntouch final-a\ntouch interm-b\ntouch final-b\n"; +&compare_output($answer, &get_logfile(1)); + +unlink('orig1-a', 'orig2-a', 'interm-a', 'final-a'); +unlink('orig1-b', 'orig2-b', 'interm-b', 'final-b'); + +# TEST 1 +# -t should not touch files with no commands. + +$makefile2 = &get_tmpfile; + +open(MAKEFILE, "> $makefile2"); +print MAKEFILE <<'EOMAKE'; + +PHOOEY: xxx +xxx: ; @: + +EOMAKE +close(MAKEFILE); + +&run_make_with_options($makefile2, "-t", &get_logfile); +$answer = "touch xxx\n"; +&compare_output($answer, &get_logfile(1)); + +unlink('xxx'); + +1; diff --git a/tests/scripts/options/eval b/tests/scripts/options/eval new file mode 100644 index 0000000..06a035c --- /dev/null +++ b/tests/scripts/options/eval @@ -0,0 +1,19 @@ +# -*-perl-*- + +$description = "Test the --eval option."; + +$details = "Verify that --eval options take effect, +and are passed to sub-makes."; + +# Verify that --eval is evaluated first +run_make_test(q! +BAR = bar +all: ; @echo all +recurse: ; @$(MAKE) -f #MAKEFILE# && echo recurse!, + '--eval=\$\(info\ eval\) FOO=\$\(BAR\)', "eval\nall"); + +# Make sure that --eval is handled correctly during recursion +run_make_test(undef, '--no-print-directory --eval=\$\(info\ eval\) recurse', + "eval\neval\nall\nrecurse"); + +1; diff --git a/tests/scripts/options/general b/tests/scripts/options/general new file mode 100644 index 0000000..d35bb35 --- /dev/null +++ b/tests/scripts/options/general @@ -0,0 +1,35 @@ +# -*-perl-*- +$description = "Test generic option processing.\n"; + +open(MAKEFILE, "> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "foo 1foo: ; \@echo \$\@\n"; + +close(MAKEFILE); + +# TEST 0 + +&run_make_with_options($makefile, "-j 1foo", &get_logfile); +if (!$parallel_jobs) { + $answer = "$make_name: Parallel jobs (-j) are not supported on this platform.\n$make_name: Resetting to single job (-j1) mode.\n1foo\n"; +} +else { + $answer = "1foo\n"; +} + +# TEST 1 + +# This test prints the usage string; I don't really know a good way to +# test it. I guess I could invoke make with a known-bad option to see +# what the usage looks like, then compare it to what I get here... :( + +# If I were always on UNIX, I could invoke it with 2>/dev/null, then +# just check the error code. + +&run_make_with_options($makefile, "-j1foo 2>/dev/null", &get_logfile, 512); +$answer = ""; +&compare_output($answer, &get_logfile(1)); + +1; diff --git a/tests/scripts/options/symlinks b/tests/scripts/options/symlinks new file mode 100644 index 0000000..40d2564 --- /dev/null +++ b/tests/scripts/options/symlinks @@ -0,0 +1,68 @@ +# -*-perl-*- + +$description = "Test the -L option."; + +$details = "Verify that symlink handling with and without -L works properly."; + +# Only run these tests if the system sypports symlinks + +# Apparently the Windows port of Perl reports that it does support symlinks +# (in that the symlink() function doesn't fail) but it really doesn't, so +# check for it explicitly. + +if ($port_type eq 'W32' || !( eval { symlink("",""); 1 })) { + # This test is N/A + -1; +} else { + + # Set up a symlink sym -> dep + # We'll make both dep and targ older than sym + $pwd =~ m%/([^/]+)$%; + $dirnm = $1; + &utouch(-10, 'dep'); + &utouch(-5, 'targ'); + symlink("../$dirnm/dep", 'sym'); + + # Without -L, nothing should happen + # With -L, it should update targ + run_make_test('targ: sym ; @echo make $@ from $<', '', + "#MAKE#: `targ' is up to date."); + run_make_test(undef, '-L', "make targ from sym"); + + # Now update dep; in all cases targ should be out of date. + &touch('dep'); + run_make_test(undef, '', "make targ from sym"); + run_make_test(undef, '-L', "make targ from sym"); + + # Now update targ; in all cases targ should be up to date. + &touch('targ'); + run_make_test(undef, '', "#MAKE#: `targ' is up to date."); + run_make_test(undef, '-L', "#MAKE#: `targ' is up to date."); + + # Add in a new link between sym and dep. Be sure it's newer than targ. + sleep(1); + rename('dep', 'dep1'); + symlink('dep1', 'dep'); + + # Without -L, nothing should happen + # With -L, it should update targ + run_make_test(undef, '', "#MAKE#: `targ' is up to date."); + run_make_test(undef, '-L', "make targ from sym"); + + rmfiles('targ', 'dep', 'sym', 'dep1'); + + # Check handling when symlinks point to non-existent files. Without -L we + # should get an error: with -L we should use the timestamp of the symlink. + + symlink("../$dirname/dep", 'sym'); + run_make_test('targ: sym ; @echo make $@ from $<', '', + "#MAKE#: *** No rule to make target `sym', needed by `targ'. Stop.", 512); + + run_make_test('targ: sym ; @echo make $@ from $<', '-L', + 'make targ from sym'); + + + rmfiles('targ', 'sym'); + + 1; +} diff --git a/tests/scripts/options/warn-undefined-variables b/tests/scripts/options/warn-undefined-variables new file mode 100644 index 0000000..34bfaea --- /dev/null +++ b/tests/scripts/options/warn-undefined-variables @@ -0,0 +1,25 @@ +# -*-perl-*- + +$description = "Test the --warn-undefined-variables option."; + +$details = "Verify that warnings are printed for referencing undefined variables."; + +# Without --warn-undefined-variables, nothing should happen +run_make_test(' +EMPTY = +EREF = $(EMPTY) +UREF = $(UNDEFINED) + +SEREF := $(EREF) +SUREF := $(UREF) + +all: ; @echo ref $(EREF) $(UREF)', + '', 'ref'); + +# With --warn-undefined-variables, it should warn me +run_make_test(undef, '--warn-undefined-variables', + "#MAKEFILE#:7: warning: undefined variable `UNDEFINED' +#MAKEFILE#:9: warning: undefined variable `UNDEFINED' +ref"); + +1; diff --git a/tests/scripts/targets/DEFAULT b/tests/scripts/targets/DEFAULT new file mode 100644 index 0000000..0cabde9 --- /dev/null +++ b/tests/scripts/targets/DEFAULT @@ -0,0 +1,53 @@ +$description = "The following test creates a makefile to override part\n" + ."of one Makefile with Another Makefile with the .DEFAULT\n" + ."rule."; + +$details = "This tests the use of the .DEFAULT special target to say that \n" + ."to remake any target that cannot be made fram the information\n" + ."in the containing makefile, make should look in another makefile\n" + ."This test gives this makefile the target bar which is not \n" + ."defined here but passes the target bar on to another makefile\n" + ."which does have the target bar defined.\n"; + +$makefile2 = &get_tmpfile; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "foo:\n"; +print MAKEFILE "\t\@echo Executing rule FOO\n\n"; +print MAKEFILE ".DEFAULT:\n"; +print MAKEFILE "\t\@\$(MAKE) -f $makefile2 \$\@ \n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + + +open(MAKEFILE,"> $makefile2"); + +print MAKEFILE "bar:\n"; +print MAKEFILE "\t\@echo Executing rule BAR\n\n"; + +close(MAKEFILE); + +&run_make_with_options($makefile,'bar',&get_logfile); + +# Create the answer to what should be produced by this Makefile +$answer = "${make_name}[1]: Entering directory `$pwd'\n" + . "Executing rule BAR\n" + . "${make_name}[1]: Leaving directory `$pwd'\n"; + +# COMPARE RESULTS + +&compare_output($answer,&get_logfile(1)); + +# This tells the test driver that the perl test script executed properly. +1; + + + + + + diff --git a/tests/scripts/targets/FORCE b/tests/scripts/targets/FORCE new file mode 100644 index 0000000..eb8f251 --- /dev/null +++ b/tests/scripts/targets/FORCE @@ -0,0 +1,40 @@ +# -*-perl-*- + +$description = "The following tests rules without Commands or Dependencies."; + +$details = "If the rule ...\n"; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE ".IGNORE :\n"; +print MAKEFILE "clean: FORCE\n"; +print MAKEFILE "\t$delete_command clean\n"; +print MAKEFILE "FORCE:\n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + + +# Create a file named "clean". This is the same name as the target clean +# and tricks the target into thinking that it is up to date. (Unless you +# use the .PHONY target. +&touch("clean"); + +$answer = "$delete_command clean\n"; +&run_make_with_options($makefile,"clean",&get_logfile); + +&compare_output($answer,&get_logfile(1)); + +1; + + + + + + + + + diff --git a/tests/scripts/targets/INTERMEDIATE b/tests/scripts/targets/INTERMEDIATE new file mode 100644 index 0000000..4fdd7a2 --- /dev/null +++ b/tests/scripts/targets/INTERMEDIATE @@ -0,0 +1,108 @@ +# -*-perl-*- + +$description = "Test the behaviour of the .INTERMEDIATE target."; + +$details = "\ +Test the behavior of the .INTERMEDIATE special target. +Create a makefile where a file would not normally be considered +intermediate, then specify it as .INTERMEDIATE. Build and ensure it's +deleted properly. Rebuild to ensure that it's not created if it doesn't +exist but doesn't need to be built. Change the original and ensure +that the intermediate file and the ultimate target are both rebuilt, and +that the intermediate file is again deleted. + +Try this with implicit rules and explicit rules: both should work.\n"; + +open(MAKEFILE,"> $makefile"); + +print MAKEFILE <<'EOF'; + +.INTERMEDIATE: foo.e bar.e + +# Implicit rule test +%.d : %.e ; cp $< $@ +%.e : %.f ; cp $< $@ + +foo.d: foo.e + +# Explicit rule test +foo.c: foo.e bar.e; cat $^ > $@ +EOF + +close(MAKEFILE); + +# TEST #0 + +&utouch(-20, 'foo.f', 'bar.f'); + +&run_make_with_options($makefile,'foo.d',&get_logfile); +$answer = "cp foo.f foo.e\ncp foo.e foo.d\nrm foo.e\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST #1 + +&run_make_with_options($makefile,'foo.d',&get_logfile); +$answer = "$make_name: `foo.d' is up to date.\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST #2 + +&utouch(-10, 'foo.d'); +&touch('foo.f'); + +&run_make_with_options($makefile,'foo.d',&get_logfile); +$answer = "cp foo.f foo.e\ncp foo.e foo.d\nrm foo.e\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST #3 + +&run_make_with_options($makefile,'foo.c',&get_logfile); +$answer = "cp foo.f foo.e\ncp bar.f bar.e\ncat foo.e bar.e > foo.c\nrm bar.e foo.e\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST #4 + +&run_make_with_options($makefile,'foo.c',&get_logfile); +$answer = "$make_name: `foo.c' is up to date.\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST #5 + +&utouch(-10, 'foo.c'); +&touch('foo.f'); + +&run_make_with_options($makefile,'foo.c',&get_logfile); +$answer = "cp foo.f foo.e\ncp bar.f bar.e\ncat foo.e bar.e > foo.c\nrm bar.e foo.e\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST #6 -- added for PR/1669: don't remove files mentioned on the cmd line. + +&run_make_with_options($makefile,'foo.e',&get_logfile); +$answer = "cp foo.f foo.e\n"; +&compare_output($answer, &get_logfile(1)); + +unlink('foo.f', 'foo.e', 'foo.d', 'foo.c', 'bar.f', 'bar.e', 'bar.d', 'bar.c'); + +# TEST #7 -- added for PR/1423 + +$makefile2 = &get_tmpfile; + +open(MAKEFILE, "> $makefile2"); + +print MAKEFILE <<'EOF'; +all: foo +foo.a: ; touch $@ +%: %.a ; touch $@ +.INTERMEDIATE: foo.a +EOF + +close(MAKEFILE); + +&run_make_with_options($makefile2, '-R', &get_logfile); +$answer = "touch foo.a\ntouch foo\nrm foo.a\n"; +&compare_output($answer, &get_logfile(1)); + +unlink('foo'); + +# This tells the test driver that the perl test script executed properly. +1; diff --git a/tests/scripts/targets/ONESHELL b/tests/scripts/targets/ONESHELL new file mode 100644 index 0000000..997423f --- /dev/null +++ b/tests/scripts/targets/ONESHELL @@ -0,0 +1,69 @@ +# -*-perl-*- + +$description = "Test the behaviour of the .ONESHELL target."; + +$details = ""; + + +# Simple + +run_make_test(q! +.ONESHELL: +all: + a=$$$$ + [ 0"$$a" -eq "$$$$" ] || echo fail +!, + '', 'a=$$ +[ 0"$a" -eq "$$" ] || echo fail +'); + +# Again, but this time with inner prefix chars + +run_make_test(q! +.ONESHELL: +all: + a=$$$$ + @-+ [ 0"$$a" -eq "$$$$" ] || echo fail +!, + '', 'a=$$ +[ 0"$a" -eq "$$" ] || echo fail +'); + +# This time with outer prefix chars + +run_make_test(q! +.ONESHELL: +all: + @a=$$$$ + [ 0"$$a" -eq "$$$$" ] || echo fail +!, + '', ''); + + +# This time with outer and inner prefix chars + +run_make_test(q! +.ONESHELL: +all: + @a=$$$$ + -@ +[ 0"$$a" -eq "$$$$" ] || echo fail +!, + '', ''); + + +# Now try using a different interpreter + +run_make_test(q! +.RECIPEPREFIX = > +.ONESHELL: +SHELL = #PERL# +.SHELLFLAGS = -e +all: +> @$$a=5 +> +7; +> @y=qw(a b c); +>print "a = $$a, y = (@y)\n"; +!, + '', "a = 12, y = (a b c)\n"); + +1; diff --git a/tests/scripts/targets/PHONY b/tests/scripts/targets/PHONY new file mode 100644 index 0000000..c8e2110 --- /dev/null +++ b/tests/scripts/targets/PHONY @@ -0,0 +1,54 @@ +# -*-perl-*- + +$description = "The following tests the use of a PHONY target. It makes\n" + ."sure that the rules under a target get executed even if\n" + ."a filename of the same name of the target exists in the\n" + ."directory.\n"; + +$details = "This makefile in this test declares the target clean to be a \n" + ."PHONY target. We then create a file named \"clean\" in the \n" + ."directory. Although this file exists, the rule under the target\n" + ."clean should still execute because of it's phony status."; + +$example = "EXAMPLE_FILE"; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE ".PHONY : clean \n"; +print MAKEFILE "all: \n"; +print MAKEFILE "\t\@echo This makefile did not clean the dir ... good\n"; +print MAKEFILE "clean: \n"; +print MAKEFILE "\t$delete_command $example clean\n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&touch($example); + +# Create a file named "clean". This is the same name as the target clean +# and tricks the target into thinking that it is up to date. (Unless you +# use the .PHONY target. +&touch("clean"); + +$answer = "$delete_command $example clean\n"; +&run_make_with_options($makefile,"clean",&get_logfile); + +if (-f $example) { + $test_passed = 0; +} + +&compare_output($answer,&get_logfile(1)); + +1; + + + + + + + + + diff --git a/tests/scripts/targets/POSIX b/tests/scripts/targets/POSIX new file mode 100644 index 0000000..9c30e18 --- /dev/null +++ b/tests/scripts/targets/POSIX @@ -0,0 +1,33 @@ +# -*-perl-*- + +$description = "Test the behaviour of the .PHONY target."; + +$details = ""; + + +# Ensure turning on .POSIX enables the -e flag for the shell +# We can't assume the exit value of "false" because on different systems it's +# different. + +my $script = 'false; true'; +my $flags = '-ec'; +my $out = `/bin/sh $flags '$script' 2>&1`; +my $err = $? >> 8; +run_make_test(qq! +.POSIX: +all: ; \@$script +!, + '', "#MAKE#: *** [all] Error $err\n", 512); + +# User settings must override .POSIX +$flags = '-xc'; +$out = `/bin/sh $flags '$script' 2>&1`; +run_make_test(qq! +.SHELLFLAGS = $flags +.POSIX: +all: ; \@$script +!, + '', $out); + +# This tells the test driver that the perl test script executed properly. +1; diff --git a/tests/scripts/targets/SECONDARY b/tests/scripts/targets/SECONDARY new file mode 100644 index 0000000..c954ee9 --- /dev/null +++ b/tests/scripts/targets/SECONDARY @@ -0,0 +1,189 @@ +#! -*-perl-*- + +$description = "Test the behaviour of the .SECONDARY target."; + +$details = "\ +Test the behavior of the .SECONDARY special target. +Create a makefile where a file would not normally be considered +intermediate, then specify it as .SECONDARY. Build and note that it's +not automatically deleted. Delete the file. Rebuild to ensure that +it's not created if it doesn't exist but doesn't need to be built. +Change the original and ensure that the secondary file and the ultimate +target are both rebuilt, and that the secondary file is not deleted. + +Try this with implicit rules and explicit rules: both should work.\n"; + +open(MAKEFILE,"> $makefile"); + +print MAKEFILE <<'EOF'; + +.SECONDARY: foo.e + +# Implicit rule test +%.d : %.e ; cp $< $@ +%.e : %.f ; cp $< $@ + +foo.d: foo.e + +# Explicit rule test +foo.c: foo.e ; cp $< $@ +EOF + +close(MAKEFILE); + +# TEST #1 + +&utouch(-20, 'foo.f'); + +&run_make_with_options($makefile,'foo.d',&get_logfile); +$answer = "cp foo.f foo.e\ncp foo.e foo.d\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST #2 + +unlink('foo.e'); + +&run_make_with_options($makefile,'foo.d',&get_logfile); +$answer = "$make_name: `foo.d' is up to date.\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST #3 + +&utouch(-10, 'foo.d'); +&touch('foo.f'); + +&run_make_with_options($makefile,'foo.d',&get_logfile); +$answer = "cp foo.f foo.e\ncp foo.e foo.d\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST #4 + +&run_make_with_options($makefile,'foo.c',&get_logfile); +$answer = "cp foo.e foo.c\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST #5 + +unlink('foo.e'); + +&run_make_with_options($makefile,'foo.c',&get_logfile); +$answer = "$make_name: `foo.c' is up to date.\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST #6 + +&utouch(-10, 'foo.c'); +&touch('foo.f'); + +&run_make_with_options($makefile,'foo.c',&get_logfile); +$answer = "cp foo.f foo.e\ncp foo.e foo.c\n"; +&compare_output($answer, &get_logfile(1)); + +unlink('foo.f', 'foo.e', 'foo.d', 'foo.c'); + +# TEST #7 -- test the "global" .SECONDARY, with no targets. + +$makefile2 = &get_tmpfile; + +open(MAKEFILE, "> $makefile2"); + +print MAKEFILE <<'EOF'; +.SECONDARY: + +final: intermediate +intermediate: source + +final intermediate source: + echo $< > $@ +EOF + +close(MAKEFILE); + +&utouch(-10, 'source'); +touch('final'); + +&run_make_with_options($makefile2, '', &get_logfile); +$answer = "$make_name: `final' is up to date.\n"; +&compare_output($answer, &get_logfile(1)); + +unlink('source', 'final', 'intermediate'); + + +# TEST #8 -- test the "global" .SECONDARY, with .PHONY. + +touch('version2'); +run_make_test(' +.PHONY: version +.SECONDARY: +version2: version ; @echo GOOD +all: version2', + 'all', 'GOOD'); + +unlink('version2'); + +# TEST #9 -- Savannah bug #15919 +# The original fix for this bug caused a new bug, shown here. + +touch(qw(1.a 2.a)); + +run_make_test(' +%.c : %.b ; cp $< $@ +%.b : %.a ; cp $< $@ +all : 1.c 2.c', '-rR -j', +'cp 1.a 1.b +cp 2.a 2.b +cp 1.b 1.c +cp 2.b 2.c +rm 1.b 2.b'); + +unlink(qw(1.a 2.a 1.c 2.c)); + +# TEST #10 -- Savannah bug #15919 +touch('test.0'); +run_make_test(' +.SECONDARY : test.1 test.2 test.3 + +test : test.4 + +%.4 : %.int %.3 ; touch $@ + +%.int : %.3 %.2 ; touch $@ + +%.3 : | %.2 ; touch $@ + +%.2 : %.1 ; touch $@ + +%.1 : %.0 ; touch $@', '-rR -j 2', +'touch test.1 +touch test.2 +touch test.3 +touch test.int +touch test.4 +rm test.int'); + +# After a touch of test.0 it should give the same output, except we don't need +# to rebuild test.3 (order-only) +sleep(1); +touch('test.0'); +run_make_test(undef, '-rR -j 2', +'touch test.1 +touch test.2 +touch test.int +touch test.4 +rm test.int'); + +# With both test.0 and test.3 updated it should still build everything except +# test.3 +sleep(1); +touch('test.0', 'test.3'); +run_make_test(undef, '-rR -j 2', +'touch test.1 +touch test.2 +touch test.int +touch test.4 +rm test.int'); + +unlink(qw(test.0 test.1 test.2 test.3 test.4)); + +# This tells the test driver that the perl test script executed properly. +1; diff --git a/tests/scripts/targets/SILENT b/tests/scripts/targets/SILENT new file mode 100644 index 0000000..4bb0a0f --- /dev/null +++ b/tests/scripts/targets/SILENT @@ -0,0 +1,42 @@ +# -*-perl-*- + +$description = "The following tests the special target .SILENT. By simply\n" + ."mentioning this as a target, it tells make not to print\n" + ."commands before executing them."; + +$details = "This test is the same as the clean test except that it should\n" + ."not echo its command before deleting the specified file.\n"; + +$example = "EXAMPLE_FILE"; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE ".SILENT : clean\n"; +print MAKEFILE "clean: \n"; +print MAKEFILE "\t$delete_command EXAMPLE_FILE\n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&touch($example); + +$answer = ""; +&run_make_with_options($makefile,"clean",&get_logfile,0); +if (-f $example) { + $test_passed = 0; +} +&compare_output($answer,&get_logfile(1)); + +1; + + + + + + + + + diff --git a/tests/scripts/targets/clean b/tests/scripts/targets/clean new file mode 100644 index 0000000..b32c976 --- /dev/null +++ b/tests/scripts/targets/clean @@ -0,0 +1,50 @@ +# -*-perl-*- + +$description = "The following test creates a makefile to delete a \n" + ."file in the directory. It tests to see if make will \n" + ."NOT execute the command unless the rule is given in \n" + ."the make command line."; + +$example = "EXAMPLE_FILE"; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE "all: \n"; +print MAKEFILE "\t\@echo This makefile did not clean the dir... good\n"; +print MAKEFILE "clean: \n"; +print MAKEFILE "\t$delete_command EXAMPLE_FILE\n"; + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +&touch($example); + + +&run_make_with_options($makefile,"",&get_logfile,0); + +# Create the answer to what should be produced by this Makefile +$answer = "This makefile did not clean the dir... good\n"; + +&compare_output($answer,&get_logfile(1)) || &error ("abort"); + + +$answer = "$delete_command $example\n"; +&run_make_with_options($makefile,"clean",&get_logfile,0); +if (-f $example) { + $test_passed = 0; +} +&compare_output($answer,&get_logfile(1)) || &error ("abort"); + +1; + + + + + + + + + diff --git a/tests/scripts/test_template b/tests/scripts/test_template new file mode 100644 index 0000000..3fd3f95 --- /dev/null +++ b/tests/scripts/test_template @@ -0,0 +1,29 @@ +# -*-perl-*- + +$description = "<FILL IN SHORT DESCRIPTION HERE>"; +$details = "<FILL IN DETAILS OF HOW YOU TEST WHAT YOU SAY YOU ARE TESTING>"; + +# Run a make test. See the documentation of run_make_test() in +# run_make_tests.pl, but briefly the first argument is a string with the +# contents of a makefile to be tested, the second is a string containing the +# arguments to be passed to the make invocation, the third is a string +# containing the expected output. The fourth is the expected exit code for +# make. If not specified, it's assumed that the make program should succeed +# (exit with 0). + +run_make_test('Your test makefile goes here', + 'Arguments to pass to make go here', + 'Expected output from the invocation goes here'); + +# There are various special tokens, options, etc. See the full documentation +# in run_make_tests.pl. + + +# This tells the test driver that the perl test script executed properly. +1; + + + + + + diff --git a/tests/scripts/variables/CURDIR b/tests/scripts/variables/CURDIR new file mode 100644 index 0000000..ee7cacb --- /dev/null +++ b/tests/scripts/variables/CURDIR @@ -0,0 +1,20 @@ +# -*-perl-*- + +$description = "This tests the CURDIR varaible."; + +$details = "Echo CURDIR both with and without -C. Also ensure overrides work."; + +open(MAKEFILE,"> $makefile"); +print MAKEFILE "all: ; \@echo \$(CURDIR)\n"; +close(MAKEFILE); + + +# TEST #1 +# ------- + +&run_make_with_options($makefile,"",&get_logfile); +$answer = "$pwd\n"; +&compare_output($answer,&get_logfile(1)); + + +1; diff --git a/tests/scripts/variables/DEFAULT_GOAL b/tests/scripts/variables/DEFAULT_GOAL new file mode 100644 index 0000000..1c06506 --- /dev/null +++ b/tests/scripts/variables/DEFAULT_GOAL @@ -0,0 +1,87 @@ +# -*-perl-*- +$description = "Test the .DEFAULT_GOAL special variable."; + +$details = ""; + + +# Test #1: basic logic. +# +run_make_test(' +# Basics. +# +foo: ; @: + +ifneq ($(.DEFAULT_GOAL),foo) +$(error ) +endif + +# Reset to empty. +# +.DEFAULT_GOAL := + +bar: ; @: + +ifneq ($(.DEFAULT_GOAL),bar) +$(error ) +endif + +# Change to a different goal. +# + +.DEFAULT_GOAL := baz + +baz: ; @echo $@ +', +'', +'baz'); + + +# Test #2: unknown goal. +# +run_make_test(' +.DEFAULT_GOAL = foo +', +'', +'#MAKE#: *** No rule to make target `foo\'. Stop.', +512); + + +# Test #3: more than one goal. +# +run_make_test(' +.DEFAULT_GOAL := foo bar +', +'', +'#MAKE#: *** .DEFAULT_GOAL contains more than one target. Stop.', +512); + + +# Test #4: Savannah bug #12226. +# +run_make_test(' +define rule +foo: ; @echo $$@ +endef + +define make-rule +$(eval $(rule)) +endef + +$(call make-rule) + +', +'', +'foo'); + +# TEST #5: .DEFAULT_GOAL containing just whitespace (Savannah bug #25697) + +run_make_test(' +N = +.DEFAULT_GOAL = $N $N # Just whitespace + +foo: ; @echo "boo" +', + '', "#MAKE#: *** No targets. Stop.\n", 512); + +# This tells the test driver that the perl test script executed properly. +1; diff --git a/tests/scripts/variables/INCLUDE_DIRS b/tests/scripts/variables/INCLUDE_DIRS new file mode 100644 index 0000000..c9662e9 --- /dev/null +++ b/tests/scripts/variables/INCLUDE_DIRS @@ -0,0 +1,46 @@ +# -*-perl-*- +$description = "Test the .INCLUDE_DIRS special variable."; + +$details = ""; + +use Cwd; + +$dir = cwd; +$dir =~ s,.*/([^/]+)$,../$1,; + +# Test #1: The content of .INCLUDE_DIRS depends on the platform for which +# make was built. What we know for sure is that it shouldn't be +# empty. +# +run_make_test(' +ifeq ($(.INCLUDE_DIRS),) +$(warning .INCLUDE_DIRS is empty) +endif + +.PHONY: all +all:;@: +', +'', +''); + + +# Test #2: Make sure -I paths end up in .INCLUDE_DIRS. +# +run_make_test(' +ifeq ($(dir),) +$(warning dir is empty) +endif + +ifeq ($(filter $(dir),$(.INCLUDE_DIRS)),) +$(warning .INCLUDE_DIRS does not contain $(dir)) +endif + +.PHONY: all +all:;@: +', +"-I$dir dir=$dir", +''); + + +# This tells the test driver that the perl test script executed properly. +1; diff --git a/tests/scripts/variables/LIBPATTERNS b/tests/scripts/variables/LIBPATTERNS new file mode 100644 index 0000000..826f2fa --- /dev/null +++ b/tests/scripts/variables/LIBPATTERNS @@ -0,0 +1,38 @@ +# -*-perl-*- + +$description = "Test .LIBPATTERNS special variable."; + +$details = ""; + +# TEST 0: basics + +touch('mtest_foo.a'); + +run_make_test(' +.LIBPATTERNS = mtest_%.a +all: -lfoo ; @echo "build $@ from $<" +', + '', "build all from mtest_foo.a\n"); + +# TEST 1: Handle elements that are not patterns. + +run_make_test(' +.LIBPATTERNS = mtest_foo.a mtest_%.a +all: -lfoo ; @echo "build $@ from $<" +', + '', "#MAKE#: .LIBPATTERNS element `mtest_foo.a' is not a pattern +build all from mtest_foo.a\n"); + +# TEST 2: target-specific override + +# Uncomment this when we add support, see Savannah bug #25703 +# run_make_test(' +# .LIBPATTERNS = mbad_%.a +# all: .LIBPATTERNS += mtest_%.a +# all: -lfoo ; @echo "build $@ from $<" +# ', +# '', "build all from mtest_foo.a\n"); + +unlink('mtest_foo.a'); + +1; diff --git a/tests/scripts/variables/MAKE b/tests/scripts/variables/MAKE new file mode 100644 index 0000000..d1081da --- /dev/null +++ b/tests/scripts/variables/MAKE @@ -0,0 +1,24 @@ +# -*-perl-*- + +$description = "Test proper behavior of the MAKE variable"; + +$details = "DETAILS"; + +run_make_test(q! +TMP := $(MAKE) +MAKE := $(subst X=$(X),,$(MAKE)) +all: + @echo $(TMP) + $(MAKE) -f #MAKEFILE# foo + +foo: + @echo $(MAKE) +!, + '', + "#MAKEPATH#\n#MAKEPATH# -f #MAKEFILE# foo\n" + . "#MAKE#[1]: Entering directory `#PWD#'\n" + . "#MAKEPATH#\n#MAKE#[1]: Leaving directory `#PWD#'\n"); + +rmfiles("foo"); + +1; diff --git a/tests/scripts/variables/MAKECMDGOALS b/tests/scripts/variables/MAKECMDGOALS new file mode 100644 index 0000000..879283b --- /dev/null +++ b/tests/scripts/variables/MAKECMDGOALS @@ -0,0 +1,52 @@ +# -*-perl-*- + +$description = "Test the MAKECMDGOALS variable."; + +$details = "\ +We construct a makefile with various targets, all of which print out +\$(MAKECMDGOALS), then call it different ways."; + +open(MAKEFILE,"> $makefile"); +print MAKEFILE "\ +.DEFAULT all: + \@echo \$(MAKECMDGOALS) +"; +close(MAKEFILE); + +# TEST #1 + +&run_make_with_options($makefile, + "", + &get_logfile, + 0); +$answer = "\n"; +&compare_output($answer,&get_logfile(1)); + +# TEST #2 + +&run_make_with_options($makefile, + "all", + &get_logfile, + 0); +$answer = "all\n"; +&compare_output($answer,&get_logfile(1)); + + +# TEST #3 + +&run_make_with_options($makefile, + "foo bar baz yaz", + &get_logfile, + 0); +$answer = "foo bar baz yaz\nfoo bar baz yaz\nfoo bar baz yaz\nfoo bar baz yaz\n"; +&compare_output($answer,&get_logfile(1)); + + +# This tells the test driver that the perl test script executed properly. +1; + + + + + + diff --git a/tests/scripts/variables/MAKEFILES b/tests/scripts/variables/MAKEFILES new file mode 100644 index 0000000..b23da8e --- /dev/null +++ b/tests/scripts/variables/MAKEFILES @@ -0,0 +1,53 @@ +# -*-perl-*- + +$description = "Test the MAKEFILES variable."; + +$makefile2 = &get_tmpfile; +$makefile3 = &get_tmpfile; + +open(MAKEFILE,"> $makefile"); +print MAKEFILE 'all: ; @echo DEFAULT RULE: M2=$(M2) M3=$(M3)', "\n"; +close(MAKEFILE); + + +open(MAKEFILE,"> $makefile2"); +print MAKEFILE <<EOF; +M2 = m2 +NDEF: ; \@echo RULE FROM MAKEFILE 2 +EOF +close(MAKEFILE); + + +open(MAKEFILE,"> $makefile3"); +print MAKEFILE <<EOF; +M3 = m3 +NDEF3: ; \@echo RULE FROM MAKEFILE 3 +EOF +close(MAKEFILE); + + +&run_make_with_options($makefile, "MAKEFILES='$makefile2 $makefile3'", + &get_logfile); +$answer = "DEFAULT RULE: M2=m2 M3=m3\n"; +&compare_output($answer,&get_logfile(1)); + +# TEST 2: Verify that included makefiles don't set the default goal. +# See Savannah bug #13401. + +create_file('xx-inc.mk', ' +include_goal: ; @echo $@ +include xx-ind.mk +'); + +create_file('xx-ind.mk', ' +indirect_goal: ; @echo $@ +'); + +run_make_test(q! +top: ; @echo $@ +!, + 'MAKEFILES=xx-inc.mk', "top\n"); + +unlink(qw(xx-inc.mk xx-ind.mk)); + +1; diff --git a/tests/scripts/variables/MAKEFLAGS b/tests/scripts/variables/MAKEFLAGS new file mode 100644 index 0000000..0b567e8 --- /dev/null +++ b/tests/scripts/variables/MAKEFLAGS @@ -0,0 +1,43 @@ +# -*-perl-*- + +$description = "Test proper behavior of MAKEFLAGS"; + +$details = "DETAILS"; + +# Normal flags aren't prefixed with "-" +run_make_test(q! +all: ; @echo $(MAKEFLAGS) +!, + '-e -r -R', 'Rre'); + +# Long arguments mean everything is prefixed with "-" +run_make_test(q! +all: ; @echo $(MAKEFLAGS) +!, + '--no-print-directory -e -r -R', '--no-print-directory -Rre'); + + +if ($all_tests) { + # Recursive invocations of make should accumulate MAKEFLAGS values. + # Savannah bug #2216 + run_make_test(q! +MSG = Fails +all: + @echo '$@: MAKEFLAGS=$(MAKEFLAGS)' + @MSG=Works $(MAKE) -e -f #MAKEFILE# jump +jump: + @echo '$@: MAKEFLAGS=$(MAKEFLAGS)' + @$(MAKE) -f #MAKEFILE# print +print: + @echo '$@: MAKEFLAGS=$(MAKEFLAGS)' + @echo $(MSG) +.PHONY: all jump print +!, + '--no-print-directory', + 'all: MAKEFLAGS= --no-print-directory +jump: MAKEFLAGS= --no-print-directory -e +print: MAKEFLAGS= --no-print-directory -e +Works'); +} + +1; diff --git a/tests/scripts/variables/MAKELEVEL b/tests/scripts/variables/MAKELEVEL new file mode 100644 index 0000000..96a4e74 --- /dev/null +++ b/tests/scripts/variables/MAKELEVEL @@ -0,0 +1,33 @@ +# -*-perl-*- + +$description = "The following test creates a makefile to test +makelevels in Make. It prints \$(MAKELEVEL) and then +prints the environment variable MAKELEVEL"; + +open(MAKEFILE,"> $makefile"); + +# The Contents of the MAKEFILE ... + +print MAKEFILE <<EOF; +all: +\t\@echo MAKELEVEL is \$(MAKELEVEL) +\techo \$\$MAKELEVEL +EOF + +# END of Contents of MAKEFILE + +close(MAKEFILE); + +# RUN MAKE + +&run_make_with_options($makefile,"",&get_logfile); + +# SET ANSWER + +$answer = "MAKELEVEL is 0\necho \$MAKELEVEL\n1\n"; + +# COMPARE RESULTS + +&compare_output($answer,&get_logfile(1)); + +1; diff --git a/tests/scripts/variables/MAKE_RESTARTS b/tests/scripts/variables/MAKE_RESTARTS new file mode 100644 index 0000000..53ab738 --- /dev/null +++ b/tests/scripts/variables/MAKE_RESTARTS @@ -0,0 +1,62 @@ +# -*-perl-*- + +$description = "Test the MAKE_RESTARTS variable."; + +# Test basic capability + +run_make_test(' +all: ; @: +$(info MAKE_RESTARTS=$(MAKE_RESTARTS)) +include foo.x +foo.x: ; @touch $@ +', + '', 'MAKE_RESTARTS= +#MAKEFILE#:4: foo.x: No such file or directory +MAKE_RESTARTS=1'); + +rmfiles('foo.x'); + +# Test multiple restarts + +run_make_test(' +all: ; @: +$(info MAKE_RESTARTS=$(MAKE_RESTARTS)) +include foo.x +foo.x: ; @echo "include bar.x" > $@ +bar.x: ; @touch $@ +', + '', 'MAKE_RESTARTS= +#MAKEFILE#:4: foo.x: No such file or directory +MAKE_RESTARTS=1 +foo.x:1: bar.x: No such file or directory +MAKE_RESTARTS=2'); + +rmfiles('foo.x', 'bar.x'); + +# Test multiple restarts and make sure the variable is cleaned up + +run_make_test(' +recurse: + @echo recurse MAKE_RESTARTS=$$MAKE_RESTARTS + @$(MAKE) -f #MAKEFILE# all +all: + @echo all MAKE_RESTARTS=$$MAKE_RESTARTS +$(info MAKE_RESTARTS=$(MAKE_RESTARTS)) +include foo.x +foo.x: ; @echo "include bar.x" > $@ +bar.x: ; @touch $@ +', + '', "MAKE_RESTARTS= +#MAKEFILE#:8: foo.x: No such file or directory +MAKE_RESTARTS=1 +foo.x:1: bar.x: No such file or directory +MAKE_RESTARTS=2 +recurse MAKE_RESTARTS= +MAKE_RESTARTS= +#MAKE#[1]: Entering directory `#PWD#' +all MAKE_RESTARTS= +#MAKE#[1]: Leaving directory `#PWD#'"); + +rmfiles('foo.x', 'bar.x'); + +1; diff --git a/tests/scripts/variables/MFILE_LIST b/tests/scripts/variables/MFILE_LIST new file mode 100644 index 0000000..076e42d --- /dev/null +++ b/tests/scripts/variables/MFILE_LIST @@ -0,0 +1,30 @@ +# -*-perl-*- + +$description = "Test the MAKEFILE_LIST variable."; + +$makefile2 = &get_tmpfile; + +open(MAKEFILE,"> $makefile"); +print MAKEFILE <<EOF; +m1 := \$(MAKEFILE_LIST) +include $makefile2 +m3 := \$(MAKEFILE_LIST) + +all: +\t\@echo \$(m1) +\t\@echo \$(m2) +\t\@echo \$(m3) +EOF +close(MAKEFILE); + + +open(MAKEFILE,"> $makefile2"); +print MAKEFILE "m2 := \$(MAKEFILE_LIST)\n"; +close(MAKEFILE); + + +&run_make_with_options($makefile, "", &get_logfile); +$answer = "$makefile\n$makefile $makefile2\n$makefile $makefile2\n"; +&compare_output($answer,&get_logfile(1)); + +1; diff --git a/tests/scripts/variables/SHELL b/tests/scripts/variables/SHELL new file mode 100644 index 0000000..7b7e7fe --- /dev/null +++ b/tests/scripts/variables/SHELL @@ -0,0 +1,86 @@ +# -*-perl-*- + +$description = "Test proper handling of SHELL."; + +# Find the default value when SHELL is not set. On UNIX it will be /bin/sh, +# but on other platforms who knows? +resetENV(); +delete $ENV{SHELL}; +$mshell = `echo 'all:;\@echo \$(SHELL)' | $make_path -f-`; +chop $mshell; + +# According to POSIX, the value of SHELL in the environment has no impact on +# the value in the makefile. +# Note %extraENV takes precedence over the default value for the shell. + +$extraENV{SHELL} = '/dev/null'; +run_make_test('all:;@echo "$(SHELL)"', '', $mshell); + +# According to POSIX, any value of SHELL set in the makefile should _NOT_ be +# exported to the subshell! I wanted to set SHELL to be $^X (perl) in the +# makefile, but make runs $(SHELL) -c 'commandline' and that doesn't work at +# all when $(SHELL) is perl :-/. So, we just add an extra initial /./ which +# works well on UNIX and seems to work OK on at least some non-UNIX systems. + +$extraENV{SHELL} = $mshell; + +run_make_test("SHELL := /./$mshell\n".' +all:;@echo "$(SHELL) $$SHELL" +', '', "/./$mshell $mshell"); + +# As a GNU make extension, if make's SHELL variable is explicitly exported, +# then we really _DO_ export it. + +$extraENV{SHELL} = $mshell; + +run_make_test("export SHELL := /./$mshell\n".' +all:;@echo "$(SHELL) $$SHELL" +', '', "/./$mshell /./$mshell"); + + +# Test out setting of SHELL, both exported and not, as a target-specific +# variable. + +$extraENV{SHELL} = $mshell; + +run_make_test("all: SHELL := /./$mshell\n".' +all:;@echo "$(SHELL) $$SHELL" +', '', "/./$mshell $mshell"); + +$extraENV{SHELL} = $mshell; + +run_make_test(" +SHELL := /././$mshell +one: two +two: export SHELL := /./$mshell\n".' +one two:;@echo "$@: $(SHELL) $$SHELL" +', '', "two: /./$mshell /./$mshell\none: /././$mshell $mshell\n"); + +# Test .SHELLFLAGS + +# We don't know the output here: on Solaris for example, every line printed +# by the shell in -x mode has a trailing space (!!) +my $script = 'true; true'; +my $flags = '-xc'; +my $out = `/bin/sh $flags '$script' 2>&1`; + +run_make_test(qq! +.SHELLFLAGS = $flags +all: ; \@$script +!, + '', $out); + +# We can't just use "false" because on different systems it provides a +# different exit code--once again Solaris: false exits with 255 not 1 +$script = 'true; false; true'; +$flags = '-xec'; +$out = `/bin/sh $flags '$script' 2>&1`; +my $err = $? >> 8; + +run_make_test(qq! +.SHELLFLAGS = $flags +all: ; \@$script +!, + '', "$out#MAKE#: *** [all] Error $err\n", 512); + +1; diff --git a/tests/scripts/variables/automatic b/tests/scripts/variables/automatic new file mode 100644 index 0000000..33c482d --- /dev/null +++ b/tests/scripts/variables/automatic @@ -0,0 +1,122 @@ +# -*-perl-*- + +$description = "Test automatic variable setting."; + +$details = ""; + +use Cwd; + +$dir = cwd; +$dir =~ s,.*/([^/]+)$,../$1,; + +open(MAKEFILE, "> $makefile"); +print MAKEFILE "dir = $dir\n"; +print MAKEFILE <<'EOF'; +.SUFFIXES: +.SUFFIXES: .x .y .z +$(dir)/foo.x : baz.z $(dir)/bar.y baz.z + @echo '$$@ = $@, $$(@D) = $(@D), $$(@F) = $(@F)' + @echo '$$* = $*, $$(*D) = $(*D), $$(*F) = $(*F)' + @echo '$$< = $<, $$(<D) = $(<D), $$(<F) = $(<F)' + @echo '$$^ = $^, $$(^D) = $(^D), $$(^F) = $(^F)' + @echo '$$+ = $+, $$(+D) = $(+D), $$(+F) = $(+F)' + @echo '$$? = $?, $$(?D) = $(?D), $$(?F) = $(?F)' + touch $@ + +$(dir)/bar.y baz.z : ; touch $@ +EOF +close(MAKEFILE); + +# TEST #0 -- simple test +# ------- + +# Touch these into the past +&utouch(-10, qw(foo.x baz.z)); + +&run_make_with_options($makefile, "", &get_logfile); +$answer = "touch $dir/bar.y +\$\@ = $dir/foo.x, \$(\@D) = $dir, \$(\@F) = foo.x +\$* = $dir/foo, \$(*D) = $dir, \$(*F) = foo +\$< = baz.z, \$(<D) = ., \$(<F) = baz.z +\$^ = baz.z $dir/bar.y, \$(^D) = . $dir, \$(^F) = baz.z bar.y +\$+ = baz.z $dir/bar.y baz.z, \$(+D) = . $dir ., \$(+F) = baz.z bar.y baz.z +\$? = $dir/bar.y, \$(?D) = $dir, \$(?F) = bar.y +touch $dir/foo.x\n"; +&compare_output($answer, &get_logfile(1)); + +unlink(qw(foo.x bar.y baz.z)); + +# TEST #1 -- test the SysV emulation of $$@ etc. +# ------- + +$makefile2 = &get_tmpfile; + +open(MAKEFILE, "> $makefile2"); +print MAKEFILE "dir = $dir\n"; +print MAKEFILE <<'EOF'; +.SECONDEXPANSION: +.SUFFIXES: +.DEFAULT: ; @echo '$@' + +$(dir)/foo $(dir)/bar: $@.x $$@.x $$$@.x $$$$@.x $$(@D).x $$(@F).x + +$(dir)/x.z $(dir)/y.z: $(dir)/%.z : $@.% $$@.% $$$@.% $$$$@.% $$(@D).% $$(@F).% + +$(dir)/biz: $$(@).x $${@}.x $${@D}.x $${@F}.x +EOF + +close(MAKEFILE); + +&run_make_with_options($makefile2, "$dir/foo $dir/bar", &get_logfile); +$answer = ".x\n$dir/foo.x\nx\n\$@.x\n$dir.x\nfoo.x\n$dir/bar.x\nbar.x\n"; +&compare_output($answer, &get_logfile(1)); + +&run_make_with_options($makefile2, "$dir/x.z $dir/y.z", &get_logfile); +$answer = ".x\n$dir/x.z.x\nx\n\$@.x\n$dir.x\nx.z.x\n.y\n$dir/y.z.y\n\y\n\$@.y\n$dir.y\ny.z.y\n"; +&compare_output($answer, &get_logfile(1)); + +&run_make_with_options($makefile2, "$dir/biz", &get_logfile); +$answer = "$dir/biz.x\n$dir.x\nbiz.x\n"; +&compare_output($answer, &get_logfile(1)); + +# TEST #2 -- test for Savannah bug #12320. +# +run_make_test(' +.SUFFIXES: .b .src + +mbr.b: mbr.src + @echo $* + +mbr.src: ; @:', + '', + 'mbr'); + +# TEST #3 -- test for Savannah bug #8154 +# Make sure that nonexistent prerequisites are listed in $?, since they are +# considered reasons for the target to be rebuilt. +# +# See also Savannah bugs #16002 and #16051. + +touch('foo'); + +run_make_test(' +foo: bar ; @echo "\$$? = $?" +bar: ;', + '', + '$? = bar'); + +unlink('foo'); + +# TEST #4: ensure prereq ordering is correct when the commmand target has none +# See Savannah bug #21198 + +run_make_test(' +all : A B +all : ; @echo $@ -- $^ -- $< +all : C D +all : E F +A B C D E F G H : ; @: +', + '', "all -- A B C D E F -- A\n"); + +1; diff --git a/tests/scripts/variables/define b/tests/scripts/variables/define new file mode 100644 index 0000000..f91519e --- /dev/null +++ b/tests/scripts/variables/define @@ -0,0 +1,234 @@ +# -*-perl-*- + +$description = "Test define/endef variable assignments."; + +$details = ""; + +# TEST 0: old-style basic define/endef + +run_make_test(' +define multi +@echo hi +echo there +endef + +all: ; $(multi) +', + '', "hi\necho there\nthere\n"); + +# TEST 1: Various new-style define/endef + +run_make_test(' +FOO = foo + +define multi = +echo hi +@echo $(FOO) +endef # this is the end + +define simple := +@echo $(FOO) +endef + +append = @echo a + +define append += + +@echo b +endef + +define cond ?= # this is a conditional +@echo first +endef + +define cond ?= +@echo second +endef + +FOO = there + +all: ; $(multi) + $(simple) + $(append) + $(cond) +', + '', "echo hi\nhi\nthere\nfoo\na\nb\nfirst\n"); + +# TEST 2: define in true section of conditional (containing conditional) + +run_make_test(' +FOO = foo +NAME = def +def = +ifdef BOGUS + define $(subst e,e,$(NAME)) = + ifeq (1,1) + FOO = bar + endif + endef +endif + +$(eval $(def)) +all: ; @echo $(FOO) +', + 'BOGUS=1', "bar\n"); + +# TEST 3: define in false section of conditional (containing conditional) + +run_make_test(undef, '', "foo\n"); + +# TEST 4: nested define (supported?) + +run_make_test(' +define outer + define inner + A = B + endef +endef + +$(eval $(outer)) + +outer: ; @echo $(inner) +', + '', "A = B\n"); + +# TEST 5: NEGATIVE: Missing variable name + +run_make_test(' +NAME = +define $(NAME) = +ouch +endef +all: ; @echo ouch +', + '', "#MAKEFILE#:3: *** empty variable name. Stop.\n", 512); + +# TEST 6: NEGATIVE: extra text after define + +run_make_test(' +NAME = +define NAME = $(NAME) +ouch +endef +all: ; @echo ok +', + '', "#MAKEFILE#:3: extraneous text after `define' directive\nok\n"); + +# TEST 7: NEGATIVE: extra text after endef + +run_make_test(' +NAME = +define NAME = +ouch +endef $(NAME) +all: ; @echo ok +', + '', "#MAKEFILE#:5: extraneous text after `endef' directive\nok\n"); + +# TEST 8: NEGATIVE: missing endef + +run_make_test(' +NAME = +all: ; @echo ok +define NAME = +ouch +endef$(NAME) +', + '', "#MAKEFILE#:4: *** missing `endef', unterminated `define'. Stop.\n", 512); + +# ------------------------- +# Make sure that prefix characters apply properly to define/endef values. +# +# There's a bit of oddness here if you try to use a variable to hold the +# prefix character for a define. Even though something like this: +# +# define foo +# echo bar +# endef +# +# all: ; $(V)$(foo) +# +# (where V=@) can be seen by the user to be obviously different than this: +# +# define foo +# $(V)echo bar +# endef +# +# all: ; $(foo) +# +# and the user thinks it should behave the same as when the "@" is literal +# instead of in a variable, that can't happen because by the time make +# expands the variables for the command line and sees it begins with a "@" it +# can't know anymore whether the prefix character came before the variable +# reference or was included in the first line of the variable reference. + +# TEST #5 +# ------- + +run_make_test(' +define FOO +$(V1)echo hello +$(V2)echo world +endef +all: ; @$(FOO) +', '', 'hello +world'); + +# TEST #6 +# ------- + +run_make_test(undef, 'V1=@ V2=@', 'hello +world'); + +# TEST #7 +# ------- + +run_make_test(' +define FOO +$(V1)echo hello +$(V2)echo world +endef +all: ; $(FOO) +', 'V1=@', 'hello +echo world +world'); + +# TEST #8 +# ------- + +run_make_test(undef, 'V2=@', 'echo hello +hello +world'); + +# TEST #9 +# ------- + +run_make_test(undef, 'V1=@ V2=@', 'hello +world'); + +# TEST #10 +# ------- +# Test the basics; a "@" internally to the variable applies to only one line. +# A "@" before the variable applies to the entire variable. + +run_make_test(' +define FOO +@echo hello +echo world +endef +define BAR +echo hello +echo world +endef + +all: foo bar +foo: ; $(FOO) +bar: ; @$(BAR) +', '', 'hello +echo world +world +hello +world +'); + +1; diff --git a/tests/scripts/variables/flavors b/tests/scripts/variables/flavors new file mode 100644 index 0000000..92feed6 --- /dev/null +++ b/tests/scripts/variables/flavors @@ -0,0 +1,76 @@ +# -*-perl-*- + +$description = "Test various flavors of make variable setting."; + +$details = ""; + +# TEST 0: Recursive + +run_make_test(' +ugh = Goodbye +foo = $(bar) +bar = ${ugh} +ugh = Hello +all: ; @echo $(foo) +', + '', "Hello\n"); + +# TEST 1: Simple + +run_make_test(' +bar = Goodbye +foo := $(bar) +bar = ${ugh} +ugh = Hello +all: ; @echo $(foo) +', + '', "Goodbye\n"); + +# TEST 2: Append to recursive + +run_make_test(' +foo = Hello +ugh = Goodbye +foo += $(bar) +bar = ${ugh} +ugh = Hello +all: ; @echo $(foo) +', + '', "Hello Hello\n"); + +# TEST 3: Append to simple + +run_make_test(' +foo := Hello +ugh = Goodbye +bar = ${ugh} +foo += $(bar) +ugh = Hello +all: ; @echo $(foo) +', + '', "Hello Goodbye\n"); + +# TEST 4: Conditional pre-set + +run_make_test(' +foo = Hello +ugh = Goodbye +bar = ${ugh} +foo ?= $(bar) +ugh = Hello +all: ; @echo $(foo) +', + '', "Hello\n"); + +# TEST 5: Conditional unset + +run_make_test(' +ugh = Goodbye +bar = ${ugh} +foo ?= $(bar) +ugh = Hello +all: ; @echo $(foo) +', + '', "Hello\n"); + +1; diff --git a/tests/scripts/variables/negative b/tests/scripts/variables/negative new file mode 100644 index 0000000..16a72b8 --- /dev/null +++ b/tests/scripts/variables/negative @@ -0,0 +1,46 @@ +# -*-perl-*- + +$description = "Run some negative tests (things that should fail)."; + +# TEST #0 +# Check that non-terminated variable references are detected (and +# reported using the best filename/lineno info +run_make_test(' +foo = bar +x = $(foo +y = $x + +all: ; @echo $y +', + '', '#MAKEFILE#:3: *** unterminated variable reference. Stop.', + 512); + +# TEST #1 +# Bogus variable value passed on the command line. +run_make_test(undef, + 'x=\$\(other', + '#MAKEFILE#:4: *** unterminated variable reference. Stop.', + 512); + +# TEST #2 +# Again, but this time while reading the makefile. +run_make_test(' +foo = bar +x = $(foo +y = $x + +z := $y + +all: ; @echo $y +', + '', '#MAKEFILE#:3: *** unterminated variable reference. Stop.', + 512); + +# TEST #3 +# Bogus variable value passed on the command line. +run_make_test(undef, + 'x=\$\(other', + '#MAKEFILE#:4: *** unterminated variable reference. Stop.', + 512); + +1; diff --git a/tests/scripts/variables/private b/tests/scripts/variables/private new file mode 100644 index 0000000..b4baf5f --- /dev/null +++ b/tests/scripts/variables/private @@ -0,0 +1,78 @@ +# -*-perl-*- + +$description = "Test 'private' variables."; + +$details = ""; + +# 1: Simple verification that private variables are not inherited +&run_make_test(' +a: +F = g +a: F = a +b: private F = b + +a b c: ; @echo $@: F=$(F) +a: b +b: c +', + '', "c: F=a\nb: F=b\na: F=a\n"); + +# 2: Again, but this time we start with "b" so "a"'s variable is not in scope +&run_make_test(undef, 'b', "c: F=g\nb: F=b\n"); + +# 3: Verification with pattern-specific variables +&run_make_test(' +t.a: + +F1 = g +F2 = g +%.a: private F1 = a +%.a: F2 = a + +t.a t.b: ; @echo $@: F1=$(F1) / F2=$(F2) +t.a: t.b +', + '', "t.b: F1=g / F2=a\nt.a: F1=a / F2=a\n"); + +# 4: Test private global variables +&run_make_test(' +a: +private F = g +G := $(F) +a: +b: F = b + +a b: ; @echo $@: F=$(F) / G=$(G) +a: b +', + '', "b: F=b / G=g\na: F= / G=g\n"); + +# 5: Multiple conditions on the same variable. Test export. +delete $ENV{'_X'}; +&run_make_test(' +_X = x +a: export override private _X = a +a: ; @echo _X=$(_X) / _X=$$_X +', + '', "_X=a / _X=a"); + +# 6: Test override. +&run_make_test(undef, '_X=c', "_X=a / _X=a\n"); + +# 7: Ensure keywords still work as targets +&run_make_test(' +a: export override private foo bar +foo bar export override private: ; @echo $@ +', + '', "export\noverride\nprivate\nfoo\nbar\n"); + +# 8: Ensure keywords still work as variables +&run_make_test(' +private = g +a: private = a +a: b +a b: ; @echo $@=$(private) +', + '', "b=a\na=a\n"); + +1; diff --git a/tests/scripts/variables/special b/tests/scripts/variables/special new file mode 100644 index 0000000..a1e15c2 --- /dev/null +++ b/tests/scripts/variables/special @@ -0,0 +1,117 @@ +# -*-perl-*- + +$description = "Test special GNU make variables."; + +$details = ""; + +&run_make_test(' + +X1 := $(sort $(filter FOO BAR,$(.VARIABLES))) + +FOO := foo + +X2 := $(sort $(filter FOO BAR,$(.VARIABLES))) + +BAR := bar + +all: + @echo X1 = $(X1) + @echo X2 = $(X2) + @echo LAST = $(sort $(filter FOO BAR,$(.VARIABLES))) +', + '', "X1 =\nX2 = FOO\nLAST = BAR FOO\n"); + + + +# $makefile2 = &get_tmpfile; +# open(MAKEFILE, "> $makefile2"); + +# print MAKEFILE <<'EOF'; + +# X1 := $(sort $(.TARGETS)) + +# all: foo +# @echo X1 = $(X1) +# @echo X2 = $(X2) +# @echo LAST = $(sort $(.TARGETS)) + +# X2 := $(sort $(.TARGETS)) + +# foo: + +# EOF + +# close(MAKEFILE); + +# # TEST #2 +# # ------- + +# &run_make_with_options($makefile2, "", &get_logfile); +# $answer = "X1 =\nX2 = all\nLAST = all foo\n"; +# &compare_output($answer, &get_logfile(1)); + +# Test the .RECIPEPREFIX variable +&run_make_test(' +define foo +: foo-one \ +foo-two +: foo-three + : foo-four +endef + +orig: ; : orig-one + : orig-two \ +orig-three \ + orig-four \ + orig-five \\\\ + : orig-six + $(foo) + +.RECIPEPREFIX = > +test: ; : test-one +>: test-two \ +test-three \ +>test-four \ +> test-five \\\\ +>: test-six +>$(foo) + +.RECIPEPREFIX = +reset: ; : reset-one + : reset-two \ +reset-three \ + reset-four \ + reset-five \\\\ + : reset-six + $(foo) +', + 'orig test reset', + ': orig-one +: orig-two \ +orig-three \ +orig-four \ + orig-five \\\\ +: orig-six +: foo-one foo-two +: foo-three +: foo-four +: test-one +: test-two \ +test-three \ +test-four \ + test-five \\\\ +: test-six +: foo-one foo-two +: foo-three +: foo-four +: reset-one +: reset-two \ +reset-three \ +reset-four \ + reset-five \\\\ +: reset-six +: foo-one foo-two +: foo-three +: foo-four'); + +1; diff --git a/tests/scripts/variables/undefine b/tests/scripts/variables/undefine new file mode 100644 index 0000000..38707b8 --- /dev/null +++ b/tests/scripts/variables/undefine @@ -0,0 +1,73 @@ +# -*-perl-*- + +$description = "Test variable undefine."; + +$details = ""; + +# TEST 0: basic undefine functionality + +run_make_test(' +a = a +b := b +define c +c +endef + +$(info $(flavor a) $(flavor b) $(flavor c)) + +n := b + +undefine a +undefine $n +undefine c + +$(info $(flavor a) $(flavor b) $(flavor c)) + + +all: ;@: +', +'', "recursive simple recursive\nundefined undefined undefined"); + + +# TEST 1: override + +run_make_test(' +undefine a +override undefine b + +$(info $(flavor a) $(flavor b)) + + +all: ;@: +', +'a=a b=b', "recursive undefined"); + +1; + +# TEST 2: undefine in eval (make sure we undefine from the global var set) + +run_make_test(' +define undef +$(eval undefine $$1) +endef + +a := a +$(call undef,a) +$(info $(flavor a)) + + +all: ;@: +', +'', "undefined"); + + +# TEST 3: Missing variable name + +run_make_test(' +a = +undefine $a +all: ;@echo ouch +', +'', "#MAKEFILE#:3: *** empty variable name. Stop.\n", 512); + +1; diff --git a/tests/test_driver.pl b/tests/test_driver.pl new file mode 100644 index 0000000..dec869d --- /dev/null +++ b/tests/test_driver.pl @@ -0,0 +1,1237 @@ +#!/usr/bin/perl +# -*-perl-*- +# +# Modification history: +# Written 91-12-02 through 92-01-01 by Stephen McGee. +# Modified 92-02-11 through 92-02-22 by Chris Arthur to further generalize. +# +# Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, +# 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software +# Foundation, Inc. +# This file is part of GNU Make. +# +# GNU Make is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 3 of the License, or (at your option) any later +# version. +# +# GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +# details. +# +# You should have received a copy of the GNU General Public License along with +# this program. If not, see <http://www.gnu.org/licenses/>. + + +# Test driver routines used by a number of test suites, including +# those for SCS, make, roll_dir, and scan_deps (?). +# +# this routine controls the whole mess; each test suite sets up a few +# variables and then calls &toplevel, which does all the real work. + +# $Id: test_driver.pl,v 1.30 2010/07/28 05:39:50 psmith Exp $ + + +# The number of test categories we've run +$categories_run = 0; +# The number of test categroies that have passed +$categories_passed = 0; +# The total number of individual tests that have been run +$total_tests_run = 0; +# The total number of individual tests that have passed +$total_tests_passed = 0; +# The number of tests in this category that have been run +$tests_run = 0; +# The number of tests in this category that have passed +$tests_passed = 0; + + +# Yeesh. This whole test environment is such a hack! +$test_passed = 1; + + +# Timeout in seconds. If the test takes longer than this we'll fail it. +$test_timeout = 5; + +# Path to Perl +$perl_name = $^X; + +# %makeENV is the cleaned-out environment. +%makeENV = (); + +# %extraENV are any extra environment variables the tests might want to set. +# These are RESET AFTER EVERY TEST! +%extraENV = (); + +# %origENV is the caller's original environment +%origENV = %ENV; + +sub resetENV +{ + # We used to say "%ENV = ();" but this doesn't work in Perl 5.000 + # through Perl 5.004. It was fixed in Perl 5.004_01, but we don't + # want to require that here, so just delete each one individually. + foreach $v (keys %ENV) { + delete $ENV{$v}; + } + + %ENV = %makeENV; + foreach $v (keys %extraENV) { + $ENV{$v} = $extraENV{$v}; + delete $extraENV{$v}; + } +} + +sub toplevel +{ + # Pull in benign variables from the user's environment + + foreach (# UNIX-specific things + 'TZ', 'TMPDIR', 'HOME', 'USER', 'LOGNAME', 'PATH', + # Purify things + 'PURIFYOPTIONS', + # Windows NT-specific stuff + 'Path', 'SystemRoot', + # DJGPP-specific stuff + 'DJDIR', 'DJGPP', 'SHELL', 'COMSPEC', 'HOSTNAME', 'LFN', + 'FNCASE', '387', 'EMU387', 'GROUP' + ) { + $makeENV{$_} = $ENV{$_} if $ENV{$_}; + } + + # Make sure our compares are not foiled by locale differences + + $makeENV{LC_ALL} = 'C'; + + # Replace the environment with the new one + # + %origENV = %ENV; + + resetENV(); + + $| = 1; # unbuffered output + + $debug = 0; # debug flag + $profile = 0; # profiling flag + $verbose = 0; # verbose mode flag + $detail = 0; # detailed verbosity + $keep = 0; # keep temp files around + $workdir = "work"; # The directory where the test will start running + $scriptdir = "scripts"; # The directory where we find the test scripts + $tmpfilesuffix = "t"; # the suffix used on tmpfiles + $default_output_stack_level = 0; # used by attach_default_output, etc. + $default_input_stack_level = 0; # used by attach_default_input, etc. + $cwd = "."; # don't we wish we knew + $cwdslash = ""; # $cwd . $pathsep, but "" rather than "./" + + &get_osname; # sets $osname, $vos, $pathsep, and $short_filenames + + &set_defaults; # suite-defined + + &parse_command_line (@ARGV); + + print "OS name = `$osname'\n" if $debug; + + $workpath = "$cwdslash$workdir"; + $scriptpath = "$cwdslash$scriptdir"; + + &set_more_defaults; # suite-defined + + &print_banner; + + if (-d $workpath) + { + print "Clearing $workpath...\n"; + &remove_directory_tree("$workpath/") + || &error ("Couldn't wipe out $workpath\n"); + } + else + { + mkdir ($workpath, 0777) || &error ("Couldn't mkdir $workpath: $!\n"); + } + + if (!-d $scriptpath) + { + &error ("Failed to find $scriptpath containing perl test scripts.\n"); + } + + if (@TESTS) + { + print "Making work dirs...\n"; + foreach $test (@TESTS) + { + if ($test =~ /^([^\/]+)\//) + { + $dir = $1; + push (@rmdirs, $dir); + -d "$workpath/$dir" + || mkdir ("$workpath/$dir", 0777) + || &error ("Couldn't mkdir $workpath/$dir: $!\n"); + } + } + } + else + { + print "Finding tests...\n"; + opendir (SCRIPTDIR, $scriptpath) + || &error ("Couldn't opendir $scriptpath: $!\n"); + @dirs = grep (!/^(\..*|CVS|RCS)$/, readdir (SCRIPTDIR) ); + closedir (SCRIPTDIR); + foreach $dir (@dirs) + { + next if ($dir =~ /^(\..*|CVS|RCS)$/ || ! -d "$scriptpath/$dir"); + push (@rmdirs, $dir); + mkdir ("$workpath/$dir", 0777) + || &error ("Couldn't mkdir $workpath/$dir: $!\n"); + opendir (SCRIPTDIR, "$scriptpath/$dir") + || &error ("Couldn't opendir $scriptpath/$dir: $!\n"); + @files = grep (!/^(\..*|CVS|RCS|.*~)$/, readdir (SCRIPTDIR) ); + closedir (SCRIPTDIR); + foreach $test (@files) + { + -d $test and next; + push (@TESTS, "$dir/$test"); + } + } + } + + if (@TESTS == 0) + { + &error ("\nNo tests in $scriptpath, and none were specified.\n"); + } + + print "\n"; + + &run_each_test; + + foreach $dir (@rmdirs) + { + rmdir ("$workpath/$dir"); + } + + $| = 1; + + $categories_failed = $categories_run - $categories_passed; + $total_tests_failed = $total_tests_run - $total_tests_passed; + + if ($total_tests_failed) + { + print "\n$total_tests_failed Test"; + print "s" unless $total_tests_failed == 1; + print " in $categories_failed Categor"; + print ($categories_failed == 1 ? "y" : "ies"); + print " Failed (See .$diffext files in $workdir dir for details) :-(\n\n"; + return 0; + } + else + { + print "\n$total_tests_passed Test"; + print "s" unless $total_tests_passed == 1; + print " in $categories_passed Categor"; + print ($categories_passed == 1 ? "y" : "ies"); + print " Complete ... No Failures :-)\n\n"; + return 1; + } +} + +sub get_osname +{ + # Set up an initial value. In perl5 we can do it the easy way. + $osname = defined($^O) ? $^O : ''; + + # Find a path to Perl + + # See if the filesystem supports long file names with multiple + # dots. DOS doesn't. + $short_filenames = 0; + (open (TOUCHFD, "> fancy.file.name") && close (TOUCHFD)) + || ($short_filenames = 1); + unlink ("fancy.file.name") || ($short_filenames = 1); + + if (! $short_filenames) { + # Thanks go to meyering@cs.utexas.edu (Jim Meyering) for suggesting a + # better way of doing this. (We used to test for existence of a /mnt + # dir, but that apparently fails on an SGI Indigo (whatever that is).) + # Because perl on VOS translates /'s to >'s, we need to test for + # VOSness rather than testing for Unixness (ie, try > instead of /). + + mkdir (".ostest", 0777) || &error ("Couldn't create .ostest: $!\n", 1); + open (TOUCHFD, "> .ostest>ick") && close (TOUCHFD); + chdir (".ostest") || &error ("Couldn't chdir to .ostest: $!\n", 1); + } + + if (! $short_filenames && -f "ick") + { + $osname = "vos"; + $vos = 1; + $pathsep = ">"; + } + else + { + # the following is regrettably knarly, but it seems to be the only way + # to not get ugly error messages if uname can't be found. + # Hmmm, BSD/OS 2.0's uname -a is excessively verbose. Let's try it + # with switches first. + eval "chop (\$osname = `sh -c 'uname -nmsr 2>&1'`)"; + if ($osname =~ /not found/i) + { + $osname = "(something posixy with no uname)"; + } + elsif ($@ ne "" || $?) + { + eval "chop (\$osname = `sh -c 'uname -a 2>&1'`)"; + if ($@ ne "" || $?) + { + $osname = "(something posixy)"; + } + } + $vos = 0; + $pathsep = "/"; + } + + if (! $short_filenames) { + chdir ("..") || &error ("Couldn't chdir to ..: $!\n", 1); + unlink (".ostest>ick"); + rmdir (".ostest") || &error ("Couldn't rmdir .ostest: $!\n", 1); + } +} + +sub parse_command_line +{ + @argv = @_; + + # use @ARGV if no args were passed in + + if (@argv == 0) + { + @argv = @ARGV; + } + + # look at each option; if we don't recognize it, maybe the suite-specific + # command line parsing code will... + + while (@argv) + { + $option = shift @argv; + if ($option =~ /^-debug$/i) + { + print "\nDEBUG ON\n"; + $debug = 1; + } + elsif ($option =~ /^-usage$/i) + { + &print_usage; + exit 0; + } + elsif ($option =~ /^-(h|help)$/i) + { + &print_help; + exit 0; + } + elsif ($option =~ /^-profile$/i) + { + $profile = 1; + } + elsif ($option =~ /^-verbose$/i) + { + $verbose = 1; + } + elsif ($option =~ /^-detail$/i) + { + $detail = 1; + $verbose = 1; + } + elsif ($option =~ /^-keep$/i) + { + $keep = 1; + } + elsif (&valid_option($option)) + { + # The suite-defined subroutine takes care of the option + } + elsif ($option =~ /^-/) + { + print "Invalid option: $option\n"; + &print_usage; + exit 0; + } + else # must be the name of a test + { + $option =~ s/\.pl$//; + push(@TESTS,$option); + } + } +} + +sub max +{ + local($num) = shift @_; + local($newnum); + + while (@_) + { + $newnum = shift @_; + if ($newnum > $num) + { + $num = $newnum; + } + } + + return $num; +} + +sub print_centered +{ + local($width, $string) = @_; + local($pad); + + if (length ($string)) + { + $pad = " " x ( ($width - length ($string) + 1) / 2); + print "$pad$string"; + } +} + +sub print_banner +{ + local($info); + local($line); + local($len); + + $info = "Running tests for $testee on $osname\n"; # $testee is suite-defined + $len = &max (length ($line), length ($testee_version), + length ($banner_info), 73) + 5; + $line = ("-" x $len) . "\n"; + if ($len < 78) + { + $len = 78; + } + + &print_centered ($len, $line); + &print_centered ($len, $info); + &print_centered ($len, $testee_version); # suite-defined + &print_centered ($len, $banner_info); # suite-defined + &print_centered ($len, $line); + print "\n"; +} + +sub run_each_test +{ + $categories_run = 0; + + foreach $testname (sort @TESTS) + { + ++$categories_run; + $suite_passed = 1; # reset by test on failure + $num_of_logfiles = 0; + $num_of_tmpfiles = 0; + $description = ""; + $details = ""; + $old_makefile = undef; + $testname =~ s/^$scriptpath$pathsep//; + $perl_testname = "$scriptpath$pathsep$testname"; + $testname =~ s/(\.pl|\.perl)$//; + $testpath = "$workpath$pathsep$testname"; + # Leave enough space in the extensions to append a number, even + # though it needs to fit into 8+3 limits. + if ($short_filenames) { + $logext = 'l'; + $diffext = 'd'; + $baseext = 'b'; + $runext = 'r'; + $extext = ''; + } else { + $logext = 'log'; + $diffext = 'diff'; + $baseext = 'base'; + $runext = 'run'; + $extext = '.'; + } + $log_filename = "$testpath.$logext"; + $diff_filename = "$testpath.$diffext"; + $base_filename = "$testpath.$baseext"; + $run_filename = "$testpath.$runext"; + $tmp_filename = "$testpath.$tmpfilesuffix"; + + &setup_for_test; # suite-defined + + $output = "........................................................ "; + + substr($output,0,length($testname)) = "$testname "; + + print $output; + + # Run the actual test! + $tests_run = 0; + $tests_passed = 0; + + $code = do $perl_testname; + + $total_tests_run += $tests_run; + $total_tests_passed += $tests_passed; + + # How did it go? + if (!defined($code)) + { + $suite_passed = 0; + if (length ($@)) { + warn "\n*** Test died ($testname): $@\n"; + } else { + warn "\n*** Couldn't run $perl_testname\n"; + } + } + elsif ($code == -1) { + $suite_passed = 0; + } + elsif ($code != 1 && $code != -1) { + $suite_passed = 0; + warn "\n*** Test returned $code\n"; + } + + if ($suite_passed) { + ++$categories_passed; + $status = "ok ($tests_passed passed)"; + for ($i = $num_of_tmpfiles; $i; $i--) + { + &rmfiles ($tmp_filename . &num_suffix ($i) ); + } + + for ($i = $num_of_logfiles ? $num_of_logfiles : 1; $i; $i--) + { + &rmfiles ($log_filename . &num_suffix ($i) ); + &rmfiles ($base_filename . &num_suffix ($i) ); + } + } + elsif (!defined $code || $code > 0) { + $status = "FAILED ($tests_passed/$tests_run passed)"; + } + elsif ($code < 0) { + $status = "N/A"; + --$categories_run; + } + + # If the verbose option has been specified, then a short description + # of each test is printed before displaying the results of each test + # describing WHAT is being tested. + + if ($verbose) + { + if ($detail) + { + print "\nWHAT IS BEING TESTED\n"; + print "--------------------"; + } + print "\n\n$description\n\n"; + } + + # If the detail option has been specified, then the details of HOW + # the test is testing what it says it is testing in the verbose output + # will be displayed here before the results of the test are displayed. + + if ($detail) + { + print "\nHOW IT IS TESTED\n"; + print "----------------"; + print "\n\n$details\n\n"; + } + + print "$status\n"; + } +} + +# If the keep flag is not set, this subroutine deletes all filenames that +# are sent to it. + +sub rmfiles +{ + local(@files) = @_; + + if (!$keep) + { + return (unlink @files); + } + + return 1; +} + +sub print_standard_usage +{ + local($plname,@moreusage) = @_; + local($line); + + print "usage:\t$plname [testname] [-verbose] [-detail] [-keep]\n"; + print "\t\t\t[-profile] [-usage] [-help] [-debug]\n"; + foreach (@moreusage) { + print "\t\t\t$_\n"; + } +} + +sub print_standard_help +{ + local(@morehelp) = @_; + local($line); + local($tline); + local($t) = " "; + + $line = "Test Driver For $testee"; + print "$line\n"; + $line = "=" x length ($line); + print "$line\n"; + + &print_usage; + + print "\ntestname\n" + . "${t}You may, if you wish, run only ONE test if you know the name\n" + . "${t}of that test and specify this name anywhere on the command\n" + . "${t}line. Otherwise ALL existing tests in the scripts directory\n" + . "${t}will be run.\n" + . "-verbose\n" + . "${t}If this option is given, a description of every test is\n" + . "${t}displayed before the test is run. (Not all tests may have\n" + . "${t}descriptions at this time)\n" + . "-detail\n" + . "${t}If this option is given, a detailed description of every\n" + . "${t}test is displayed before the test is run. (Not all tests\n" + . "${t}have descriptions at this time)\n" + . "-profile\n" + . "${t}If this option is given, then the profile file\n" + . "${t}is added to other profiles every time $testee is run.\n" + . "${t}This option only works on VOS at this time.\n" + . "-keep\n" + . "${t}You may give this option if you DO NOT want ANY\n" + . "${t}of the files generated by the tests to be deleted. \n" + . "${t}Without this option, all files generated by the test will\n" + . "${t}be deleted IF THE TEST PASSES.\n" + . "-debug\n" + . "${t}Use this option if you would like to see all of the system\n" + . "${t}calls issued and their return status while running the tests\n" + . "${t}This can be helpful if you're having a problem adding a test\n" + . "${t}to the suite, or if the test fails!\n"; + + foreach $line (@morehelp) + { + $tline = $line; + if (substr ($tline, 0, 1) eq "\t") + { + substr ($tline, 0, 1) = $t; + } + print "$tline\n"; + } +} + +####################################################################### +########### Generic Test Driver Subroutines ########### +####################################################################### + +sub get_caller +{ + local($depth); + local($package); + local($filename); + local($linenum); + + $depth = defined ($_[0]) ? $_[0] : 1; + ($package, $filename, $linenum) = caller ($depth + 1); + return "$filename: $linenum"; +} + +sub error +{ + local($message) = $_[0]; + local($caller) = &get_caller (1); + + if (defined ($_[1])) + { + $caller = &get_caller ($_[1] + 1) . " -> $caller"; + } + + die "$caller: $message"; +} + +sub compare_output +{ + local($answer,$logfile) = @_; + local($slurp, $answer_matched) = ('', 0); + + print "Comparing Output ........ " if $debug; + + $slurp = &read_file_into_string ($logfile); + + # For make, get rid of any time skew error before comparing--too bad this + # has to go into the "generic" driver code :-/ + $slurp =~ s/^.*modification time .*in the future.*\n//gm; + $slurp =~ s/^.*Clock skew detected.*\n//gm; + + ++$tests_run; + + if ($slurp eq $answer) { + $answer_matched = 1; + } else { + # See if it is a slash or CRLF problem + local ($answer_mod, $slurp_mod) = ($answer, $slurp); + + $answer_mod =~ tr,\\,/,; + $answer_mod =~ s,\r\n,\n,gs; + + $slurp_mod =~ tr,\\,/,; + $slurp_mod =~ s,\r\n,\n,gs; + + $answer_matched = ($slurp_mod eq $answer_mod); + + # If it still doesn't match, see if the answer might be a regex. + if (!$answer_matched && $answer =~ m,^/(.+)/$,) { + $answer_matched = ($slurp =~ /$1/); + if (!$answer_matched && $answer_mod =~ m,^/(.+)/$,) { + $answer_matched = ($slurp_mod =~ /$1/); + } + } + } + + if ($answer_matched && $test_passed) + { + print "ok\n" if $debug; + ++$tests_passed; + return 1; + } + + if (! $answer_matched) { + print "DIFFERENT OUTPUT\n" if $debug; + + &create_file (&get_basefile, $answer); + &create_file (&get_runfile, $command_string); + + print "\nCreating Difference File ...\n" if $debug; + + # Create the difference file + + local($command) = "diff -c " . &get_basefile . " " . $logfile; + &run_command_with_output(&get_difffile,$command); + } else { + &rmfiles (); + } + + $suite_passed = 0; + return 0; +} + +sub read_file_into_string +{ + local($filename) = @_; + local($oldslash) = $/; + + undef $/; + + open (RFISFILE, $filename) || return ""; + local ($slurp) = <RFISFILE>; + close (RFISFILE); + + $/ = $oldslash; + + return $slurp; +} + +sub attach_default_output +{ + local ($filename) = @_; + local ($code); + + if ($vos) + { + $code = system "++attach_default_output_hack $filename"; + $code == -2 || &error ("adoh death\n", 1); + return 1; + } + + open ("SAVEDOS" . $default_output_stack_level . "out", ">&STDOUT") + || &error ("ado: $! duping STDOUT\n", 1); + open ("SAVEDOS" . $default_output_stack_level . "err", ">&STDERR") + || &error ("ado: $! duping STDERR\n", 1); + + open (STDOUT, "> " . $filename) + || &error ("ado: $filename: $!\n", 1); + open (STDERR, ">&STDOUT") + || &error ("ado: $filename: $!\n", 1); + + $default_output_stack_level++; +} + +# close the current stdout/stderr, and restore the previous ones from +# the "stack." + +sub detach_default_output +{ + local ($code); + + if ($vos) + { + $code = system "++detach_default_output_hack"; + $code == -2 || &error ("ddoh death\n", 1); + return 1; + } + + if (--$default_output_stack_level < 0) + { + &error ("default output stack has flown under!\n", 1); + } + + close (STDOUT); + close (STDERR); + + open (STDOUT, ">&SAVEDOS" . $default_output_stack_level . "out") + || &error ("ddo: $! duping STDOUT\n", 1); + open (STDERR, ">&SAVEDOS" . $default_output_stack_level . "err") + || &error ("ddo: $! duping STDERR\n", 1); + + close ("SAVEDOS" . $default_output_stack_level . "out") + || &error ("ddo: $! closing SCSDOSout\n", 1); + close ("SAVEDOS" . $default_output_stack_level . "err") + || &error ("ddo: $! closing SAVEDOSerr\n", 1); +} + +# This runs a command without any debugging info. +sub _run_command +{ + my $code; + + # We reset this before every invocation. On Windows I think there is only + # one environment, not one per process, so I think that variables set in + # test scripts might leak into subsequent tests if this isn't reset--??? + resetENV(); + + eval { + local $SIG{ALRM} = sub { die "timeout\n"; }; + alarm $test_timeout; + $code = system(@_); + alarm 0; + }; + if ($@) { + # The eval failed. If it wasn't SIGALRM then die. + $@ eq "timeout\n" or die; + + # Timed out. Resend the alarm to our process group to kill the children. + $SIG{ALRM} = 'IGNORE'; + kill -14, $$; + $code = 14; + } + + return $code; +} + +# run one command (passed as a list of arg 0 - n), returning 0 on success +# and nonzero on failure. + +sub run_command +{ + print "\nrun_command: @_\n" if $debug; + my $code = _run_command(@_); + print "run_command returned $code.\n" if $debug; + + return $code; +} + +# run one command (passed as a list of arg 0 - n, with arg 0 being the +# second arg to this routine), returning 0 on success and non-zero on failure. +# The first arg to this routine is a filename to connect to the stdout +# & stderr of the child process. + +sub run_command_with_output +{ + my $filename = shift; + + print "\nrun_command_with_output($filename,$runname): @_\n" if $debug; + &attach_default_output ($filename); + my $code = _run_command(@_); + &detach_default_output; + print "run_command_with_output returned $code.\n" if $debug; + + return $code; +} + +# performs the equivalent of an "rm -rf" on the first argument. Like +# rm, if the path ends in /, leaves the (now empty) directory; otherwise +# deletes it, too. + +sub remove_directory_tree +{ + local ($targetdir) = @_; + local ($nuketop) = 1; + local ($ch); + + $ch = substr ($targetdir, length ($targetdir) - 1); + if ($ch eq "/" || $ch eq $pathsep) + { + $targetdir = substr ($targetdir, 0, length ($targetdir) - 1); + $nuketop = 0; + } + + if (! -e $targetdir) + { + return 1; + } + + &remove_directory_tree_inner ("RDT00", $targetdir) || return 0; + if ($nuketop) + { + rmdir $targetdir || return 0; + } + + return 1; +} + +sub remove_directory_tree_inner +{ + local ($dirhandle, $targetdir) = @_; + local ($object); + local ($subdirhandle); + + opendir ($dirhandle, $targetdir) || return 0; + $subdirhandle = $dirhandle; + $subdirhandle++; + while ($object = readdir ($dirhandle)) + { + if ($object =~ /^(\.\.?|CVS|RCS)$/) + { + next; + } + + $object = "$targetdir$pathsep$object"; + lstat ($object); + + if (-d _ && &remove_directory_tree_inner ($subdirhandle, $object)) + { + rmdir $object || return 0; + } + else + { + unlink $object || return 0; + } + } + closedir ($dirhandle); + return 1; +} + +# We used to use this behavior for this function: +# +#sub touch +#{ +# local (@filenames) = @_; +# local ($now) = time; +# local ($file); +# +# foreach $file (@filenames) +# { +# utime ($now, $now, $file) +# || (open (TOUCHFD, ">> $file") && close (TOUCHFD)) +# || &error ("Couldn't touch $file: $!\n", 1); +# } +# return 1; +#} +# +# But this behaves badly on networked filesystems where the time is +# skewed, because it sets the time of the file based on the _local_ +# host. Normally when you modify a file, it's the _remote_ host that +# determines the modtime, based on _its_ clock. So, instead, now we open +# the file and write something into it to force the remote host to set +# the modtime correctly according to its clock. +# + +sub touch +{ + local ($file); + + foreach $file (@_) { + (open(T, ">> $file") && print(T "\n") && close(T)) + || &error("Couldn't touch $file: $!\n", 1); + } +} + +# Touch with a time offset. To DTRT, call touch() then use stat() to get the +# access/mod time for each file and apply the offset. + +sub utouch +{ + local ($off) = shift; + local ($file); + + &touch(@_); + + local (@s) = stat($_[0]); + + utime($s[8]+$off, $s[9]+$off, @_); +} + +# open a file, write some stuff to it, and close it. + +sub create_file +{ + local ($filename, @lines) = @_; + + open (CF, "> $filename") || &error ("Couldn't open $filename: $!\n", 1); + foreach $line (@lines) + { + print CF $line; + } + close (CF); +} + +# create a directory tree described by an associative array, wherein each +# key is a relative pathname (using slashes) and its associated value is +# one of: +# DIR indicates a directory +# FILE:contents indicates a file, which should contain contents +\n +# LINK:target indicates a symlink, pointing to $basedir/target +# The first argument is the dir under which the structure will be created +# (the dir will be made and/or cleaned if necessary); the second argument +# is the associative array. + +sub create_dir_tree +{ + local ($basedir, %dirtree) = @_; + local ($path); + + &remove_directory_tree ("$basedir"); + mkdir ($basedir, 0777) || &error ("Couldn't mkdir $basedir: $!\n", 1); + + foreach $path (sort keys (%dirtree)) + { + if ($dirtree {$path} =~ /^DIR$/) + { + mkdir ("$basedir/$path", 0777) + || &error ("Couldn't mkdir $basedir/$path: $!\n", 1); + } + elsif ($dirtree {$path} =~ /^FILE:(.*)$/) + { + &create_file ("$basedir/$path", $1 . "\n"); + } + elsif ($dirtree {$path} =~ /^LINK:(.*)$/) + { + symlink ("$basedir/$1", "$basedir/$path") + || &error ("Couldn't symlink $basedir/$path -> $basedir/$1: $!\n", 1); + } + else + { + &error ("Bogus dirtree type: \"$dirtree{$path}\"\n", 1); + } + } + if ($just_setup_tree) + { + die "Tree is setup...\n"; + } +} + +# compare a directory tree with an associative array in the format used +# by create_dir_tree, above. +# The first argument is the dir under which the structure should be found; +# the second argument is the associative array. + +sub compare_dir_tree +{ + local ($basedir, %dirtree) = @_; + local ($path); + local ($i); + local ($bogus) = 0; + local ($contents); + local ($target); + local ($fulltarget); + local ($found); + local (@files); + local (@allfiles); + + opendir (DIR, $basedir) || &error ("Couldn't open $basedir: $!\n", 1); + @allfiles = grep (!/^(\.\.?|CVS|RCS)$/, readdir (DIR) ); + closedir (DIR); + if ($debug) + { + print "dirtree: (%dirtree)\n$basedir: (@allfiles)\n"; + } + + foreach $path (sort keys (%dirtree)) + { + if ($debug) + { + print "Checking $path ($dirtree{$path}).\n"; + } + + $found = 0; + foreach $i (0 .. $#allfiles) + { + if ($allfiles[$i] eq $path) + { + splice (@allfiles, $i, 1); # delete it + if ($debug) + { + print " Zapped $path; files now (@allfiles).\n"; + } + lstat ("$basedir/$path"); + $found = 1; + last; + } + } + + if (!$found) + { + print "compare_dir_tree: $path does not exist.\n"; + $bogus = 1; + next; + } + + if ($dirtree {$path} =~ /^DIR$/) + { + if (-d _ && opendir (DIR, "$basedir/$path") ) + { + @files = readdir (DIR); + closedir (DIR); + @files = grep (!/^(\.\.?|CVS|RCS)$/ && ($_ = "$path/$_"), @files); + push (@allfiles, @files); + if ($debug) + { + print " Read in $path; new files (@files).\n"; + } + } + else + { + print "compare_dir_tree: $path is not a dir.\n"; + $bogus = 1; + } + } + elsif ($dirtree {$path} =~ /^FILE:(.*)$/) + { + if (-l _ || !-f _) + { + print "compare_dir_tree: $path is not a file.\n"; + $bogus = 1; + next; + } + + if ($1 ne "*") + { + $contents = &read_file_into_string ("$basedir/$path"); + if ($contents ne "$1\n") + { + print "compare_dir_tree: $path contains wrong stuff." + . " Is:\n$contentsShould be:\n$1\n"; + $bogus = 1; + } + } + } + elsif ($dirtree {$path} =~ /^LINK:(.*)$/) + { + $target = $1; + if (!-l _) + { + print "compare_dir_tree: $path is not a link.\n"; + $bogus = 1; + next; + } + + $contents = readlink ("$basedir/$path"); + $contents =~ tr/>/\//; + $fulltarget = "$basedir/$target"; + $fulltarget =~ tr/>/\//; + if (!($contents =~ /$fulltarget$/)) + { + if ($debug) + { + $target = $fulltarget; + } + print "compare_dir_tree: $path should be link to $target, " + . "not $contents.\n"; + $bogus = 1; + } + } + else + { + &error ("Bogus dirtree type: \"$dirtree{$path}\"\n", 1); + } + } + + if ($debug) + { + print "leftovers: (@allfiles).\n"; + } + + foreach $file (@allfiles) + { + print "compare_dir_tree: $file should not exist.\n"; + $bogus = 1; + } + + return !$bogus; +} + +# this subroutine generates the numeric suffix used to keep tmp filenames, +# log filenames, etc., unique. If the number passed in is 1, then a null +# string is returned; otherwise, we return ".n", where n + 1 is the number +# we were given. + +sub num_suffix +{ + local($num) = @_; + + if (--$num > 0) { + return "$extext$num"; + } + + return ""; +} + +# This subroutine returns a log filename with a number appended to +# the end corresponding to how many logfiles have been created in the +# current running test. An optional parameter may be passed (0 or 1). +# If a 1 is passed, then it does NOT increment the logfile counter +# and returns the name of the latest logfile. If either no parameter +# is passed at all or a 0 is passed, then the logfile counter is +# incremented and the new name is returned. + +sub get_logfile +{ + local($no_increment) = @_; + + $num_of_logfiles += !$no_increment; + + return ($log_filename . &num_suffix ($num_of_logfiles)); +} + +# This subroutine returns a base (answer) filename with a number +# appended to the end corresponding to how many logfiles (and thus +# base files) have been created in the current running test. +# NO PARAMETERS ARE PASSED TO THIS SUBROUTINE. + +sub get_basefile +{ + return ($base_filename . &num_suffix ($num_of_logfiles)); +} + +# This subroutine returns a difference filename with a number appended +# to the end corresponding to how many logfiles (and thus diff files) +# have been created in the current running test. + +sub get_difffile +{ + return ($diff_filename . &num_suffix ($num_of_logfiles)); +} + +# This subroutine returns a command filename with a number appended +# to the end corresponding to how many logfiles (and thus command files) +# have been created in the current running test. + +sub get_runfile +{ + return ($run_filename . &num_suffix ($num_of_logfiles)); +} + +# just like logfile, only a generic tmp filename for use by the test. +# they are automatically cleaned up unless -keep was used, or the test fails. +# Pass an argument of 1 to return the same filename as the previous call. + +sub get_tmpfile +{ + local($no_increment) = @_; + + $num_of_tmpfiles += !$no_increment; + + return ($tmp_filename . &num_suffix ($num_of_tmpfiles)); +} + +1; |