Skip to content

Update Makefiles to make build more configurable - #22

Open
d-torrance wants to merge 4 commits into
coin-or:masterfrom
d-torrance:configurable-build
Open

Update Makefiles to make build more configurable#22
d-torrance wants to merge 4 commits into
coin-or:masterfrom
d-torrance:configurable-build

Conversation

@d-torrance

Copy link
Copy Markdown

We update the Makefiles to make things more configurable, which should be helpful for downstream package maintainers.

Here's a summary of the updates:

  • Respect CFLAGS either from the environment (which are currently ignored) or passed via make CFLAGS=... (which currently overwrites flags we need like -I../include).
  • New BLAS_LIBS, OPENMP_CFLAGS, and OPENMP_LIBS for configuring BLAS/LAPACK and OpenMP flags.
  • Detect macros as needed (BIT64, USESIGTERM, etc.) (this feature requires using GNU make)
  • Switch from -ansi to -std=gnu99 so we can use Clang's OpenMP headers, which use inline.
  • Use $(MAKE) instead of make for the subdirectories.
  • Lots of variables for configuring directories, etc. as well as TOOL_PREFIX for distros like Debian who rename the binaries, e.g., theta -> csdp-theta.
  • .PHONY targets added, which fixes a problem on macOS where make install wouldn't run because INSTALL already existed.
  • Added targets for building shared libraries, as well as a .pc file, header guards, and C++ support for the include files.

The changes were tested on lots of different systems and compilers: https://github.com/d-torrance/Csdp/actions/runs/31973784789

🤖 AI Disclosure 🤖

Claude Code generated the first draft of the changes, but I made lots of tweaks.

@d-torrance
d-torrance force-pushed the configurable-build branch 2 times, most recently from d572c7a to 03894b0 Compare August 17, 2026 00:27
d-torrance and others added 4 commits August 17, 2026 08:14
The top level Makefile did "export CFLAGS=-m64 -march=native -mtune=native
-Ofast -fopenmp -ansi -Wall -DBIT64 ... -I../include".  A makefile
assignment beats the environment, so "CFLAGS=... make" was silently
ignored, and "make CFLAGS=..." replaced the whole line, taking -I../include
and the feature macros with it.  There was no LDFLAGS at all, so linker
flags could not be passed either.  Distributors have worked around this in a
variety of ways, most of them involving smuggling flags in through CC.

Move the settings into a new Makefile.inc, included by each Makefile, and
split the flags the build itself requires (CSDP_CPPFLAGS, CSDP_CFLAGS) from
the ones the user owns (CPPFLAGS, CFLAGS, LDFLAGS, LIBS).  Neither can now
clobber the other.  OpenMP gets its own OPENMP_CFLAGS/OPENMP_LIBS pair,
since it is spelled differently on macOS, and USEOPENMP/SETNUMTHREADS are
defined only when it is actually enabled -- they include <omp.h> and call
the OpenMP runtime.

Also:

  - Drop -m64, -march=native, -mtune=native, -Ofast, -ansi and -static from
    the defaults.  -Ofast implies -ffast-math and on glibc links
    crtfastmath.o, which sets FTZ/DAZ process-wide; that is a poor default
    for a numerical solver.  Pin -std=gnu99 in place of -ansi: the sources
    use K&R function definitions, which C23 removed, so the standard has to
    be pinned somewhere below C23.  gnu99 is the lowest setting that still
    makes an implicit function declaration an error, and GNU rather than
    strict mode because the code calls POSIX interfaces that a strict mode
    is not obliged to declare.

  - Use $(MAKE) -C rather than "cd dir; make", so that the subdirectory
    builds inherit the jobserver.

  - Use $(AR) rather than a hardcoded ar, so that a cross build can pass
    its own archiver, and add the "s" flag so the archive always carries an
    index.

  - Honor prefix, bindir and DESTDIR when installing, and use install(1)
    rather than cp.  Add TOOL_PREFIX for distributors who rename theta,
    complement, graphtoprob and rand_graph to avoid clashes.

  - Mark install as .PHONY, so that "make install" keeps working on case
    insensitive filesystems, where the INSTALL file would otherwise satisfy
    the target.

This requires GNU make, which upstream's Makefiles did not: the feature
probes need $(shell), and the conditionals need ifeq/ifneq.  Every consumer
already uses it, and the FreeBSD port already sets USES=gmake.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Only the five programs were installed, and only to a hardcoded location:
libsdp.a and the headers were left in the build tree, so a distribution
could not ship anything that another package could link against.  Install
libsdp.a into $(libdir), the headers into $(includedir)/csdp, and a
pkg-config file into $(pkgconfigdir).

The headers keep including each other with quotes, so they work both in the
build tree and after installation, where a quoted include resolves next to
the including file.  Consumers can therefore write either

  #include <csdp/declarations.h>
  #include "declarations.h"

whichever suits them; csdp.pc puts both directories on the include path.
Add the include guards that blockmat.h, index.h and parameters.h were
missing, and extern "C" to all four, since they are public headers now.

SHARED=yes additionally builds a shared library -- libsdp.so.0 on ELF
systems, libsdp.0.dylib on macOS -- and the programs then link against it,
since -lsdp prefers the shared library when both are present.  The default
is still a static build, so nothing changes for distributions that only
want the programs.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
macOS names a shared library libsdp.<version>.dylib rather than
libsdp.so.<version>, records an install name in the library itself instead of
a soname, and builds it with -dynamiclib rather than -shared.  Add that shape,
selected by asking the compiler whether it defines __APPLE__ rather than by
asking uname what we are running on, so that it is right when cross compiling
as well as natively.

Kept separate from the base shared library support, so that a distribution
that only needs the ELF shape does not have to carry it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Windows has no sonames and no symlinks, and names a shared library for its
ABI version rather than its release version.  The artifacts are a versioned
DLL, which belongs next to the programs because that is where Windows looks
for it, and an import library, which is what goes in $(libdir).  Code there
is always position independent, so -fPIC is not used.

Which of the three shapes to build is decided by asking the compiler what it
defines rather than by asking uname what we are running on, so this is
correct when cross compiling with mingw as well as natively under MSYS2.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant