Skip to content

Commit

Permalink
Merge pull request #10972 from rouault/embedded_resources
Browse files Browse the repository at this point in the history
RFC102 implementation: embedded resources
  • Loading branch information
rouault authored Oct 29, 2024
2 parents 1fd36d7 + a5fde40 commit b4a3fde
Show file tree
Hide file tree
Showing 90 changed files with 2,387 additions and 1,189 deletions.
10 changes: 10 additions & 0 deletions .github/workflows/fedora_rawhide/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,17 @@ cmake ${GDAL_SOURCE_DIR:=..} \
-DCMAKE_CXX_FLAGS="-std=c++20 -Werror -O1 -D_FORTIFY_SOURCE=2" \
-DCMAKE_SHARED_LINKER_FLAGS="-lstdc++" \
-DUSE_CCACHE=ON \
-DEMBED_RESOURCE_FILES=ON \
-DCMAKE_INSTALL_PREFIX=/usr \
-DWERROR_DEV_FLAG="-Werror=dev"
make -j$(nproc)
make -j$(nproc) install DESTDIR=/tmp/install-gdal

ctest -V -j $(nproc)

rm -rf data
cmake ${GDAL_SOURCE_DIR:=..} \
-DUSE_ONLY_EMBEDDED_RESOURCE_FILES=ON
rm -rf /tmp/install-gdal
make -j$(nproc)
make -j$(nproc) install DESTDIR=/tmp/install-gdal
15 changes: 14 additions & 1 deletion .github/workflows/linux_build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -264,18 +264,31 @@ jobs:
# FIXME the default BUILD_CMD here isn't working...we get an error
# about the quotes not matching.
- name: Build
env:
TRAVIS: yes
TRAVIS_BRANCH: ${{ matrix.travis_branch }}
BUILD_NAME: ${{ matrix.travis_branch }}
run: |
if test -f ".github/workflows/${{ matrix.id }}/${{ matrix.build_script }}"; then
BUILD_CMD="$(pwd)/.github/workflows/${{ matrix.id }}/${{ matrix.build_script }}"
else
BUILD_CMD="sh -c 'cmake .. && make -j$(nproc)'"
fi
# For cache
mkdir -p .gdal
mkdir -p build-${{ matrix.id }}
docker run --name gdal-build \
--rm \
-e CI \
-e GITHUB_WORKFLOW \
-e TRAVIS \
-e TRAVIS_BRANCH \
-e BUILD_NAME \
-e "GDAL_SOURCE_DIR=$(pwd)" \
-u $(id -u ${USER}):$(id -g ${USER}) \
-v $(pwd)/.gdal:/.gdal:rw \
-v $(pwd):$(pwd):rw \
-v ${{ github.workspace }}/.ccache:/.ccache:rw \
--workdir $(pwd)/build-${{ matrix.id }} \
Expand Down Expand Up @@ -322,7 +335,7 @@ jobs:
fi
# For cache
mkdir .gdal
mkdir -p .gdal
docker run \
-e CI \
Expand Down
25 changes: 14 additions & 11 deletions autotest/gcore/basic_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,17 +176,20 @@ def test_basic_test_8():
license_text.startswith("GDAL/OGR is released under the MIT license")
or "GDAL/OGR Licensing" in license_text
)

# Use a subprocess to avoid the cached license text
env = os.environ.copy()
env["GDAL_DATA"] = "tmp"
with open("tmp/LICENSE.TXT", "wt") as f:
f.write("fake_license")
license_text = subprocess.check_output(
[sys.executable, "basic_test_subprocess.py"], env=env
).decode("utf-8")
os.unlink("tmp/LICENSE.TXT")
assert license_text.startswith("fake_license")
if "EMBED_RESOURCE_FILES=YES" in gdal.VersionInfo("BUILD_INFO"):
assert len(license_text) > 1000

if "USE_ONLY_EMBEDDED_RESOURCE_FILES=YES" not in gdal.VersionInfo("BUILD_INFO"):
# Use a subprocess to avoid the cached license text
env = os.environ.copy()
env["GDAL_DATA"] = "tmp"
with open("tmp/LICENSE.TXT", "wt") as f:
f.write("fake_license")
license_text = subprocess.check_output(
[sys.executable, "basic_test_subprocess.py"], env=env
).decode("utf-8")
os.unlink("tmp/LICENSE.TXT")
assert license_text.startswith("fake_license")


###############################################################################
Expand Down
7 changes: 7 additions & 0 deletions autotest/ogr/ogr_osm.py
Original file line number Diff line number Diff line change
Expand Up @@ -921,6 +921,13 @@ def test_ogr_osm_tags_json_special_characters():

