윈도우 용 Gnuplot 빌드해보기

2024. 2. 1. 01:15프로그래밍

728x90

비주얼 스튜디오 2019 커뮤니티 버전을 받았습니다.

그리고 Gnuplot 빌드를 도전해 보기로 합니다.

우선 소스를 다음 사이트에서 받았습니다.

 

 

gnuplot

Download gnuplot for free. A portable, multi-platform, command-line driven graphing utility. A famous scientific plotting package, features include 2D and 3D plotting, a huge number of output formats, interactive input or script-driven options, and a large

sourceforge.net

저는 포터블을 받았습니다.

마지막으로 gnuplot git 사이트에서 현재 버전을 다음과 같이 다운로드 받습니다.

git clone https://github.com/gnuplot/gnuplot.git
 

그리고 나서, .git 폴더를 다음과 같이 옮겨 주었습니다.

 

현재 버전은 오류가 납니다. 수정 버전인 파일을

post.trm
0.16MB

아래 위치에 복사해 넣어 줍니다.

~\gnuplot-6.0.0\term
 

준비과정을 끝난 것 같으니, cmd 창을 열고서 다음 디렉토리를 검색 해 봅시다.

앞서 말했지만 비주얼스튜디오 2019를 설치 했습니다(커뮤니티버전)

dir "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\"
 

위의 명령을 다음과 같이 실행 해 보면

"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat"
 

다음과 같은 리스트가 나타 날 것입니다.

요즘은 64비트가 대세니 음... 아래서 두번째꺼로

"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat" x64 8.1
 

환경이 좀 안 맞나 보네요.. 그냥 첫번째 걸로 하겠습니다.

 

다 되었으니, 빌드를 수행 해 보도록 하겠습니다.

nmake -f Makefile clean && nmake -f Makefile
 
 

그리고 다시 빌드를 수행 해 봅니다.

마지막 링크 시에 다음과 같은 오류를 만납니다.

filters.obj : error LNK2019: bisect_hitsharpen 함수에서 참조되는 확인할 수 없는 외부 기호
wgnuplot.exe : fatal error LNK1120: 1개의 확인할 수 없는 외부 참조입니다.
NMAKE : fatal error U1077: '"~\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\bin\HostX86\x64\link.EXE"' : '0x460' 반환 코드입니다.
Stop.
 

일단 filters.c 파일에 있는 sharpen 함수를 다음과 같이 처리 해 줄 수 있습니다.

void
sharpen(struct curve_points *plot)
{
    struct axis *y_axis = &axis_array[plot->y_axis];
    int newcount = plot->p_count;
    struct coordinate *p;

    /* Restrictions */
    if (parametric || polar)
	return;

    /* Make more than enough room for new points */
    cp_extend(plot, 1.5 * plot->p_count);
    p = plot->points;

    /* We expect that sharpened peaks may go to +/- Infinity
     * and in fact the plot may already contain such points.
     * Because these were tagged UNDEFINED in store_and_update_range()
     * they will be lost when the points are sorted.
     * As a work-around we look for these and flag them OUTRANGE instead.
     * If there are other UNDEFINED points we set y to 0 so that they
     * do not cause the f'' approximation to blow up.
     */
    for (int i = 0; i < plot->p_count; i++) {
	if (p[i].type == UNDEFINED) {
	    if (p[i].y >= VERYLARGE) {
		p[i].type = OUTRANGE;
		p[i].y = VERYLARGE;
	    } else if (p[i].y <= -VERYLARGE) {
		p[i].type = OUTRANGE;
		p[i].y = -VERYLARGE;
	    } else
		p[i].y = 0;
	}
    }

    /* Look for minima in a sliding window */
    /* This is a very simple test; it may not be sufficient
     *   f(i) is lower than its neighbors
     *   f''(x) is negative on at least one side
     */
    for (int i = 4; i < plot->p_count-4; i++) {
		TBOOLEAN criterion = FALSE;
		criterion = (fpp_SG5(&p[i-2]) < 0 || fpp_SG5(&p[i+2]) < 0);

			if (p[i].y <= p[i-1].y && p[i].y <= p[i+1].y
			&&  p[i].y <= p[i-2].y && p[i].y <= p[i+2].y
			&&  criterion)
			{
				double hit_x = p[i].x;
				double hit_y = p[i].y;
=========> 아래 꺼 주석 처리
				//bisect_hit( plot, BISECT_MINIMIZE, &hit_x, &hit_y, p[i-1].x, p[i+1].x );
				p[newcount] = p[i];	/* copy any other properties */
				p[newcount].x = hit_x;
				p[newcount].y = hit_y;
				/* Use sharpened peak for autoscaling only if it approaches zero,
				 * not if it's heading towards +/- Infinity!
				 */
				if (fabs(hit_y) < 1.e-7 && !y_axis->log)
				autoscale_one_point(y_axis, hit_y);
				if (!inrange(hit_y, y_axis->min, y_axis->max))
				p[newcount].type = OUTRANGE;
				else
				p[newcount].type = INRANGE;
				if (debug)
				FPRINTF((stderr, "\tbisect min [%4g %g]\tto [%4g %4g]\n",
					p[i].x, p[i].y, hit_x, hit_y));
				newcount++;
			}
		}

		/* Equivalent search for maxima */
		for (int i = 4; i < plot->p_count-4; i++) {
			TBOOLEAN criterion = FALSE;
			if (p[i].type == UNDEFINED || p[i-1].type == UNDEFINED || p[i+1].type == UNDEFINED)
				continue;
			criterion = (fpp_SG5(&p[i-2]) > 0 || fpp_SG5(&p[i+2]) > 0);

			if (p[i].y >= p[i-1].y && p[i].y >= p[i+1].y
			&&  p[i].y >= p[i-2].y && p[i].y >= p[i+2].y
			&&  criterion)
			{
				double hit_x = p[i].x;
				double hit_y = p[i].y;
=========> 아래 꺼 주석 처리
				//bisect_hit( plot, BISECT_MAXIMIZE, &hit_x, &hit_y, p[i-1].x, p[i+1].x );
				p[newcount] = p[i];	/* copy any other properties */
				p[newcount].x = hit_x;
				p[newcount].y = hit_y;
				if (fabs(hit_y) < 1.e-7 && !y_axis->log)
				autoscale_one_point(y_axis, hit_y);
				if (!inrange(hit_y, y_axis->min, y_axis->max))
				p[newcount].type = OUTRANGE;
				else
				p[newcount].type = INRANGE;
				if (debug)
				FPRINTF((stderr, "\tbisect max [%4g %g]\tto [%4g %4g]\n",
					p[i].x, p[i].y, hit_x, hit_y));
				newcount++;
			}
    }

    /* Move new points into proper order */
    if (newcount > plot->p_count) {
	plot->p_count = newcount;
		gp_qsort(plot->points, newcount, sizeof(struct coordinate), compare_x);
    }
}
 

