Skip to content

Commit

Permalink
Merge pull request #316 from AlysonStahl-NOAA/as_build
Browse files Browse the repository at this point in the history
Fix library build issues and test on MacOS
  • Loading branch information
AlysonStahl-NOAA authored Feb 18, 2025
2 parents 5f6e3b9 + c105812 commit 84c2364
Show file tree
Hide file tree
Showing 5 changed files with 168 additions and 85 deletions.
69 changes: 69 additions & 0 deletions .github/workflows/MacOS.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# This is a GitHub actions workflow for wgrib2.
#
# This builds the develop branch on MacOS.
#
# Alyson Stahl, 2/11/2025
name: MacOS
on:
push:
branches:
- develop
pull_request:
branches:
- develop

# Cancel in-progress workflows when pushing to a branch
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
MacOS:
runs-on: macos-latest
env:
FC: gfortran-12
strategy:
fail-fast: false
matrix:
ccompiler: [gcc, clang]
sharedlib: [ON, OFF]
jasper: [ON, OFF]
openjpeg: [ON, OFF]
exclude:
- jasper: ON
openjpeg: ON
- jasper: OFF
openjpeg: OFF

steps:
- name: install-dependencies
run: |
find /Library/Frameworks/ -name "png*"
sudo rm -rf /Library/Frameworks/Mono.framework
brew install jasper libpng jpeg-turbo openjpeg libaec libomp
- name: "Build dependencies"
uses: NOAA-EMC/ci-build-nceplibs@develop
with:
g2c-version: develop
g2c-cmake-args: -DUSE_OpenJPEG=${{matrix.openjpeg}} -DUSE_Jasper=${{matrix.jasper}}
ip-version: develop

- name: checkout
uses: actions/checkout@v4
with:
path: wgrib2

- name: build
run: |
cd wgrib2
mkdir build
cd build
#export CFLAGS='-I/Users/runner/work/wgrib2/wgrib2/nceplibs/NCEPLIBS-g2c/include'
cmake -DCMAKE_PREFIX_PATH="$GITHUB_WORKSPACE/nceplibs/jasper;$GITHUB_WORKSPACE/nceplibs/NCEPLIBS-g2c;$GITHUB_WORKSPACE/nceplibs/NCEPLIBS-ip" .. -DUSE_AEC=ON -DUSE_PNG=ON -DUSE_JASPER=${{matrix.jasper}} -DUSE_OPENJPEG=${{matrix.openjpeg}} -DBUILD_SHARED_LIB=${{matrix.sharedlib}} -DMAKE_FTN_API=ON
make VERBOSE=1
- name: test
run: |
cd $GITHUB_WORKSPACE/wgrib2/build
ctest --verbose --output-on-failure --rerun-failed
96 changes: 44 additions & 52 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This is the main CMake build file for the wgrib2 project.
#
# Kyle Gerheiser, Edward Hartnett, Wesley Ebisuzaki
# Kyle Gerheiser, Edward Hartnett, Wesley Ebisuzaki, Alyson Stahl
cmake_minimum_required(VERSION 3.15)

# Read the current version number from file VERSION.
Expand All @@ -9,6 +9,12 @@ file(STRINGS "VERSION" pVersion)
# Set up project with version number from VERSION file.
project(wgrib2 VERSION ${pVersion} LANGUAGES C)

# Provide install directories according to GNU standards.
include(GNUInstallDirs)

# Find CMake code we need.
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")

# Handle user build options.
option(ENABLE_DOCS "Enable generation of doxygen-based documentation." OFF)
option(USE_NETCDF "Use NetCDF" off)
Expand Down Expand Up @@ -54,86 +60,56 @@ endif()
SET(TEST_FILE_DIR "." CACHE STRING "Check this directory for test files before using FTP.")
message(STATUS "Finding test data files in directory ${TEST_FILE_DIR}.")

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")

# Set default install path if not provided.
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(CMAKE_INSTALL_PREFIX
"${CMAKE_BINARY_DIR}/install"
CACHE PATH "default install path" FORCE)
endif()

include(GNUInstallDirs)

message(STATUS "Setting compiler flags...")
if(CMAKE_C_COMPILER_ID MATCHES "^(Intel|IntelLLVM)$")
set(CMAKE_C_FLAGS "-g -traceback ${CMAKE_C_FLAGS} -DIFORT")
if(CMAKE_C_COMPILER_ID MATCHES "^(IntelLLVM)$")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Rno-debug-disables-optimization")
endif()
set(CMAKE_C_FLAGS_DEBUG "-O0")
elseif(CMAKE_C_COMPILER_ID MATCHES "^(GNU)$")
set(CMAKE_C_FLAGS "-g ${CMAKE_C_FLAGS} -DGFORTRAN")
set(CMAKE_C_FLAGS_DEBUG "-O0")
endif()

