# DIRECTORIES
maindir=beampower
srcdir=$(maindir)/src
libdir=$(maindir)/lib

# Automatic platform detection
UNAME_S := $(shell uname -s)
UNAME_M := $(shell uname -m)

# Define compilers
NVCC=nvcc

# Auto-detect C compiler based on platform
ifeq ($(UNAME_S),Darwin)
    # macOS: prefer clang for ARM64, gcc for Intel
    ifeq ($(UNAME_M),arm64)
        CC=clang
    else
        CC=gcc
    endif
else
    # Linux and others: use gcc
    CC=gcc
endif

# Define commands
all: $(libdir)/beamform_cpu.so $(libdir)/beamform_gpu.so
python_CPU: $(libdir)/beamform_cpu.so
python_GPU: $(libdir)/beamform_gpu.so
.SUFFIXES: .c .cu

# -----------------------------------------------
#                CPU FLAGS
# -----------------------------------------------
COPTIMFLAGS_CPU=-O3

# Auto-detect OpenMP configuration for macOS and Linux
ifeq ($(UNAME_S),Darwin)
    # macOS: Priority order - venv/conda (with -fopenmp=libomp) > brew libomp (with paths) > system
    
    # Check for venv/conda first
    VENV_PATHS := $(shell python -c "import sys, os; is_venv = hasattr(sys, 'real_prefix') or (hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix); in_conda = 'CONDA_PREFIX' in os.environ; prefix = os.environ.get('CONDA_PREFIX', sys.prefix) if (is_venv or in_conda) else ''; print(prefix if prefix else '')")
    
    ifneq ($(VENV_PATHS),)
        # In venv/conda: use -fopenmp=libomp with venv paths
        CFLAGS_CPU=-fopenmp=libomp -L$(VENV_PATHS)/lib -I$(VENV_PATHS)/include -fPIC -ftree-vectorize -march=native -std=c99
        LDFLAGS_CPU=-shared -fuse-ld=lld
    else
        # Not in venv/conda: check for brew libomp
        ifeq ($(UNAME_M),arm64)
            BREW_LIBOMP_PATH := /opt/homebrew/opt/libomp
        else
            BREW_LIBOMP_PATH := /usr/local/opt/libomp
        endif
        
        ifeq ($(shell [ -d $(BREW_LIBOMP_PATH) ] && echo 1 || echo 0),1)
            # Use brew libomp with explicit linking (GitHub Actions)
            # Don't use -fopenmp flag; instead explicitly link with -lomp
            CFLAGS_CPU=-L$(BREW_LIBOMP_PATH)/lib -I$(BREW_LIBOMP_PATH)/include -fPIC -ftree-vectorize -march=native -std=c99
            LDFLAGS_CPU=-L$(BREW_LIBOMP_PATH)/lib -lomp -shared
        else
            # Fall back to system OpenMP
            CFLAGS_CPU=-fopenmp -fPIC -ftree-vectorize -march=native -std=c99
            LDFLAGS_CPU=-shared
        endif
    endif
else
    # Linux and Unix-like systems
    CFLAGS_CPU=-fopenmp -fPIC -ftree-vectorize -march=native -std=c99
    LDFLAGS_CPU=-shared
endif

# -----------------------------------------------
#              GPU FLAGS
# -----------------------------------------------
COPTIMFLAGS_GPU=-O3
CFLAGS_GPU=-Xcompiler "-fopenmp -fPIC -march=native -ftree-vectorize" -Xlinker -lgomp
ARCHFLAG=-gencode arch=compute_70,code=sm_70\
         -gencode arch=compute_75,code=sm_75\
         -gencode arch=compute_80,code=sm_80

LDFLAGS_GPU=--shared

# build for python
$(libdir)/beamform_cpu.so: $(srcdir)/beamform.c
	$(CC) $(COPTIMFLAGS_CPU) $(CFLAGS_CPU) $(LDFLAGS_CPU) $< -o $@

$(libdir)/beamform_gpu.so: $(srcdir)/beamform.cu
	$(NVCC) $(COPTIMFLAGS_GPU) $(CFLAGS_GPU) $(ARCHFLAG) $(LDFLAGS_GPU) $< -o $@

clean:
	rm -f $(libdir)/*.so