def test_ogr_osmconf_ini():

if "EMBED_RESOURCE_FILES=YES" in gdal.VersionInfo(
"BUILD_INFO"
) or "USE_ONLY_EMBEDDED_RESOURCE_FILES=YES" in gdal.VersionInfo("BUILD_INFO"):
pytest.skip(
"Test cannot work with EMBED_RESOURCE_FILES=YES/USE_ONLY_EMBEDDED_RESOURCE_FILES=YES"
)

import configparser

with ogr.Open("data/osm/test_json.pbf") as ds:
Expand Down
6 changes: 3 additions & 3 deletions autotest/ogr/ogr_sxf.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,11 @@ def test_ogr_sxf_2():
# Open SXF datasource with custom RSC file.


def test_ogr_sxf_3():
def test_ogr_sxf_3(tmp_path):

lyr_names = ["SYSTEM", "Not_Classified"]
sxf_name = "tmp/test_ogr_sxf_3.sxf"
rsc_name = "tmp/test_ogr_sxf_3.rsc"
sxf_name = str(tmp_path / "test_ogr_sxf_3.sxf")
rsc_name = str(tmp_path / "test_ogr_sxf_3.rsc")
fake_rsc = open(rsc_name, "w")
fake_rsc.close()
shutil.copy("data/sxf/100_test.sxf", sxf_name)
Expand Down
13 changes: 13 additions & 0 deletions cmake/helpers/GdalDriverHelper.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -559,3 +559,16 @@ macro(ogr_default_driver name desc)
add_feature_info(ogr_${key} OGR_ENABLE_DRIVER_${key} "${desc}")
add_subdirectory(${name})
endmacro()

function(add_driver_embedded_resources driver_target is_plugin_var c_filename)
add_library(${driver_target}_resources OBJECT ${c_filename})
gdal_standard_includes(${driver_target}_resources)
set_property(TARGET ${driver_target}_resources PROPERTY POSITION_INDEPENDENT_CODE ${GDAL_OBJECT_LIBRARIES_POSITION_INDEPENDENT_CODE})
target_compile_definitions(${driver_target} PRIVATE EMBED_RESOURCE_FILES)
set_target_properties(${driver_target}_resources PROPERTIES C_STANDARD 23)
if (${${is_plugin_var}})
target_sources(${driver_target} PRIVATE $<TARGET_OBJECTS:${driver_target}_resources>)
else()
target_sources(${GDAL_LIB_TARGET_NAME} PRIVATE $<TARGET_OBJECTS:${driver_target}_resources>)
endif()
endfunction()
30 changes: 30 additions & 0 deletions doc/source/development/building_from_source.rst
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,36 @@ All cached entries can be viewed using ``cmake -LAH`` from a build directory.
`CMAKE_SKIP_INSTALL_RPATH <https://cmake.org/cmake/help/latest/variable/CMAKE_SKIP_INSTALL_RPATH.html>`__
variable is not set.

Resource files embedding
++++++++++++++++++++++++

Starting with GDAL 3.11, if a C23-compatible compiler is used, such as
clang >= 19 or GCC >= 15, it is possible to embed resource files inside
the GDAL library, without relying on resource files to be available on the file
system (such resource files are located through an hard-coded
path at build time in ``${CMAKE_INSTALL_PREFIX}/share/gdal``, or at run-time
through the :config:`GDAL_DATA` configuration option).

The following CMake options control that behavior:

.. option:: EMBED_RESOURCE_FILES=ON/OFF

.. versionadded:: 3.11

Default is OFF for shared library builds (BUILD_SHARED_LIBS=ON), and ON
for static library builds (BUILD_SHARED_LIBS=OFF).
When ON, resource files needed by GDAL will be embedded into the GDAL library
and/or relevant plugins.

.. option:: USE_ONLY_EMBEDDED_RESOURCE_FILES=ON/OFF

.. versionadded:: 3.11

Even if EMBED_RESOURCE_FILES=ON, GDAL will still try to locate resource
files on the file system by default , and fallback to the embedded version if
not found. By setting USE_ONLY_EMBEDDED_RESOURCE_FILES=ON, no attempt
at locating resource files on the file system is made. Default is OFF.

CMake package dependent options
+++++++++++++++++++++++++++++++