if(CMAKE_Fortran_COMPILER_ID MATCHES "^(Intel|IntelLLVM)$")
set(CMAKE_Fortran_FLAGS "-g -traceback ${CMAKE_Fortran_FLAGS}")
set(CMAKE_Fortran_FLAGS_DEBUG "-O0")
elseif(CMAKE_Fortran_COMPILER_ID MATCHES "^(GNU)$")
set(CMAKE_Fortran_FLAGS "-g -fbacktrace ${CMAKE_Fortran_FLAGS}")
set(CMAKE_Fortran_FLAGS_DEBUG "-ggdb -O0")
endif()

message(STATUS "Checking if user wants to use NCEPLIBS-g2c...")
if(USE_G2CLIB)
if(USE_PNG)
message(FATAL_ERROR "If USE_G2CLIB is on, USE_PNG must be off")
endif()
if(USE_OPENJPEG AND USE_JASPER)
message(FATAL_ERROR "USE_OPENJPEG OR USE_JASPER, not both")
endif()

if (BUILD_SHARED_LIB AND NOT BUILD_LIB)
message(FATAL_ERROR "BUILD_SHARED_LIB is on but BUILD_LIB is off")
endif()

if(MAKE_FTN_API AND NOT BUILD_LIB)
message(FATAL_ERROR "MAKE_FTN_API should only be on when building library")
endif()

# If user wants to use NCEPLIBS-ip, find it and the sp library.
message(STATUS "Checking if the user want to use NCEPLIBS-ip...")
if(USE_IPOLATES)
find_package(ip 5.1.0 CONFIG REQUIRED)
list(APPEND definitions_list -DIPOLATES_LIB="ipolates_lib_d")
# list(APPEND definitions_list -DUSE_IPOLATES)
endif()

message(STATUS "Checking if the user want to use NetCDF...")
if(USE_NETCDF)
find_package(NetCDF MODULE REQUIRED COMPONENTS C)
endif()

if(USE_OPENJPEG AND USE_JASPER)
message(FATAL_ERROR "USE_OPENJPEG OR USE_JASPER, not both")
endif()

message(STATUS "Checking if the user wants to use Jasper...")
if(USE_JASPER)
find_package(g2c 1.9.0 CONFIG REQUIRED)
endif()

# Find required packages to use OpenJPEG
message(STATUS "Checking if the user wants to use OpenJPEG...")
if(USE_OPENJPEG)
if(USE_JASPER OR USE_OPENJPEG OR USE_PNG)
find_package(g2c 1.9.0 CONFIG REQUIRED)
message(STATUS "Checking if the user wants to use Jasper or OpenJPEG...")
if(USE_JASPER)
find_package(Jasper 2.0.25 REQUIRED)
elseif(USE_OPENJPEG)
find_package(OpenJPEG REQUIRED)
endif()
message(STATUS "Checking if the user wants to use PNG...")
if(USE_PNG)
find_package(PNG REQUIRED)
endif()
endif()

message(STATUS "Checking if the user want to use OpenMP...")
if(USE_OPENMP)
find_package(OpenMP REQUIRED COMPONENTS C)
endif()

message(STATUS "Checking if the user wants to use PNG...")
if(USE_PNG)
find_package(g2c 1.9.0 CONFIG REQUIRED)
endif()

# Find required packages to use AEC
message(STATUS "Checking if the user wants to use AEC...")
if(USE_AEC)
Expand All @@ -149,10 +125,6 @@ message(STATUS "Adding wgrib2, aux_probs subdirectories...")
add_subdirectory(wgrib2)
add_subdirectory(aux_progs)

if(MAKE_FTN_API AND NOT BUILD_LIB)
message(FATAL_ERROR "MAKE_FTN_API should only be on when building library")
endif()

if(BUILD_LIB)
message(STATUS "Adding wgrib2 library build...")
### Package config
Expand Down Expand Up @@ -187,6 +159,26 @@ if (BUILD_WGRIB)
add_subdirectory(wgrib)
endif()

