From d16f56291a60c28b437446b5d7f10dba930561d1 Mon Sep 17 00:00:00 2001 From: Paul Wessel Date: Mon, 11 May 2020 16:29:43 -1000 Subject: [PATCH 01/14] Create develop.rst Add new document to help developers write modules and compile supplements. --- doc/rst/source/develop.rst | 121 +++++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 doc/rst/source/develop.rst diff --git a/doc/rst/source/develop.rst b/doc/rst/source/develop.rst new file mode 100644 index 00000000000..e0f339febd9 --- /dev/null +++ b/doc/rst/source/develop.rst @@ -0,0 +1,121 @@ +.. index:: ! debug + +************************ +Debugging for Developers +************************ + +GMT developers may need to run GMT in a debugger to figure out the problem reported by +an issue. Often there is a bit of detective work involved to find out where a module +crashes and then step carefully through that section, examining variables etc., to learn +why something fails. This process depends on the particular debug tool one uses. This page +will explain the steps a developer must take to build gmt so it is suitable for your debug +tool and how to use that tool. + +Xcode on macOS +-------------- + +Developers on macOS are most likely to want to use Xcode for this purpose. Chances are they +are already using the command-line tools from Xcode (gcc, linker) anyway. To use the GUI +part of Xcode you must have installed the full Xcode (you most likely did, but there are +ways to *only* install the command-line tools, so make sure you have an Xcode icon under +Applications). Xcode may change as versions change; the images below is for Xcode 10-11. + +#. You will need to make some changes to your *cmake/ConfigUserAdvanced.cmake* file. Scroll down to the + section that says "# Extra debugging for developers:" and uncomment the ~6 lines that has + the if-test on "Xcode". This will pass a few flags that are used when debugging via Xcode. + Also uncomment the two "add_definitions" lines that contain the word "DEBUG" in it somewhere. + +#. You will need to build GMT again. I recommend you do this in a separate build directory (I + call mine *xbuild*, and while at it I use *rbuild* for "Release Builds" and *dbuild* for regular + debug command line builds, and *build* for the final build for the releases). If you are in + the *xbuild* directory, these two commands will do the build:: + + cmake -DCMAKE_INSTALL_PREFIX=gmt6 -DCMAKE_BUILD_TYPE=Debug -G Xcode .. + xcodebuild + +#. After this step you can launch the Xcode application and then use the File->Open menu to + open the project file *xbuild/GMT.xcodeproj*. After it opens it may looks something like + this (click on the figure to enlarge it): + + .. figure:: /_images/xcode-1.* + :width: 100% + :align: center + +#. Pull down the tab that says "@ ALL_BUILD" and select "gmt" about 35 lines down, then in the + left sidebar open the folder called gmt->Source Files and select gmt.c. Now you may wish + to drag the window to be a bit wider so the lines don't wrap around so much. After that step + your screen may look more like this: + + .. figure:: /_images/xcode-2.* + :width: 100% + :align: center + +#. Scroll down to the part around line 119 and click the line number to place a stop point; it + will add a blue fat arrow at that line: + + .. figure:: /_images/xcode-3.* + :width: 100% + :align: center + + This is *usually* the first stop you want in Xcode. The exception would be if you are debugging + gmt.c itself or you need to examine the code that creates the session via a call to GMT_Create_Session + earlier in the program. + +#. Now we need to specify the particular command we wish to debug. Let's pretend that :doc:`pstext` + crashes when we run the command:: + + gmt pstext my_text.txt -R0/30/-10/20 -JM15c -Baf -F+f16p > text.ps + + Copy that command minus the initial "gmt " part. Now pull down the menu item "Product->Scheme->Edit Scheme", + then make sure "Arguments" is highlighted in blue in the top table, then click the "+" symbol beneath the + section that says "Arguments Passed on Launch" and paste in our command; it should result in this display: + + .. figure:: /_images/xcode-4.* + :width: 100% + :align: center + + Normally you do not need to set any "Environmental Variables", but if you are debugging a module that + calls an external program (e.g., gs, gdal_translate, etc.) then you may need to add the name PATH and + place the path to that program under "Value". Likewise, if the module needs to find a particular environmental + setting like $X2SYS_HOME, then you must set those here as well. + +#. Any data files your command will read must either be placed in the *xbuild/src/Debug* subdirectory or you must + change the command you pasted above to use the full path instead. In other words, when Xcode runs + your command, your current directory becomes *xbuild/src/Debug*. + +#. Click close and hit the "Play" button next to the green circle in the top left corner. It may do some + building and indexing before it starts and then stops at your highlighted line, opening up a display console + below the source code: + + .. figure:: /_images/xcode-5.* + :width: 100% + :align: center + + You will see the current line is highlighted light greenish and the execution is stopped. Below the code is a new window that + lists some of the variables in the current scope. You can examine that window to see what the variables are set + to, you can type "print variable" in the lldb command window on the right (e.g., "print argc"), or you can place + the cursor over a variable and a pop-up box will display its value. Below I placed the cursor on the variable + "module" on line 119 and this is what it looks like (minus the cursor which is not screen-grabbed!). + + .. figure:: /_images/xcode-6.* + :width: 100% + :align: center + +#. The tool bar below the source code has a pause-play button (continue to next stop point), a step-over button (execute + next step but do not go *into* a function, the step-into button (execute next step which may be going into a function) + and the step-out button (finish running current function then step back out). Step into the GMT_Call_Module function + using the step-into button, then scroll down to around line 10094 and place another stop point there like I did. Press + the pause-play button and you are now about to call your actual C function that correspond to the module (here pstext): + + .. figure:: /_images/xcode-7.* + :width: 100% + :align: center + +#. Click the step-into button and find yourself at the first executable line of code in GMT_pstext, the underlying + C function at the heart of the pstext module. You can now step your way down the code, using step-over to avoid going + into the details of GMT sub-functions (or step-into it if that is the problem), set stop points and push pause-play to + advance to the next stop point, examine variables, and so on. + + .. figure:: /_images/xcode-8.* + :width: 100% + :align: center From 2c85c8b75a06d06fc90f25c07c17e994fe735cc4 Mon Sep 17 00:00:00 2001 From: Paul Wessel Date: Mon, 11 May 2020 17:08:17 -1000 Subject: [PATCH 02/14] Update develop.rst --- doc/rst/source/develop.rst | 211 ++++++++++++++++--------------------- 1 file changed, 90 insertions(+), 121 deletions(-) diff --git a/doc/rst/source/develop.rst b/doc/rst/source/develop.rst index e0f339febd9..16c98a3a7bc 100644 --- a/doc/rst/source/develop.rst +++ b/doc/rst/source/develop.rst @@ -1,121 +1,90 @@ -.. index:: ! debug - -************************ -Debugging for Developers -************************ - -GMT developers may need to run GMT in a debugger to figure out the problem reported by -an issue. Often there is a bit of detective work involved to find out where a module -crashes and then step carefully through that section, examining variables etc., to learn -why something fails. This process depends on the particular debug tool one uses. This page -will explain the steps a developer must take to build gmt so it is suitable for your debug -tool and how to use that tool. - -Xcode on macOS --------------- - -Developers on macOS are most likely to want to use Xcode for this purpose. Chances are they -are already using the command-line tools from Xcode (gcc, linker) anyway. To use the GUI -part of Xcode you must have installed the full Xcode (you most likely did, but there are -ways to *only* install the command-line tools, so make sure you have an Xcode icon under -Applications). Xcode may change as versions change; the images below is for Xcode 10-11. - -#. You will need to make some changes to your *cmake/ConfigUserAdvanced.cmake* file. Scroll down to the - section that says "# Extra debugging for developers:" and uncomment the ~6 lines that has - the if-test on "Xcode". This will pass a few flags that are used when debugging via Xcode. - Also uncomment the two "add_definitions" lines that contain the word "DEBUG" in it somewhere. - -#. You will need to build GMT again. I recommend you do this in a separate build directory (I - call mine *xbuild*, and while at it I use *rbuild* for "Release Builds" and *dbuild* for regular - debug command line builds, and *build* for the final build for the releases). If you are in - the *xbuild* directory, these two commands will do the build:: - - cmake -DCMAKE_INSTALL_PREFIX=gmt6 -DCMAKE_BUILD_TYPE=Debug -G Xcode .. - xcodebuild - -#. After this step you can launch the Xcode application and then use the File->Open menu to - open the project file *xbuild/GMT.xcodeproj*. After it opens it may looks something like - this (click on the figure to enlarge it): - - .. figure:: /_images/xcode-1.* - :width: 100% - :align: center - -#. Pull down the tab that says "@ ALL_BUILD" and select "gmt" about 35 lines down, then in the - left sidebar open the folder called gmt->Source Files and select gmt.c. Now you may wish - to drag the window to be a bit wider so the lines don't wrap around so much. After that step - your screen may look more like this: - - .. figure:: /_images/xcode-2.* - :width: 100% - :align: center - -#. Scroll down to the part around line 119 and click the line number to place a stop point; it - will add a blue fat arrow at that line: - - .. figure:: /_images/xcode-3.* - :width: 100% - :align: center - - This is *usually* the first stop you want in Xcode. The exception would be if you are debugging - gmt.c itself or you need to examine the code that creates the session via a call to GMT_Create_Session - earlier in the program. - -#. Now we need to specify the particular command we wish to debug. Let's pretend that :doc:`pstext` - crashes when we run the command:: - - gmt pstext my_text.txt -R0/30/-10/20 -JM15c -Baf -F+f16p > text.ps - - Copy that command minus the initial "gmt " part. Now pull down the menu item "Product->Scheme->Edit Scheme", - then make sure "Arguments" is highlighted in blue in the top table, then click the "+" symbol beneath the - section that says "Arguments Passed on Launch" and paste in our command; it should result in this display: - - .. figure:: /_images/xcode-4.* - :width: 100% - :align: center - - Normally you do not need to set any "Environmental Variables", but if you are debugging a module that - calls an external program (e.g., gs, gdal_translate, etc.) then you may need to add the name PATH and - place the path to that program under "Value". Likewise, if the module needs to find a particular environmental - setting like $X2SYS_HOME, then you must set those here as well. - -#. Any data files your command will read must either be placed in the *xbuild/src/Debug* subdirectory or you must - change the command you pasted above to use the full path instead. In other words, when Xcode runs - your command, your current directory becomes *xbuild/src/Debug*. - -#. Click close and hit the "Play" button next to the green circle in the top left corner. It may do some - building and indexing before it starts and then stops at your highlighted line, opening up a display console - below the source code: - - .. figure:: /_images/xcode-5.* - :width: 100% - :align: center - - You will see the current line is highlighted light greenish and the execution is stopped. Below the code is a new window that - lists some of the variables in the current scope. You can examine that window to see what the variables are set - to, you can type "print variable" in the lldb command window on the right (e.g., "print argc"), or you can place - the cursor over a variable and a pop-up box will display its value. Below I placed the cursor on the variable - "module" on line 119 and this is what it looks like (minus the cursor which is not screen-grabbed!). - - .. figure:: /_images/xcode-6.* - :width: 100% - :align: center - -#. The tool bar below the source code has a pause-play button (continue to next stop point), a step-over button (execute - next step but do not go *into* a function, the step-into button (execute next step which may be going into a function) - and the step-out button (finish running current function then step back out). Step into the GMT_Call_Module function - using the step-into button, then scroll down to around line 10094 and place another stop point there like I did. Press - the pause-play button and you are now about to call your actual C function that correspond to the module (here pstext): - - .. figure:: /_images/xcode-7.* - :width: 100% - :align: center - -#. Click the step-into button and find yourself at the first executable line of code in GMT_pstext, the underlying - C function at the heart of the pstext module. You can now step your way down the code, using step-over to avoid going - into the details of GMT sub-functions (or step-into it if that is the problem), set stop points and push pause-play to - advance to the next stop point, examine variables, and so on. - - .. figure:: /_images/xcode-8.* - :width: 100% - :align: center +.. index:: ! develop + +********************************** +Developing Modules and Supplements +********************************** + +GMT developers do from time to time need to add new modules to the core library, +and occasionally they add an entire new supplement to the official distribution. In +addition, there are unofficial supplements that are not part of the GMT code base +but needs to be built with GMT (or piggyback off the GMT build process), and then +there are supplements that need to be built by themselves that have dependencies +of various kinds on GMT. This document discusses the mechanics around those issues. + +Adding a new module +------------------- + +To add a new module, the starting point is to duplicate the most similar module you can think +of. It is not essential to get this right, but if your new module deals with grids then +start with one of the grd modules such as :doc:`grd2xyz`, and if it needs to deal with tables +then maybe something like :doc:`gmtselect`. If plotting is involved then start with one that +makes plots, and so on. Obviously, there will be lots of changes to your starting point and +those are completely dependent on what the new module will do. Yet, here are some steps +you are likely to encounter and some of them are required exactly as is and for others you +must adapt them to your module's specific purpose. + +#. The first C code lines below the initial comments list a set of seven define statements + that start with **THIS_MODULE_**. Most of them are fairly easy to update, such as stating + the new module's name and purpose. Then there is the **THIS_MODULE_OPTIONS* parameter which + is just a listing of all the common GMT options this module can use. The next item is + **THIS_MODULE_NEEDS** and it tells GMT if this module requires a region (e.g., via **-R**) + and a projection (via **-J**). Modules that must set a region to operate will either have + the codes **R** (must take **-R**), **d** (can determine the region from given data sets), + or **g** (can determine the region from a given grid). There is also the mode **r** which + means 'not normally required' but may be required depending on module options. As an example, + consider :doc:`pslegend` which does not need **-R** if **-Dx** is used but *does* need **-R** if + other selections are made. For the same reason there is the **j** code for projections when + it depends on other options whether **-J** is needed or not. Most plot modules NEEDS will + include **J**. Finally, there is the very cryptic **THIS_MODULE_KEYS** setting. At this point, + please read all the comments in the code for *GMT_Encode_Options* in gmt_api.c. The **KEYS** + are not used by the command line modules and only enters for some external interfaces, such + as MATLAB and Julia. You should have a discussion with those maintainers about what those + **KEYS** should be. + +#. Do some global replacements of strings: Replace the uppercase name of the template module + with the new module uppercase name, and do the same for the lowercase name. This will ensure that + your Ctrl structures and local static functions are named correctly (you may still need to + delete some of them and add others). All functions local to this module shall have names + starting with the module name and an underscores (e.g., grdinfo_report_tiles*) and they shall + be stated as GMT_LOCAL instead of static (GMT_LOCAL is normally defined to mean static but + in certain debugging cases we may wish to change that). The exceptions to this rule are the + functions* New_Ctrl*, *Free_Ctrl*, *usage*, and *parse*; they are all static and have the + same names in all modules. + +#. After listing all local variables inside the main GMT_module function, all modules start with + a section labeled *Standard module initialization and parsing*. It is extremely unlikely + you will need to make any changes in this section. Ask for help if you think you do. + +#. For style, argument checking, usage layout, use of built-in constants for the synopsis line, + just follow the module template and draw inspiration from other modules. + +#. Make sure you create a separate git branch and add your new code to that branch. New modules + should never go into master and will have to undergo much scrutiny before the branch may + be merged into master. + +#. Try to compile GMT with your new module. We automatically detect all the modules in the *src* + directory (as well as supplemental source directories) and various needed "glue" functions + are automatically created and compiled as part of the process. You are likely to get some + compilation errors. Keep addressing them until the module compiles. Running gmt *modulename* + should print the full usage message. + +#. The documentation of the module should be carefully designed. You will need to add at least a + module.rst file in the doc/rst/source directory that explains what the module does. Again, + start with a copy of another suitable module's RST file and make suitable changes. Make sure + you add some examples that others can try without getting data (e.g., use remote files as much + as possible). + +#. You must also edit the *modules.rst* file and add your new module and its purpose in two + separate places. Just search for a known module to see what is expected. With these edits + you should be able to build the full documentation and have your module show up under the + Modules page. + +#. Adding a new module to one of the official supplements pretty much follows the same steps. + It is best to start from one of the other modules in that supplement since some of them + have specific include files and setups. Including the new supplemental module in the build + process is automatic (done by CMake). + +Compiling supplements +--------------------- + +For the purpose of this discussion, we will distinguish be \ No newline at end of file From cb9373367018c230e77a023c172f8d40f41fc7b9 Mon Sep 17 00:00:00 2001 From: Paul Wessel Date: Mon, 11 May 2020 17:13:23 -1000 Subject: [PATCH 03/14] Update develop.rst --- doc/rst/source/develop.rst | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/doc/rst/source/develop.rst b/doc/rst/source/develop.rst index 16c98a3a7bc..ff3cdc02192 100644 --- a/doc/rst/source/develop.rst +++ b/doc/rst/source/develop.rst @@ -87,4 +87,15 @@ must adapt them to your module's specific purpose. Compiling supplements --------------------- -For the purpose of this discussion, we will distinguish be \ No newline at end of file +For the purpose of this discussion, we will distinguish between several types of supplements: + +#. Regular supplements included in the GMT distribution (e.g., *seis*, *spotter*). +#. External supplements not part of the GMT distribution but the developer wish to + piggyback off the GMT build process instead of having a full-blown CMakeLists.txt setup. + The modules depend on (and include) gmt_dev.h, just like the core modules. +#. External supplements not part of the GMT distribution but has their own build setup. + The modules depend on (and include) gmt_dev.h, just like the core modules. One such + example are the MB-System src/gmt tools. +#. External supplements not part of the GMT distribution but has their own build setup. + THe modules only depend on (and include) gmt.h, the official GMT API. + From b2cde42118c957e0e0e8fe43f23d9009f73e1053 Mon Sep 17 00:00:00 2001 From: Paul Wessel Date: Mon, 11 May 2020 17:40:35 -1000 Subject: [PATCH 04/14] Update doc/rst/source/develop.rst Co-authored-by: Dongdong Tian --- doc/rst/source/develop.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/doc/rst/source/develop.rst b/doc/rst/source/develop.rst index ff3cdc02192..450dc1eb464 100644 --- a/doc/rst/source/develop.rst +++ b/doc/rst/source/develop.rst @@ -25,7 +25,7 @@ must adapt them to your module's specific purpose. #. The first C code lines below the initial comments list a set of seven define statements that start with **THIS_MODULE_**. Most of them are fairly easy to update, such as stating - the new module's name and purpose. Then there is the **THIS_MODULE_OPTIONS* parameter which + the new module's name and purpose. Then there is the **THIS_MODULE_OPTIONS** parameter which is just a listing of all the common GMT options this module can use. The next item is **THIS_MODULE_NEEDS** and it tells GMT if this module requires a region (e.g., via **-R**) and a projection (via **-J**). Modules that must set a region to operate will either have @@ -98,4 +98,3 @@ For the purpose of this discussion, we will distinguish between several types of example are the MB-System src/gmt tools. #. External supplements not part of the GMT distribution but has their own build setup. THe modules only depend on (and include) gmt.h, the official GMT API. - From ebd7ff13d531754c0d385d072665813039b63be1 Mon Sep 17 00:00:00 2001 From: Paul Wessel Date: Mon, 11 May 2020 17:40:42 -1000 Subject: [PATCH 05/14] Update doc/rst/source/develop.rst Co-authored-by: Dongdong Tian --- doc/rst/source/develop.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/rst/source/develop.rst b/doc/rst/source/develop.rst index 450dc1eb464..a6ad5d73205 100644 --- a/doc/rst/source/develop.rst +++ b/doc/rst/source/develop.rst @@ -45,7 +45,7 @@ must adapt them to your module's specific purpose. with the new module uppercase name, and do the same for the lowercase name. This will ensure that your Ctrl structures and local static functions are named correctly (you may still need to delete some of them and add others). All functions local to this module shall have names - starting with the module name and an underscores (e.g., grdinfo_report_tiles*) and they shall + starting with the module name and an underscores (e.g., *grdinfo_report_tiles*) and they shall be stated as GMT_LOCAL instead of static (GMT_LOCAL is normally defined to mean static but in certain debugging cases we may wish to change that). The exceptions to this rule are the functions* New_Ctrl*, *Free_Ctrl*, *usage*, and *parse*; they are all static and have the From d37928127bed83b6a261e85ac863161febd5654d Mon Sep 17 00:00:00 2001 From: Paul Wessel Date: Mon, 11 May 2020 17:40:52 -1000 Subject: [PATCH 06/14] Update doc/rst/source/develop.rst Co-authored-by: Dongdong Tian --- doc/rst/source/develop.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/rst/source/develop.rst b/doc/rst/source/develop.rst index a6ad5d73205..159b8dcadb6 100644 --- a/doc/rst/source/develop.rst +++ b/doc/rst/source/develop.rst @@ -48,7 +48,7 @@ must adapt them to your module's specific purpose. starting with the module name and an underscores (e.g., *grdinfo_report_tiles*) and they shall be stated as GMT_LOCAL instead of static (GMT_LOCAL is normally defined to mean static but in certain debugging cases we may wish to change that). The exceptions to this rule are the - functions* New_Ctrl*, *Free_Ctrl*, *usage*, and *parse*; they are all static and have the + functions *New_Ctrl*, *Free_Ctrl*, *usage*, and *parse*; they are all static and have the same names in all modules. #. After listing all local variables inside the main GMT_module function, all modules start with From bac45aa00bf228e975ea7e44a5d6f357b6e6168c Mon Sep 17 00:00:00 2001 From: Paul Wessel Date: Mon, 11 May 2020 17:41:16 -1000 Subject: [PATCH 07/14] Update doc/rst/source/develop.rst Co-authored-by: Dongdong Tian --- doc/rst/source/develop.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/rst/source/develop.rst b/doc/rst/source/develop.rst index 159b8dcadb6..c2fae75c367 100644 --- a/doc/rst/source/develop.rst +++ b/doc/rst/source/develop.rst @@ -74,7 +74,7 @@ must adapt them to your module's specific purpose. you add some examples that others can try without getting data (e.g., use remote files as much as possible). -#. You must also edit the *modules.rst* file and add your new module and its purpose in two +#. You must also edit the *modules.rst* and *modules-classic.rst* files and add your new module and its purpose in three separate places. Just search for a known module to see what is expected. With these edits you should be able to build the full documentation and have your module show up under the Modules page. From 436cdbef7bc315d571ef84d9269d8b1cdf1c3a7a Mon Sep 17 00:00:00 2001 From: Paul Wessel Date: Mon, 11 May 2020 17:43:23 -1000 Subject: [PATCH 08/14] Update develop.rst --- doc/rst/source/develop.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/rst/source/develop.rst b/doc/rst/source/develop.rst index c2fae75c367..65fc9898de0 100644 --- a/doc/rst/source/develop.rst +++ b/doc/rst/source/develop.rst @@ -62,6 +62,9 @@ must adapt them to your module's specific purpose. should never go into master and will have to undergo much scrutiny before the branch may be merged into master. +#. To let CMake know about the new module, edit src/CMakeLists.txt and search for **GMT_PROGS_SRCS**. + Add your new module to the list. + #. Try to compile GMT with your new module. We automatically detect all the modules in the *src* directory (as well as supplemental source directories) and various needed "glue" functions are automatically created and compiled as part of the process. You are likely to get some From 89304ec3578a243f70caccda8357e122545e57a5 Mon Sep 17 00:00:00 2001 From: Paul Wessel Date: Tue, 12 May 2020 09:20:53 -1000 Subject: [PATCH 09/14] Add OpenMP comments --- doc/rst/source/develop.rst | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/doc/rst/source/develop.rst b/doc/rst/source/develop.rst index 65fc9898de0..8ad2d9942c2 100644 --- a/doc/rst/source/develop.rst +++ b/doc/rst/source/develop.rst @@ -87,6 +87,26 @@ must adapt them to your module's specific purpose. have specific include files and setups. Including the new supplemental module in the build process is automatic (done by CMake). +Using OpenMP pragmas +-------------------- + +Many algorithms in GMT can be sped up considerably by using OpenMP. This scheme is deceptively +simple and one only needs to add a set of three comments and great speed is attained. This +section discusses our experiences with the "#pragma omp parallel for" statements in GMT. +Here are some simple rules to live by; see actual examples in the modules. + +#. Due to cross-platform compatibility, we must for now always used signed for-loop variables + in places where OpenMP is used. We hope this will go away one day. +#. Every variable addressed by the for-loop must be listed in either the *private* or *shared* + groups in the pragma statement. Be vary careful when doing this as pretty much all failures + to get it to work has to do with making mistakes here. This simple rule should help: If a + variable is *assigned* inside the for-loop then it must go in *private*, all else must go in + *shared*. None can be left out. +#. Try to avoid having if-tests inside the for-loop. It may be much faster to move the if-test + outside the loop and possibly do a near-duplication of the loop. +#. At this point, the OpenMP builds work well on all platforms, but not well integrated with + the XCode framework on macOS. Building with gcc works well. + Compiling supplements --------------------- From dbbbbe35cf7931351c04ff99e990d964238ceb92 Mon Sep 17 00:00:00 2001 From: Paul Wessel Date: Tue, 12 May 2020 12:07:58 -1000 Subject: [PATCH 10/14] Update doc/rst/source/develop.rst Co-authored-by: Dongdong Tian --- doc/rst/source/develop.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/rst/source/develop.rst b/doc/rst/source/develop.rst index 8ad2d9942c2..f2f7ffdebbb 100644 --- a/doc/rst/source/develop.rst +++ b/doc/rst/source/develop.rst @@ -98,7 +98,7 @@ Here are some simple rules to live by; see actual examples in the modules. #. Due to cross-platform compatibility, we must for now always used signed for-loop variables in places where OpenMP is used. We hope this will go away one day. #. Every variable addressed by the for-loop must be listed in either the *private* or *shared* - groups in the pragma statement. Be vary careful when doing this as pretty much all failures + groups in the pragma statement. Be very careful when doing this as pretty much all failures to get it to work has to do with making mistakes here. This simple rule should help: If a variable is *assigned* inside the for-loop then it must go in *private*, all else must go in *shared*. None can be left out. From 33254fb15e81c1b3433586289c6e39efb2593a8f Mon Sep 17 00:00:00 2001 From: Paul Wessel Date: Tue, 12 May 2020 23:01:34 -1000 Subject: [PATCH 11/14] Update develop.rst --- doc/rst/source/develop.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/rst/source/develop.rst b/doc/rst/source/develop.rst index f2f7ffdebbb..13117652ed6 100644 --- a/doc/rst/source/develop.rst +++ b/doc/rst/source/develop.rst @@ -77,7 +77,8 @@ must adapt them to your module's specific purpose. you add some examples that others can try without getting data (e.g., use remote files as much as possible). -#. You must also edit the *modules.rst* and *modules-classic.rst* files and add your new module and its purpose in three +#. You must also edit the *modules.rst*, *modules-classic.rst* and *module_core_purpose.rst_* + files and add your new module and its purpose in three separate places. Just search for a known module to see what is expected. With these edits you should be able to build the full documentation and have your module show up under the Modules page. From 09f38018af9340a90a3bc0199f92a39e61ee7caf Mon Sep 17 00:00:00 2001 From: Paul Wessel Date: Wed, 13 May 2020 08:48:04 -1000 Subject: [PATCH 12/14] Hook to sidebar --- doc/rst/source/index.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/rst/source/index.rst b/doc/rst/source/index.rst index a8af46d1e65..0a2c4b98915 100644 --- a/doc/rst/source/index.rst +++ b/doc/rst/source/index.rst @@ -74,6 +74,7 @@ Quick links Contributing Guide Code of Conduct reStructuredText Cheatsheet + New Modules and Supplements Debugging GMT GMT C API PostScriptLight C API From c5cc380b98f88c02a6b58e18ae9befb984f931dc Mon Sep 17 00:00:00 2001 From: Paul Wessel Date: Thu, 14 May 2020 12:39:04 -1000 Subject: [PATCH 13/14] Update doc/rst/source/develop.rst Co-authored-by: Dongdong Tian --- doc/rst/source/develop.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/rst/source/develop.rst b/doc/rst/source/develop.rst index 13117652ed6..4dccfa74cfc 100644 --- a/doc/rst/source/develop.rst +++ b/doc/rst/source/develop.rst @@ -77,10 +77,10 @@ must adapt them to your module's specific purpose. you add some examples that others can try without getting data (e.g., use remote files as much as possible). -#. You must also edit the *modules.rst*, *modules-classic.rst* and *module_core_purpose.rst_* - files and add your new module and its purpose in three - separate places. Just search for a known module to see what is expected. With these edits - you should be able to build the full documentation and have your module show up under the +#. You must also edit the *modules.rst* and *modules-classic.rst* files and add your new module + and its purpose in three separate places. Just search for a known module to see what is expected. + Also change into src directory and run `gmt_make_module_purpose.sh` to update two module purpose files. + With these edits you should be able to build the full documentation and have your module show up under the Modules page. #. Adding a new module to one of the official supplements pretty much follows the same steps. From 3f8efccdcbd2a6ed81ddfd4386261765a5fd43af Mon Sep 17 00:00:00 2001 From: Paul Wessel Date: Sun, 28 Jun 2020 11:15:51 -1000 Subject: [PATCH 14/14] Update develop.rst --- doc/rst/source/develop.rst | 44 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/doc/rst/source/develop.rst b/doc/rst/source/develop.rst index 4dccfa74cfc..54b44a1a563 100644 --- a/doc/rst/source/develop.rst +++ b/doc/rst/source/develop.rst @@ -101,8 +101,9 @@ Here are some simple rules to live by; see actual examples in the modules. #. Every variable addressed by the for-loop must be listed in either the *private* or *shared* groups in the pragma statement. Be very careful when doing this as pretty much all failures to get it to work has to do with making mistakes here. This simple rule should help: If a - variable is *assigned* inside the for-loop then it must go in *private*, all else must go in - *shared*. None can be left out. + variable is just *accessed* (read) inside the for-loop then it should go in *shared*, all else must go in + *private*. None can be left out. Often, loops are over grids and the grid pointer is *shared* + so that all threads can add their contributions - this is the whole point of the splitting. #. Try to avoid having if-tests inside the for-loop. It may be much faster to move the if-test outside the loop and possibly do a near-duplication of the loop. #. At this point, the OpenMP builds work well on all platforms, but not well integrated with @@ -122,3 +123,42 @@ For the purpose of this discussion, we will distinguish between several types of example are the MB-System src/gmt tools. #. External supplements not part of the GMT distribution but has their own build setup. THe modules only depend on (and include) gmt.h, the official GMT API. + +:: + + !! This section will be under construction as long as this sign is present !! + +Regular supplements +=================== + +If you (presumably a developers) is considering to add a new official GMT supplement then +you should completely model it based on one of the existing supplements. You will notice that +your supplement name (the directory) needs to be added to src/CMakeLists.txt. Just search for +an existing name there and it is obvious what to change. Rebuilding everything will automatically +include your new modules. + +Lazy External supplements +========================= + +These are supplements that uses the same layout as the official supplements but of course they +are not blessed by us and thus cannot go into src. The solution is to place the supplemental +directory somewhere else and then set a symbolic link from src to your supplement. These links +must be called *newsuppl1*, *newsuppl2*, etc. Your supplements CMakeLists.txt must set a few +variables to be included by the GMT build process: **SUPPL_LIB_NAME** is the name of your supplement. +If it is set we build a separate shared library for it, but if not set it gets added to the GMT +supplemental shared library. + +External supplements needing gmt_dev.h +====================================== + +These are stand-alone software that can be built as shared libraries we can access from GMT +via the **GMT_CUSTOM_LIBS** default setting. The MB-System is a good example of such a system, +since it requires access to lower-level (developmental) libraries in GMT and thus must include +gmt_dev.h. + + +External supplements only using the API +======================================= + +These are supplements that contains modules that are all build just using the GMT API, i.e., they +only include gmt.h. These typically have their own build system and only link with libgmt.