Expand Down
1 change: 1 addition & 0 deletions doc/source/spelling_wordlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,7 @@ cid
CInt
circularstrings
ClampRequests
clang
ClassificationCode
Clayers
CleanTimeout
Expand Down
151 changes: 80 additions & 71 deletions frmts/grib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -59,77 +59,86 @@ endif()

gdal_standard_includes(gdal_GRIB)

set(GDAL_DATA_FILES
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_versions.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_center.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_process.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_subcenter.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_0_0.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_0_13.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_0_14.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_0_15.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_0_16.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_0_17.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_0_18.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_0_190.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_0_191.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_0_19.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_0_1.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_0_20.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_0_21.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_0_2.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_0_3.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_0_4.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_0_5.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_0_6.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_0_7.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_10_0.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_10_191.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_10_1.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_10_2.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_10_3.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_10_4.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_1_0.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_1_1.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_1_2.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_20_0.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_20_1.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_20_2.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_2_0.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_2_3.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_2_4.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_2_5.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_2_6.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_3_0.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_3_1.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_3_2.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_3_3.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_3_4.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_3_5.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_3_6.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_4_0.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_4_10.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_4_1.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_4_2.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_4_3.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_4_4.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_4_5.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_4_6.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_4_7.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_4_8.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_4_9.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_local_Canada.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_local_HPC.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_local_index.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_local_MRMS.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_local_NCEP.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_local_NDFD.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_5.csv
)
set_property(
TARGET ${GDAL_LIB_TARGET_NAME}
APPEND
PROPERTY RESOURCE "${GDAL_DATA_FILES}")
if (NOT USE_ONLY_EMBEDDED_RESOURCE_FILES)
set(GDAL_DATA_FILES
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_versions.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_center.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_process.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_subcenter.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_0_0.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_0_13.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_0_14.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_0_15.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_0_16.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_0_17.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_0_18.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_0_190.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_0_191.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_0_19.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_0_1.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_0_20.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_0_21.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_0_2.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_0_3.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_0_4.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_0_5.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_0_6.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_0_7.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_10_0.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_10_191.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_10_1.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_10_2.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_10_3.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_10_4.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_1_0.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_1_1.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_1_2.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_20_0.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_20_1.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_20_2.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_2_0.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_2_3.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_2_4.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_2_5.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_2_6.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_3_0.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_3_1.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_3_2.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_3_3.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_3_4.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_3_5.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_3_6.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_4_0.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_4_10.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_4_1.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_4_2.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_4_3.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_4_4.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_4_5.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_4_6.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_4_7.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_4_8.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_4_9.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_local_Canada.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_local_HPC.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_local_index.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_local_MRMS.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_local_NCEP.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_2_local_NDFD.csv
${CMAKE_CURRENT_SOURCE_DIR}/data/grib2_table_4_5.csv
)
set_property(
TARGET ${GDAL_LIB_TARGET_NAME}
APPEND
PROPERTY RESOURCE "${GDAL_DATA_FILES}")
endif()

if (EMBED_RESOURCE_FILES)
add_driver_embedded_resources(gdal_GRIB GDAL_ENABLE_DRIVER_GRIB_PLUGIN degrib/degrib/embedded_resources.c)
endif()
if (USE_ONLY_EMBEDDED_RESOURCE_FILES)
target_compile_definitions(gdal_GRIB PRIVATE USE_ONLY_EMBEDDED_RESOURCE_FILES)
endif()

target_include_directories(
gdal_GRIB PRIVATE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/degrib/degrib>
Expand Down
23 changes: 23 additions & 0 deletions frmts/grib/degrib/degrib/embedded_resources.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// SPDX-License-Identifier: MIT
// Copyright 2024, Even Rouault <even.rouault at spatialys.com>

#include "embedded_resources.h"

#include "embedded_resources_gen1.c"

const char *GRIBGetCSVFileContent(const char* pszFilename)
{
static const struct
{
const char* pszFilename;
const char* pszContent;
} asResources[] = {
#include "embedded_resources_gen2.c"
};
for( size_t i = 0; i < sizeof(asResources) / sizeof(asResources[0]); ++i )
{
if( strcmp(pszFilename, asResources[i].pszFilename) == 0 )
return asResources[i].pszContent;
}
return NULL;
}
10 changes: 10 additions & 0 deletions frmts/grib/degrib/degrib/embedded_resources.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// SPDX-License-Identifier: MIT
// Copyright 2024, Even Rouault <even.rouault at spatialys.com>

#include "cpl_port.h"

CPL_C_START

const char *GRIBGetCSVFileContent(const char* pszFilename);

CPL_C_END
Loading

0 comments on commit b4a3fde

Please sign in to comment.