message(STATUS "Setting compiler flags...")
if(CMAKE_C_COMPILER_ID MATCHES "^(Intel|IntelLLVM)$")
set(CMAKE_C_FLAGS "-g -traceback ${CMAKE_C_FLAGS} -DIFORT")
if(CMAKE_C_COMPILER_ID MATCHES "^(IntelLLVM)$")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Rno-debug-disables-optimization")
endif()
set(CMAKE_C_FLAGS_DEBUG "-O0")
elseif(CMAKE_C_COMPILER_ID MATCHES "^(GNU|Clang|AppleClang)$")
set(CMAKE_C_FLAGS "-g ${CMAKE_C_FLAGS} -DGFORTRAN")
set(CMAKE_C_FLAGS_DEBUG "-O0")
endif()

if(CMAKE_Fortran_COMPILER_ID MATCHES "^(Intel|IntelLLVM)$")
set(CMAKE_Fortran_FLAGS "-g -traceback ${CMAKE_Fortran_FLAGS}")
set(CMAKE_Fortran_FLAGS_DEBUG "-O0")
elseif(CMAKE_C_COMPILER_ID MATCHES "^(GNU|Clang|AppleClang)$")
set(CMAKE_Fortran_FLAGS "-g -fbacktrace ${CMAKE_Fortran_FLAGS}")
set(CMAKE_Fortran_FLAGS_DEBUG "-ggdb -O0")
endif()

# Turn on unit testing.
include(CTest)
if(BUILD_TESTING)
Expand Down
2 changes: 1 addition & 1 deletion tests/test_lib.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
echo "see if shared library made"
set -xe

if [ ! -f ../wgrib2/libwgrib2.so -a ! -f ../wgrib2/libwgrib2.a ] ; then
if [[ ! -f ../wgrib2/libwgrib2.so && ! -f ../wgrib2/libwgrib2.a && ! -f ../wgrib2/libwgrib2.dylib ]]; then
echo "failed: did not find libwgrib2"
exit 1
fi
Expand Down
4 changes: 2 additions & 2 deletions tests/test_shared_lib.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
echo "see if shared library made"
set -xe

if [ ! -f ../wgrib2/libwgrib2.so ] ; then
echo "failed: did not find libwgrib2.so"
if [[ ! -f ../wgrib2/libwgrib2.so && ! -f ../wgrib2/libwgrib2.dylib ]]; then
echo "failed: did not find shared library"
exit 1
fi

Expand Down
82 changes: 52 additions & 30 deletions wgrib2/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,6 @@ if(MAKE_FTN_API)
endif()

# make this an object lib so we can re-use most of object files
# The only files that differ are ${callable_src} which are compiled
# with -DCALLABLE_WGRIB2
add_library(obj_lib OBJECT ${lib_src})
target_compile_definitions(obj_lib PUBLIC ${definitions_list})

Expand All @@ -79,72 +77,96 @@ configure_file (
"${PROJECT_BINARY_DIR}/wgrib2/wgrib2_meta.h"
)

if(BUILD_LIB)
add_executable(wgrib2_exe wgrib2_main.c)
set_target_properties(wgrib2_exe PROPERTIES OUTPUT_NAME wgrib2)

if(BUILD_LIB)
if(BUILD_SHARED_LIB)
add_library(wgrib2_lib SHARED ${lib_src} )
add_library(wgrib2_lib SHARED ${lib_src})
set_property(TARGET wgrib2_lib PROPERTY POSITION_INDEPENDENT_CODE ON)
else()
add_library(wgrib2_lib STATIC ${lib_src} $<TARGET_OBJECTS:gctpc> )
# add_library(wgrib2_lib STATIC ${lib_src} )
add_library(wgrib2_lib STATIC ${lib_src} $<TARGET_OBJECTS:gctpc>)
set_property(TARGET wgrib2_lib PROPERTY POSITION_INDEPENDENT_CODE ON)
endif()

# library and executable have same name (wgrib2) but different target names
set_target_properties(wgrib2_lib PROPERTIES OUTPUT_NAME wgrib2)
# target_compile_definitions(wgrib2_lib PRIVATE CALLABLE_WGRIB2)
endif()


add_executable(wgrib2_exe wgrib2_main.c)
set_target_properties(wgrib2_exe PROPERTIES OUTPUT_NAME wgrib2)

if(USE_NETCDF)
target_link_libraries(obj_lib PUBLIC NetCDF::NetCDF_C)
if(BUILD_SHARED_LIB)
target_link_libraries(wgrib2_exe PRIVATE NetCDF::NetCDF_C)
if(BUILD_LIB)
target_link_libraries(wgrib2_lib PUBLIC NetCDF::NetCDF_C)
endif()
target_link_libraries(wgrib2_exe PUBLIC NetCDF::NetCDF_C)
endif()

