GSL linkage on Windows

廉价感情. 提交于 2021-01-07 03:09:38

问题


I am trying to compile examples from GSL documentation. Windows, Cmake + MSVS + GSL 2.6 installed under conda.

Basic example gets compiled and works just fine:

cmake_minimum_required(VERSION 3.15)
project(test)

find_package(GSL REQUIRED)

add_executable(test)
target_sources(test PRIVATE main.cpp)
target_include_directories(test PRIVATE "${GSL_INCLUDE_DIRS}")
target_link_libraries(test "${GSL_LIBRARIES}")
#include <stdio.h>
#include <gsl/gsl_sf_bessel.h>

int main (void)
{
    double x = 5.0;
    double y = gsl_sf_bessel_J0 (x);
    printf ("J0(%g) = %.18e\n", x, y);
    return 0;
}

But this one fails with a linkage error:

error LNK2001: unresolved external symbol gsl_odeiv2_step_rk8pd

#include <stdio.h>
#include <gsl/gsl_errno.h>
#include <gsl/gsl_matrix.h>
#include <gsl/gsl_odeiv2.h>

int
func (double t, const double y[], double f[],
      void *params)
{
    (void)(t); /* avoid unused parameter warning */
    double mu = *(double *)params;
    f[0] = y[1];
    f[1] = -y[0] - mu*y[1]*(y[0]*y[0] - 1);
    return GSL_SUCCESS;
}

int
jac (double t, const double y[], double *dfdy,
     double dfdt[], void *params)
{
    (void)(t); /* avoid unused parameter warning */
    double mu = *(double *)params;
    gsl_matrix_view dfdy_mat
            = gsl_matrix_view_array (dfdy, 2, 2);
    gsl_matrix * m = &dfdy_mat.matrix;
    gsl_matrix_set (m, 0, 0, 0.0);
    gsl_matrix_set (m, 0, 1, 1.0);
    gsl_matrix_set (m, 1, 0, -2.0*mu*y[0]*y[1] - 1.0);
    gsl_matrix_set (m, 1, 1, -mu*(y[0]*y[0] - 1.0));
    dfdt[0] = 0.0;
    dfdt[1] = 0.0;
    return GSL_SUCCESS;
}

int
main (void)
{
    double mu = 10;
    gsl_odeiv2_system sys = {func, jac, 2, &mu};

    gsl_odeiv2_driver * d =
            gsl_odeiv2_driver_alloc_y_new (&sys, gsl_odeiv2_step_rk8pd,
                                           1e-6, 1e-6, 0.0);
    int i;
    double t = 0.0, t1 = 100.0;
    double y[2] = { 1.0, 0.0 };

    for (i = 1; i <= 100; i++)
    {
        double ti = i * t1 / 100.0;
        int status = gsl_odeiv2_driver_apply (d, &t, ti, y);

        if (status != GSL_SUCCESS)
        {
            printf ("error, return value=%d\n", status);
            break;
        }

        printf ("%.5e %.5e %.5e\n", t, y[0], y[1]);
    }

    gsl_odeiv2_driver_free (d);
    return 0;
}

gsl_odeiv2_step_rk8pd is defined somewhere in GSL like this: GSL_VAR const gsl_odeiv2_step_type *gsl_odeiv2_step_rk8pd;, where GSL_VAR means extern.

What am I missing?


回答1:


Binary compatibility of the GSL and your application must be the same: only Win64 buld GSL library project can be used with Win64 your application (or Win32 GSL library with Win32 application, respectively), also build your project and GSL in one mode (Debug/Release) and one compiler.




回答2:


you need re-compile the gsl source codes using vcpkg . vcpkg can compile gsl automatically with CMake. Please google vcpkg. it is very easy and no mistakes.



来源:https://stackoverflow.com/questions/59438874/gsl-linkage-on-windows

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!