아니면 다음과 같이 정의 되지 않을 함수를 넣어 주도록 했습니다.

#define PHIM1 0.618034
#define EPS 3.0E-8
static void
bisect_hit(struct curve_points *plot, t_bisection_target target,
	   double *xhit, double *yhit, double xlow, double xhigh)
{
    double x0, x1, x2, x3;
    double f1, f2;		/* f1 = f(x1),  f2 = f(x2) */
    struct value a;
    TBOOLEAN left;

    double epsilon = (target == BISECT_MATCH) ? EPS : 1.e-14;

    x0 = xlow;
    x3 = xhigh;
    if (fabs(xhigh - *xhit) > fabs(*xhit - xlow)) {
	x1 = *xhit;
	x2 = *xhit + (1.0-PHIM1) * (xhigh - *xhit);
    } else {
	x2 = *xhit;
	x1 = *xhit - (1.0-PHIM1) * (*xhit - xlow);
    }

    Gcomplex( &(plot->plot_function.dummy_values[0]), x1, 0 );
    evaluate_at(plot->plot_function.at, &a);
    f1 = real(&a);
    Gcomplex( &(plot->plot_function.dummy_values[0]), x2, 0 );
    evaluate_at(plot->plot_function.at, &a);
    f2 = real(&a);

    /* Iterate until convergence of estimated xhit */
    while (fabs(x3-x0) > epsilon * (fabs(x1) + fabs(x2))) {

	if (target == BISECT_MINIMIZE)
	    left = (f2 < f1);
	else if (target == BISECT_MAXIMIZE)
	    left = (f2 > f1);
	else /* minimize difference of f(x) from *yhit */
	    left = (fabs(f2 - *yhit) < fabs(f1 - *yhit));

	if (left) {
	    x0 = x1;
	    x1 = x2;
	    x2 = PHIM1*x2 + (1.0-PHIM1)*x3;
	    f1 = f2;
	    Gcomplex( &(plot->plot_function.dummy_values[0]), x2, 0 );
	    evaluate_at(plot->plot_function.at, &a);
	    f2 = real(&a);
	} else {
	    x3 = x2;
	    x2 = x1;
	    x1 = PHIM1*x1 + (1.0-PHIM1)*x0;
	    f2 = f1;
	    Gcomplex( &(plot->plot_function.dummy_values[0]), x1, 0 );
	    evaluate_at(plot->plot_function.at, &a);
	    f1 = real(&a);
	}

	if ((fabs(x1) + fabs(x2)) < epsilon)
	    break;
    }

    /* Update and return hit coordinates */
    if (target == BISECT_MINIMIZE)
	left = (f2 < f1);
    else if (target == BISECT_MAXIMIZE)
	left = (f2 > f1);
    else /* minimize difference of f(x) from *yhit */
	left = (fabs(f2 - *yhit) < fabs(f1 - *yhit));

    if (left) {
	*xhit = x2;
	*yhit = f2;
    } else {
	*xhit = x1;
	*yhit = f1;
    }
}
 

 

빌드가 다 되면 다음과 같이 실행 파일이 생성 된 것을 확인 할 수 있습니다.

 

 

 

버그리포트를 썼는 데.. 고쳐지겠죠?

 

이상.

728x90