if(USE_OPENMP)
target_link_libraries(obj_lib PUBLIC OpenMP::OpenMP_C)
if(BUILD_SHARED_LIB)
target_link_libraries(wgrib2_exe PRIVATE OpenMP::OpenMP_C)
if(BUILD_LIB)
target_link_libraries(wgrib2_lib PUBLIC OpenMP::OpenMP_C)
endif()
endif()

if(USE_IPOLATES)
target_link_libraries(obj_lib PUBLIC ip::ip_d)
target_link_libraries(wgrib2_exe PUBLIC ip::ip_d)

# Link to the Fortran runtime library for each compiler if using ip2.
# The wgrib2 exectuable is created using the C compiler and
# doesn't link the necessary Fortran library required for ip2.
if(CMAKE_Fortran_COMPILER_ID MATCHES "^(Intel)$")
target_link_libraries(wgrib2_exe PRIVATE "-lifcore")
elseif(CMAKE_Fortran_COMPILER_ID MATCHES "^(GNU)$")
target_link_libraries(wgrib2_exe PRIVATE "-lgfortran")
target_link_libraries(wgrib2_exe PRIVATE ip::ip_d)
if(BUILD_LIB)
target_link_libraries(wgrib2_lib PUBLIC ip::ip_d)
endif()

endif()

## target_link_libraries(obj_lib PUBLIC gctpc -lm)

# Link to gctpc directly because object libraries do not link transitively
target_link_libraries(wgrib2_exe PRIVATE gctpc -lm)

if(USE_AEC)
target_link_libraries(obj_lib PUBLIC ${LIBAEC_LIBRARIES})
target_include_directories(obj_lib PUBLIC "${LIBAEC_INCLUDE_DIRS}")
target_link_libraries(wgrib2_exe PRIVATE ${LIBAEC_LIBRARIES})
target_include_directories(wgrib2_exe PRIVATE "${LIBAEC_INCLUDE_DIRS}")
if(BUILD_LIB)
target_link_libraries(wgrib2_lib PUBLIC ${LIBAEC_LIBRARIES})
target_include_directories(wgrib2_lib PUBLIC "${LIBAEC_INCLUDE_DIRS}")
endif()
endif()

if(USE_JASPER OR USE_OPENJPEG OR USE_PNG)
target_link_libraries(obj_lib PUBLIC g2c::g2c)
target_link_libraries(wgrib2_exe PRIVATE g2c::g2c)
if(BUILD_LIB)
target_link_libraries(wgrib2_lib PUBLIC g2c::g2c)
endif()
endif()

if(USE_JASPER)
target_link_libraries(obj_lib PUBLIC ${JASPER_LIBRARIES})
target_include_directories(obj_lib PUBLIC "${JASPER_INCLUDE_DIR}")
target_link_libraries(wgrib2_exe PRIVATE ${JASPER_LIBRARIES})
target_include_directories(wgrib2_exe PRIVATE "${JASPER_INCLUDE_DIR}")
if(BUILD_LIB)
target_link_libraries(wgrib2_lib PUBLIC ${JASPER_LIBRARIES})
target_include_directories(wgrib2_lib PUBLIC "${JASPER_INCLUDE_DIR}")
endif()
elseif(USE_OPENJPEG)
target_link_libraries(obj_lib PUBLIC ${OpenJPEG_LIBRARIES})
target_link_libraries(wgrib2_exe PRIVATE ${OpenJPEG_LIBRARIES})
if(BUILD_LIB)
target_link_libraries(wgrib2_lib PUBLIC ${OpenJPEG_LIBRARIES})
endif()
endif()

if(USE_PNG)
target_link_libraries(obj_lib PUBLIC ${PNG_LIBRARIES})
target_include_directories(obj_lib PUBLIC "${PNG_INCLUDE_DIRS}")
target_link_libraries(wgrib2_exe PRIVATE ${PNG_LIBRARIES})
target_include_directories(wgrib2_exe PRIVATE "${PNG_INCLUDE_DIRS}")
if(BUILD_LIB)
target_link_libraries(wgrib2_lib PUBLIC ${PNG_LIBRARIES})
target_include_directories(wgrib2_lib PUBLIC "${PNG_INCLUDE_DIRS}")
endif()
endif()

# Link to gctpc directly because object libraries do not link transitively
target_link_libraries(wgrib2_exe PRIVATE gctpc -lm)
target_link_libraries(wgrib2_exe PRIVATE obj_lib)
# target_link_libraries(wgrib2_exe PRIVATE wgrib2_lib)

if(BUILD_LIB)
set(headers wgrib2_api.h wgrib2.h ${CMAKE_BINARY_DIR}/wgrib2/wgrib2_meta.h)
Expand Down

0 comments on commit 84c2364

Please sign in to comment.