You can subscribe to this list here.
| 2003 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(19) |
Nov
(45) |
Dec
(80) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2004 |
Jan
(58) |
Feb
(127) |
Mar
(74) |
Apr
(34) |
May
(117) |
Jun
(14) |
Jul
(26) |
Aug
(13) |
Sep
(1) |
Oct
(38) |
Nov
(13) |
Dec
(5) |
| 2005 |
Jan
(108) |
Feb
(134) |
Mar
(54) |
Apr
(133) |
May
(16) |
Jun
(54) |
Jul
(128) |
Aug
(99) |
Sep
(157) |
Oct
(182) |
Nov
(236) |
Dec
(212) |
| 2006 |
Jan
(86) |
Feb
(76) |
Mar
(121) |
Apr
(27) |
May
(7) |
Jun
(1) |
Jul
(6) |
Aug
(28) |
Sep
(1) |
Oct
(27) |
Nov
(5) |
Dec
|
| 2007 |
Jan
(32) |
Feb
(22) |
Mar
(22) |
Apr
(11) |
May
(3) |
Jun
(12) |
Jul
(11) |
Aug
(9) |
Sep
(37) |
Oct
(4) |
Nov
(9) |
Dec
(51) |
| 2008 |
Jan
(7) |
Feb
(31) |
Mar
(46) |
Apr
(31) |
May
(5) |
Jun
(27) |
Jul
(12) |
Aug
(5) |
Sep
(13) |
Oct
(24) |
Nov
(112) |
Dec
(15) |
| 2009 |
Jan
(6) |
Feb
(103) |
Mar
(66) |
Apr
(9) |
May
(8) |
Jun
(1) |
Jul
(20) |
Aug
(9) |
Sep
(2) |
Oct
(81) |
Nov
(88) |
Dec
(30) |
| 2010 |
Jan
(65) |
Feb
(57) |
Mar
(22) |
Apr
(12) |
May
(4) |
Jun
(12) |
Jul
(43) |
Aug
(6) |
Sep
(6) |
Oct
(4) |
Nov
(6) |
Dec
(3) |
| 2011 |
Jan
(10) |
Feb
(27) |
Mar
(11) |
Apr
(9) |
May
(69) |
Jun
(73) |
Jul
(67) |
Aug
(116) |
Sep
(40) |
Oct
(11) |
Nov
(34) |
Dec
(19) |
| 2012 |
Jan
|
Feb
(4) |
Mar
(28) |
Apr
(18) |
May
(9) |
Jun
(7) |
Jul
(4) |
Aug
(155) |
Sep
(264) |
Oct
(172) |
Nov
(15) |
Dec
(40) |
| 2013 |
Jan
(1) |
Feb
(2) |
Mar
|
Apr
|
May
|
Jun
(20) |
Jul
(76) |
Aug
(67) |
Sep
(49) |
Oct
(27) |
Nov
(3) |
Dec
(3) |
| 2014 |
Jan
(7) |
Feb
(7) |
Mar
(16) |
Apr
|
May
(4) |
Jun
(1) |
Jul
(18) |
Aug
|
Sep
|
Oct
|
Nov
(1) |
Dec
|
| 2015 |
Jan
(6) |
Feb
(5) |
Mar
(3) |
Apr
(23) |
May
(5) |
Jun
|
Jul
(2) |
Aug
(4) |
Sep
|
Oct
|
Nov
(2) |
Dec
(4) |
| 2016 |
Jan
(2) |
Feb
(7) |
Mar
(2) |
Apr
(1) |
May
(14) |
Jun
(3) |
Jul
|
Aug
(3) |
Sep
|
Oct
|
Nov
(1) |
Dec
(3) |
| 2017 |
Jan
(6) |
Feb
|
Mar
(3) |
Apr
|
May
|
Jun
|
Jul
|
Aug
(12) |
Sep
(6) |
Oct
|
Nov
(3) |
Dec
|
| 2018 |
Jan
(4) |
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(1) |
Aug
(8) |
Sep
|
Oct
|
Nov
|
Dec
(1) |
| 2019 |
Jan
|
Feb
|
Mar
(4) |
Apr
|
May
|
Jun
|
Jul
|
Aug
(3) |
Sep
(8) |
Oct
|
Nov
(2) |
Dec
(25) |
| 2020 |
Jan
|
Feb
(3) |
Mar
|
Apr
|
May
(1) |
Jun
|
Jul
|
Aug
|
Sep
(3) |
Oct
(53) |
Nov
(33) |
Dec
|
| 2021 |
Jan
(2) |
Feb
|
Mar
|
Apr
|
May
|
Jun
(2) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(4) |
Dec
(5) |
| 2022 |
Jan
(1) |
Feb
|
Mar
|
Apr
|
May
|
Jun
(5) |
Jul
(93) |
Aug
(206) |
Sep
(39) |
Oct
(19) |
Nov
(11) |
Dec
|
| 2023 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(2) |
Jun
(150) |
Jul
(124) |
Aug
(14) |
Sep
(5) |
Oct
|
Nov
(1) |
Dec
|
| 2024 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(12) |
Jul
(62) |
Aug
|
Sep
(7) |
Oct
|
Nov
(7) |
Dec
|
| 2025 |
Jan
|
Feb
|
Mar
|
Apr
(14) |
May
(3) |
Jun
|
Jul
|
Aug
(76) |
Sep
(214) |
Oct
(6) |
Nov
|
Dec
|
|
From: <kin...@us...> - 2025-09-15 05:58:57
|
Revision: 7436
http://sourceforge.net/p/teem/code/7436
Author: kindlmann
Date: 2025-09-15 05:58:55 +0000 (Mon, 15 Sep 2025)
Log Message:
-----------
reformat of unu about info
Modified Paths:
--------------
teem/trunk/src/unrrdu/about.c
Modified: teem/trunk/src/unrrdu/about.c
===================================================================
--- teem/trunk/src/unrrdu/about.c 2025-09-15 05:44:52 UTC (rev 7435)
+++ teem/trunk/src/unrrdu/about.c 2025-09-15 05:58:55 UTC (rev 7436)
@@ -53,13 +53,12 @@
"http://teem.sf.net\". "
"Alternatively, please email gl...@uc... and briefly describe "
"how Teem software has helped in your work.\n "
- "Please also consider joining the teem-users mailing list: "
- "<http://lists.sourceforge.net/lists/listinfo/teem-users>.\n "
"\n "
"\t\t\t"
- "Or, new for 2025 and Teem v2: join the Teem-users Discord: "
- "https://discord.gg/xBBqZGXkF7 to share how Teem works or doesn't work for "
- "you.\n ";
+ "(New for 2025 and Teem v2) Join the Teem-users Discord via "
+ "<https://discord.gg/xBBqZGXkF7> to share how Teem works or doesn't work "
+ "for you. Or, traditionalists can join the teem-users mailing list via "
+ "<http://lists.sourceforge.net/lists/listinfo/teem-users>.\n ";
char par3[] = "\t\t\t\t"
"A summary list of unu commands is generated by running simply \"unu\". "
"Running a unu command without additional arguments "
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <kin...@us...> - 2025-09-15 05:44:54
|
Revision: 7435
http://sourceforge.net/p/teem/code/7435
Author: kindlmann
Date: 2025-09-15 05:44:52 +0000 (Mon, 15 Sep 2025)
Log Message:
-----------
fixing typo
Modified Paths:
--------------
teem/trunk/README.txt
Modified: teem/trunk/README.txt
===================================================================
--- teem/trunk/README.txt 2025-09-15 05:26:51 UTC (rev 7434)
+++ teem/trunk/README.txt 2025-09-15 05:44:52 UTC (rev 7435)
@@ -89,7 +89,7 @@
Source files for Teem command-line tools, including "unu" and "tend"
* UseTeemCMakeDemo/
- An stand-alone example of how to use the Teem::Teem package, created by CMake
+ A stand-alone example of how to use the Teem::Teem package, created by CMake
(via the new CMake files re-written Sept 2025)
* include/
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <kin...@us...> - 2025-09-15 05:26:53
|
Revision: 7434
http://sourceforge.net/p/teem/code/7434
Author: kindlmann
Date: 2025-09-15 05:26:51 +0000 (Mon, 15 Sep 2025)
Log Message:
-----------
oops have to add tendLmdemo in actual CMakeLists.txt
Modified Paths:
--------------
teem/trunk/src/ten/CMakeLists.txt
Modified: teem/trunk/src/ten/CMakeLists.txt
===================================================================
--- teem/trunk/src/ten/CMakeLists.txt 2025-09-15 05:18:35 UTC (rev 7433)
+++ teem/trunk/src/ten/CMakeLists.txt 2025-09-15 05:26:51 UTC (rev 7434)
@@ -64,6 +64,7 @@
tendTconv.c
tendTriple.c
tendUnmf.c
+ tendLmdemo.c
tensor.c
triple.c
experSpec.c
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <kin...@us...> - 2025-09-15 05:18:36
|
Revision: 7433
http://sourceforge.net/p/teem/code/7433
Author: kindlmann
Date: 2025-09-15 05:18:35 +0000 (Mon, 15 Sep 2025)
Log Message:
-----------
adding Lmdemo to old CMakeLists.txt (will soon be mooted by v2 switch over)
Modified Paths:
--------------
teem/trunk/src/ten/CMakeLists-v1.txt
Modified: teem/trunk/src/ten/CMakeLists-v1.txt
===================================================================
--- teem/trunk/src/ten/CMakeLists-v1.txt 2025-09-14 22:53:00 UTC (rev 7432)
+++ teem/trunk/src/ten/CMakeLists-v1.txt 2025-09-15 05:18:35 UTC (rev 7433)
@@ -64,6 +64,7 @@
tendTconv.c
tendTriple.c
tendUnmf.c
+ tendLmdemo.c
tensor.c
triple.c
experSpec.c
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <kin...@us...> - 2025-09-14 22:53:02
|
Revision: 7432
http://sourceforge.net/p/teem/code/7432
Author: kindlmann
Date: 2025-09-14 22:53:00 +0000 (Sun, 14 Sep 2025)
Log Message:
-----------
updating anticipating Teem v2
Modified Paths:
--------------
teem/trunk/README.txt
Modified: teem/trunk/README.txt
===================================================================
--- teem/trunk/README.txt 2025-09-14 22:09:05 UTC (rev 7431)
+++ teem/trunk/README.txt 2025-09-14 22:53:00 UTC (rev 7432)
@@ -1,25 +1,34 @@
===============
- Teem: Tools to process and visualize scientific data and images
- Copyright (C) 2009--2023 University of Chicago
- Copyright (C) 2005--2008 Gordon Kindlmann
- Copyright (C) 1998--2004 University of Utah
+Teem: Tools to process and visualize scientific data and images
+Copyright (C) 2009--2025 University of Chicago
+Copyright (C) 2005--2008 Gordon Kindlmann
+Copyright (C) 1998--2004 University of Utah
- This library is free software; you can redistribute it and/or modify it under the terms
- of the GNU Lesser General Public License (LGPL) as published by the Free Software
- Foundation; either version 2.1 of the License, or (at your option) any later version.
- The terms of redistributing and/or modifying this software also include exceptions to
- the LGPL that facilitate static linking.
+This library is free software; you can redistribute it and/or modify it under the terms
+of the GNU Lesser General Public License (LGPL) as published by the Free Software
+Foundation; either version 2.1 of the License, or (at your option) any later version.
+The terms of redistributing and/or modifying this software also include exceptions to
+the LGPL that facilitate static linking.
- This library 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 Lesser General Public License for more details.
- You should have received a copy of the GNU Lesser General Public License
- along with this library; if not, see <https://www.gnu.org/licenses/>.
+This library 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 Lesser General Public License for more details.
+You should have received a copy of the GNU Lesser General Public License
+along with this library; if not, see <https://www.gnu.org/licenses/>.
+
+=============== How to connect with other Teem users.
+
+In preparation for the Teem v2 release, there's a new Discord server:
+
+ https://discord.gg/xBBqZGXkF7
+
+Join!
+
=============== License information
-See above. This preamble should appear on all released files. Full text of the
-Simple Library Usage License (SLUL) should be in the file "LICENSE.txt". The
-SLUL is the GNU Lesser General Public License, plus an exception:
+See above. This preamble should appear on all released source files. Full text
+of the Simple Library Usage License (SLUL) should be in the file "LICENSE.txt".
+The SLUL is the GNU Lesser General Public License v2.1, plus an exception:
statically-linked binaries that link with Teem can be destributed under the
terms of your choice, with very modest provisions.
@@ -33,25 +42,45 @@
(with static-linking):
svn co https://svn.code.sf.net/p/teem/code/teem/trunk teem-src
- mkdir teem-build
- cd teem-build
+ TEEM_SRC=$(cd teem-src && pwd)
+ TEEM_INSTALL=$(mkdir teem-install && cd teem-install && pwd)
+ mkdir teem-build && cd teem-build
cmake \
- -D BUILD_SHARED_LIBS=OFF -D BUILD_TESTING=OFF \
+ -D BUILD_SHARED_LIBS=ON -D BUILD_TESTING=OFF \
-D CMAKE_BUILD_TYPE=Release \
- -D Teem_BZIP2=OFF -D Teem_FFTW3=OFF -D Teem_LEVMAR=OFF -D Teem_PTHREAD=OFF \
- -D Teem_PNG=ON -D Teem_ZLIB=ON \
- -D CMAKE_INSTALL_PREFIX:PATH=../teem-install \
+ -D Teem_USE_FFTW3=OFF -D Teem_USE_LEVMAR=OFF \
+ -D Teem_USE_BZIP2=ON -D Teem_USE_PNG=ON \
+ -D Teem_USE_ZLIB=ON -D Teem_USE_PTHREAD=ON \
+ -D CMAKE_INSTALL_PREFIX=$TEEM_INSTALL \
../teem-src
make install
-Use BUILD_SHARED_LIBS=ON to make a libteem shared library, which is the
-basis of the python wrappers (e.g. teem/python/cffi)
+If you're squeamish about your command-line tools relying on shared libraries,
+use BUILD_SHARED_LIBS=OFF. btw Teem's CMake sets the rpath in the command-line
+tools to be relative, so the install directory can be moved elsewhere, as long
+as the `bin` and `lib` directories stay side-by-side.
+Using BUILD_SHARED_LIBS=ON makes a libteem shared library, which enables the
+python/CFFI wrapping, which you do with this (with a python3 that can
+"import cffi"):
+
+ cd $TEEM_SRC/python/cffi && python3 build_teem.py $TEEM_INSTALL
+
+Then you can, in python3:
+
+ import teem
+
+and have fast compiled access to the entire Teem API, with biff error messages
+turned into Python exceptions.
+
=============== Directory Structure
+* CMake/
+ Files related to compiling Teem with CMake
+
* src/
- With one subdirectory for each of the teem libraries, all the
- source for the libraries is in here. See library listing below.
+ With one subdirectory for each of the teem libraries (air, biff, hest, nrrd, etc);
+ All the source for the libraries is in here. See library listing below.
The src/CODING.txt file documents Teem coding conventions.
* src/make
Files related to compiling Teem with src/GNUmakefile, the old way
@@ -59,56 +88,55 @@
* src/bin
Source files for Teem command-line tools, including "unu" and "tend"
+* UseTeemCMakeDemo/
+ An stand-alone example of how to use the Teem::Teem package, created by CMake
+ (via the new CMake files re-written Sept 2025)
+
* include/
Some short header files that are used to check the setting of compiler
- variables
- * include/teem/
- When using the old GNU make system, the include (.h) files for all the
- libraries (such as nrrd.h) get put here (but don't originate here).
+ variables while building Teem, but not used by any downstream user.
+ Currently just teemPng.h, which ensures that support for zlib compression
+ is being compiled in if png format is being compiled in.
-* CMake/
- Files related to compiling Teem with CMake
+* python/
+ For python wrappings
+ * python/cffi
+ Bindings for python via CFFI, for all of Teem (in teem.py), as well as a
+ way (exult.py) to create bindings for other C libraries that depend on Teem
+ (created in August 2022)
+ * python/ctypes
+ Bindings for python via ctypes; currently out of date because it
+ depended on the moribund gccxml
-* Testing/
- Tests run by CTest. More should be added.
-
-* data/
- Small reference datasets; more may be added for testing
-
* built/
- The old GNU make system (non-CMake) puts things here:
+ The non-CMake GNUmake system puts things here:
* include/
the headers
* lib/
- all libraries put both their static/archive (.a) and
- shared/dynamic (.so) library files here (such as libnrrd.a)
+ all libraries put their static/archive (.a) ibrary files here
* bin/
- all libraries put their binaries here, hopefully in a way which
- doesn't cause name clashes
+ all command-line tools (like unu) go here
* obj/
- make puts all the .o files in here, for all libraries. When
- compiling "dev", it also puts libraries here, so that "tests"
- can link against them there
+ make puts all the .o files in here, for all libraries, hopefully with no
+ name clashes.
-* python/
- For python wrappings
- * python/cffi
- Bindings for python via CFFI, for all of Teem (in teem.py), as well
- as a way (exult.py) to create bindings for other C libraries that
- depend on Teem (created in August 2022)
- * python/ctypes
- Bindings for python via ctypes; currently out of date because it
- depended on the moribund gccxml
+* tests/
+ * ctest/
+ Tests run by CTest. More should be added.
+ * python/
+ Future home of tests that access Teem via Python/CFFI bindings
-* Examples/
- Place for examples of Teem-using programs, but unfortunately
- not populated by much right now. A work in progress.
+* data/
+ Small reference datasets; more may be added for testing
+* matlab/
+ Matlab bindings written in 2005, not touched since then; do they still work?
+
=============== Teem libraries
-Teem is a coordinated collection of libraries, with a stable
-dependency graph. Below is a listing of the libraries (with
-indication of the libraries upon which it depends). (TEEM_LIB_LIST)
+Teem is a coordinated collection of libraries, with a stable dependency graph.
+Below is a listing of the libraries (with indication of the libraries upon
+which it depends). (TEEM_LIB_LIST)
* air: Basic utility functions, used throughout Teem
@@ -116,24 +144,24 @@
* biff: Accumulation of error messages (air)
-* nrrd: Nearly Raw Raster Data- library for raster data manipulation,
-and support for NRRD file format (biff, hest, air)
+* nrrd: Nearly Raw Raster Data- library for raster data manipulation, and
+support for NRRD file format (biff, hest, air)
-* ell: Linear algebra: operations on vectors, matrices and quaternions,
-and solving cubic polynomials. (nrrd, biff, air)
+* ell: Linear algebra: operations on vectors, matrices and quaternions, and
+solving cubic polynomials. (nrrd, biff, air)
* moss: Processing of 2D multi-channel images (ell, nrrd, biff, hest, air)
-* unrrdu: internals of "unu" command-line tool, and some machinery used
-in other multi-command tools (like "tend") (moss, nrrd, biff, hest, air)
-"unu ilk" is new home for "ilk" image transformer built on moss
+* unrrdu: internals of "unu" command-line tool, and some machinery used in
+other multi-command tools (like "tend") (moss, nrrd, biff, hest, air). "unu
+ilk" is new home for "ilk" image transformer built on moss
* alan: Reaction-diffusion textures (nrrd, ell, biff, air)
* tijk: Spherical harmonics and higher-order tensors (ell, nrrd, air)
-* gage: Convolution-based measurement of 3D fields, or 4D scale-space
-(ell, nrrd, biff, air)
+* gage: Convolution-based measurement of 3D fields, or 4D scale-space (ell,
+nrrd, biff, air)
* dye: Color spaces and conversion (ell, biff, air)
@@ -141,18 +169,18 @@
(gage, unrrdu, nrrd, biff, air)
* limn: Basics of computer graphics, including polygonal data representation
-and manipulation (gage, ell, unrrdu, nrrd, biff, hest, air)
+and manipulation (ell, unrrdu, nrrd, biff, hest, air)
* echo: Simple ray-tracer, written for class (limn, ell, nrrd, biff, air)
-* hoover: Framework for multi-thread ray-casting volume renderer
-(limn, ell, nrrd, biff, air)
+* hoover: Framework for multi-thread ray-casting volume renderer (limn, ell,
+nrrd, biff, air)
-* seek: Extraction of polygonal features from volume data, including
-Marching Cubes and ridge surfaces (limn, gage, ell, nrrd, biff, hest, air)
+* seek: Extraction of polygonal features from volume data, including Marching
+Cubes and ridge surfaces (limn, gage, ell, nrrd, biff, hest, air)
* ten: Visualization and analysis of diffusion imaging and diffusion tensor
-fields (echo, limn, dye, gage, unrrdu, ell, nrrd, biff, air)
+fields (echo, limn, gage, unrrdu, ell, nrrd, biff, air)
* elf: Visualization/processing of high-angular resolution diffusion imaging
(ten, tijk, limn, ell, nrrd, air)
@@ -162,26 +190,29 @@
* coil: Non-linear image filtering (ten, ell, nrrd, biff, air)
-* push: Original implmentation of glyph packing for DTI
-(ten, gage, ell, nrrd, biff, air)
+* push: Original implmentation of glyph packing for DTI (ten, gage, ell, nrrd,
+biff, air)
-* mite: Hoover-based volume rendering with gage-based transfer functions
-(ten, hoover, limn, gage, ell, nrrd, biff, air)
+* mite: Hoover-based volume rendering with gage-based transfer functions (ten,
+hoover, limn, gage, ell, nrrd, biff, air)
-* meet: Uniform API to things common to all Teem libraries
-(mite, push, coil, pull, elf, ten, seek, hoover, echo, limn, bane, dye,
-gage, tijk, moss, alan, unrrdu, ell, nrrd, biff, hest, air)
+* meet: Uniform API to things common to all Teem libraries (mite, push, coil,
+pull, elf, ten, seek, hoover, echo, limn, bane, dye, gage, tijk, moss, alan,
+unrrdu, ell, nrrd, biff, hest, air)
=============== Teem comand-line tools
-The easiest way to access the functionality in Teem is with its
-command-line tools. Originally intended only as demos for the Teem
-libraries and using their APIs, the command-line tools have become a
-significant way of getting real work done. Source for the tools is in
-teem/src/bin. The most commonly used tools are:
+The easiest way to access the functionality in Teem is with its command-line
+tools. Originally intended only as demos for the Teem libraries and using
+their APIs, the command-line tools have become a significant way of getting
+real work done. Source for the tools is in teem/src/bin. The most commonly
+used tools are:
-* unu: uses the "nrrd" library; a fast way to do raster data processing
-and visualization
+* unu: uses the "nrrd" library; a fast way to do raster data processing and
+visualization. What the rest of the world does in numpy, you maybe able to do
+on the command-line with unu. Type "unu" to see the commands; type "unu all" to
+see extra hidden commands (like "unu undos" for converting text files from
+Windows to normal)
* tend: uses the "ten" library; for DW-MRI and DTI processing
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <kin...@us...> - 2025-09-14 22:09:06
|
Revision: 7431
http://sourceforge.net/p/teem/code/7431
Author: kindlmann
Date: 2025-09-14 22:09:05 +0000 (Sun, 14 Sep 2025)
Log Message:
-----------
This never developed into a useful set of examples, and now with the python bindings, it seems even less likely that will do so in the future
Removed Paths:
-------------
teem/trunk/Examples/
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <kin...@us...> - 2025-09-14 09:28:40
|
Revision: 7430
http://sourceforge.net/p/teem/code/7430
Author: kindlmann
Date: 2025-09-14 09:28:38 +0000 (Sun, 14 Sep 2025)
Log Message:
-----------
basically done with self-contained instructive example of using the levmar functions
Modified Paths:
--------------
teem/trunk/src/ten/tendLmdemo.c
Modified: teem/trunk/src/ten/tendLmdemo.c
===================================================================
--- teem/trunk/src/ten/tendLmdemo.c 2025-09-13 20:12:21 UTC (rev 7429)
+++ teem/trunk/src/ten/tendLmdemo.c 2025-09-14 09:28:38 UTC (rev 7430)
@@ -45,34 +45,6 @@
"GNUmake-ing with environment variable TEEM_LEVMAR.");
#endif
-/* excerpts from levmar.h:
-
--- double precision LM, with & without Jacobian --
--- unconstrained minimization --
-extern int dlevmar_der(
- void (*func)(double *p, double *hx, int m, int n, void *adata),
- void (*jacf)(double *p, double *j, int m, int n, void *adata),
- double *p, double *x, int m, int n, int itmax, double *opts,
- double *info, double *work, double *covar, void *adata);
-
-extern int dlevmar_dif(
- void (*func)(double *p, double *hx, int m, int n, void *adata),
- double *p, double *x, int m, int n, int itmax, double *opts,
- double *info, double *work, double *covar, void *adata);
-
--- box-constrained minimization --
-extern int dlevmar_bc_der(
- void (*func)(double *p, double *hx, int m, int n, void *adata),
- void (*jacf)(double *p, double *j, int m, int n, void *adata),
- double *p, double *x, int m, int n, double *lb, double *ub, double *dscl,
- int itmax, double *opts, double *info, double *work, double *covar, void *adata);
-
-extern int dlevmar_bc_dif(
- void (*func)(double *p, double *hx, int m, int n, void *adata),
- double *p, double *x, int m, int n, double *lb, double *ub, double *dscl,
- int itmax, double *opts, double *info, double *work, double *covar, void *adata);
-*/
-
static double
polyEval(const double *parmCurr, unsigned int M, double xx) {
double ret = 0;
@@ -94,7 +66,7 @@
/*
funcPredict: the "func" callback for levmar functions
-Forward modeling or prediction callback for both dlevmar_der and dlevmar_dif, which
+Forward modeling or prediction, for all of dlevmar{_bc,}_{der,dif}, which
the https://users.ics.forth.gr/~lourakis/levmar/ docs describe as:
functional relation describing measurements.
A pc[] \in R^mm yields a \hat{y} \in R^nn
@@ -108,9 +80,9 @@
funcPredict(double *parmCurr, double *hy, int mm, int nn, void *adata) {
bagOstate *bag = (bagOstate *)adata;
if (bag->verb > 2) {
- printf("%s: called at parmCurr =", __func__);
+ printf("%s: called at parmCurr =", __func__);
for (int pi = 0; pi < mm; pi++) {
- printf(" %g", parmCurr[pi]);
+ printf(" %.17g", parmCurr[pi]);
}
printf("\n");
}
@@ -123,14 +95,47 @@
return;
}
+/* Analytic Jacobian J[i,j] = d(predVal[i]) / d(parm[j])
+ * e.g. polynomial p(x) = a + b*x + c*x*x => m = #parms = 3 => j=0..2
+ * => i'th row of J = [ 1 xi xi*xi ]
+ * levmar wants "row-major" => rows are contiguous in memory
+ * => j is faster axis, and i is slower axis
+ */
+static void
+funcJacobian(double *parmCurr, double *jac, int mm, int nn, void *adata) {
+ bagOstate *bag = (bagOstate *)adata;
+ if (bag->verb > 2) {
+ printf("%s: called at parmCurr =", __func__);
+ for (int pi = 0; pi < mm; pi++) {
+ printf(" %.17g", parmCurr[pi]);
+ }
+ printf("\n");
+ }
+ assert(AIR_UINT(mm) == bag->M);
+ assert(AIR_UINT(nn) == bag->N);
+ for (int si = 0; si < nn; si++) { // si = sample index
+ double sx = NRRD_CELL_POS(bag->xmm[0], bag->xmm[1], nn, si);
+ double pxj = 1; // pow(x,j) = x^j but computed incrementally
+ for (int jj = 0; jj < mm; jj++) {
+ jac[si * mm + jj] = pxj; // jj faster, si slower
+ /* If using this busted Jacobian: jac[jj * nn + si] = pxj; levmar still converges
+ (at least it can converge due to small Dp) but with a huge residual. There does
+ NOT seem to be any internal levmar sanity check that the Jacobian callback is
+ giving results consistent with the data prediction callback */
+ pxj *= sx;
+ }
+ }
+ return;
+}
+
// Synthesize data and store in ndata
static void
-dataSynth(Nrrd *ndata, const bagOstate *bag, double rnStdv, unsigned int rnSeed,
+dataSynth(Nrrd *ndata, const bagOstate *bag, const double rndStdvSeed[2],
airArray *mop) {
double *data = AIR_CAST(double *, ndata->data);
airJSFRand *jsf = NULL;
- if (rnStdv > 0) {
- jsf = airJSFRandNew(rnSeed);
+ if (rndStdvSeed[0] > 0) {
+ jsf = airJSFRandNew(AIR_UINT(rndStdvSeed[1]));
airMopAdd(mop, jsf, (airMopper)airJSFRandNix, airMopAlways);
}
unsigned int N = AIR_UINT(ndata->axis[0].size); // N = # of data points
@@ -138,11 +143,11 @@
for (unsigned int si = 0; si < N; si++) { // si = sample index
double sx = NRRD_CELL_POS(bag->xmm[0], bag->xmm[1], N, si);
double val = polyEval(bag->tp, bag->M, sx);
- double noise = jsf ? rnStdv * airJSFRandNormal_d(jsf) : 0;
+ double noise = jsf ? rndStdvSeed[0] * airJSFRandNormal_d(jsf) : 0;
/*
if (bag->verb > 1) {
- printf("%s: data[%u] = poly(%g) + noise = %g + %g = %g\n", __func__, si, sx, val,
- noise, val + noise);
+ printf("%s: data[%u] = poly(%.17g) + noise = %.17g + %.17g = %.17g\n", __func__,
+ si, sx, val, noise, val + noise);
}
*/
data[si] = val + noise;
@@ -157,68 +162,162 @@
To be instructive, this levmar wrapper function is trying to be general purpose;
the fact that funcPredict is evaluating a polynomial and that we're here to fit a
polynomial should not be exposed by this function.
+
+Summary of info from from https://users.ics.forth.gr/~lourakis/levmar/
+and https://users.ics.forth.gr/~lourakis/levmar/levmar.pdf
+and the levmar-2.6 source code, specifically lm_core.c and lmbc_core.c
+
+notation:
+e in R^n = epsilon vector = (given data x - predicted data hx or \hat{x})
+p in R^m = parameter vector
+Dp in R^m = delta p = last step taken in parameter space
+J nxm matrix = Jacobian of i'th predicted data w.r.t j'th parm; J_ij = d hx_i / d p_j
+mu in R = damping term added to diagonal of [J^T J] to normalize it
+ (mu set to tau * max[J^T J]_ii)
+lb, ub = lower (per-parameter) bounds, upper bounds
+
+double opts[5] for controlling levmar functions:
+opts[0] = (\tau) the scale factor for initial \mu (default LM_INIT_MU)
+(GLK renamed these eps from "epsilon" to avoid confusion with epsilon vector e)
+opts[1] = (\eps1) stopping threshold for ||J^T e||_inf (default LM_STOP_THRESH)
+opts[2] = (\eps2) stopping threshold for ||Dp||_2 (default LM_STOP_THRESH)
+opts[3] = (\eps3) stopping threshold for ||e||_2 (default LM_STOP_THRESH)
+(opts[4] is only for dlevmar_dif(), and it is not a stopping threshold;
+ dlevmar_der() only reads opts[0..3])
+opts[4] = (\delta) step size used in difference approximation of Jacobian.
+If \delta<0, the Jacobian is approximated with central differences which
+are more accurate (but slower!) compared to the forward differences
+(as employed by default). (default LM_DIFF_DELTA)
+Set to opts=NULL for defaults to be used (listed above)
+
+GLK's understanding of these functions is also in the `if (bag->verb)` diagnostics
+about the info[LM_INFO_SZ] vector and interpreting the stopping info[6]
*/
+#if TEEM_LEVMAR
+// these constants come from levmar.h
+static double optsDefault[5] = {LM_INIT_MU, // 0 (from looking at lm_core.c)
+ LM_STOP_THRESH, // 1
+ LM_STOP_THRESH, // 2
+ LM_STOP_THRESH, // 3
+ LM_DIFF_DELTA}; // 4
+#else
+static double optsDefault[5] = {0, 0, 0, 0, 0};
+#endif
+
static void
-doLM(Nrrd *ndata, int itmax, /* const */ double opts[5], bagOstate *bag) {
- int iters = -1;
+levmarCall(Nrrd *ndata, int ajac, int itmax,
+ /* const (levmar sadly has no const correctness) */ double *bndLo,
+ /* const */ double *bndHi,
+ /* const */ double opts[5], bagOstate *bag) {
+ int IT = -1; // short variable name just for formatting
+ double info[10]; // == LM_INFO_SZ, but hard-coding so non-LEVMAR version compiles
+ // NaN-out the output info[] vector
+ for (unsigned int ii = 0; ii < 10; ii++) {
+ info[ii] = AIR_NAN;
+ }
+ int M = (int)(bag->M);
+ int N = (int)(bag->N);
+ assert(!!bndLo == !!bndHi); // either have both bndLo and bndHi or neither
+ double *ym = (double *)(ndata->data); // measured y values
AIR_UNUSED(ndata);
AIR_UNUSED(itmax);
- double info[LM_INFO_SZ];
- for (unsigned int ii = 0; ii < LM_INFO_SZ; ii++) {
- info[ii] = AIR_NAN;
- }
+ AIR_UNUSED(M);
+ AIR_UNUSED(N);
+ AIR_UNUSED(ym);
+ char lmfname[AIR_STRLEN_SMALL + 1];
+ if (ajac) { // analytic Jacobian
+ if (!bndLo) { // no lower bounds or upper bounds
+ strcpy(lmfname, "dlevmar_der");
+ /* extern int dlevmar_der(
+ void (*func)(double *p, double *hx, int m, int n, void *adata),
+ void (*jacf)(double *p, double *j, int m, int n, void *adata),
+ double *p, double *x, int m, int n, int itmax, double *opts,
+ double *info, double *work, double *covar, void *adata); */
#if TEEM_LEVMAR
- double *ym = (double *)(ndata->data); // measured y values
- /* extern int dlevmar_dif(
+ IT = dlevmar_der(funcPredict, //
+ funcJacobian, //
+ bag->parmCurr, ym, M, N, itmax, opts, //
+ info, NULL, NULL, AIR_VOIDP(bag));
+#endif
+ } else { // bndLo and bndHi form _b_ox _c_constraints -> bc
+ strcpy(lmfname, "dlevmar_bc_der");
+ /* Why do the bc functions need dscl? GLK not sure. Quoting from lmbc_core.c:
+ "The algorithm implemented by this function employs projected gradient steps. Since
+ steepest descent is very sensitive to poor scaling, diagonal scaling has been
+ implemented through the dscl argument: Instead of minimizing f(p) for p, f(D*q) is
+ minimized for q=D^-1*p, D being a diagonal scaling matrix whose diagonal equals
+ dscl (see Nocedal-Wright p.27). dscl should contain "typical" magnitudes for the
+ parameters p. A NULL value for dscl implies no scaling. i.e. D=I. To account for
+ scaling, the code divides the starting point and box bounds pointwise by dscl.
+ Moreover, before calling func and jacf the scaling has to be undone (by
+ multiplying), as should be done with the final point. Note also that jac_q=jac_p*D,
+ where jac_q, jac_p are the jacobians w.r.t. q & p, resp."
+ (but nothing there about dscl is specific to having box constraints?) */
+ /* extern int dlevmar_bc_der(
void (*func)(double *p, double *hx, int m, int n, void *adata),
- double *p, double *x, int m, int n, int itmax, double *opts,
- double *info, double *work, double *covar, void *adata); */
- iters = dlevmar_dif(funcPredict, //
- bag->parmCurr, ym, (int)(bag->M), (int)(bag->N), itmax, opts, //
- info, NULL, NULL, AIR_VOIDP(bag));
-#else
- printf("%s: not calling dlevmar_dif() because we don't have TEEM_LEVMAR\n", __func__);
+ void (*jacf)(double *p, double *j, int m, int n, void *adata),
+ double *p, double *x, int m, int n, double *lb, double *ub, double *dscl,
+ int itmax, double *opts, double *info, double *work, double *covar, void *adata);
+ */
+#if TEEM_LEVMAR
+ IT = dlevmar_bc_der(funcPredict, //
+ funcJacobian, //
+ bag->parmCurr, ym, M, N, bndLo, bndHi, NULL, //
+ itmax, opts, info, NULL, NULL, AIR_VOIDP(bag));
#endif
- printf("%s: after %d iters, ended at parmCurr =", __func__, iters);
+ }
+ } else { // !ajac: numerical derivatives of predicted data
+ if (!bndLo) {
+ strcpy(lmfname, "dlevmar_dif");
+ /* extern int dlevmar_dif(
+ void (*func)(double *p, double *hx, int m, int n, void *adata),
+ double *p, double *x, int m, int n, int itmax, double *opts,
+ double *info, double *work, double *covar, void *adata); */
+#if TEEM_LEVMAR
+ IT = dlevmar_dif(funcPredict, //
+ bag->parmCurr, ym, M, N, itmax, opts, //
+ info, NULL, NULL, AIR_VOIDP(bag));
+#endif
+ } else {
+ strcpy(lmfname, "dlevmar_bc_dif");
+ /* extern int dlevmar_bc_dif(
+ void (*func)(double *p, double *hx, int m, int n, void *adata),
+ double *p, double *x, int m, int n, double *lb, double *ub, double *dscl,
+ int itmax, double *opts, double *info, double *work, double *covar, void *adata);
+ */
+#if TEEM_LEVMAR
+ IT = dlevmar_bc_dif(funcPredict, //
+ bag->parmCurr, ym, M, N, bndLo, bndHi, NULL, //
+ itmax, opts, info, NULL, NULL, AIR_VOIDP(bag));
+#endif
+ }
+ }
+#if !(TEEM_LEVMAR)
+ printf("%s: Did NOT call %s() because we don't have TEEM_LEVMAR\n", __func__, lmfname);
+#endif
+ printf("%s: After %d iters, %s ended at parmCurr =\n", __func__, IT, lmfname);
for (unsigned int pi = 0; pi < bag->M; pi++) {
- printf(" %g", bag->parmCurr[pi]);
+ printf(" %.17g", bag->parmCurr[pi]);
}
printf("\n");
if (bag->verb) {
- /*
- Summary of info from from https://users.ics.forth.gr/~lourakis/levmar/
- and https://users.ics.forth.gr/~lourakis/levmar/levmar.pdf
- e in R^n = epsilon vector = given data - predicted data
- p in R^m = parameter vector
- dp in R^m = delta p = last step taken in parameter space
- J nxm matrix = Jacobian; J_ij = d hx_i / d p_j
- mu in R = damping term added to diagonal of [J^T J] to normalize it
- (mu set to tau * max[J^T J]_ii)
-
- double opts[5] for controlling levmar functions:
- opts[0-4] = [\tau, \epsilon1, \epsilon2, \epsilon3, \delta]. Respectively
- opts[0] = (\tau) the scale factor for initial \mu,
- opts[1] = (\epsilon1) stopping threshold for ||J^T e||_inf,
- opts[2] = (\epsilon2) stopping threshold for ||Dp||_2
- opts[3] = (\epsilon3) stopping threshold for ||e||_2
- opts[4] = (\delta) stopping thresh for step used in difference approximation of
- Jacobian. If \delta<0, the Jacobian is approximated with central differences which
- are more accurate (but slower!) compared to the forward differences employed by
- default. Set to opts=NULL for defaults to be used.
- */
- printf("info[0]: Error at initial p (||e||^2): %g\n", info[0]);
- printf("info[1]: Error at final p (||e||^2): %g\n", info[1]);
- printf("info[2]: Gradient norm at final p (||J^T e||_inf): %g\n", info[2]);
- printf("info[3]: Norm of last step (||dp||_2): %g\n", info[3]);
- printf("info[4]: Final damping scaling tau (mu/max[J^T J]_ii): %g\n", info[4]);
+ printf("info[0]: Chi^2 error at initial p (||e||^2): %.17g\n", info[0]);
+ printf("info[1]: Chi^2 error at final p (||e||^2): %.17g\n", info[1]);
+ printf("info[2]: Gradient norm at final p (||J^T e||_inf): %.17g\n", info[2]);
+ printf("info[3]: Norm of last step (||Dp||_2): %.17g\n", info[3]);
+ printf("info[4]: Final damping scaling tau (mu/max[J^T J]_ii): %.17g\n", info[4]);
printf("info[5]: # of iterations: %.0f\n", info[5]);
printf("info[6]: Termination reason: ");
- switch ((int)(info[6] + 0.5)) { // round to nearest int
+ char obuff[AIR_STRLEN_SMALL + 1];
+#define OPTS(I) \
+ (opts ? (sprintf(obuff, "%.17g", opts[I]), obuff) \
+ : (sprintf(obuff, "default %.17g", optsDefault[I]), obuff))
+ switch ((int)(info[6])) {
case 1:
- printf("(1) stopped by small gradient J^T e\n");
+ printf("(1) stopped by small gradient ||J^T e||_inf < %s = eps1\n", OPTS(1));
break;
case 2:
- printf("(2) stopped by small dp\n");
+ printf("(2) stopped by small parameter step ||Dp||_2 < %s = eps2\n", OPTS(2));
break;
case 3:
printf("(3) stopped by itmax %d\n", itmax);
@@ -231,7 +330,7 @@
printf("(5) no further error reduction is possible. Restart with increased mu\n");
break;
case 6:
- printf("(6) stopped by small ||e||_2\n");
+ printf("(6) stopped by small residual ||e||_2 < %s = eps3\n", OPTS(3));
break;
case 7:
printf("(7) stopped by invalid (i.e. NaN or Inf) func values; a user error\n");
@@ -255,32 +354,73 @@
char *perr, *err;
bagOstate bag[1]; // allocate one bag-o-state; can access member m with bag->m
- hestOptAdd_Nv_Double(&hopt, "tp", "true poly coeffs", 1, -1, &(bag->tp), "1",
+ hestOptAdd_Nv_Double(&hopt, "tp", "true poly coeffs", 1, -1, &(bag->tp), NULL,
"coefficients of (ground-truth) polynomial to sample, to "
"synthsize the data to later fit. \"-tp A B C\" means "
"A + Bx + Cx^2. These coefficients are the _M_ "
"parameters that the LM method seeks to recover",
&(bag->M));
+ // HEY should add hest opt for initial parameter vector
hestOptAdd_1_UInt(&hopt, "N", "# points", &(bag->N), "42",
"How many times to sample polynomial to generate data _N_ data "
- "points. Part of the purpose of this demo is to connect the "
+ "points. Part of the purpose of this demo is to connect the "
"stupid single-letter variable names used in the levmar docs "
- "to this concrete example.");
+ "to this concrete example. NOTE that how the levmar code and docs "
+ "use \"n\" vs \"m\" is *flipped* from many other presentations of "
+ "Levenberg-Marquardt.");
hestOptAdd_2_Double(&hopt, "xmm", "xmin xmax", bag->xmm, "-1 1",
"polynomial will be evaluated at _N_ cell-centered points along "
"this interval on X axis");
- double rnStdv;
- hestOptAdd_1_Double(&hopt, "r", "noise", &rnStdv, "0",
+ double rndStdvSeed[2];
+ hestOptAdd_2_Double(&hopt, "noise", "stdv seed", rndStdvSeed, "0 67",
"Gaussian noise of this stdv will be added to polynomial "
- "evaluations to generate data");
- unsigned int rnSeed;
- hestOptAdd_1_UInt(&hopt, "e", "rng sEed", &rnSeed, "67",
- "Seed for random number generator");
+ "evaluations to generate data, and the seed value (cast to "
+ "a uint) will be used to initialized the RNG");
char *outS;
hestOptAdd_1_String(&hopt, "o", "data out", &outS, NULL,
"If given a filename here, will save out synthetic data");
int itmax;
- hestOptAdd_1_Int(&hopt, "im", "itmax", &itmax, "100", "cap on # iterations");
+ hestOptAdd_1_Int(&hopt, "itmax", "# iters", &itmax, "100", "cap on # iterations");
+// https://gcc.gnu.org/onlinedocs/cpp/Stringizing.html#Stringizing
+#if TEEM_LEVMAR
+# define _str(s) #s
+# define str(s) _str(s)
+#else
+# define str(s) ("nan")
+#endif
+ double tau;
+ hestOptAdd_1_Double(&hopt, "tau", "tau", &tau, str(LM_INIT_MU),
+ "Initial damping mu is found by multiplying max[J^T J]_ii by this "
+ "number, called tau");
+ double eps1;
+ hestOptAdd_1_Double(&hopt, "eps1", "thresh", &eps1, str(LM_STOP_THRESH),
+ "stopping thresh on (Linf of) the parm gradient [J^T (x-hx)]");
+ double eps2;
+ hestOptAdd_1_Double(&hopt, "eps2", "thresh", &eps2, str(LM_STOP_THRESH),
+ "stopping thresh on (L2 of) the parm delta Dp");
+ double eps3;
+ hestOptAdd_1_Double(&hopt, "eps3", "thresh", &eps3, str(LM_STOP_THRESH),
+ "stopping thresh on (L2 of) the (x-hx) residual vector");
+ int ajac;
+ hestOptAdd_Flag(&hopt, "ajac", &ajac,
+ "use analytic Jacobian of predicted (modeled) data w.r.t parameters");
+ double bc;
+ hestOptAdd_1_Double(&hopt, "bc", "scaling", &bc, "0.0",
+ "If > 0, then create box constraints around the parameter "
+ "by first finding pmax the max absolute value of the "
+ "ground truth parameters, then box is bc*[-pmax,pmax]^M. "
+ "So to give breathing room want bc well above 1, but can "
+ "set bc < 1 for testing purposes.");
+ double delta;
+ hestOptAdd_1_Double(&hopt, "delta", "delta", &delta, str(LM_DIFF_DELTA),
+ "if not using analytic Jacobian, this is the "
+ "per-parameter delta to use for numerically computing it, "
+ "via forward (delta>0) or central (delta<0) differences");
+ int nulopt;
+ hestOptAdd_Flag(&hopt, "nulopt", &nulopt,
+ "Instead of creating the opts[] vector from the previous "
+ "tau,eps{1,2,3},delta options, just use NULL, which invokes "
+ "levmar's internal defaults");
hestOptAdd_1_Int(&hopt, "v", "verbosity", &(bag->verb), "1", "verbosity level");
airArray *mop = airMopNew();
@@ -307,7 +447,7 @@
return 1;
}
// synthesize the data and maybe save it out
- dataSynth(ndata, bag, rnStdv, rnSeed, mop);
+ dataSynth(ndata, bag, rndStdvSeed, mop);
if (airStrlen(outS)) {
NrrdIoState *nio = nrrdIoStateNew();
airMopAdd(mop, nio, (airMopper)nrrdIoStateNix, airMopAlways);
@@ -321,16 +461,42 @@
}
}
- // prepare for LM call
+ // prepare for levmar call
bag->parmCurr = AIR_MALLOC(bag->M, double);
assert(bag->parmCurr);
airMopAdd(mop, bag->parmCurr, airFree, airMopAlways);
+ double *bndLo = NULL, *bndHi = NULL;
+ if (bc > 0) {
+ double pmax = 0;
+ for (unsigned int pi = 0; pi < bag->M; pi++) {
+ pmax = AIR_MAX(pmax, fabs(bag->tp[pi]));
+ }
+ if (!pmax) {
+ pmax = 1;
+ }
+ bndLo = AIR_MALLOC(bag->M, double);
+ assert(bndLo);
+ airMopAdd(mop, bndLo, airFree, airMopAlways);
+ bndHi = AIR_MALLOC(bag->M, double);
+ assert(bndHi);
+ airMopAdd(mop, bndHi, airFree, airMopAlways);
+ double bnd = bc * pmax;
+ for (unsigned int pi = 0; pi < bag->M; pi++) {
+ bndLo[pi] = -bnd;
+ bndHi[pi] = bnd;
+ }
+ if (bag->verb) {
+ printf("%s: bc %g, pmax %g => box constraints [%g,%g]\n", me, bc, pmax, -bnd, bnd);
+ }
+ }
// initialize parms that will be fitted
for (unsigned int pi = 0; pi < bag->M; pi++) {
bag->parmCurr[pi] = 0;
}
- AIR_UNUSED(funcPredict); // to quiet warnings if not levmar
- doLM(ndata, itmax, /* opts */ NULL, bag);
+ AIR_UNUSED(funcPredict); // to quiet warnings if no TEEM_LEVMAR
+ AIR_UNUSED(funcJacobian); // to quiet warnings if no TEEM_LEVMAR
+ double opts[5] = {tau, eps1, eps2, eps3, delta};
+ levmarCall(ndata, ajac, itmax, bndLo, bndHi, nulopt ? NULL : opts, bag);
airMopOkay(mop);
return 0;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <kin...@us...> - 2025-09-13 20:12:23
|
Revision: 7429
http://sourceforge.net/p/teem/code/7429
Author: kindlmann
Date: 2025-09-13 20:12:21 +0000 (Sat, 13 Sep 2025)
Log Message:
-----------
more progress in documenting how to control levmar functions
Modified Paths:
--------------
teem/trunk/src/ten/tendLmdemo.c
Modified: teem/trunk/src/ten/tendLmdemo.c
===================================================================
--- teem/trunk/src/ten/tendLmdemo.c 2025-09-13 09:37:57 UTC (rev 7428)
+++ teem/trunk/src/ten/tendLmdemo.c 2025-09-13 20:12:21 UTC (rev 7429)
@@ -36,9 +36,9 @@
// like these C++-style comments, and variables declared as you go, and __func__
// which makes writing C a little less annoying
#else
-# define INFO "(no levmar => cannot run) Demo of levmar"
+# define INFO "(no LEVMAR => cannot run) Demo of levmar"
static const char *_tend_lmdemoInfoL
- = (INFO ". Because this Teem was built without the "
+ = (INFO ". Because this Teem was built withOUT the "
"https://users.ics.forth.gr/~lourakis/levmar/ implementation of "
"Levenberg-Marquardt (LM), this demo does not do anything useful. Try "
"CMake-configuring with Teem_USE_LEVMAR, or "
@@ -74,10 +74,10 @@
*/
static double
-polyEval(const double *pc, unsigned int M, double xx) {
+polyEval(const double *parmCurr, unsigned int M, double xx) {
double ret = 0;
for (unsigned int ci = M; ci-- > 0;) { // ci = coefficient index, with "-->" operator
- ret = ret * xx + pc[ci];
+ ret = ret * xx + parmCurr[ci];
}
return ret;
}
@@ -84,12 +84,12 @@
// the bag-of-state struct passed via "adata" arg for additional data
typedef struct {
- double *tp; // ground truth polynomial coefficients (should really be const)
- unsigned int M, // # parameters to estimate = length of tp[]
- N; // # of samples in interval
- double xmm[2]; // interval in which we do N cell-centered samples
- int verb; // verbosity
- double *pf; // the polynomial as currently being fitted
+ double *tp; // ground truth polynomial coefficients (should really be const)
+ unsigned int M, // # parameters to estimate = length of tp[]
+ N; // # of samples in interval
+ double xmm[2]; // interval in which we do N cell-centered samples
+ int verb; // verbosity
+ double *parmCurr; // the polynomial as currently being fitted
} bagOstate;
/*
@@ -97,20 +97,20 @@
Forward modeling or prediction callback for both dlevmar_der and dlevmar_dif, which
the https://users.ics.forth.gr/~lourakis/levmar/ docs describe as:
functional relation describing measurements.
- A pf[] \in R^mm yields a \hat{y} \in R^nn
+ A pc[] \in R^mm yields a \hat{y} \in R^nn
except that we've done some renaming:
- "p" (parameter vector) --> "pf" current polynomial we're trying
+ "p" (parameter vector) --> "pc" = parmCurr = current polynomial we're trying
"m" (# parameters) --> "mm" to be less annoying
- "hx" (predicted data) --> "hy" predicted y=pf(x) polynomial values
+ "hx" (predicted data) --> "hy" predicted y=pc(x) polynomial values
"n" (# data points) --> "nn" to be less annoying
*/
static void
-funcPredict(double *pf, double *hy, int mm, int nn, void *adata) {
+funcPredict(double *parmCurr, double *hy, int mm, int nn, void *adata) {
bagOstate *bag = (bagOstate *)adata;
if (bag->verb > 2) {
- printf("%s: called at pf =", __func__);
+ printf("%s: called at parmCurr =", __func__);
for (int pi = 0; pi < mm; pi++) {
- printf(" %g", pf[pi]);
+ printf(" %g", parmCurr[pi]);
}
printf("\n");
}
@@ -118,7 +118,7 @@
assert(AIR_UINT(nn) == bag->N);
for (int si = 0; si < nn; si++) { // si = sample index
double sx = NRRD_CELL_POS(bag->xmm[0], bag->xmm[1], nn, si);
- hy[si] = polyEval(pf, mm, sx);
+ hy[si] = polyEval(parmCurr, mm, sx);
}
return;
}
@@ -153,29 +153,98 @@
return;
}
+/*
+To be instructive, this levmar wrapper function is trying to be general purpose;
+the fact that funcPredict is evaluating a polynomial and that we're here to fit a
+polynomial should not be exposed by this function.
+*/
static void
-doLM(Nrrd *ndata, int itmax, bagOstate *bag) {
+doLM(Nrrd *ndata, int itmax, /* const */ double opts[5], bagOstate *bag) {
int iters = -1;
AIR_UNUSED(ndata);
AIR_UNUSED(itmax);
+ double info[LM_INFO_SZ];
+ for (unsigned int ii = 0; ii < LM_INFO_SZ; ii++) {
+ info[ii] = AIR_NAN;
+ }
#if TEEM_LEVMAR
double *ym = (double *)(ndata->data); // measured y values
- double info[LM_INFO_SZ];
/* extern int dlevmar_dif(
void (*func)(double *p, double *hx, int m, int n, void *adata),
double *p, double *x, int m, int n, int itmax, double *opts,
double *info, double *work, double *covar, void *adata); */
- iters = dlevmar_dif(funcPredict, //
- bag->pf, ym, (int)(bag->M), (int)(bag->N), itmax, NULL, //
+ iters = dlevmar_dif(funcPredict, //
+ bag->parmCurr, ym, (int)(bag->M), (int)(bag->N), itmax, opts, //
info, NULL, NULL, AIR_VOIDP(bag));
#else
printf("%s: not calling dlevmar_dif() because we don't have TEEM_LEVMAR\n", __func__);
#endif
- printf("%s: after %d iters, ended up at pf =", __func__, iters);
+ printf("%s: after %d iters, ended at parmCurr =", __func__, iters);
for (unsigned int pi = 0; pi < bag->M; pi++) {
- printf(" %g", bag->pf[pi]);
+ printf(" %g", bag->parmCurr[pi]);
}
printf("\n");
+ if (bag->verb) {
+ /*
+ Summary of info from from https://users.ics.forth.gr/~lourakis/levmar/
+ and https://users.ics.forth.gr/~lourakis/levmar/levmar.pdf
+ e in R^n = epsilon vector = given data - predicted data
+ p in R^m = parameter vector
+ dp in R^m = delta p = last step taken in parameter space
+ J nxm matrix = Jacobian; J_ij = d hx_i / d p_j
+ mu in R = damping term added to diagonal of [J^T J] to normalize it
+ (mu set to tau * max[J^T J]_ii)
+
+ double opts[5] for controlling levmar functions:
+ opts[0-4] = [\tau, \epsilon1, \epsilon2, \epsilon3, \delta]. Respectively
+ opts[0] = (\tau) the scale factor for initial \mu,
+ opts[1] = (\epsilon1) stopping threshold for ||J^T e||_inf,
+ opts[2] = (\epsilon2) stopping threshold for ||Dp||_2
+ opts[3] = (\epsilon3) stopping threshold for ||e||_2
+ opts[4] = (\delta) stopping thresh for step used in difference approximation of
+ Jacobian. If \delta<0, the Jacobian is approximated with central differences which
+ are more accurate (but slower!) compared to the forward differences employed by
+ default. Set to opts=NULL for defaults to be used.
+ */
+ printf("info[0]: Error at initial p (||e||^2): %g\n", info[0]);
+ printf("info[1]: Error at final p (||e||^2): %g\n", info[1]);
+ printf("info[2]: Gradient norm at final p (||J^T e||_inf): %g\n", info[2]);
+ printf("info[3]: Norm of last step (||dp||_2): %g\n", info[3]);
+ printf("info[4]: Final damping scaling tau (mu/max[J^T J]_ii): %g\n", info[4]);
+ printf("info[5]: # of iterations: %.0f\n", info[5]);
+ printf("info[6]: Termination reason: ");
+ switch ((int)(info[6] + 0.5)) { // round to nearest int
+ case 1:
+ printf("(1) stopped by small gradient J^T e\n");
+ break;
+ case 2:
+ printf("(2) stopped by small dp\n");
+ break;
+ case 3:
+ printf("(3) stopped by itmax %d\n", itmax);
+ break;
+ case 4:
+ printf("(4) singular (augmented normal) matrix. Restart from current p with "
+ "increased mu\n");
+ break;
+ case 5:
+ printf("(5) no further error reduction is possible. Restart with increased mu\n");
+ break;
+ case 6:
+ printf("(6) stopped by small ||e||_2\n");
+ break;
+ case 7:
+ printf("(7) stopped by invalid (i.e. NaN or Inf) func values; a user error\n");
+ break;
+ default:
+ printf("Unknown code %.0f\n", info[6]);
+ }
+ printf("info[7]: # of function evals: %.0f\n", info[7]);
+ printf("info[8]: # of Jacobian evals: %.0f\n", info[8]);
+ printf(
+ "info[9]: # linear systems solved, i.e. # attempts for reducing error: %.0f\n",
+ info[9]);
+ }
return;
}
@@ -186,7 +255,7 @@
char *perr, *err;
bagOstate bag[1]; // allocate one bag-o-state; can access member m with bag->m
- hestOptAdd_Nv_Double(&hopt, "tp", "true poly coeffs", 1, 10, &(bag->tp), "1",
+ hestOptAdd_Nv_Double(&hopt, "tp", "true poly coeffs", 1, -1, &(bag->tp), "1",
"coefficients of (ground-truth) polynomial to sample, to "
"synthsize the data to later fit. \"-tp A B C\" means "
"A + Bx + Cx^2. These coefficients are the _M_ "
@@ -253,15 +322,15 @@
}
// prepare for LM call
- bag->pf = AIR_MALLOC(bag->M, double);
- assert(bag->pf);
- airMopAdd(mop, bag->pf, airFree, airMopAlways);
+ bag->parmCurr = AIR_MALLOC(bag->M, double);
+ assert(bag->parmCurr);
+ airMopAdd(mop, bag->parmCurr, airFree, airMopAlways);
// initialize parms that will be fitted
for (unsigned int pi = 0; pi < bag->M; pi++) {
- bag->pf[pi] = 0;
+ bag->parmCurr[pi] = 0;
}
AIR_UNUSED(funcPredict); // to quiet warnings if not levmar
- doLM(ndata, itmax, bag);
+ doLM(ndata, itmax, /* opts */ NULL, bag);
airMopOkay(mop);
return 0;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <kin...@us...> - 2025-09-13 09:38:00
|
Revision: 7428
http://sourceforge.net/p/teem/code/7428
Author: kindlmann
Date: 2025-09-13 09:37:57 +0000 (Sat, 13 Sep 2025)
Log Message:
-----------
finally got some kind of hierarchical target dumper working
Modified Paths:
--------------
teem/trunk/CMake/DumpTarget.cmake
teem/trunk/CMakeLists-v2.txt
Modified: teem/trunk/CMake/DumpTarget.cmake
===================================================================
--- teem/trunk/CMake/DumpTarget.cmake 2025-09-13 08:50:42 UTC (rev 7427)
+++ teem/trunk/CMake/DumpTarget.cmake 2025-09-13 09:37:57 UTC (rev 7428)
@@ -92,3 +92,49 @@
message("")
endfunction()
+
+
+function(_td_dump_dir dir indent)
+ if(NOT indent)
+ set(indent "")
+ endif()
+
+ message("${indent}Directory: ${dir}")
+
+ # Targets created by add_library/add_executable/add_custom_target in this dir
+ get_property(_dir_targets DIRECTORY "${dir}" PROPERTY BUILDSYSTEM_TARGETS)
+ if(_dir_targets)
+ foreach(_t IN LISTS _dir_targets)
+ message("${indent}>>>>> target: ${_t}")
+ # call user-provided per-target dumper
+ dump_target(${_t})
+ endforeach()
+ endif()
+
+ # Imported targets added in this directory (CMake >= 3.21)
+ get_property(_dir_imported DIRECTORY "${dir}" PROPERTY IMPORTED_TARGETS)
+ if(_dir_imported)
+ foreach(_it IN LISTS _dir_imported)
+ message("${indent}>>>>> imported: ${_it}")
+ dump_target(${_it})
+ endforeach()
+ endif()
+
+ # Recurse into subdirectories
+ get_property(_subdirs DIRECTORY "${dir}" PROPERTY SUBDIRECTORIES)
+ foreach(_sd IN LISTS _subdirs)
+ # _sd is a directory path (absolute or relative); calling recursively is fine.
+ _td_dump_dir("${_sd}" "${indent}====")
+ endforeach()
+endfunction()
+
+function(dump_targets_all)
+ message("vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv")
+ message("=============== Begin Hierarchical Target Dump ==============")
+
+ _td_dump_dir("${CMAKE_SOURCE_DIR}" "")
+
+ message("================ End Hierarchical Target Dump ===============")
+ message("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^")
+
+endfunction()
Modified: teem/trunk/CMakeLists-v2.txt
===================================================================
--- teem/trunk/CMakeLists-v2.txt 2025-09-13 08:50:42 UTC (rev 7427)
+++ teem/trunk/CMakeLists-v2.txt 2025-09-13 09:37:57 UTC (rev 7428)
@@ -37,6 +37,7 @@
# TeemConfig.cmake.in
# CheckAirExists.cmake (new for Teem v2)
# CheckLibmNeeded.cmake (new for Teem v2)
+# DumpTarget.cmake (new for Teem v2)
# - src/bin/CMakeLists.txt
# - src/{air,biff,...}/CMakeLists.txt
# - CTestConfig.cmake
@@ -617,7 +618,8 @@
if(0)
include(DumpTarget)
- dump_target(Teem)
- dump_target(unu)
- dump_target(PNG::PNG)
+ dump_targets_all()
+ #dump_target(Teem)
+ #dump_target(unu)
+ #dump_target(PNG::PNG)
endif()
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <kin...@us...> - 2025-09-13 08:50:43
|
Revision: 7427
http://sourceforge.net/p/teem/code/7427
Author: kindlmann
Date: 2025-09-13 08:50:42 +0000 (Sat, 13 Sep 2025)
Log Message:
-----------
example of trying to debug target properties
Modified Paths:
--------------
teem/trunk/CMakeLists-v2.txt
Modified: teem/trunk/CMakeLists-v2.txt
===================================================================
--- teem/trunk/CMakeLists-v2.txt 2025-09-13 08:48:52 UTC (rev 7426)
+++ teem/trunk/CMakeLists-v2.txt 2025-09-13 08:50:42 UTC (rev 7427)
@@ -265,10 +265,6 @@
endif()
endforeach()
-## to confirm that PNG::PNG links to ZLIB::ZLIB
-#get_target_property(_png_libs PNG::PNG INTERFACE_LINK_LIBRARIES)
-#message(STATUS "PNG::PNG links to: ${_png_libs}")
-
###-------------------------------------------------------------------------------------
# Describe install directory layout with variables:
# HEADERS_INSTALL_DIR, LIB_INSTALL_DIR, BIN_INSTALL_DIR, CONFIG_INSTALL_DIR
@@ -403,37 +399,6 @@
add_subdirectory(src/${_dir})
endforeach()
-if(0) # inspecting the properties set so far
- # confirm results of prior target_link_libraries(PRIVATE)s
- # (what dependencies do I consume)
- get_target_property(_Teem_libs Teem LINK_LIBRARIES)
- message(STATUS "Teem LINK_LIBRARIES = ${_Teem_libs}")
-
- ## Not interesting for Teem: what dependencies do I expose
- #get_target_property(_Teem_libs Teem INTERFACE_LINK_LIBRARIES)
- #message(STATUS "Teem INTERFACE_LINK_LIBRARIES = ${_Teem_libs}")
- ## This will show "_Teem_libs-NOTFOUND" because of
- ## Teem's API/ABI invariance w.r.t dependencies
-
- # confirm results of prior target_include_directories()s:
- # PRIVATE --> INCLUDE_DIRECTORIES
- # PUBLIC --> INCLUDE_DIRECTORIES and INTERFACE_INCLUDE_DIRECTORIES
- # INTERFACE --> INTERFACE_INCLUDE_DIRECTORIES
- get_target_property(_teem_incdirs Teem INCLUDE_DIRECTORIES)
- message(STATUS "Teem INCLUDE_DIRECTORIES: ${_teem_incdirs}")
- get_target_property(_teem_inter_incdirs Teem INTERFACE_INCLUDE_DIRECTORIES)
- message(STATUS "Teem INTERFACE_INCLUDE_DIRECTORIES: ${teem_inter_incdirs}")
-
- # confirm results of prior target_compile_definitions()s:
- # PRIVATE --> COMPILE_DEFINITIONS
- # PUBLIC --> COMPILE_DEFINITIONS and INTERFACE_COMPILE_DEFINITIONS
- # INTERFACE --> INTERFACE_COMPILE_DEFINITIONS
- get_target_property(_teem_compdefs Teem COMPILE_DEFINITIONS)
- message(STATUS "Teem COMPILE_DEFINITIONS: ${_teem_compdefs}")
- get_target_property(_teem_inter_compdefs Teem INTERFACE_INCLUDE_DIRECTORIES)
- message(STATUS "Teem INTERFACE_COMPILE_DEFINITIONS: ${teem_inter_compdefs}")
-endif()
-
###-------------------------------------------------------------------------------------
# Declare Teem's public headers
@@ -646,3 +611,13 @@
DESTINATION ${CMAKE_INSTALL_BINDIR}
)
endif()
+
+###-------------------------------------------------------------------------------------
+# Some possible debugging of various targets
+
+if(0)
+ include(DumpTarget)
+ dump_target(Teem)
+ dump_target(unu)
+ dump_target(PNG::PNG)
+endif()
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <kin...@us...> - 2025-09-13 08:48:54
|
Revision: 7426
http://sourceforge.net/p/teem/code/7426
Author: kindlmann
Date: 2025-09-13 08:48:52 +0000 (Sat, 13 Sep 2025)
Log Message:
-----------
for debugging
Added Paths:
-----------
teem/trunk/CMake/DumpTarget.cmake
Added: teem/trunk/CMake/DumpTarget.cmake
===================================================================
--- teem/trunk/CMake/DumpTarget.cmake (rev 0)
+++ teem/trunk/CMake/DumpTarget.cmake 2025-09-13 08:48:52 UTC (rev 7426)
@@ -0,0 +1,94 @@
+## DumpTarget.cmake: utilities for printing target properties
+# Copyright (C) 2025 University of Chicago
+# See ../LICENSE.txt for licensing terms
+
+# This is the result of GLK nudging ChatGPT to explain what exactly is the state built up
+# inside CMake as a result of procesing a CMakeLists.txt; among all the new Teem v2 CMake
+# files this one is most experimental and for learning-by-doing. The intent, at least,
+# is to make something useful for debugging.
+
+# print_prop(pfx prop val) describes how property `prop` has value `val`,
+# (including handling NOTFOUND), prefixing each line with `pfx`
+function(print_prop pfx prop val)
+ # Check for NOTFOUND marker (CMake sometimes returns "<something>-NOTFOUND")
+ # (a value that CMake's if() considers false!)
+ if(val MATCHES "NOTFOUND$")
+ message("${pfx}(${prop} not set)")
+ elseif(val STREQUAL "")
+ message("${pfx}${prop} = \"\"")
+ #elseif(val) # not falsey
+ # message("${pfx}${prop} = ${val}")
+ else()
+ set(_genx "")
+ if(val MATCHES "\\$<.*>")
+ set(_genx " ⬅︎ generator expression")
+ endif()
+ message("${pfx}${prop} = ${val}${_genx}")
+ endif()
+endfunction()
+
+# dump_target(tgt) prints a bunch of stuff about the target tgt
+function(dump_target tgt)
+ if(NOT TARGET "${tgt}")
+ message(WARNING "Target ${tgt} does not exist")
+ return()
+ endif()
+
+ message("")
+ message("=====[ Target NAME ${tgt} ]=====")
+
+ # --- Basic info ---
+ set(_Basic_props
+ TYPE
+ IMPORTED
+ #CXX_STANDARD
+ #C_STANDARD
+ POSITION_INDEPENDENT_CODE
+ COMPILE_OPTIONS # set via target_compile_options
+ LINK_FLAGS # set via target_link_options
+ #RUNTIME_OUTPUT_DIRECTORY
+ #LIBRARY_OUTPUT_DIRECTORY
+ #ARCHIVE_OUTPUT_DIRECTORY
+ # EXPORT_SET # not set until later, so not informative during configure time
+ )
+ foreach(_prop IN LISTS _Basic_props)
+ get_target_property(_val "${tgt}" "${_prop}")
+ print_prop(" " "${_prop}" "${_val}")
+ endforeach()
+
+ # lists of property lists
+ set(_Compile_props
+ INCLUDE_DIRECTORIES
+ INTERFACE_INCLUDE_DIRECTORIES
+ COMPILE_DEFINITIONS
+ INTERFACE_COMPILE_DEFINITIONS
+ SOURCES
+ )
+ set(_Link_props
+ LINK_LIBRARIES
+ INTERFACE_LINK_LIBRARIES
+ OUTPUT_NAME
+ )
+ set(_Install_props
+ INSTALL_RPATH
+ )
+
+ foreach(_Group IN ITEMS Compile Link Install)
+ message(" • ${_Group} properties")
+ foreach(_prop IN LISTS _${_Group}_props)
+ get_target_property(_val "${tgt}" "${_prop}")
+ if("${_prop}" STREQUAL "SOURCES")
+ # special handling of SOURCES Compile property: normalize source paths
+ set(_full_srcs "")
+ foreach(s IN LISTS _val)
+ get_filename_component(_abs "${s}" ABSOLUTE "${CMAKE_CURRENT_SOURCE_DIR}")
+ list(APPEND _full_srcs "${_abs}")
+ endforeach()
+ string(JOIN ";" _val "${_full_srcs}")
+ endif()
+ print_prop(" " "${_prop}" "${_val}")
+ endforeach()
+ endforeach()
+
+ message("")
+endfunction()
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <kin...@us...> - 2025-09-12 10:10:49
|
Revision: 7425
http://sourceforge.net/p/teem/code/7425
Author: kindlmann
Date: 2025-09-12 10:10:47 +0000 (Fri, 12 Sep 2025)
Log Message:
-----------
only print DEP_VERSION if is non-empty
Modified Paths:
--------------
teem/trunk/CMakeLists-v2.txt
Modified: teem/trunk/CMakeLists-v2.txt
===================================================================
--- teem/trunk/CMakeLists-v2.txt 2025-09-12 10:05:19 UTC (rev 7424)
+++ teem/trunk/CMakeLists-v2.txt 2025-09-12 10:10:47 UTC (rev 7425)
@@ -246,7 +246,7 @@
find_package(${_Teem_dep_cpname_${_tdep}} ${_Teem_dep_version_${_tdep}} QUIET)
if(${_Teem_dep_found_${_tdep}})
set(Teem_HAVE_${_tdep} TRUE)
- if(DEFINED ${_tdep}_VERSION)
+ if(DEFINED ${_tdep}_VERSION AND ${_tdep}_VERSION)
message(CHECK_PASS "Found version ${${_tdep}_VERSION}")
else()
message(CHECK_PASS "Found")
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <kin...@us...> - 2025-09-12 10:05:21
|
Revision: 7424
http://sourceforge.net/p/teem/code/7424
Author: kindlmann
Date: 2025-09-12 10:05:19 +0000 (Fri, 12 Sep 2025)
Log Message:
-----------
forgot to list some cmake things
Modified Paths:
--------------
teem/trunk/CMakeLists-v2.txt
Modified: teem/trunk/CMakeLists-v2.txt
===================================================================
--- teem/trunk/CMakeLists-v2.txt 2025-09-12 10:02:41 UTC (rev 7423)
+++ teem/trunk/CMakeLists-v2.txt 2025-09-12 10:05:19 UTC (rev 7424)
@@ -39,8 +39,10 @@
# CheckLibmNeeded.cmake (new for Teem v2)
# - src/bin/CMakeLists.txt
# - src/{air,biff,...}/CMakeLists.txt
+# - CTestConfig.cmake
# - tests/ctest/CMakeLists.txt
# - tests/ctest/{air,biff,...}/CMakeLists.txt
+# - UseTeemCMakeDemo/CMakeLists.txt
# were re-written entirely for Teem v2, by me (GLK), with help from ChatGPT. This is the
# first time I've really scrutinized and tried to understand the CMake files, and the
# first time I've tried anything non-trivial with ChatGPT. Current generative AI tools
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <kin...@us...> - 2025-09-12 10:02:43
|
Revision: 7423
http://sourceforge.net/p/teem/code/7423
Author: kindlmann
Date: 2025-09-12 10:02:41 +0000 (Fri, 12 Sep 2025)
Log Message:
-----------
cmake windows needs new testing in general; these minutia are ancient
Modified Paths:
--------------
teem/trunk/src/TODO.txt
Modified: teem/trunk/src/TODO.txt
===================================================================
--- teem/trunk/src/TODO.txt 2025-09-12 09:50:48 UTC (rev 7422)
+++ teem/trunk/src/TODO.txt 2025-09-12 10:02:41 UTC (rev 7423)
@@ -237,10 +237,6 @@
** The items below have accumulated over time, but the importance of them
** should be re-evaluated.
-for cmake:
- - see if wild-card expansion works as expected on windows
- - make cmd-line utilities link with static libs
-
[portable54-250:~/d/parepi/6] gk%
tend estim -new -sigma 0.01 -est wls -i 6crop-dwi.nrrd \
-B kvp -knownB0 false -t 250 -o tmp.nrrd
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <kin...@us...> - 2025-09-12 09:50:52
|
Revision: 7422
http://sourceforge.net/p/teem/code/7422
Author: kindlmann
Date: 2025-09-12 09:50:48 +0000 (Fri, 12 Sep 2025)
Log Message:
-----------
tweaking comments
Modified Paths:
--------------
teem/trunk/CMakeLists-v2.txt
teem/trunk/tests/ctest/CMakeLists.txt
Modified: teem/trunk/CMakeLists-v2.txt
===================================================================
--- teem/trunk/CMakeLists-v2.txt 2025-09-12 09:47:19 UTC (rev 7421)
+++ teem/trunk/CMakeLists-v2.txt 2025-09-12 09:50:48 UTC (rev 7422)
@@ -31,8 +31,6 @@
# All these CMake files:
# - this CMakeLists.txt
-# - src/bin/CMakeLists.txt
-# - src/{air,hest,biff,...}/CMakeLists.txt
# - CMake/
# FindFFTW3.cmake
# FindLEVMAR.cmake
@@ -39,6 +37,10 @@
# TeemConfig.cmake.in
# CheckAirExists.cmake (new for Teem v2)
# CheckLibmNeeded.cmake (new for Teem v2)
+# - src/bin/CMakeLists.txt
+# - src/{air,biff,...}/CMakeLists.txt
+# - tests/ctest/CMakeLists.txt
+# - tests/ctest/{air,biff,...}/CMakeLists.txt
# were re-written entirely for Teem v2, by me (GLK), with help from ChatGPT. This is the
# first time I've really scrutinized and tried to understand the CMake files, and the
# first time I've tried anything non-trivial with ChatGPT. Current generative AI tools
Modified: teem/trunk/tests/ctest/CMakeLists.txt
===================================================================
--- teem/trunk/tests/ctest/CMakeLists.txt 2025-09-12 09:47:19 UTC (rev 7421)
+++ teem/trunk/tests/ctest/CMakeLists.txt 2025-09-12 09:50:48 UTC (rev 7422)
@@ -20,6 +20,8 @@
# cd <builddir>
# ctest -D Nightly # or Experimental, Continuous
+# HEY: how to do coverage tests?
+
###-------------------------------------------------------------------------------------
# Basic set-up
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <kin...@us...> - 2025-09-12 09:47:20
|
Revision: 7421
http://sourceforge.net/p/teem/code/7421
Author: kindlmann
Date: 2025-09-12 09:47:19 +0000 (Fri, 12 Sep 2025)
Log Message:
-----------
ready (or ready enough) for switching over
Modified Paths:
--------------
teem/trunk/CMakeLists-v2.txt
Modified: teem/trunk/CMakeLists-v2.txt
===================================================================
--- teem/trunk/CMakeLists-v2.txt 2025-09-12 09:38:35 UTC (rev 7420)
+++ teem/trunk/CMakeLists-v2.txt 2025-09-12 09:47:19 UTC (rev 7421)
@@ -17,8 +17,6 @@
# along with this library; if not, see <https://www.gnu.org/licenses/>.
#
-# Teem/CMakeLists.txt Version 11.2
-
# This CMakeLists.txt describes a Teem package that contains:
# (1) a library ("libteem" on unix) and
# (2) associated command-line tools (like "unu").
@@ -31,6 +29,39 @@
# development, but there's no reason to complicate this CMakeLists.txt with describing
# those smaller libraries and their inter-dependencies.
+# All these CMake files:
+# - this CMakeLists.txt
+# - src/bin/CMakeLists.txt
+# - src/{air,hest,biff,...}/CMakeLists.txt
+# - CMake/
+# FindFFTW3.cmake
+# FindLEVMAR.cmake
+# TeemConfig.cmake.in
+# CheckAirExists.cmake (new for Teem v2)
+# CheckLibmNeeded.cmake (new for Teem v2)
+# were re-written entirely for Teem v2, by me (GLK), with help from ChatGPT. This is the
+# first time I've really scrutinized and tried to understand the CMake files, and the
+# first time I've tried anything non-trivial with ChatGPT. Current generative AI tools
+# tend to normalize and mechanize intellectual property theft, with a huge carbon
+# footprint. They are unsustainable in so many ways. In this case my deep reservations
+# about ChatGPT were overcome by my deeper distaste for CMake. OpenAI will never be
+# honest about this, but ChatGPT's training likely consumed all available CMakeLists.txt
+# files and online discussion about CMake, regardless of the licensing terms. I apologize
+# to all those developers whose thoughtful online activity around CMake empowered ChatGPT
+# but who receive no compensation from OpenAI.
+
+# As you might guess, ChatGPT was not able to modernize the CMake files in one go; it was
+# a slow fumbling two-ish weeks of over-confident changes balanced by careful human
+# debugging, documentation searching, and reorganization. It's almost as if ChatGPT is
+# trying to maximize usage duration and future dependency. The pseudo-dictionary
+# variables like ${_Teem_dep_target_${_tdep}} (to uniformly access target names
+# "PNG::PNG" vs "FFTW3::fftw3" vs "BZip2::BZip2") were my idea, fwiw. The whole process
+# did less to educate me on CMake's functioning than I hoped, so issues may remain,
+# especially on Windows. Still, I now recognize what a good resource this is:
+# https://gist.github.com/mbinna/c61dbb39bca0e4fb7d1f73b0d66a4fd1
+
+# Feedback and improvements are very welcome: https://discord.gg/xBBqZGXkF7
+
###-------------------------------------------------------------------------------------
# Project setup: version, metadata, and language
@@ -40,8 +71,8 @@
cmake_minimum_required(VERSION 3.25)
# Teem version number (must match values in src/air/air.h)
-set(Teem_VERSION_MAJOR 1)
-set(Teem_VERSION_MINOR 12)
+set(Teem_VERSION_MAJOR 2)
+set(Teem_VERSION_MINOR 0)
set(Teem_VERSION_PATCH 0)
set(Teem_VERSION_STRING ${Teem_VERSION_MAJOR}.${Teem_VERSION_MINOR}.${Teem_VERSION_PATCH})
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <kin...@us...> - 2025-09-12 09:38:38
|
Revision: 7420
http://sourceforge.net/p/teem/code/7420
Author: kindlmann
Date: 2025-09-12 09:38:35 +0000 (Fri, 12 Sep 2025)
Log Message:
-----------
first stab at handling windows
Modified Paths:
--------------
teem/trunk/CMakeLists-v2.txt
teem/trunk/src/bin/CMakeLists-v2.txt
Modified: teem/trunk/CMakeLists-v2.txt
===================================================================
--- teem/trunk/CMakeLists-v2.txt 2025-09-12 09:03:45 UTC (rev 7419)
+++ teem/trunk/CMakeLists-v2.txt 2025-09-12 09:38:35 UTC (rev 7420)
@@ -17,7 +17,7 @@
# along with this library; if not, see <https://www.gnu.org/licenses/>.
#
-# Teem/CMakeLists.txt Version 11
+# Teem/CMakeLists.txt Version 11.2
# This CMakeLists.txt describes a Teem package that contains:
# (1) a library ("libteem" on unix) and
@@ -303,15 +303,17 @@
target_compile_definitions(Teem PUBLIC "$<$<NOT:$<BOOL:${BUILD_SHARED_LIBS}>>:TEEM_STATIC>")
# Do we need to link with -lm? This finishes by setting LIBM_NEEDED
-include(CheckLibmNeeded)
-if(LIBM_NEEDED)
- message(STATUS "Will explicitly link with -lm")
- target_link_libraries(Teem
- PRIVATE m # Teem itself links (especially for shared library)
- INTERFACE m # Consumers (especially for static builds) automatically link
- )
-else()
- message(STATUS "Do not need to link with -lm")
+if(NOT WIN32) # this is all moot on Windows, which has no "m"
+ include(CheckLibmNeeded)
+ if(LIBM_NEEDED)
+ message(STATUS "Will explicitly link with -lm")
+ target_link_libraries(Teem
+ PRIVATE m # Teem itself links (especially for shared library)
+ INTERFACE m # Consumers (especially for static builds) automatically link
+ )
+ else()
+ message(STATUS "Do not need to link with -lm")
+ endif()
endif()
# Set remaining target properties
@@ -445,13 +447,13 @@
###-------------------------------------------------------------------------------------
# Describe Teem's command-line executables (e.g. "unu")
-# Only on Mac with shared libraries: clean out old installed RPATH-aware files before
-# installing new ones, because getting the RPATH stuff to be set correctly after the
-# first "make install", but *not* modified after a second "make install", is just too
-# annoying to figure out. This hack has to *precede* any other install() commands, which
-# is why this shows up here, before src/bin/CMakeLists.txt's teem_add_executable() can
-# call install()
if(BUILD_SHARED_LIBS)
+ # Only on Mac with shared libraries: clean out old installed RPATH-aware files before
+ # installing new ones, because getting the RPATH stuff to be set correctly after the
+ # first "make install", but *not* modified after a second "make install", is just too
+ # annoying to figure out. This hack has to *precede* any other install() commands,
+ # which is why this shows up here, before src/bin/CMakeLists.txt's
+ # teem_add_executable() can call install()
if(APPLE)
install(CODE "
file(GLOB old_bins \"\$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/*\")
@@ -467,6 +469,13 @@
endif()
")
endif()
+ if(WIN32)
+ # Ensure Teem.dll and import library go to a common bin directory
+ set_target_properties(Teem PROPERTIES
+ RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
+ LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
+ )
+ endif()
endif()
# Describe all the command-line tools (unu and friends)
@@ -569,34 +578,36 @@
RENAME LICENSE)
###-------------------------------------------------------------------------------------
-# For non-CMake consumers: create teem.pc for pkg-config, and teem-config script
+# For non-CMake non-Windows users: create teem.pc for pkg-config, and teem-config script
-# Collect all private -llib dependency flags
-set(_pc_private_libs "")
-foreach(_tdep IN LISTS _Teem_DEPS)
- if(Teem_HAVE_${_tdep})
- string(APPEND _pc_private_libs " ${_Teem_dep_llink_${_tdep}}")
+if(NOT WIN32)
+ # Collect all private -llib dependency flags
+ set(_pc_private_libs "")
+ foreach(_tdep IN LISTS _Teem_DEPS)
+ if(Teem_HAVE_${_tdep})
+ string(APPEND _pc_private_libs " ${_Teem_dep_llink_${_tdep}}")
+ endif()
+ endforeach()
+ if(LIBM_NEEDED)
+ string(APPEND _pc_private_libs " -lm")
endif()
-endforeach()
-if(LIBM_NEEDED)
- string(APPEND _pc_private_libs " -lm")
-endif()
-set(Teem_PC_PRIVATE_LIBS "${_pc_private_libs}")
+ set(Teem_PC_PRIVATE_LIBS "${_pc_private_libs}")
-# Generate pkg-config teem.pc file
-configure_file(
- ${CMAKE_CURRENT_SOURCE_DIR}/CMake/teem.pc.in
- ${CMAKE_CURRENT_BINARY_DIR}/teem.pc @ONLY
-)
-install(FILES ${CMAKE_CURRENT_BINARY_DIR}/teem.pc
- DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig
-)
+ # Generate pkg-config teem.pc file
+ configure_file(
+ ${CMAKE_CURRENT_SOURCE_DIR}/CMake/teem.pc.in
+ ${CMAKE_CURRENT_BINARY_DIR}/teem.pc @ONLY
+ )
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/teem.pc
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig
+ )
-# Generate teem-config helper script
-configure_file(
- ${CMAKE_CURRENT_SOURCE_DIR}/CMake/teem-config.in
- ${CMAKE_CURRENT_BINARY_DIR}/teem-config @ONLY
-)
-install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/teem-config
- DESTINATION ${CMAKE_INSTALL_BINDIR}
-)
+ # Generate teem-config helper script
+ configure_file(
+ ${CMAKE_CURRENT_SOURCE_DIR}/CMake/teem-config.in
+ ${CMAKE_CURRENT_BINARY_DIR}/teem-config @ONLY
+ )
+ install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/teem-config
+ DESTINATION ${CMAKE_INSTALL_BINDIR}
+ )
+endif()
Modified: teem/trunk/src/bin/CMakeLists-v2.txt
===================================================================
--- teem/trunk/src/bin/CMakeLists-v2.txt 2025-09-12 09:03:45 UTC (rev 7419)
+++ teem/trunk/src/bin/CMakeLists-v2.txt 2025-09-12 09:38:35 UTC (rev 7420)
@@ -7,6 +7,14 @@
RUNTIME DESTINATION ${BIN_INSTALL_DIR}
COMPONENT Runtime
)
+ if(WIN32 AND BUILD_SHARED_LIBS)
+ # Ensure every exe ${name} sees the DLL by copying it to their output folder
+ add_custom_command(TARGET ${name} POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different
+ $<TARGET_FILE:Teem>
+ $<TARGET_FILE_DIR:${name}>
+ )
+ endif()
endfunction()
# List of all Teem command-line tools. TeemV2 stripped down the number of tools built;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <kin...@us...> - 2025-09-12 09:03:48
|
Revision: 7419
http://sourceforge.net/p/teem/code/7419
Author: kindlmann
Date: 2025-09-12 09:03:45 +0000 (Fri, 12 Sep 2025)
Log Message:
-----------
maybe finally done with these
Modified Paths:
--------------
teem/trunk/CMake/FindFFTW3-v2.cmake
teem/trunk/CMake/FindLEVMAR-v2.cmake
teem/trunk/CMakeLists-v2.txt
Modified: teem/trunk/CMake/FindFFTW3-v2.cmake
===================================================================
--- teem/trunk/CMake/FindFFTW3-v2.cmake 2025-09-12 08:20:59 UTC (rev 7418)
+++ teem/trunk/CMake/FindFFTW3-v2.cmake 2025-09-12 09:03:45 UTC (rev 7419)
@@ -1,4 +1,5 @@
## FindFFTW3.cmake: Slightly better way of looking for FFTW3 package
+# ("fftw3" = http://www.fftw.org)
# Copyright (C) 2025 University of Chicago
# See ../LICENSE.txt for licensing terms
@@ -7,10 +8,31 @@
# actually does, so find_package(FFTW3) can succeed but is not able to define imported
# targets for use with target_link_libraries(FFTW3::fftw3) This is a long-standing issue:
# https://github.com/FFTW/fftw3/issues/130
-# and there must be various solutions out there, since ChatGPT basically wrote the code
-# below (and is characterically unable to provide a citation for similarly simple but
-# working code online)
#
+# This module defines:
+# FFTW3_FOUND - True if both header and library were found
+# FFTW3_INCLUDE_DIR - Directory containing fftw3.h
+# (legacy; for include_directories)
+# FFTW3_LIBRARY - Full path to the fftw3 library file
+# (legacy; for direct linking)
+# FFTW3_INCLUDE_DIRS - Directories to add to include path
+# (legacy; currently just fftw3)
+# FFTW3_LIBRARIES - Libraries to link
+# (legacy; just fftw3, no transitive deps)
+# FFTW3_VERSION - Optional version string for the library; not reliably
+# parse-able from fftw3.h, so will be empty unless
+# supplied by the user or cache.
+#
+# Imported target (modern CMake usage):
+# FFTW3::fftw3 - Imported target for modern target_link_libraries usage
+#
+# Usage:
+# find_package(FFTW3 REQUIRED)
+# target_link_libraries(myexe PRIVATE FFTW3::fftw3)
+# # or for legacy code:
+# target_include_directories(myexe PRIVATE ${FFTW3_INCLUDE_DIRS})
+# target_link_libraries(myexe PRIVATE ${FFTW3_LIBRARIES})
+#
# For comparison look at:
# https://github.com/egpbos/findFFTW
# https://github.com/acoustid/chromaprint/blob/master/cmake/modules/FindFFTW3.cmake
@@ -52,23 +74,44 @@
# This fallback only runs when FFTW3_FOUND is still FALSE.
if(NOT FFTW3_FOUND)
- # Look for the FFTW3 header. Users can help by setting FFTW3_DIR or
+ # Find the directory containing fftw3.h. Users can help by setting FFTW3_DIR or
# by making sure the header is somewhere in the default search paths.
find_path(FFTW3_INCLUDE_DIR
NAMES fftw3.h
- HINTS ENV FFTW3_DIR # WHAT MORE hints?
- PATH_SUFFIXES include
+ HINTS
+ $ENV{FFTW3_DIR}
+ ${CMAKE_INSTALL_PREFIX}
+ /usr
+ /usr/local
+ PATH_SUFFIXES
+ include
+ include/fftw3
+ DOC "Directory containing fftw3.h"
)
_status("find_path result: FFTW3_INCLUDE_DIR='${FFTW3_INCLUDE_DIR}'")
- # Look for the FFTW3 library. Allow FFTW3_DIR to point to its prefix.
+ # Look for the FFTW3 library. Can set FFTW3_DIR to containing directory.
find_library(FFTW3_LIBRARY
NAMES fftw3
- HINTS ENV FFTW3_DIR # WHAT MORE hints?
- PATH_SUFFIXES lib
+ HINTS
+ $ENV{FFTW3_DIR}
+ ${CMAKE_INSTALL_PREFIX}
+ /usr
+ /usr/local
+ PATH_SUFFIXES
+ lib
+ lib64
+ DOC "Full path to the libfftw3.\{a\|so\|dylib\|lib\} file"
)
_status("find_library result: FFTW3_LIBRARY='${FFTW3_LIBRARY}'")
+ # Optional user-provided version (since fftw3.h does not seem to declare its own
+ # version in any way that can be learned at configure- or compile-time (the info is
+ # available at run-time, but that's too annoying).
+ if(NOT DEFINED FFTW3_VERSION)
+ set(FFTW3_VERSION "" CACHE STRING "Optional: version of FFTW3 library")
+ endif()
+
# Include the helper macro for standard handling of results
include(FindPackageHandleStandardArgs)
# Sets FFTW3_FOUND if successful
@@ -75,9 +118,14 @@
_check_start("find_package_handle_standard_args(FFTW3)")
find_package_handle_standard_args(FFTW3
REQUIRED_VARS FFTW3_LIBRARY FFTW3_INCLUDE_DIR
+ VERSION_VAR FFTW3_VERSION
)
if (FFTW3_FOUND)
+ # for use by old-style CMake code
+ set(FFTW3_INCLUDE_DIRS ${FFTW3_INCLUDE_DIR})
+ set(FFTW3_LIBRARIES ${FFTW3_LIBRARY})
+
# If we did find FFTW3, but no imported target exists yet,
# create our own IMPORTED target so downstream code can use:
# target_link_libraries(myprog PRIVATE FFTW3::fftw3)
@@ -86,7 +134,7 @@
set_target_properties(FFTW3::fftw3 PROPERTIES
IMPORTED_LOCATION "${FFTW3_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${FFTW3_INCLUDE_DIR}"
- # HEY no INTERFACE_LINK_LIBRARIES ?
+ INTERFACE_LINK_LIBRARIES "${FFTW3_LIBRARY}" # maybe redundant?
)
endif()
_check_pass("Found:\n ${_dep}_INCLUDE_DIR=${${_dep}_INCLUDE_DIR}\n ${_dep}_LIBRARY=${${_dep}_LIBRARY}")
Modified: teem/trunk/CMake/FindLEVMAR-v2.cmake
===================================================================
--- teem/trunk/CMake/FindLEVMAR-v2.cmake 2025-09-12 08:20:59 UTC (rev 7418)
+++ teem/trunk/CMake/FindLEVMAR-v2.cmake 2025-09-12 09:03:45 UTC (rev 7419)
@@ -101,6 +101,7 @@
set(LEVMAR_VERSION "${CMAKE_MATCH_1}")
_status("From levmar.h parsed version: ${LEVMAR_VERSION}")
endif()
+ unset(_levmar_header)
endif()
# Try to find full path to liblevmar library file
Modified: teem/trunk/CMakeLists-v2.txt
===================================================================
--- teem/trunk/CMakeLists-v2.txt 2025-09-12 08:20:59 UTC (rev 7418)
+++ teem/trunk/CMakeLists-v2.txt 2025-09-12 09:03:45 UTC (rev 7419)
@@ -203,7 +203,7 @@
endforeach()
# With all that uniformity set up: try to find_package() for all DEPs requested,
-# and set Teem_HAVE_DEP if we did find it (i.e. we "have" it)
+# and set Teem_HAVE_DEP if we did find it (i.e. we "have" found the dependency)
foreach(_tdep IN LISTS _Teem_DEPS)
if(Teem_USE_${_tdep})
# this DEP is requested
@@ -211,7 +211,11 @@
find_package(${_Teem_dep_cpname_${_tdep}} ${_Teem_dep_version_${_tdep}} QUIET)
if(${_Teem_dep_found_${_tdep}})
set(Teem_HAVE_${_tdep} TRUE)
- message(CHECK_PASS "Found")
+ if(DEFINED ${_tdep}_VERSION)
+ message(CHECK_PASS "Found version ${${_tdep}_VERSION}")
+ else()
+ message(CHECK_PASS "Found")
+ endif()
else()
if(DEFINED ${_tdep}_VERSION AND _Teem_dep_version_${_tdep})
message(CHECK_FAIL
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <kin...@us...> - 2025-09-12 08:21:04
|
Revision: 7418
http://sourceforge.net/p/teem/code/7418
Author: kindlmann
Date: 2025-09-12 08:20:59 +0000 (Fri, 12 Sep 2025)
Log Message:
-----------
finally fixing duplicate library issue, and improving documentation
Modified Paths:
--------------
teem/trunk/CMake/FindLEVMAR-v2.cmake
Modified: teem/trunk/CMake/FindLEVMAR-v2.cmake
===================================================================
--- teem/trunk/CMake/FindLEVMAR-v2.cmake 2025-09-12 07:51:39 UTC (rev 7417)
+++ teem/trunk/CMake/FindLEVMAR-v2.cmake 2025-09-12 08:20:59 UTC (rev 7418)
@@ -3,16 +3,40 @@
# Copyright (C) 2025 University of Chicago
# See ../LICENSE.txt for licensing terms
-# This module defines:
-# LEVMAR_FOUND - True if both header and library were found
+# This module tries to find a Levmar library and header, and sets variables/targets
+# so other CMake projects can use it.
+#
+# Variables defined by this module:
+# LEVMAR_FOUND - True if both levmar.h and the levmar library were found
# LEVMAR_INCLUDE_DIR - Directory containing levmar.h
-# LEVMAR_LIBRARY - Full path to levmar library file
-# LEVMAR_INCLUDE_DIRS - Directories to add to include path (currently just levmar)
-# LEVMAR_LIBRARIES - Libraries to link (levmar plus lapack/blas if found)
+# (legacy; for include_directories)
+# LEVMAR_LIBRARY - Full path to the levmar library file
+# (legacy; for direct linking)
+# LEVMAR_INCLUDE_DIRS - List of include directories
+# (legacy; typically just LEVMAR_INCLUDE_DIR)
+# LEVMAR_LIBRARIES - List of libraries to link
+# (legacy; levmar plus optional LAPACK/BLAS)
+# LEVMAR_VERSION - Version string parsed from levmar.h (if available)
#
-# Usage:
+# Imported target (modern CMake usage):
+# LEVMAR::LEVMAR - Imported target encapsulating include directories,
+# library, and optional transitive dependencies
+# (LAPACK/BLAS).
+#
+# Usage (modern style):
# find_package(LEVMAR REQUIRED)
+# target_link_libraries(myexe PRIVATE LEVMAR::LEVMAR)
+#
+# Usage (legacy style, for code expecting variables):
+# find_package(LEVMAR REQUIRED)
# target_link_libraries(myexe PRIVATE ${LEVMAR_LIBRARIES})
+# include_directories(${LEVMAR_INCLUDE_DIRS})
+#
+# Notes:
+# - This module attempts to find LAPACK and BLAS libraries if a levmar library is found.
+# These are included in the imported target and ${LEVMAR_LIBRARIES} if available.
+# - Versions prior to 2.5 did not provide levmar.h (used lm.h instead), so failing
+# to find levmar.h will result in LEVMAR_FOUND=FALSE.
# how we identify ourselves
set(_dep "LEVMAR")
@@ -100,6 +124,7 @@
# LAPACK and BLAS; we just try to find them if we did find levmar. And we don't if
# LAPACK or BLAS are not found, but if they are required for this levmar, then we may
# have linker error later.
+set(_dep_libraries "") # list of transitive dependencies
if(LEVMAR_LIBRARY)
_status("Looking for LAPACK & BLAS (may trigger Threads find)")
# if we didn't find LEVMAR, no point in looking for LAPACK, BLAS
@@ -106,6 +131,7 @@
find_package(LAPACK QUIET)
if(LAPACK_FOUND)
_status("LAPACK found: ${LAPACK_LIBRARIES}")
+ list(APPEND _dep_libraries ${LAPACK_LIBRARIES})
else()
_status("LAPACK *not* found")
endif()
@@ -113,11 +139,15 @@
find_package(BLAS QUIET)
if(BLAS_FOUND)
_status("BLAS found: ${BLAS_LIBRARIES}")
+ list(APPEND _dep_libraries ${BLAS_LIBRARIES})
else()
_status("BLAS *not* found")
endif()
endif()
+# Deduplicate only transitive dependencies (LAPACK/BLAS) to avoid ld warnings
+list(REMOVE_DUPLICATES _dep_libraries)
+
# Include the helper macro for standard handling of results
include(FindPackageHandleStandardArgs)
_check_start("find_package_handle_standard_args(LEVMAR)")
@@ -131,13 +161,9 @@
if(LEVMAR_FOUND)
set(LEVMAR_INCLUDE_DIRS ${LEVMAR_INCLUDE_DIR})
- set(LEVMAR_LIBRARIES ${LEVMAR_LIBRARY})
- if(LAPACK_FOUND)
- list(APPEND LEVMAR_LIBRARIES ${LAPACK_LIBRARIES})
- endif()
- if(BLAS_FOUND)
- list(APPEND LEVMAR_LIBRARIES ${BLAS_LIBRARIES})
- endif()
+ # for explicit linking by old-style code
+ set(LEVMAR_LIBRARIES ${_dep_libraries})
+ list(APPEND LEVMAR_LIBRARIES ${LEVMAR_LIBRARY})
# If we did find LEVMAR, but no imported target exists yet,
# create our own IMPORTED target so downstream code can use:
@@ -147,7 +173,7 @@
set_target_properties(LEVMAR::LEVMAR PROPERTIES
IMPORTED_LOCATION "${LEVMAR_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${LEVMAR_INCLUDE_DIR}"
- INTERFACE_LINK_LIBRARIES "${LEVMAR_LIBRARIES}"
+ INTERFACE_LINK_LIBRARIES "${_dep_libraries}" # only LAPACK/BLAS, NOT LEVMAR_LIBRARY itself
)
endif()
_check_pass("Found:\n ${_dep}_INCLUDE_DIR=${${_dep}_INCLUDE_DIR}\n ${_dep}_LIBRARY=${${_dep}_LIBRARY}")
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <kin...@us...> - 2025-09-12 07:51:40
|
Revision: 7417
http://sourceforge.net/p/teem/code/7417
Author: kindlmann
Date: 2025-09-12 07:51:39 +0000 (Fri, 12 Sep 2025)
Log Message:
-----------
more consistency tweaks (and adding ability to require dependency version)
Modified Paths:
--------------
teem/trunk/CMake/FindFFTW3-v2.cmake
teem/trunk/CMake/FindLEVMAR-v2.cmake
teem/trunk/CMakeLists-v2.txt
Modified: teem/trunk/CMake/FindFFTW3-v2.cmake
===================================================================
--- teem/trunk/CMake/FindFFTW3-v2.cmake 2025-09-12 06:07:42 UTC (rev 7416)
+++ teem/trunk/CMake/FindFFTW3-v2.cmake 2025-09-12 07:51:39 UTC (rev 7417)
@@ -23,26 +23,26 @@
set(_dep "FFTW3")
# Option to enable extra debug output from this module
-option(Teem_${_dep}_DEBUG "Print detailed debug about finding ${_dep}" OFF)
+option(Teem_DEBUG_${_dep} "Print detailed debug about finding ${_dep}" OFF)
-# Helper macros to print only when Teem_${_dep}_DEBUG is enabled
+# Helper macros to print only when Teem_DEBUG_${_dep} is enabled
macro(_status msg)
- if(Teem_${_dep}_DEBUG)
+ if(Teem_DEBUG_${_dep})
message(STATUS "[Find${_dep}] ${msg}")
endif()
endmacro()
macro(_check_start msg)
- if(Teem_${_dep}_DEBUG)
+ if(Teem_DEBUG_${_dep})
message(CHECK_START "[Find${_dep}] ${msg}")
endif()
endmacro()
macro(_check_fail msg)
- if(Teem_${_dep}_DEBUG)
+ if(Teem_DEBUG_${_dep})
message(CHECK_FAIL "${msg}")
endif()
endmacro()
macro(_check_pass msg)
- if(Teem_${_dep}_DEBUG)
+ if(Teem_DEBUG_${_dep})
message(CHECK_PASS "${msg}")
endif()
endmacro()
@@ -89,7 +89,7 @@
# HEY no INTERFACE_LINK_LIBRARIES ?
)
endif()
- _check_pass("Found: ${_dep}_INCLUDE_DIR=${${_dep}_INCLUDE_DIR} ${_dep}_LIBRARY=${${_dep}_LIBRARY}")
+ _check_pass("Found:\n ${_dep}_INCLUDE_DIR=${${_dep}_INCLUDE_DIR}\n ${_dep}_LIBRARY=${${_dep}_LIBRARY}")
else()
_check_fail("Not found")
endif()
Modified: teem/trunk/CMake/FindLEVMAR-v2.cmake
===================================================================
--- teem/trunk/CMake/FindLEVMAR-v2.cmake 2025-09-12 06:07:42 UTC (rev 7416)
+++ teem/trunk/CMake/FindLEVMAR-v2.cmake 2025-09-12 07:51:39 UTC (rev 7417)
@@ -3,14 +3,6 @@
# Copyright (C) 2025 University of Chicago
# See ../LICENSE.txt for licensing terms
-# TODO:
-# how is cmake detecting of this levmar also needs lapack and blas?
-# how does find_package(LAPACK/BLAS QUIET) work? is that CMake built-in?
-# check hints to find_path and find_library
-# make sure we're getting the right version of levmar
-# BUILD_SHARED_LIBS with liblevmar.a: [ 96%] Linking C shared library libteem.dylib
-# ld: warning: ignoring duplicate libraries: '-ldl', '-lm', '/Users/gk/src/levmar-2.6/liblevmar.a'
-
# This module defines:
# LEVMAR_FOUND - True if both header and library were found
# LEVMAR_INCLUDE_DIR - Directory containing levmar.h
@@ -26,26 +18,26 @@
set(_dep "LEVMAR")
# Option to enable extra debug output from this module
-option(Teem_${_dep}_DEBUG "Print detailed debug about finding ${_dep}" OFF)
+option(Teem_DEBUG_${_dep} "Print detailed debug about finding ${_dep}" OFF)
-# Helper macros to print only when Teem_${_dep}_DEBUG is enabled
+# Helper macros to print only when Teem_DEBUG_${_dep} is enabled
macro(_status msg)
- if(Teem_${_dep}_DEBUG)
+ if(Teem_DEBUG_${_dep})
message(STATUS "[Find${_dep}] ${msg}")
endif()
endmacro()
macro(_check_start msg)
- if(Teem_${_dep}_DEBUG)
+ if(Teem_DEBUG_${_dep})
message(CHECK_START "[Find${_dep}] ${msg}")
endif()
endmacro()
macro(_check_fail msg)
- if(Teem_${_dep}_DEBUG)
+ if(Teem_DEBUG_${_dep})
message(CHECK_FAIL "${msg}")
endif()
endmacro()
macro(_check_pass msg)
- if(Teem_${_dep}_DEBUG)
+ if(Teem_DEBUG_${_dep})
message(CHECK_PASS "${msg}")
endif()
endmacro()
@@ -55,33 +47,62 @@
find_path(LEVMAR_INCLUDE_DIR
NAMES levmar.h
HINTS
- ${CMAKE_INSTALL_PREFIX}/include
- /usr/include
- /usr/local/include
+ $ENV{LEVMAR_DIR}
+ ${CMAKE_INSTALL_PREFIX}
+ /usr
+ /usr/local
PATH_SUFFIXES
include
- levmar
+ include/levmar
DOC "Directory containing levmar.h"
)
_status("find_path result: LEVMAR_INCLUDE_DIR='${LEVMAR_INCLUDE_DIR}'")
+# Learn the levmar version number from levmar.h. Versions 2.4 and prior didn't have a
+# levmar.h; they had lm.h, so failing to find levmar.h is one brute-force way to enforce
+# that we're looking at a version >= 2.5. Version 2.5 has:
+# #define LM_VERSION "2.5 (December 2009)"
+# and Version 2.6 has:
+# #define LM_VERSION "2.6 (November 2011)"
+# To learn the version from levmar.h:
+if(LEVMAR_INCLUDE_DIR AND EXISTS "${LEVMAR_INCLUDE_DIR}/levmar.h")
+ file(READ "${LEVMAR_INCLUDE_DIR}/levmar.h" _levmar_header)
+
+ # Match e.g.: #define LM_VERSION "2.6 (November 2011)"
+ # https://cmake.org/cmake/help/latest/command/string.html
+ # sets CMAKE_MATCH_<N> for the N'th parethesized subexpression
+ string(REGEX MATCH "#define[ \t]+LM_VERSION[ \t]+\"([0-9]+\\.[0-9]+)" _match "${_levmar_header}")
+
+ if(CMAKE_MATCH_1)
+ set(LEVMAR_VERSION "${CMAKE_MATCH_1}")
+ _status("From levmar.h parsed version: ${LEVMAR_VERSION}")
+ endif()
+endif()
+
# Try to find full path to liblevmar library file
find_library(LEVMAR_LIBRARY
NAMES levmar
HINTS
- ${CMAKE_INSTALL_PREFIX}/lib
- /usr/lib
- /usr/local/lib
+ $ENV{LEVMAR_DIR}
+ ${CMAKE_INSTALL_PREFIX}
+ /usr
+ /usr/local
PATH_SUFFIXES
lib
+ lib64
DOC "Full path to the liblevmar.\{a\|so\|dylib\|lib\} file"
)
_status("find_library result: LEVMAR_LIBRARY='${LEVMAR_LIBRARY}'")
-# If we found the library but levmar depends on LAPACK and BLAS, try to find them.
-# Levmar's docs advise having LAPACK/BLAS available to use the full feature set.
-# (This is optional — we don't fail if LAPACK isn't present.)
-if(LEVMAR_LIBRARY) # HEY is this conditional useful?
+# If we found the library but levmar *may* depend in turn on LAPACK and BLAS (more levmar
+# functions are available that way), so we try to find them using their built-in CMake
+# modules. It's not that CMake can detect now whether the levmar found indeed depends on
+# LAPACK and BLAS; we just try to find them if we did find levmar. And we don't if
+# LAPACK or BLAS are not found, but if they are required for this levmar, then we may
+# have linker error later.
+if(LEVMAR_LIBRARY)
+ _status("Looking for LAPACK & BLAS (may trigger Threads find)")
+ # if we didn't find LEVMAR, no point in looking for LAPACK, BLAS
find_package(LAPACK QUIET)
if(LAPACK_FOUND)
_status("LAPACK found: ${LAPACK_LIBRARIES}")
@@ -103,6 +124,8 @@
# Standard handling macro: sets LEVMAR_FOUND if successful
find_package_handle_standard_args(LEVMAR
REQUIRED_VARS LEVMAR_INCLUDE_DIR LEVMAR_LIBRARY
+ # report to caller of find_package(LEVMAR) what version they're getting
+ VERSION_VAR LEVMAR_VERSION
)
if(LEVMAR_FOUND)
@@ -127,7 +150,7 @@
INTERFACE_LINK_LIBRARIES "${LEVMAR_LIBRARIES}"
)
endif()
- _check_pass("Found: ${_dep}_INCLUDE_DIR=${${_dep}_INCLUDE_DIR} ${_dep}_LIBRARY=${${_dep}_LIBRARY}")
+ _check_pass("Found:\n ${_dep}_INCLUDE_DIR=${${_dep}_INCLUDE_DIR}\n ${_dep}_LIBRARY=${${_dep}_LIBRARY}")
else()
_check_fail("Not found")
endif()
Modified: teem/trunk/CMakeLists-v2.txt
===================================================================
--- teem/trunk/CMakeLists-v2.txt 2025-09-12 06:07:42 UTC (rev 7416)
+++ teem/trunk/CMakeLists-v2.txt 2025-09-12 07:51:39 UTC (rev 7417)
@@ -55,8 +55,7 @@
** Please join the Teem-users Discord https://discord.gg/xBBqZGXkF7
** to share how Teem works or does not work for you!
** For example, are these re-written CMakeLists.txt files working?
-********************************************************************
-")
+********************************************************************")
###-------------------------------------------------------------------------------------
# Include helpers and module paths
@@ -176,8 +175,11 @@
set(_Teem_dep_llink_ZLIB "-lz")
set(_Teem_dep_llink_BZIP2 "-lbz2")
set(_Teem_dep_llink_PTHREAD "-pthread")
+# Special cases for requiring specific version (else "" for no such requirement)
+# (HEY should better document here what versions the Teem code is assuming)
+set(_Teem_dep_version_LEVMAR "2.6")
-# Make sure _Teem_dep_{cpack,target,found,llink}_DEP are defined for all DEPS
+# Make sure _Teem_dep_{cpack,target,found,llink,version}_DEP are defined for all DEPS
# CMake (still) doesn't have anything like a dictionary, so we don't have
# (for example): _Teem_dep_cpname[_tdep]
# but after the following, we do have: ${_Teem_dep_cpname_${_tdep}}
@@ -195,6 +197,9 @@
string(TOLOWER ${_tdep} _dep_lc)
set(_Teem_dep_llink_${_tdep} "-l${_dep_lc}")
endif()
+ if(NOT DEFINED _Teem_dep_version_${_tdep})
+ set(_Teem_dep_version_${_tdep} "")
+ endif()
endforeach()
# With all that uniformity set up: try to find_package() for all DEPs requested,
@@ -202,11 +207,20 @@
foreach(_tdep IN LISTS _Teem_DEPS)
if(Teem_USE_${_tdep})
# this DEP is requested
- message(STATUS "Trying find_package(${_Teem_dep_cpname_${_tdep}})")
- find_package(${_Teem_dep_cpname_${_tdep}} QUIET)
+ message(CHECK_START "Trying find_package( ${_Teem_dep_cpname_${_tdep}} ${_Teem_dep_version_${_tdep}})")
+ find_package(${_Teem_dep_cpname_${_tdep}} ${_Teem_dep_version_${_tdep}} QUIET)
if(${_Teem_dep_found_${_tdep}})
set(Teem_HAVE_${_tdep} TRUE)
+ message(CHECK_PASS "Found")
else()
+ if(DEFINED ${_tdep}_VERSION AND _Teem_dep_version_${_tdep})
+ message(CHECK_FAIL
+ "Found ${_tdep} version ${${_tdep}_VERSION}, "
+ "but version ${_Teem_dep_version_${_tdep}} or newer is required."
+ )
+ else()
+ message(CHECK_FAIL "Not found")
+ endif()
set(Teem_USE_${_tdep} OFF CACHE BOOL "${_Teem_dep_doc_${_tdep}}" FORCE)
endif()
endif()
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <kin...@us...> - 2025-09-12 06:07:43
|
Revision: 7416
http://sourceforge.net/p/teem/code/7416
Author: kindlmann
Date: 2025-09-12 06:07:42 +0000 (Fri, 12 Sep 2025)
Log Message:
-----------
tweaks to how diagnostics are printed
Modified Paths:
--------------
teem/trunk/CMake/CheckAirExists.cmake
teem/trunk/CMake/CheckLibmNeeded.cmake
teem/trunk/CMake/FindFFTW3-v2.cmake
teem/trunk/CMake/FindLEVMAR-v2.cmake
teem/trunk/CMakeLists-v2.txt
Modified: teem/trunk/CMake/CheckAirExists.cmake
===================================================================
--- teem/trunk/CMake/CheckAirExists.cmake 2025-09-12 05:05:03 UTC (rev 7415)
+++ teem/trunk/CMake/CheckAirExists.cmake 2025-09-12 06:07:42 UTC (rev 7416)
@@ -1,4 +1,4 @@
-# CMake/CheckAirExists.cmake: see if AIR_EXISTS() macro works like isfinite()
+## CheckAirExists.cmake: see if AIR_EXISTS() macro works like isfinite()
# Copyright (C) 2025 University of Chicago
# See ../LICENSE.txt for licensing terms
@@ -19,6 +19,7 @@
# Defines:
# AIR_EXISTS_MACRO_FAILS -- TRUE if AIR_EXISTS() fails with current compiler settings
+set(_me "[CheckAirExists]")
# "taex" = Test Air_EXists
set(_taex_src "${CMAKE_CURRENT_LIST_DIR}/TestAIR_EXISTS.c")
@@ -41,7 +42,7 @@
endif()
# Compile the probe
-message(CHECK_START "Testing whether macro ${_taex_me} detects IEEE754 special values")
+message(CHECK_START "${_me} Testing whether macro ${_taex_me} detects IEEE754 special values")
try_compile(
_taex_compiles # boolean result: TRUE if compile succeeded
SOURCES "${_taex_src}" # one or more source files for the test
@@ -56,23 +57,23 @@
)
# Always show the captured compile output, as progress indication
string(REPLACE "\n" "\n " _taex_compile_out_indented "${_taex_compile_out}")
-message(STATUS "Compile output:\n ${_taex_compile_out_indented}")
+message(STATUS "${_me} Compile output:\n ${_taex_compile_out_indented}")
if(NOT _taex_compiles)
message(CHECK_FAIL "compile failed")
- message(FATAL_ERROR "Could not compile ${_taex_src}")
+ message(FATAL_ERROR "${_me} Could not compile ${_taex_src}")
elseif(_taex_copy_error)
message(CHECK_FAIL "copy failed")
- message(FATAL_ERROR "Test program compiled but could not copy: ${_taex_copy_error}")
+ message(FATAL_ERROR "${_me} Test program compiled but could not copy: ${_taex_copy_error}")
elseif(NOT EXISTS "${_taex_copy}")
message(CHECK_FAIL "missing executable")
- message(FATAL_ERROR "Test program compiled but file not found at ${_taex_copy}")
+ message(FATAL_ERROR "${_me} Test program compiled but file not found at ${_taex_copy}")
else()
message(CHECK_PASS "compiled successfully")
endif()
# Run the test program
-message(CHECK_START "Running ${_taex_me} test program")
+message(CHECK_START "${_me} Running ${_taex_me} test program")
# https://cmake.org/cmake/help/latest/command/execute_process.html
execute_process(
COMMAND "${_taex_copy}"
@@ -89,11 +90,11 @@
# Always show stdout/stderr from the probe as indented sub-log
if(_taex_run_out)
string(REPLACE "\n" "\n " _taex_run_out_indented "${_taex_run_out}")
- message(STATUS "Probe stdout:\n ${_taex_run_out_indented}")
+ message(STATUS "${_me} Probe stdout:\n ${_taex_run_out_indented}")
endif()
if(_taex_run_err)
string(REPLACE "\n" "\n " _taex_run_err_indented "${_taex_run_err}")
- message(STATUS "Probe stderr:\n ${_taex_run_err_indented}")
+ message(STATUS "${_me} Probe stderr:\n ${_taex_run_err_indented}")
endif()
message(CHECK_FAIL "NO, it FAILS to detect IEEE754 special values")
set(AIR_EXISTS_MACRO_FAILS 1 CACHE INTERNAL "AIR_EXISTS macro fails")
@@ -105,3 +106,6 @@
# or
# execute_process(COMMAND /bin/sh -c "read -p 'Press ENTER to continue...'")
# )
+
+# Cleanup
+unset(_me)
Modified: teem/trunk/CMake/CheckLibmNeeded.cmake
===================================================================
--- teem/trunk/CMake/CheckLibmNeeded.cmake 2025-09-12 05:05:03 UTC (rev 7415)
+++ teem/trunk/CMake/CheckLibmNeeded.cmake 2025-09-12 06:07:42 UTC (rev 7416)
@@ -1,4 +1,4 @@
-# CMake/CheckLibM.cmake: learn if need to link with -lm for math functions
+## CheckLibmNeeded.cmake: learn if linking bin with math-using lib also needs -lm
# Copyright (C) 2025 University of Chicago
# See ../LICENSE.txt for licensing terms
@@ -20,9 +20,9 @@
# LIBM_NEEDED -- TRUE if executables must link with -lm for current library type
#
# Usage example
-# include(CheckLibM)
+# include(CheckLibmNeeded)
# if(LIBM_NEEDED)
-# target_link_libraries(Teem PRIVATE m)
+# target_link_libraries(mylib PRIVATE m)
# endif()
### ------------------------------------------------------------------------
@@ -32,6 +32,8 @@
return()
endif()
+set(_me "[CheckLibmNeeded]")
+
# BUILD_SHARED_LIBS informs what kind of libtiny we make
if(BUILD_SHARED_LIBS)
set(_lib_type SHARED)
@@ -39,8 +41,6 @@
set(_lib_type STATIC)
endif()
-set(_me "[CheckLibM]")
-
set(_lmn_desc "Need to add -lm when linking with math-using ${_lib_type} lib?")
message(STATUS "${_me} ${_lmn_desc}")
@@ -156,3 +156,6 @@
### ------------------------------------------------------------------------
# Cleanup if we didn't crash out
file(REMOVE_RECURSE "${_checklibm_dir}")
+unset(_me)
+unset(_proj_dir)
+unset(_lib_type)
Modified: teem/trunk/CMake/FindFFTW3-v2.cmake
===================================================================
--- teem/trunk/CMake/FindFFTW3-v2.cmake 2025-09-12 05:05:03 UTC (rev 7415)
+++ teem/trunk/CMake/FindFFTW3-v2.cmake 2025-09-12 06:07:42 UTC (rev 7416)
@@ -1,4 +1,4 @@
-# CMake/FindFFTW3.cmake: Slightly better way of looking for FFTW3 package
+## FindFFTW3.cmake: Slightly better way of looking for FFTW3 package
# Copyright (C) 2025 University of Chicago
# See ../LICENSE.txt for licensing terms
@@ -10,18 +10,48 @@
# and there must be various solutions out there, since ChatGPT basically wrote the code
# below (and is characterically unable to provide a citation for similarly simple but
# working code online)
+#
+# For comparison look at:
+# https://github.com/egpbos/findFFTW
+# https://github.com/acoustid/chromaprint/blob/master/cmake/modules/FindFFTW3.cmake
+# https://git.astron.nl/RD/EveryBeam/-/blob/v0.6.2/CMake/FindFFTW3.cmake
# TODO: handle the various variants for different precisions
# See FindFFTW3-multiprec.cmake for inspiration
+# how we identify ourselves
+set(_dep "FFTW3")
+
+# Option to enable extra debug output from this module
+option(Teem_${_dep}_DEBUG "Print detailed debug about finding ${_dep}" OFF)
+
+# Helper macros to print only when Teem_${_dep}_DEBUG is enabled
+macro(_status msg)
+ if(Teem_${_dep}_DEBUG)
+ message(STATUS "[Find${_dep}] ${msg}")
+ endif()
+endmacro()
+macro(_check_start msg)
+ if(Teem_${_dep}_DEBUG)
+ message(CHECK_START "[Find${_dep}] ${msg}")
+ endif()
+endmacro()
+macro(_check_fail msg)
+ if(Teem_${_dep}_DEBUG)
+ message(CHECK_FAIL "${msg}")
+ endif()
+endmacro()
+macro(_check_pass msg)
+ if(Teem_${_dep}_DEBUG)
+ message(CHECK_PASS "${msg}")
+ endif()
+endmacro()
+
# NOTE: If a working FFTW3Config.cmake is found, it will define
# FFTW3::fftw3 for us already, so we don’t have to do anything else.
# This fallback only runs when FFTW3_FOUND is still FALSE.
-if (NOT FFTW3_FOUND)
+if(NOT FFTW3_FOUND)
- # Include the helper macro for standard handling of results
- include(FindPackageHandleStandardArgs)
-
# Look for the FFTW3 header. Users can help by setting FFTW3_DIR or
# by making sure the header is somewhere in the default search paths.
find_path(FFTW3_INCLUDE_DIR
@@ -29,6 +59,7 @@
HINTS ENV FFTW3_DIR # WHAT MORE hints?
PATH_SUFFIXES include
)
+ _status("find_path result: FFTW3_INCLUDE_DIR='${FFTW3_INCLUDE_DIR}'")
# Look for the FFTW3 library. Allow FFTW3_DIR to point to its prefix.
find_library(FFTW3_LIBRARY
@@ -36,27 +67,37 @@
HINTS ENV FFTW3_DIR # WHAT MORE hints?
PATH_SUFFIXES lib
)
+ _status("find_library result: FFTW3_LIBRARY='${FFTW3_LIBRARY}'")
- # Standard handling macro: sets FFTW3_FOUND if successful
+ # Include the helper macro for standard handling of results
+ include(FindPackageHandleStandardArgs)
+ # Sets FFTW3_FOUND if successful
+ _check_start("find_package_handle_standard_args(FFTW3)")
find_package_handle_standard_args(FFTW3
REQUIRED_VARS FFTW3_LIBRARY FFTW3_INCLUDE_DIR
)
- # If we did find FFTW3, but no imported target exists yet,
- # create our own IMPORTED target so downstream code can use:
- # target_link_libraries(myprog PRIVATE FFTW3::fftw3)
- if (FFTW3_FOUND AND NOT TARGET FFTW3::fftw3)
- add_library(FFTW3::fftw3 UNKNOWN IMPORTED)
- set_target_properties(FFTW3::fftw3 PROPERTIES
- IMPORTED_LOCATION "${FFTW3_LIBRARY}"
- INTERFACE_INCLUDE_DIRECTORIES "${FFTW3_INCLUDE_DIR}"
- # HEY no INTERFACE_LINK_LIBRARIES ?
- )
+ if (FFTW3_FOUND)
+ # If we did find FFTW3, but no imported target exists yet,
+ # create our own IMPORTED target so downstream code can use:
+ # target_link_libraries(myprog PRIVATE FFTW3::fftw3)
+ if (NOT TARGET FFTW3::fftw3)
+ add_library(FFTW3::fftw3 UNKNOWN IMPORTED)
+ set_target_properties(FFTW3::fftw3 PROPERTIES
+ IMPORTED_LOCATION "${FFTW3_LIBRARY}"
+ INTERFACE_INCLUDE_DIRECTORIES "${FFTW3_INCLUDE_DIR}"
+ # HEY no INTERFACE_LINK_LIBRARIES ?
+ )
+ endif()
+ _check_pass("Found: ${_dep}_INCLUDE_DIR=${${_dep}_INCLUDE_DIR} ${_dep}_LIBRARY=${${_dep}_LIBRARY}")
+ else()
+ _check_fail("Not found")
endif()
endif()
-if (FFTW3_FOUND)
- message(STATUS "Using FFTW3: ${FFTW3_LIBRARY}")
-else()
- message(STATUS "FFTW3 not found")
-endif()
+# clean up
+unset(_dep)
+unset(_status)
+unset(_check_start)
+unset(_check_fail)
+unset(_check_pass)
Modified: teem/trunk/CMake/FindLEVMAR-v2.cmake
===================================================================
--- teem/trunk/CMake/FindLEVMAR-v2.cmake 2025-09-12 05:05:03 UTC (rev 7415)
+++ teem/trunk/CMake/FindLEVMAR-v2.cmake 2025-09-12 06:07:42 UTC (rev 7416)
@@ -1,4 +1,4 @@
-# CMake/FindLEVMAR.cmake: Careful+verbose way of looking for levmar install
+## FindLEVMAR.cmake: Careful+verbose way of looking for a levmar install
# ("levmar" = https://users.ics.forth.gr/~lourakis/levmar/index.html)
# Copyright (C) 2025 University of Chicago
# See ../LICENSE.txt for licensing terms
@@ -118,7 +118,7 @@
# If we did find LEVMAR, but no imported target exists yet,
# create our own IMPORTED target so downstream code can use:
- # target_link_libraries(myprog PRIVATE FFTW3::fftw3)
+ # target_link_libraries(myprog PRIVATE LEVMAR::LEVMAR)
if(NOT TARGET LEVMAR::LEVMAR)
add_library(LEVMAR::LEVMAR UNKNOWN IMPORTED)
set_target_properties(LEVMAR::LEVMAR PROPERTIES
@@ -127,7 +127,7 @@
INTERFACE_LINK_LIBRARIES "${LEVMAR_LIBRARIES}"
)
endif()
- _check_pass("Found: LEVMAR_INCLUDE_DIRS=${LEVMAR_INCLUDE_DIRS} LEVMAR_LIBRARIES=${LEVMAR_LIBRARIES}")
+ _check_pass("Found: ${_dep}_INCLUDE_DIR=${${_dep}_INCLUDE_DIR} ${_dep}_LIBRARY=${${_dep}_LIBRARY}")
else()
_check_fail("Not found")
endif()
Modified: teem/trunk/CMakeLists-v2.txt
===================================================================
--- teem/trunk/CMakeLists-v2.txt 2025-09-12 05:05:03 UTC (rev 7415)
+++ teem/trunk/CMakeLists-v2.txt 2025-09-12 06:07:42 UTC (rev 7416)
@@ -17,7 +17,7 @@
# along with this library; if not, see <https://www.gnu.org/licenses/>.
#
-# Teem/CMakeLists.txt Version 10.98
+# Teem/CMakeLists.txt Version 11
# This CMakeLists.txt describes a Teem package that contains:
# (1) a library ("libteem" on unix) and
@@ -51,15 +51,11 @@
LANGUAGES C)
message(STATUS "
-
-
********************************************************************
-** Please join the Teem-users discord https://discord.gg/xBBqZGXkF7
+** Please join the Teem-users Discord https://discord.gg/xBBqZGXkF7
** to share how Teem works or does not work for you!
** For example, are these re-written CMakeLists.txt files working?
********************************************************************
-
-
")
###-------------------------------------------------------------------------------------
@@ -289,12 +285,12 @@
target_compile_definitions(Teem PUBLIC "$<$<NOT:$<BOOL:${BUILD_SHARED_LIBS}>>:TEEM_STATIC>")
# Do we need to link with -lm? This finishes by setting LIBM_NEEDED
-include(CheckLibM)
+include(CheckLibmNeeded)
if(LIBM_NEEDED)
message(STATUS "Will explicitly link with -lm")
target_link_libraries(Teem
- PRIVATE # still link to Teem itself
- INTERFACE m # this ensures consumers (executables) get -lm automatically
+ PRIVATE m # Teem itself links (especially for shared library)
+ INTERFACE m # Consumers (especially for static builds) automatically link
)
else()
message(STATUS "Do not need to link with -lm")
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <kin...@us...> - 2025-09-12 05:05:10
|
Revision: 7415
http://sourceforge.net/p/teem/code/7415
Author: kindlmann
Date: 2025-09-12 05:05:03 +0000 (Fri, 12 Sep 2025)
Log Message:
-----------
finish rename to CheckLibmNeeded.cmake (lower case m)
Added Paths:
-----------
teem/trunk/CMake/CheckLibmNeeded.cmake
Removed Paths:
-------------
teem/trunk/CMake/CheckLibMoopsNeeded.cmake
Deleted: teem/trunk/CMake/CheckLibMoopsNeeded.cmake
===================================================================
--- teem/trunk/CMake/CheckLibMoopsNeeded.cmake 2025-09-12 05:04:13 UTC (rev 7414)
+++ teem/trunk/CMake/CheckLibMoopsNeeded.cmake 2025-09-12 05:05:03 UTC (rev 7415)
@@ -1,158 +0,0 @@
-# CMake/CheckLibM.cmake: learn if need to link with -lm for math functions
-# Copyright (C) 2025 University of Chicago
-# See ../LICENSE.txt for licensing terms
-
-### Rationale
-# Different unices have different ways of tacitly linking (or not) with -lm. In the
-# interests of pedantic explicitness, we figure out if linking with -lm is needed when
-# linking with a library that calls math functions. Yes,
-# https://cmake.org/cmake/help/latest/module/CheckLibraryExists.html could probably do
-# the job here, but once I (GLK) went down the rabbit hole of understanding what the
-# problem was, I wanted to create a CMake module that replicated the minimal example I
-# used. So, this test builds a shared library `libtiny` that calls some math functions,
-# then an executable `maintiny` that calls into that library. When compiling `maintiny`,
-# we try linking:
-# 1. Without -lm
-# 2. With -lm (if needed)
-# Then we run `maintiny` to ensure the math is mathing.
-#
-# Defines:
-# LIBM_NEEDED -- TRUE if executables must link with -lm for current library type
-#
-# Usage example
-# include(CheckLibM)
-# if(LIBM_NEEDED)
-# target_link_libraries(Teem PRIVATE m)
-# endif()
-
-### ------------------------------------------------------------------------
-# Setup
-if(DEFINED LIBM_NEEDED)
- # not our first rodeo
- return()
-endif()
-
-# BUILD_SHARED_LIBS informs what kind of libtiny we make
-if(BUILD_SHARED_LIBS)
- set(_lib_type SHARED)
-else()
- set(_lib_type STATIC)
-endif()
-
-set(_me "[CheckLibM]")
-
-set(_lmn_desc "Need to add -lm when linking with math-using ${_lib_type} lib?")
-message(STATUS "${_me} ${_lmn_desc}")
-
-set(_checklibm_dir "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/tmpCheckLibM")
-file(MAKE_DIRECTORY "${_checklibm_dir}")
-
-# write `tiny.c`: single source file for libtiny, using some functions that very
-# likely do *not* exist outside the standard math library: tanf and log1pf.
-# Will evaluate with val=1.5703125, but not at compile time or else optimizer
-# will happily pre-compute the result, thus undermining this test.
-# T=log1pf(tanf(1.5703125)) ~= 7.634267208876022, so RT=(int)T should be 7
-# If 7 == RT, our exit status should be unix for "all good", i.e. 0 ==> return 7 != T
-file(WRITE "${_checklibm_dir}/tiny.c" "
-#include <stdio.h>
-#include <math.h>
-int tinyFunc(double val) {
- int ret = (7 != (int)(log1pf(tanf(val))));
- printf(\"tinyFunc: returning %d (%s)\\n\", ret, ret ? \"bad\" : \"good\");
- return ret;
-}
-")
-
-# write `maintiny.c`: single source for main() that calls into libtiny
-file(WRITE "${_checklibm_dir}/maintiny.c" "
-extern int tinyFunc(double val);
-int main(void) {
- return tinyFunc(1.5703125f);
-}
-")
-
-# Function that compiles and runs `maintiny` test
-function(_checklibm_try_build_and_run suffix extra_libs result_var)
- # Local variables inside function
- set(_proj_dir "${_checklibm_dir}/${suffix}")
- file(MAKE_DIRECTORY "${_proj_dir}")
-
- file(WRITE "${_proj_dir}/CMakeLists.txt" "
-cmake_minimum_required(VERSION 3.13)
-project(CheckLibM_${suffix} C)
-
-set(CMAKE_VERBOSE_MAKEFILE OFF)
-# Create libtiny is shared or static, according to BUILD_SHARED_LIBS
-add_library(tiny ${_lib_type} \"${_checklibm_dir}/tiny.c\")
-# Make maintiny link only with tiny and optional extra_libs
-add_executable(maintiny \"${_checklibm_dir}/maintiny.c\")
-target_link_libraries(maintiny PRIVATE tiny ${extra_libs})
- ")
-
- # Compile the project
- try_compile(_ok
- "${_proj_dir}/build"
- "${_proj_dir}"
- CheckLibM_${suffix}
- OUTPUT_VARIABLE _out)
-
- if(NOT _ok)
- message(STATUS "${_me} ${suffix} compilation failed:\n${_out}")
- set(${result_var} FALSE PARENT_SCOPE)
- else()
- # Run the resulting binary to check runtime
- set(_bin "${_proj_dir}/build/maintiny${CMAKE_EXECUTABLE_SUFFIX}")
- if(NOT EXISTS "${_bin}")
- message(FATAL_ERROR "${_me} maintiny executable missing for ${suffix} test")
- set(${result_var} FALSE PARENT_SCOPE)
- else()
- # Run the binary
- execute_process(COMMAND "${_bin}"
- RESULT_VARIABLE _runres
- OUTPUT_VARIABLE _runout
- ERROR_VARIABLE _runerr)
- if(_runres EQUAL 0)
- # 0 is unix for "all good"; what we want
- set(${result_var} TRUE PARENT_SCOPE)
- else()
- message(FATAL_ERROR
- "${_me} maintiny built in ${_suffix} mode but failed at runtime.\n"
- "Exit code: ${_runres}\n"
- "Stdout: ${_runout}\n"
- "Stderr: ${_runerr}")
- set(${result_var} FALSE PARENT_SCOPE)
- endif()
- endif()
- endif()
-endfunction()
-
-### ------------------------------------------------------------------------
-# Now run the test.
-# First try compiling + running without `-lm` ...
-_checklibm_try_build_and_run(no_libm "" _checklibm_no_libm_ok)
-
-if(_checklibm_no_libm_ok)
- # ... and either it did work without `-lm`, or ...
- set(LIBM_NEEDED FALSE CACHE BOOL ${_lmn_desc})
- message(STATUS "${_me} No, do NOT need -lm when linking with math-using ${_lib_type} lib")
-else()
- # ... it did not work without -lm.
- # Does it does work *with* -lm?
- _checklibm_try_build_and_run(with_libm "m" _checklibm_with_libm_ok)
-
- if(_checklibm_with_libm_ok)
- # Yes, it does work with -lm.
- set(LIBM_NEEDED TRUE CACHE BOOL "${_lmn_desc}")
- message(STATUS "${_me} yes, DO need -lm when linking with math-using ${_lib_type} lib")
- else()
- # Yikes, it failed both without and with -lm. Bye.
- message(FATAL_ERROR
- "${_me} math test failed even with -lm. Output:\n"
- "${_checklibm_no_libm_out}\n"
- "${_checklibm_with_libm_out}")
- endif()
-endif()
-
-### ------------------------------------------------------------------------
-# Cleanup if we didn't crash out
-file(REMOVE_RECURSE "${_checklibm_dir}")
Copied: teem/trunk/CMake/CheckLibmNeeded.cmake (from rev 7414, teem/trunk/CMake/CheckLibMoopsNeeded.cmake)
===================================================================
--- teem/trunk/CMake/CheckLibmNeeded.cmake (rev 0)
+++ teem/trunk/CMake/CheckLibmNeeded.cmake 2025-09-12 05:05:03 UTC (rev 7415)
@@ -0,0 +1,158 @@
+# CMake/CheckLibM.cmake: learn if need to link with -lm for math functions
+# Copyright (C) 2025 University of Chicago
+# See ../LICENSE.txt for licensing terms
+
+### Rationale
+# Different unices have different ways of tacitly linking (or not) with -lm. In the
+# interests of pedantic explicitness, we figure out if linking with -lm is needed when
+# linking with a library that calls math functions. Yes,
+# https://cmake.org/cmake/help/latest/module/CheckLibraryExists.html could probably do
+# the job here, but once I (GLK) went down the rabbit hole of understanding what the
+# problem was, I wanted to create a CMake module that replicated the minimal example I
+# used. So, this test builds a shared library `libtiny` that calls some math functions,
+# then an executable `maintiny` that calls into that library. When compiling `maintiny`,
+# we try linking:
+# 1. Without -lm
+# 2. With -lm (if needed)
+# Then we run `maintiny` to ensure the math is mathing.
+#
+# Defines:
+# LIBM_NEEDED -- TRUE if executables must link with -lm for current library type
+#
+# Usage example
+# include(CheckLibM)
+# if(LIBM_NEEDED)
+# target_link_libraries(Teem PRIVATE m)
+# endif()
+
+### ------------------------------------------------------------------------
+# Setup
+if(DEFINED LIBM_NEEDED)
+ # not our first rodeo
+ return()
+endif()
+
+# BUILD_SHARED_LIBS informs what kind of libtiny we make
+if(BUILD_SHARED_LIBS)
+ set(_lib_type SHARED)
+else()
+ set(_lib_type STATIC)
+endif()
+
+set(_me "[CheckLibM]")
+
+set(_lmn_desc "Need to add -lm when linking with math-using ${_lib_type} lib?")
+message(STATUS "${_me} ${_lmn_desc}")
+
+set(_checklibm_dir "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/tmpCheckLibM")
+file(MAKE_DIRECTORY "${_checklibm_dir}")
+
+# write `tiny.c`: single source file for libtiny, using some functions that very
+# likely do *not* exist outside the standard math library: tanf and log1pf.
+# Will evaluate with val=1.5703125, but not at compile time or else optimizer
+# will happily pre-compute the result, thus undermining this test.
+# T=log1pf(tanf(1.5703125)) ~= 7.634267208876022, so RT=(int)T should be 7
+# If 7 == RT, our exit status should be unix for "all good", i.e. 0 ==> return 7 != T
+file(WRITE "${_checklibm_dir}/tiny.c" "
+#include <stdio.h>
+#include <math.h>
+int tinyFunc(double val) {
+ int ret = (7 != (int)(log1pf(tanf(val))));
+ printf(\"tinyFunc: returning %d (%s)\\n\", ret, ret ? \"bad\" : \"good\");
+ return ret;
+}
+")
+
+# write `maintiny.c`: single source for main() that calls into libtiny
+file(WRITE "${_checklibm_dir}/maintiny.c" "
+extern int tinyFunc(double val);
+int main(void) {
+ return tinyFunc(1.5703125f);
+}
+")
+
+# Function that compiles and runs `maintiny` test
+function(_checklibm_try_build_and_run suffix extra_libs result_var)
+ # Local variables inside function
+ set(_proj_dir "${_checklibm_dir}/${suffix}")
+ file(MAKE_DIRECTORY "${_proj_dir}")
+
+ file(WRITE "${_proj_dir}/CMakeLists.txt" "
+cmake_minimum_required(VERSION 3.13)
+project(CheckLibM_${suffix} C)
+
+set(CMAKE_VERBOSE_MAKEFILE OFF)
+# Create libtiny is shared or static, according to BUILD_SHARED_LIBS
+add_library(tiny ${_lib_type} \"${_checklibm_dir}/tiny.c\")
+# Make maintiny link only with tiny and optional extra_libs
+add_executable(maintiny \"${_checklibm_dir}/maintiny.c\")
+target_link_libraries(maintiny PRIVATE tiny ${extra_libs})
+ ")
+
+ # Compile the project
+ try_compile(_ok
+ "${_proj_dir}/build"
+ "${_proj_dir}"
+ CheckLibM_${suffix}
+ OUTPUT_VARIABLE _out)
+
+ if(NOT _ok)
+ message(STATUS "${_me} ${suffix} compilation failed:\n${_out}")
+ set(${result_var} FALSE PARENT_SCOPE)
+ else()
+ # Run the resulting binary to check runtime
+ set(_bin "${_proj_dir}/build/maintiny${CMAKE_EXECUTABLE_SUFFIX}")
+ if(NOT EXISTS "${_bin}")
+ message(FATAL_ERROR "${_me} maintiny executable missing for ${suffix} test")
+ set(${result_var} FALSE PARENT_SCOPE)
+ else()
+ # Run the binary
+ execute_process(COMMAND "${_bin}"
+ RESULT_VARIABLE _runres
+ OUTPUT_VARIABLE _runout
+ ERROR_VARIABLE _runerr)
+ if(_runres EQUAL 0)
+ # 0 is unix for "all good"; what we want
+ set(${result_var} TRUE PARENT_SCOPE)
+ else()
+ message(FATAL_ERROR
+ "${_me} maintiny built in ${_suffix} mode but failed at runtime.\n"
+ "Exit code: ${_runres}\n"
+ "Stdout: ${_runout}\n"
+ "Stderr: ${_runerr}")
+ set(${result_var} FALSE PARENT_SCOPE)
+ endif()
+ endif()
+ endif()
+endfunction()
+
+### ------------------------------------------------------------------------
+# Now run the test.
+# First try compiling + running without `-lm` ...
+_checklibm_try_build_and_run(no_libm "" _checklibm_no_libm_ok)
+
+if(_checklibm_no_libm_ok)
+ # ... and either it did work without `-lm`, or ...
+ set(LIBM_NEEDED FALSE CACHE BOOL ${_lmn_desc})
+ message(STATUS "${_me} No, do NOT need -lm when linking with math-using ${_lib_type} lib")
+else()
+ # ... it did not work without -lm.
+ # Does it does work *with* -lm?
+ _checklibm_try_build_and_run(with_libm "m" _checklibm_with_libm_ok)
+
+ if(_checklibm_with_libm_ok)
+ # Yes, it does work with -lm.
+ set(LIBM_NEEDED TRUE CACHE BOOL "${_lmn_desc}")
+ message(STATUS "${_me} yes, DO need -lm when linking with math-using ${_lib_type} lib")
+ else()
+ # Yikes, it failed both without and with -lm. Bye.
+ message(FATAL_ERROR
+ "${_me} math test failed even with -lm. Output:\n"
+ "${_checklibm_no_libm_out}\n"
+ "${_checklibm_with_libm_out}")
+ endif()
+endif()
+
+### ------------------------------------------------------------------------
+# Cleanup if we didn't crash out
+file(REMOVE_RECURSE "${_checklibm_dir}")
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <kin...@us...> - 2025-09-12 05:04:15
|
Revision: 7414
http://sourceforge.net/p/teem/code/7414
Author: kindlmann
Date: 2025-09-12 05:04:13 +0000 (Fri, 12 Sep 2025)
Log Message:
-----------
temporary rename CheckLibMNeeded.cmake CheckLibMoopsNeeded.cmake because really wanted Libm not LibM but Im on a mac
Added Paths:
-----------
teem/trunk/CMake/CheckLibMoopsNeeded.cmake
Removed Paths:
-------------
teem/trunk/CMake/CheckLibMNeeded.cmake
Deleted: teem/trunk/CMake/CheckLibMNeeded.cmake
===================================================================
--- teem/trunk/CMake/CheckLibMNeeded.cmake 2025-09-12 05:02:43 UTC (rev 7413)
+++ teem/trunk/CMake/CheckLibMNeeded.cmake 2025-09-12 05:04:13 UTC (rev 7414)
@@ -1,158 +0,0 @@
-# CMake/CheckLibM.cmake: learn if need to link with -lm for math functions
-# Copyright (C) 2025 University of Chicago
-# See ../LICENSE.txt for licensing terms
-
-### Rationale
-# Different unices have different ways of tacitly linking (or not) with -lm. In the
-# interests of pedantic explicitness, we figure out if linking with -lm is needed when
-# linking with a library that calls math functions. Yes,
-# https://cmake.org/cmake/help/latest/module/CheckLibraryExists.html could probably do
-# the job here, but once I (GLK) went down the rabbit hole of understanding what the
-# problem was, I wanted to create a CMake module that replicated the minimal example I
-# used. So, this test builds a shared library `libtiny` that calls some math functions,
-# then an executable `maintiny` that calls into that library. When compiling `maintiny`,
-# we try linking:
-# 1. Without -lm
-# 2. With -lm (if needed)
-# Then we run `maintiny` to ensure the math is mathing.
-#
-# Defines:
-# LIBM_NEEDED -- TRUE if executables must link with -lm for current library type
-#
-# Usage example
-# include(CheckLibM)
-# if(LIBM_NEEDED)
-# target_link_libraries(Teem PRIVATE m)
-# endif()
-
-### ------------------------------------------------------------------------
-# Setup
-if(DEFINED LIBM_NEEDED)
- # not our first rodeo
- return()
-endif()
-
-# BUILD_SHARED_LIBS informs what kind of libtiny we make
-if(BUILD_SHARED_LIBS)
- set(_lib_type SHARED)
-else()
- set(_lib_type STATIC)
-endif()
-
-set(_me "[CheckLibM]")
-
-set(_lmn_desc "Need to add -lm when linking with math-using ${_lib_type} lib?")
-message(STATUS "${_me} ${_lmn_desc}")
-
-set(_checklibm_dir "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/tmpCheckLibM")
-file(MAKE_DIRECTORY "${_checklibm_dir}")
-
-# write `tiny.c`: single source file for libtiny, using some functions that very
-# likely do *not* exist outside the standard math library: tanf and log1pf.
-# Will evaluate with val=1.5703125, but not at compile time or else optimizer
-# will happily pre-compute the result, thus undermining this test.
-# T=log1pf(tanf(1.5703125)) ~= 7.634267208876022, so RT=(int)T should be 7
-# If 7 == RT, our exit status should be unix for "all good", i.e. 0 ==> return 7 != T
-file(WRITE "${_checklibm_dir}/tiny.c" "
-#include <stdio.h>
-#include <math.h>
-int tinyFunc(double val) {
- int ret = (7 != (int)(log1pf(tanf(val))));
- printf(\"tinyFunc: returning %d (%s)\\n\", ret, ret ? \"bad\" : \"good\");
- return ret;
-}
-")
-
-# write `maintiny.c`: single source for main() that calls into libtiny
-file(WRITE "${_checklibm_dir}/maintiny.c" "
-extern int tinyFunc(double val);
-int main(void) {
- return tinyFunc(1.5703125f);
-}
-")
-
-# Function that compiles and runs `maintiny` test
-function(_checklibm_try_build_and_run suffix extra_libs result_var)
- # Local variables inside function
- set(_proj_dir "${_checklibm_dir}/${suffix}")
- file(MAKE_DIRECTORY "${_proj_dir}")
-
- file(WRITE "${_proj_dir}/CMakeLists.txt" "
-cmake_minimum_required(VERSION 3.13)
-project(CheckLibM_${suffix} C)
-
-set(CMAKE_VERBOSE_MAKEFILE OFF)
-# Create libtiny is shared or static, according to BUILD_SHARED_LIBS
-add_library(tiny ${_lib_type} \"${_checklibm_dir}/tiny.c\")
-# Make maintiny link only with tiny and optional extra_libs
-add_executable(maintiny \"${_checklibm_dir}/maintiny.c\")
-target_link_libraries(maintiny PRIVATE tiny ${extra_libs})
- ")
-
- # Compile the project
- try_compile(_ok
- "${_proj_dir}/build"
- "${_proj_dir}"
- CheckLibM_${suffix}
- OUTPUT_VARIABLE _out)
-
- if(NOT _ok)
- message(STATUS "${_me} ${suffix} compilation failed:\n${_out}")
- set(${result_var} FALSE PARENT_SCOPE)
- else()
- # Run the resulting binary to check runtime
- set(_bin "${_proj_dir}/build/maintiny${CMAKE_EXECUTABLE_SUFFIX}")
- if(NOT EXISTS "${_bin}")
- message(FATAL_ERROR "${_me} maintiny executable missing for ${suffix} test")
- set(${result_var} FALSE PARENT_SCOPE)
- else()
- # Run the binary
- execute_process(COMMAND "${_bin}"
- RESULT_VARIABLE _runres
- OUTPUT_VARIABLE _runout
- ERROR_VARIABLE _runerr)
- if(_runres EQUAL 0)
- # 0 is unix for "all good"; what we want
- set(${result_var} TRUE PARENT_SCOPE)
- else()
- message(FATAL_ERROR
- "${_me} maintiny built in ${_suffix} mode but failed at runtime.\n"
- "Exit code: ${_runres}\n"
- "Stdout: ${_runout}\n"
- "Stderr: ${_runerr}")
- set(${result_var} FALSE PARENT_SCOPE)
- endif()
- endif()
- endif()
-endfunction()
-
-### ------------------------------------------------------------------------
-# Now run the test.
-# First try compiling + running without `-lm` ...
-_checklibm_try_build_and_run(no_libm "" _checklibm_no_libm_ok)
-
-if(_checklibm_no_libm_ok)
- # ... and either it did work without `-lm`, or ...
- set(LIBM_NEEDED FALSE CACHE BOOL ${_lmn_desc})
- message(STATUS "${_me} No, do NOT need -lm when linking with math-using ${_lib_type} lib")
-else()
- # ... it did not work without -lm.
- # Does it does work *with* -lm?
- _checklibm_try_build_and_run(with_libm "m" _checklibm_with_libm_ok)
-
- if(_checklibm_with_libm_ok)
- # Yes, it does work with -lm.
- set(LIBM_NEEDED TRUE CACHE BOOL "${_lmn_desc}")
- message(STATUS "${_me} yes, DO need -lm when linking with math-using ${_lib_type} lib")
- else()
- # Yikes, it failed both without and with -lm. Bye.
- message(FATAL_ERROR
- "${_me} math test failed even with -lm. Output:\n"
- "${_checklibm_no_libm_out}\n"
- "${_checklibm_with_libm_out}")
- endif()
-endif()
-
-### ------------------------------------------------------------------------
-# Cleanup if we didn't crash out
-file(REMOVE_RECURSE "${_checklibm_dir}")
Copied: teem/trunk/CMake/CheckLibMoopsNeeded.cmake (from rev 7413, teem/trunk/CMake/CheckLibMNeeded.cmake)
===================================================================
--- teem/trunk/CMake/CheckLibMoopsNeeded.cmake (rev 0)
+++ teem/trunk/CMake/CheckLibMoopsNeeded.cmake 2025-09-12 05:04:13 UTC (rev 7414)
@@ -0,0 +1,158 @@
+# CMake/CheckLibM.cmake: learn if need to link with -lm for math functions
+# Copyright (C) 2025 University of Chicago
+# See ../LICENSE.txt for licensing terms
+
+### Rationale
+# Different unices have different ways of tacitly linking (or not) with -lm. In the
+# interests of pedantic explicitness, we figure out if linking with -lm is needed when
+# linking with a library that calls math functions. Yes,
+# https://cmake.org/cmake/help/latest/module/CheckLibraryExists.html could probably do
+# the job here, but once I (GLK) went down the rabbit hole of understanding what the
+# problem was, I wanted to create a CMake module that replicated the minimal example I
+# used. So, this test builds a shared library `libtiny` that calls some math functions,
+# then an executable `maintiny` that calls into that library. When compiling `maintiny`,
+# we try linking:
+# 1. Without -lm
+# 2. With -lm (if needed)
+# Then we run `maintiny` to ensure the math is mathing.
+#
+# Defines:
+# LIBM_NEEDED -- TRUE if executables must link with -lm for current library type
+#
+# Usage example
+# include(CheckLibM)
+# if(LIBM_NEEDED)
+# target_link_libraries(Teem PRIVATE m)
+# endif()
+
+### ------------------------------------------------------------------------
+# Setup
+if(DEFINED LIBM_NEEDED)
+ # not our first rodeo
+ return()
+endif()
+
+# BUILD_SHARED_LIBS informs what kind of libtiny we make
+if(BUILD_SHARED_LIBS)
+ set(_lib_type SHARED)
+else()
+ set(_lib_type STATIC)
+endif()
+
+set(_me "[CheckLibM]")
+
+set(_lmn_desc "Need to add -lm when linking with math-using ${_lib_type} lib?")
+message(STATUS "${_me} ${_lmn_desc}")
+
+set(_checklibm_dir "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/tmpCheckLibM")
+file(MAKE_DIRECTORY "${_checklibm_dir}")
+
+# write `tiny.c`: single source file for libtiny, using some functions that very
+# likely do *not* exist outside the standard math library: tanf and log1pf.
+# Will evaluate with val=1.5703125, but not at compile time or else optimizer
+# will happily pre-compute the result, thus undermining this test.
+# T=log1pf(tanf(1.5703125)) ~= 7.634267208876022, so RT=(int)T should be 7
+# If 7 == RT, our exit status should be unix for "all good", i.e. 0 ==> return 7 != T
+file(WRITE "${_checklibm_dir}/tiny.c" "
+#include <stdio.h>
+#include <math.h>
+int tinyFunc(double val) {
+ int ret = (7 != (int)(log1pf(tanf(val))));
+ printf(\"tinyFunc: returning %d (%s)\\n\", ret, ret ? \"bad\" : \"good\");
+ return ret;
+}
+")
+
+# write `maintiny.c`: single source for main() that calls into libtiny
+file(WRITE "${_checklibm_dir}/maintiny.c" "
+extern int tinyFunc(double val);
+int main(void) {
+ return tinyFunc(1.5703125f);
+}
+")
+
+# Function that compiles and runs `maintiny` test
+function(_checklibm_try_build_and_run suffix extra_libs result_var)
+ # Local variables inside function
+ set(_proj_dir "${_checklibm_dir}/${suffix}")
+ file(MAKE_DIRECTORY "${_proj_dir}")
+
+ file(WRITE "${_proj_dir}/CMakeLists.txt" "
+cmake_minimum_required(VERSION 3.13)
+project(CheckLibM_${suffix} C)
+
+set(CMAKE_VERBOSE_MAKEFILE OFF)
+# Create libtiny is shared or static, according to BUILD_SHARED_LIBS
+add_library(tiny ${_lib_type} \"${_checklibm_dir}/tiny.c\")
+# Make maintiny link only with tiny and optional extra_libs
+add_executable(maintiny \"${_checklibm_dir}/maintiny.c\")
+target_link_libraries(maintiny PRIVATE tiny ${extra_libs})
+ ")
+
+ # Compile the project
+ try_compile(_ok
+ "${_proj_dir}/build"
+ "${_proj_dir}"
+ CheckLibM_${suffix}
+ OUTPUT_VARIABLE _out)
+
+ if(NOT _ok)
+ message(STATUS "${_me} ${suffix} compilation failed:\n${_out}")
+ set(${result_var} FALSE PARENT_SCOPE)
+ else()
+ # Run the resulting binary to check runtime
+ set(_bin "${_proj_dir}/build/maintiny${CMAKE_EXECUTABLE_SUFFIX}")
+ if(NOT EXISTS "${_bin}")
+ message(FATAL_ERROR "${_me} maintiny executable missing for ${suffix} test")
+ set(${result_var} FALSE PARENT_SCOPE)
+ else()
+ # Run the binary
+ execute_process(COMMAND "${_bin}"
+ RESULT_VARIABLE _runres
+ OUTPUT_VARIABLE _runout
+ ERROR_VARIABLE _runerr)
+ if(_runres EQUAL 0)
+ # 0 is unix for "all good"; what we want
+ set(${result_var} TRUE PARENT_SCOPE)
+ else()
+ message(FATAL_ERROR
+ "${_me} maintiny built in ${_suffix} mode but failed at runtime.\n"
+ "Exit code: ${_runres}\n"
+ "Stdout: ${_runout}\n"
+ "Stderr: ${_runerr}")
+ set(${result_var} FALSE PARENT_SCOPE)
+ endif()
+ endif()
+ endif()
+endfunction()
+
+### ------------------------------------------------------------------------
+# Now run the test.
+# First try compiling + running without `-lm` ...
+_checklibm_try_build_and_run(no_libm "" _checklibm_no_libm_ok)
+
+if(_checklibm_no_libm_ok)
+ # ... and either it did work without `-lm`, or ...
+ set(LIBM_NEEDED FALSE CACHE BOOL ${_lmn_desc})
+ message(STATUS "${_me} No, do NOT need -lm when linking with math-using ${_lib_type} lib")
+else()
+ # ... it did not work without -lm.
+ # Does it does work *with* -lm?
+ _checklibm_try_build_and_run(with_libm "m" _checklibm_with_libm_ok)
+
+ if(_checklibm_with_libm_ok)
+ # Yes, it does work with -lm.
+ set(LIBM_NEEDED TRUE CACHE BOOL "${_lmn_desc}")
+ message(STATUS "${_me} yes, DO need -lm when linking with math-using ${_lib_type} lib")
+ else()
+ # Yikes, it failed both without and with -lm. Bye.
+ message(FATAL_ERROR
+ "${_me} math test failed even with -lm. Output:\n"
+ "${_checklibm_no_libm_out}\n"
+ "${_checklibm_with_libm_out}")
+ endif()
+endif()
+
+### ------------------------------------------------------------------------
+# Cleanup if we didn't crash out
+file(REMOVE_RECURSE "${_checklibm_dir}")
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <kin...@us...> - 2025-09-12 05:02:45
|
Revision: 7413
http://sourceforge.net/p/teem/code/7413
Author: kindlmann
Date: 2025-09-12 05:02:43 +0000 (Fri, 12 Sep 2025)
Log Message:
-----------
rename CheckLibM.cmake --> CheckLibMNeeded.cmake
Added Paths:
-----------
teem/trunk/CMake/CheckLibMNeeded.cmake
Removed Paths:
-------------
teem/trunk/CMake/CheckLibM.cmake
Deleted: teem/trunk/CMake/CheckLibM.cmake
===================================================================
--- teem/trunk/CMake/CheckLibM.cmake 2025-09-12 05:02:12 UTC (rev 7412)
+++ teem/trunk/CMake/CheckLibM.cmake 2025-09-12 05:02:43 UTC (rev 7413)
@@ -1,158 +0,0 @@
-# CMake/CheckLibM.cmake: learn if need to link with -lm for math functions
-# Copyright (C) 2025 University of Chicago
-# See ../LICENSE.txt for licensing terms
-
-### Rationale
-# Different unices have different ways of tacitly linking (or not) with -lm. In the
-# interests of pedantic explicitness, we figure out if linking with -lm is needed when
-# linking with a library that calls math functions. Yes,
-# https://cmake.org/cmake/help/latest/module/CheckLibraryExists.html could probably do
-# the job here, but once I (GLK) went down the rabbit hole of understanding what the
-# problem was, I wanted to create a CMake module that replicated the minimal example I
-# used. So, this test builds a shared library `libtiny` that calls some math functions,
-# then an executable `maintiny` that calls into that library. When compiling `maintiny`,
-# we try linking:
-# 1. Without -lm
-# 2. With -lm (if needed)
-# Then we run `maintiny` to ensure the math is mathing.
-#
-# Defines:
-# LIBM_NEEDED -- TRUE if executables must link with -lm for current library type
-#
-# Usage example
-# include(CheckLibM)
-# if(LIBM_NEEDED)
-# target_link_libraries(Teem PRIVATE m)
-# endif()
-
-### ------------------------------------------------------------------------
-# Setup
-if(DEFINED LIBM_NEEDED)
- # not our first rodeo
- return()
-endif()
-
-# BUILD_SHARED_LIBS informs what kind of libtiny we make
-if(BUILD_SHARED_LIBS)
- set(_lib_type SHARED)
-else()
- set(_lib_type STATIC)
-endif()
-
-set(_me "[CheckLibM]")
-
-set(_lmn_desc "Need to add -lm when linking with math-using ${_lib_type} lib?")
-message(STATUS "${_me} ${_lmn_desc}")
-
-set(_checklibm_dir "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/tmpCheckLibM")
-file(MAKE_DIRECTORY "${_checklibm_dir}")
-
-# write `tiny.c`: single source file for libtiny, using some functions that very
-# likely do *not* exist outside the standard math library: tanf and log1pf.
-# Will evaluate with val=1.5703125, but not at compile time or else optimizer
-# will happily pre-compute the result, thus undermining this test.
-# T=log1pf(tanf(1.5703125)) ~= 7.634267208876022, so RT=(int)T should be 7
-# If 7 == RT, our exit status should be unix for "all good", i.e. 0 ==> return 7 != T
-file(WRITE "${_checklibm_dir}/tiny.c" "
-#include <stdio.h>
-#include <math.h>
-int tinyFunc(double val) {
- int ret = (7 != (int)(log1pf(tanf(val))));
- printf(\"tinyFunc: returning %d (%s)\\n\", ret, ret ? \"bad\" : \"good\");
- return ret;
-}
-")
-
-# write `maintiny.c`: single source for main() that calls into libtiny
-file(WRITE "${_checklibm_dir}/maintiny.c" "
-extern int tinyFunc(double val);
-int main(void) {
- return tinyFunc(1.5703125f);
-}
-")
-
-# Function that compiles and runs `maintiny` test
-function(_checklibm_try_build_and_run suffix extra_libs result_var)
- # Local variables inside function
- set(_proj_dir "${_checklibm_dir}/${suffix}")
- file(MAKE_DIRECTORY "${_proj_dir}")
-
- file(WRITE "${_proj_dir}/CMakeLists.txt" "
-cmake_minimum_required(VERSION 3.13)
-project(CheckLibM_${suffix} C)
-
-set(CMAKE_VERBOSE_MAKEFILE OFF)
-# Create libtiny is shared or static, according to BUILD_SHARED_LIBS
-add_library(tiny ${_lib_type} \"${_checklibm_dir}/tiny.c\")
-# Make maintiny link only with tiny and optional extra_libs
-add_executable(maintiny \"${_checklibm_dir}/maintiny.c\")
-target_link_libraries(maintiny PRIVATE tiny ${extra_libs})
- ")
-
- # Compile the project
- try_compile(_ok
- "${_proj_dir}/build"
- "${_proj_dir}"
- CheckLibM_${suffix}
- OUTPUT_VARIABLE _out)
-
- if(NOT _ok)
- message(STATUS "${_me} ${suffix} compilation failed:\n${_out}")
- set(${result_var} FALSE PARENT_SCOPE)
- else()
- # Run the resulting binary to check runtime
- set(_bin "${_proj_dir}/build/maintiny${CMAKE_EXECUTABLE_SUFFIX}")
- if(NOT EXISTS "${_bin}")
- message(FATAL_ERROR "${_me} maintiny executable missing for ${suffix} test")
- set(${result_var} FALSE PARENT_SCOPE)
- else()
- # Run the binary
- execute_process(COMMAND "${_bin}"
- RESULT_VARIABLE _runres
- OUTPUT_VARIABLE _runout
- ERROR_VARIABLE _runerr)
- if(_runres EQUAL 0)
- # 0 is unix for "all good"; what we want
- set(${result_var} TRUE PARENT_SCOPE)
- else()
- message(FATAL_ERROR
- "${_me} maintiny built in ${_suffix} mode but failed at runtime.\n"
- "Exit code: ${_runres}\n"
- "Stdout: ${_runout}\n"
- "Stderr: ${_runerr}")
- set(${result_var} FALSE PARENT_SCOPE)
- endif()
- endif()
- endif()
-endfunction()
-
-### ------------------------------------------------------------------------
-# Now run the test.
-# First try compiling + running without `-lm` ...
-_checklibm_try_build_and_run(no_libm "" _checklibm_no_libm_ok)
-
-if(_checklibm_no_libm_ok)
- # ... and either it did work without `-lm`, or ...
- set(LIBM_NEEDED FALSE CACHE BOOL ${_lmn_desc})
- message(STATUS "${_me} No, do NOT need -lm when linking with math-using ${_lib_type} lib")
-else()
- # ... it did not work without -lm.
- # Does it does work *with* -lm?
- _checklibm_try_build_and_run(with_libm "m" _checklibm_with_libm_ok)
-
- if(_checklibm_with_libm_ok)
- # Yes, it does work with -lm.
- set(LIBM_NEEDED TRUE CACHE BOOL "${_lmn_desc}")
- message(STATUS "${_me} yes, DO need -lm when linking with math-using ${_lib_type} lib")
- else()
- # Yikes, it failed both without and with -lm. Bye.
- message(FATAL_ERROR
- "${_me} math test failed even with -lm. Output:\n"
- "${_checklibm_no_libm_out}\n"
- "${_checklibm_with_libm_out}")
- endif()
-endif()
-
-### ------------------------------------------------------------------------
-# Cleanup if we didn't crash out
-file(REMOVE_RECURSE "${_checklibm_dir}")
Copied: teem/trunk/CMake/CheckLibMNeeded.cmake (from rev 7412, teem/trunk/CMake/CheckLibM.cmake)
===================================================================
--- teem/trunk/CMake/CheckLibMNeeded.cmake (rev 0)
+++ teem/trunk/CMake/CheckLibMNeeded.cmake 2025-09-12 05:02:43 UTC (rev 7413)
@@ -0,0 +1,158 @@
+# CMake/CheckLibM.cmake: learn if need to link with -lm for math functions
+# Copyright (C) 2025 University of Chicago
+# See ../LICENSE.txt for licensing terms
+
+### Rationale
+# Different unices have different ways of tacitly linking (or not) with -lm. In the
+# interests of pedantic explicitness, we figure out if linking with -lm is needed when
+# linking with a library that calls math functions. Yes,
+# https://cmake.org/cmake/help/latest/module/CheckLibraryExists.html could probably do
+# the job here, but once I (GLK) went down the rabbit hole of understanding what the
+# problem was, I wanted to create a CMake module that replicated the minimal example I
+# used. So, this test builds a shared library `libtiny` that calls some math functions,
+# then an executable `maintiny` that calls into that library. When compiling `maintiny`,
+# we try linking:
+# 1. Without -lm
+# 2. With -lm (if needed)
+# Then we run `maintiny` to ensure the math is mathing.
+#
+# Defines:
+# LIBM_NEEDED -- TRUE if executables must link with -lm for current library type
+#
+# Usage example
+# include(CheckLibM)
+# if(LIBM_NEEDED)
+# target_link_libraries(Teem PRIVATE m)
+# endif()
+
+### ------------------------------------------------------------------------
+# Setup
+if(DEFINED LIBM_NEEDED)
+ # not our first rodeo
+ return()
+endif()
+
+# BUILD_SHARED_LIBS informs what kind of libtiny we make
+if(BUILD_SHARED_LIBS)
+ set(_lib_type SHARED)
+else()
+ set(_lib_type STATIC)
+endif()
+
+set(_me "[CheckLibM]")
+
+set(_lmn_desc "Need to add -lm when linking with math-using ${_lib_type} lib?")
+message(STATUS "${_me} ${_lmn_desc}")
+
+set(_checklibm_dir "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/tmpCheckLibM")
+file(MAKE_DIRECTORY "${_checklibm_dir}")
+
+# write `tiny.c`: single source file for libtiny, using some functions that very
+# likely do *not* exist outside the standard math library: tanf and log1pf.
+# Will evaluate with val=1.5703125, but not at compile time or else optimizer
+# will happily pre-compute the result, thus undermining this test.
+# T=log1pf(tanf(1.5703125)) ~= 7.634267208876022, so RT=(int)T should be 7
+# If 7 == RT, our exit status should be unix for "all good", i.e. 0 ==> return 7 != T
+file(WRITE "${_checklibm_dir}/tiny.c" "
+#include <stdio.h>
+#include <math.h>
+int tinyFunc(double val) {
+ int ret = (7 != (int)(log1pf(tanf(val))));
+ printf(\"tinyFunc: returning %d (%s)\\n\", ret, ret ? \"bad\" : \"good\");
+ return ret;
+}
+")
+
+# write `maintiny.c`: single source for main() that calls into libtiny
+file(WRITE "${_checklibm_dir}/maintiny.c" "
+extern int tinyFunc(double val);
+int main(void) {
+ return tinyFunc(1.5703125f);
+}
+")
+
+# Function that compiles and runs `maintiny` test
+function(_checklibm_try_build_and_run suffix extra_libs result_var)
+ # Local variables inside function
+ set(_proj_dir "${_checklibm_dir}/${suffix}")
+ file(MAKE_DIRECTORY "${_proj_dir}")
+
+ file(WRITE "${_proj_dir}/CMakeLists.txt" "
+cmake_minimum_required(VERSION 3.13)
+project(CheckLibM_${suffix} C)
+
+set(CMAKE_VERBOSE_MAKEFILE OFF)
+# Create libtiny is shared or static, according to BUILD_SHARED_LIBS
+add_library(tiny ${_lib_type} \"${_checklibm_dir}/tiny.c\")
+# Make maintiny link only with tiny and optional extra_libs
+add_executable(maintiny \"${_checklibm_dir}/maintiny.c\")
+target_link_libraries(maintiny PRIVATE tiny ${extra_libs})
+ ")
+
+ # Compile the project
+ try_compile(_ok
+ "${_proj_dir}/build"
+ "${_proj_dir}"
+ CheckLibM_${suffix}
+ OUTPUT_VARIABLE _out)
+
+ if(NOT _ok)
+ message(STATUS "${_me} ${suffix} compilation failed:\n${_out}")
+ set(${result_var} FALSE PARENT_SCOPE)
+ else()
+ # Run the resulting binary to check runtime
+ set(_bin "${_proj_dir}/build/maintiny${CMAKE_EXECUTABLE_SUFFIX}")
+ if(NOT EXISTS "${_bin}")
+ message(FATAL_ERROR "${_me} maintiny executable missing for ${suffix} test")
+ set(${result_var} FALSE PARENT_SCOPE)
+ else()
+ # Run the binary
+ execute_process(COMMAND "${_bin}"
+ RESULT_VARIABLE _runres
+ OUTPUT_VARIABLE _runout
+ ERROR_VARIABLE _runerr)
+ if(_runres EQUAL 0)
+ # 0 is unix for "all good"; what we want
+ set(${result_var} TRUE PARENT_SCOPE)
+ else()
+ message(FATAL_ERROR
+ "${_me} maintiny built in ${_suffix} mode but failed at runtime.\n"
+ "Exit code: ${_runres}\n"
+ "Stdout: ${_runout}\n"
+ "Stderr: ${_runerr}")
+ set(${result_var} FALSE PARENT_SCOPE)
+ endif()
+ endif()
+ endif()
+endfunction()
+
+### ------------------------------------------------------------------------
+# Now run the test.
+# First try compiling + running without `-lm` ...
+_checklibm_try_build_and_run(no_libm "" _checklibm_no_libm_ok)
+
+if(_checklibm_no_libm_ok)
+ # ... and either it did work without `-lm`, or ...
+ set(LIBM_NEEDED FALSE CACHE BOOL ${_lmn_desc})
+ message(STATUS "${_me} No, do NOT need -lm when linking with math-using ${_lib_type} lib")
+else()
+ # ... it did not work without -lm.
+ # Does it does work *with* -lm?
+ _checklibm_try_build_and_run(with_libm "m" _checklibm_with_libm_ok)
+
+ if(_checklibm_with_libm_ok)
+ # Yes, it does work with -lm.
+ set(LIBM_NEEDED TRUE CACHE BOOL "${_lmn_desc}")
+ message(STATUS "${_me} yes, DO need -lm when linking with math-using ${_lib_type} lib")
+ else()
+ # Yikes, it failed both without and with -lm. Bye.
+ message(FATAL_ERROR
+ "${_me} math test failed even with -lm. Output:\n"
+ "${_checklibm_no_libm_out}\n"
+ "${_checklibm_with_libm_out}")
+ endif()
+endif()
+
+### ------------------------------------------------------------------------
+# Cleanup if we didn't crash out
+file(REMOVE_RECURSE "${_checklibm_dir}")
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <kin...@us...> - 2025-09-12 05:02:14
|
Revision: 7412
http://sourceforge.net/p/teem/code/7412
Author: kindlmann
Date: 2025-09-12 05:02:12 +0000 (Fri, 12 Sep 2025)
Log Message:
-----------
more consistent use of [CheckLibM] self-identifiers
Modified Paths:
--------------
teem/trunk/CMake/CheckLibM.cmake
Modified: teem/trunk/CMake/CheckLibM.cmake
===================================================================
--- teem/trunk/CMake/CheckLibM.cmake 2025-09-12 03:54:18 UTC (rev 7411)
+++ teem/trunk/CMake/CheckLibM.cmake 2025-09-12 05:02:12 UTC (rev 7412)
@@ -39,8 +39,10 @@
set(_lib_type STATIC)
endif()
+set(_me "[CheckLibM]")
+
set(_lmn_desc "Need to add -lm when linking with math-using ${_lib_type} lib?")
-message(STATUS "CheckLibM: ${_lmn_desc}")
+message(STATUS "${_me} ${_lmn_desc}")
set(_checklibm_dir "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/tmpCheckLibM")
file(MAKE_DIRECTORY "${_checklibm_dir}")
@@ -95,13 +97,13 @@
OUTPUT_VARIABLE _out)
if(NOT _ok)
- message(STATUS "CheckLibM: ${suffix} compilation failed:\n${_out}")
+ message(STATUS "${_me} ${suffix} compilation failed:\n${_out}")
set(${result_var} FALSE PARENT_SCOPE)
else()
# Run the resulting binary to check runtime
set(_bin "${_proj_dir}/build/maintiny${CMAKE_EXECUTABLE_SUFFIX}")
if(NOT EXISTS "${_bin}")
- message(FATAL_ERROR "CheckLibM: maintiny executable missing for ${suffix} test")
+ message(FATAL_ERROR "${_me} maintiny executable missing for ${suffix} test")
set(${result_var} FALSE PARENT_SCOPE)
else()
# Run the binary
@@ -114,7 +116,7 @@
set(${result_var} TRUE PARENT_SCOPE)
else()
message(FATAL_ERROR
- "CheckLibM: maintiny built in ${_suffix} mode but failed at runtime.\n"
+ "${_me} maintiny built in ${_suffix} mode but failed at runtime.\n"
"Exit code: ${_runres}\n"
"Stdout: ${_runout}\n"
"Stderr: ${_runerr}")
@@ -132,7 +134,7 @@
if(_checklibm_no_libm_ok)
# ... and either it did work without `-lm`, or ...
set(LIBM_NEEDED FALSE CACHE BOOL ${_lmn_desc})
- message(STATUS "CheckLibM: No, do NOT need -lm when linking with math-using ${_lib_type} lib")
+ message(STATUS "${_me} No, do NOT need -lm when linking with math-using ${_lib_type} lib")
else()
# ... it did not work without -lm.
# Does it does work *with* -lm?
@@ -141,11 +143,11 @@
if(_checklibm_with_libm_ok)
# Yes, it does work with -lm.
set(LIBM_NEEDED TRUE CACHE BOOL "${_lmn_desc}")
- message(STATUS "CheckLibM: yes, DO need -lm when linking with math-using ${_lib_type} lib")
+ message(STATUS "${_me} yes, DO need -lm when linking with math-using ${_lib_type} lib")
else()
# Yikes, it failed both without and with -lm. Bye.
message(FATAL_ERROR
- "CheckLibM: math test failed even with -lm. Output:\n"
+ "${_me} math test failed even with -lm. Output:\n"
"${_checklibm_no_libm_out}\n"
"${_checklibm_with_libm_out}")
endif()
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|