From dce43e78489ec82836d013fd6095fca585aca6dc Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Sun, 17 Sep 2023 10:39:03 -0600 Subject: Niggly User Guide Chap 2/3 updates [skip appveyor] Including: * New standard header * Markup, including use provided for SConstruct files instead of (renders the same, ATM). * Add a Fortran Hello, world for fun. * Don't use "we" or "our" (generic documentation advice, supposedly presents an air of superiority) * Add xml id to sections, to make permalinks (without, tools generate a numeric ID which may change over time, like: https://scons.org/doc/production/HTML/scons-user.html#idp105549032602952) Signed-off-by: Mats Wichmann --- CHANGES.txt | 8 +- RELEASE.txt | 3 +- doc/user/less-simple.xml | 157 +++++++++++++--------------- doc/user/simple.xml | 259 +++++++++++++++++++++++++---------------------- 4 files changed, 211 insertions(+), 216 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 364f128..287fd18 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -51,7 +51,7 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER If YACC_GRAPH_FILE_SUFFIX is not set, it will respect YACCVCGFILESUFFIX. From Philipp Maierhöfer: - - Fix gfortran tool initialization. Defaults to using binary named gfortran + - Fix gfortran tool initialization. Defaults to using binary named gfortran as would be expected, and properly set's SHFORTRAN flags to include -fPIC where previously it was only doing so for the other fortran versions (F77,..) @@ -165,9 +165,9 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER (Enabled/specified by SCONS_CACHE_MSVC_CONFIG). The existing cache will be discarded if there's a decode error reading it. It's possible there's a race condition creating this issue in certain CI - builds. - Also add a simple filesystem-based locking protocol to try to - avoide the problem occuring. + builds. Also add a simple filesystem-based locking protocol to try to + avoid the problem occuring. + - Update the first two chapters on building with SCons in the User Guide. From Jonathon Reinhart: - Fix another instance of `int main()` in CheckLib() causing failures diff --git a/RELEASE.txt b/RELEASE.txt index b1e49ff..e45284c 100644 --- a/RELEASE.txt +++ b/RELEASE.txt @@ -100,7 +100,7 @@ FIXES with the python logging module was refactored to prevent test failure. - MSVS: Add arm64 to the MSVS supported architectures list for VS2017 and later to be consistent with the current documentation of MSVS_ARCH. -- FORTRAN: Fix gfortran tool initialization. Defaults to using binary named gfortran +- FORTRAN: Fix gfortran tool initialization. Defaults to using binary named gfortran as would be expected, and properly set's SHFORTRAN flags to include -fPIC where previously it was only doing so for the other fortran versions (F77,..) - MSCommon: Added more error handling while reading msvc config cache. @@ -132,6 +132,7 @@ DOCUMENTATION usage, which had no problem). - Changed the message about scons -H to clarify it shows built-in options only. - Cachedir description updated. +- Updated the first two chapters on building with SCons in the User Guide. DEVELOPMENT ----------- diff --git a/doc/user/less-simple.xml b/doc/user/less-simple.xml index 3eda19c..8a30cdf 100644 --- a/doc/user/less-simple.xml +++ b/doc/user/less-simple.xml @@ -1,4 +1,9 @@ + %scons; @@ -17,46 +22,19 @@ xmlns="http://www.scons.org/dbxsd/v1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.scons.org/dbxsd/v1.0 http://www.scons.org/dbxsd/v1.0/scons.xsd"> -Less Simple Things to Do With Builds - - +Less Simple Things to Do With Builds + Of course, most builds are more complicated than in the previous chapter. In this chapter, - you will see several examples of - very simple build configurations using &SCons;, - which will demonstrate how easy - it is to use &SCons; to - build programs from several different programming languages - on different types of systems. + you will learn about builds that incorporate multiple source files, + and then about building multiple targets that share some source files. -
+
Specifying the Name of the Target (Output) File @@ -71,14 +49,15 @@ - + Program('hello.c') - + If you want to build a program with - a different name than the base of the source file name, + a different base name than the base of the source file name + (or even the same name), you simply put the target file name to the left of the source file name: @@ -95,14 +74,14 @@ int main() { printf("Hello, world!\n"); } - (&SCons; requires the target file name first, + &SCons; requires the target file name first, followed by the source file name, so that the order mimics that of an assignment statement in most programming languages, - including Python: + including &Python;: "target = source files". For an alternative way to supply this information, see - ). + . @@ -130,7 +109,7 @@ int main() { printf("Hello, world!\n"); }
-
+
Compiling Multiple Source Files @@ -141,7 +120,7 @@ int main() { printf("Hello, world!\n"); } that you'll need to build a program from many input source files, not just one. To do this, you need to put the - source files in a Python list + source files in a &Python; list (enclosed in square brackets), like so: @@ -182,15 +161,11 @@ void file2() { printf("file2.c\n"); } &SCons; will name the resulting program &prog; (or &prog_exe; on a Windows system). If you want to specify a different program name, - then (as we've seen in the previous section) + then (as described in the previous section) you slide the list of source files over to the right to make room for the output program file name. - (&SCons; puts the output file name to the left - of the source file names - so that the order mimics that of an - assignment statement: program = source files.) - This makes our example: + Here is the updated example: @@ -231,7 +206,7 @@ void file2() { printf("file2.c\n"); }
-
+
Making a list of files with &Glob; @@ -256,7 +231,8 @@ Program('program', Glob('*.c')) &f-Glob; has powerful capabilities - it matches even if the - file does not exist, but &SCons; can determine that it would + file does not currently exist, + but &SCons; can determine that it would exist after a build. You will meet it again reading about variant directories @@ -268,12 +244,12 @@ Program('program', Glob('*.c'))
-
+
Specifying Single Files Vs. Lists of Files - We've now shown you two ways to specify + You've now seen two ways to specify the source for a program, one with a list of files: @@ -295,7 +271,7 @@ Program('hello', 'hello.c') - You could actually put a single file name in a list, too, + You can actually put a single file name in a list, too, which you might prefer just for the sake of consistency: @@ -321,7 +297,7 @@ Program('hello', ['hello.c']) Although &SCons; functions are forgiving about whether or not you use a string vs. a list for a single file name, - Python itself is more strict about + &Python; itself is more strict about treating lists and strings differently. So where &SCons; allows either a string or list: @@ -336,7 +312,7 @@ Program('program2', ['program2.c']) - Trying to do "Python things" that mix strings and + Trying to do "&Python; things" that mix strings and lists will cause errors or lead to incorrect results: @@ -357,18 +333,18 @@ Program('program2', common_sources + ['program2.c'])
-
+
Making Lists of Files Easier to Read - One drawback to the use of a Python list + One drawback to the use of a &Python; list for source files is that each file name must be enclosed in quotes (either single quotes or double quotes). This can get cumbersome and difficult to read when the list of file names is long. - Fortunately, &SCons; and Python provide a number of ways + Fortunately, &SCons; and &Python; provide a number of ways to make sure that the &SConstruct; file stays easy to read. @@ -378,7 +354,7 @@ Program('program2', common_sources + ['program2.c']) To make long lists of file names easier to deal with, &SCons; provides a - &Split; function + &f-link-Split; function that takes a quoted list of file names, with the names separated by spaces or other white-space characters, and turns it into a list of separate file names. @@ -387,17 +363,17 @@ Program('program2', common_sources + ['program2.c']) - + Program('program', Split('main.c file1.c file2.c')) - + - (If you're already familiar with Python, + (If you're already familiar with &Python;, you'll have realized that this is similar to the split() method - in the Python standard string module. - Unlike the split() member function of strings, + of &Python; string objects.. + Unlike the split() method, however, the &Split; function does not require a string as input and will wrap up a single non-string object in a list, @@ -421,10 +397,10 @@ Program('program', Split('main.c file1.c file2.c')) - + src_files = Split('main.c file1.c file2.c') Program('program', src_files) - + @@ -437,44 +413,47 @@ Program('program', src_files) - -src_files = Split("""main.c - file1.c - file2.c""") + +src_files = Split(""" + main.c + file1.c + file2.c +""") Program('program', src_files) - + - (Note in this example that we used - the Python "triple-quote" syntax, - which allows a string to contain - multiple lines. + (Note this example uses + the &Python; "triple-quote" syntax, + which allows a string to span multiple lines. The three quotes can be either - single or double quotes.) + single or double quotes as long as they match.)
-
+
Keyword Arguments &SCons; also allows you to identify the output file and input source files - using Python keyword arguments + using &Python; keyword arguments target and source. - The Python syntax for this is: + A keyword argument is an argument preceded by an identifier, + of the form name=value, in a function call. + The usage looks like this example: - + src_files = Split('main.c file1.c file2.c') Program(target='program', source=src_files) - + @@ -484,10 +463,10 @@ Program(target='program', source=src_files) - + src_files = Split('main.c file1.c file2.c') Program(source=src_files, target='program') - + @@ -502,7 +481,7 @@ Program(source=src_files, target='program')
-
+
Compiling Multiple Programs @@ -549,14 +528,14 @@ void bar2() { printf("bar2.c\n"); } &SCons; does, however, recognize that the individual object files must be built before the resulting program can be built. - We'll discuss this in greater detail in - the "Dependencies" section, below. + (This will be covered in greater detail in + , below.)
-
+
Sharing Source Files Between Multiple Programs @@ -623,20 +602,20 @@ void common22() { printf("common2.c\n"); } repeating the common files in the list for each program can be a maintenance problem when you need to change the list of common files. - You can simplify this by creating a separate Python list + You can simplify this by creating a separate &Python; list to hold the common file names, and concatenating it with other lists - using the Python + operator: + using the &Python; + operator: - + common = ['common1.c', 'common2.c'] foo_files = ['foo.c'] + common bar_files = ['bar1.c', 'bar2.c'] + common Program('foo', foo_files) Program('bar', bar_files) - + diff --git a/doc/user/simple.xml b/doc/user/simple.xml index 7f35ee1..6f27b4f 100644 --- a/doc/user/simple.xml +++ b/doc/user/simple.xml @@ -1,4 +1,10 @@ + + %scons; @@ -17,51 +23,30 @@ xmlns="http://www.scons.org/dbxsd/v1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.scons.org/dbxsd/v1.0 http://www.scons.org/dbxsd/v1.0/scons.xsd"> -Simple Builds - - +Simple Builds - In this chapter, - you will see several examples of + The single most important thing you do when writing a + build system for your project is to describe the "what": + what you want to build, and which files you want to build it from. + And, in fact, simpler builds may need no more. + In this chapter, you will see several examples of very simple build configurations using &SCons;, - which will demonstrate how easy - it is to use &SCons; to - build programs from several different programming languages - on different types of systems. + which will demonstrate how easy &SCons; makes it to + build programs on different types of systems. -
+
Building Simple C / C++ Programs - Here's the famous "Hello, World!" program in C: + Here's the ubiquitous + + "Hello, World!" program in C: @@ -71,7 +56,7 @@ int main() { - printf("Hello, world!\n"); + printf("Hello, world!\n"); } @@ -94,16 +79,16 @@ int main() { printf("Hello, world!\n"); } - This minimal configuration file gives - &SCons; two pieces of information: - what you want to build - (an executable program), - and the input file from - which you want it built + This minimal build file gives + &SCons; three key pieces of information: + what you want to build (a program); + what you want to call that program (its + base name will be hello), + and the source file you want it built from (the hello.c file). - &b-link-Program; is a &builder_method;, - a Python call that tells &SCons; that you want to build an - executable program. + &b-link-Program; is a &Builder;, + an &SCons; function that you use to instruct + &SCons; about the "what" of your build. @@ -132,46 +117,75 @@ int main() { printf("Hello, world!\n"); } - First, notice that you only need - to specify the name of the source file, - and that &SCons; correctly deduces the names of - the object and executable files to be built - from the base of the source file name. + Notice that &SCons; deduced quite a bit here: it figured + out the name of the program to build, including operating + system specific suffixes (&hello; or &hello_exe;), based off + the basename of the source file; it knows an intermediate + object file should be built (&hello_o; or &hello_obj;); + and it knows how to build those things using the compiler + that is appropriate on the system you're using. + It was not necessary to instruct &SCons; about any of those + details. + This is an example of how &SCons; + makes it easy to write portable software builds. - Second, notice that the same input &SConstruct; file, - without any changes, - generates the correct output file names on both systems: - &hello_o; and &hello; on POSIX systems, - &hello_obj; and &hello_exe; on Windows systems. - This is a simple example of how &SCons; - makes it extremely easy to - write portable software builds. + For the programming languages &SCons; already knows about, + it will mostly just figure it out. + Here's the "Hello, World!" example in Fortran: - + +program hello + print *, 'Hello, World!' +end program hello + - (Note that we won't provide duplicate side-by-side - POSIX and Windows output for all of the examples in this guide; - just keep in mind that, unless otherwise specified, - any of the examples should work equally well on both types of systems.) + +Program('hello', 'hello.f90') + - + + + + +$ scons +scons: Reading SConscript files ... +scons: done reading SConscript files. +scons: Building targets ... +gfortran -o hello.o -c hello.f90 +gfortran -o hello hello.o +scons: done building targets. +
-
+
Building Object Files - The &b-link-Program; builder method is only one of - many builder methods that &SCons; provides - to build different types of files. + The &b-link-Program; builder is only one of + many builders (also called a &builder_method;) + that &SCons; provides to build different types of files. Another is the &b-link-Object; builder method, which tells &SCons; to build an object file from the specified source file: @@ -209,9 +223,18 @@ int main() { printf("Hello, world!\n"); } scons + + + (Note that this guide will not continue to provide duplicate side-by-side + POSIX and Windows output for all of the examples. + Just keep in mind that, unless otherwise specified, + any of the examples should work equally well on both types of systems.) + + +
-
+
Simple Java Builds @@ -258,28 +281,30 @@ public class Example1 - We'll cover Java builds in more detail, - including building Java archive (.jar) - and other types of file, + Java builds will be covered in much more detail, + including building a Java archive (.jar) + and other types of files, in .
-
+
Cleaning Up After a Build - When using &SCons;, it is unnecessary to add special - commands or target names to clean up after a build. - Instead, you simply use the + For cleaning up your build tree, &SCons; provides a + "clean" mode, selected by the or - option when you invoke &SCons;, - and &SCons; removes the appropriate built files. - So if we build our example above - and then invoke scons -c + option when you invoke &SCons;. + &SCons; selects the same set of targets it would in build mode, + but instead of building, removes them. + That means you can control what is cleaned + in exactly the same way as you control what gets built. + If you build the C example above + and then invoke scons -c afterwards, the output on POSIX looks like: @@ -312,14 +337,14 @@ int main() { printf("Hello, world!\n"); } Notice that &SCons; changes its output to tell you that it - is Cleaning targets ... and - done cleaning targets. + is Cleaning targets ... and + done cleaning targets.
-
+
The &SConstruct; File @@ -332,36 +357,38 @@ int main() { printf("Hello, world!\n"); } -
+
&SConstruct; Files Are Python Scripts There is, however, an important difference between an &SConstruct; file and a &Makefile;: - the &SConstruct; file is actually a Python script. - If you're not already familiar with Python, don't worry. + the &SConstruct; file is actually a &Python; script. + If you're not already familiar with &Python;, don't worry. This User's Guide will introduce you step-by-step - to the relatively small amount of Python you'll + to the relatively small amount of &Python; you'll need to know to be able to use &SCons; effectively. - And Python is very easy to learn. + And &Python; is very easy to learn. - One aspect of using Python as the + One aspect of using &Python; as the scripting language is that you can put comments - in your &SConstruct; file using Python's commenting convention; - that is, everything between a '#' and the end of the line - will be ignored: + in your &SConstruct; file using &Python;'s commenting convention: + everything between a # character + and the end of the line will be ignored + (unless the character appears inside a string constant). - + # Arrange to build the "hello" program. -Program('hello.c') # "hello.c" is the source file. - +Program("hello.c") # "hello.c" is the source file. +Program("#goodbye.c") # the # in "#goodbye" does not indicate a comment + @@ -375,21 +402,21 @@ Program('hello.c') # "hello.c" is the source file.
-
- &SCons; Functions Are Order-Independent +
+ &SCons; Builders Are Order-Independent One important way in which the &SConstruct; - file is not exactly like a normal Python script, + file is not exactly like a normal &Python; script, and is more like a &Makefile;, is that the order in which - the &SCons; functions are called in + the &SCons; Builder functions are called in the &SConstruct; file does not affect the order in which &SCons; actually builds the programs and object files - you want it to build + you want it to build. In programming parlance, the &SConstruct; file is declarative, @@ -407,7 +434,7 @@ Program('hello.c') # "hello.c" is the source file. Instead, you're telling &SCons; what you want accomplished, and it's up to &SCons; to figure out how to do that, and to take those steps if/when it's necessary. - We'll learn more about how + you'll learn more about how &SCons; decides when building or rebuilding a target is necessary in , below. @@ -422,7 +449,7 @@ Program('hello.c') # "hello.c" is the source file. when it's "just reading" the &SConstruct; file, and when it's actually building the target files. This is to make it clear when &SCons; is - executing the Python statements that make up the &SConstruct; file, + executing the &Python; statements that make up the &SConstruct; file, and when &SCons; is actually executing the commands or other actions to build the necessary files. @@ -432,10 +459,10 @@ Program('hello.c') # "hello.c" is the source file. Let's clarify this with an example. - Python has a print function that + &Python; has a print function that prints a string of characters to the screen. - If we put print calls around - our calls to the &b-Program; builder method: + If you put print calls around + the calls to the &b-Program; builder method: @@ -457,12 +484,12 @@ int main() { printf("Goodbye, world!\n"); } - Then when we execute &SCons;, - we see the output from calling the print + Then when you execute &SCons;, + you will see the output from calling the print function in between the messages about reading the &SConscript; files, indicating that is when the - Python statements are being executed: + &Python; statements are being executed: @@ -474,28 +501,16 @@ int main() { printf("Goodbye, world!\n"); } Notice that &SCons; built the &goodbye; program first, even though the "reading &SConscript;" output - shows that we called Program('hello.c') + shows that Program('hello.c') was called first in the &SConstruct; file. - - - Notice also that &SCons; was able to infer a lot of information - from the two &Program; calls. Because - &hello_c; and goodbye.c - were recognized as C-language source files, it knew to build - the intermediate target files &hello_o; and &goodbye_o; - and the final files &hello; and &goodbye; - It was not necessary to program &scons; beyond just calling &Program;. - - -
-
+
Making the &SCons; Output Less Verbose @@ -538,9 +553,9 @@ int main() { printf("Goodbye, world!\n"); } - Because we want this User's Guide to focus + So this User's Guide can focus on what &SCons; is actually doing, - we're going to use the &Q; option + the &Q; option will be used to remove these messages from the output of all the remaining examples in this Guide. -- cgit v0.12