I am trying to use the fdlibm library in C to compute sin of a large number. I used the code from this link: http://www.netlib.org/fdlibm/ and downloaded the folder "s_sin.c plus dependencies". When I run the c code in that folder "s_sin.c", I get the following error:
Undefined symbols for architecture x86_64:
"___ieee754_rem_pio2", referenced from:
_sin in s_sin-a92222.o
"___kernel_cos", referenced from:
_sin in s_sin-a92222.o
"___kernel_sin", referenced from:
_sin in s_sin-a92222.o
"_main", referenced from:
implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Any ideas how to fix this error?
Here is the code that I mentioned above:
/* #(#)s_sin.c 1.3 95/01/18 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunSoft, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/* sin(x)
* Return sine function of x.
*
* kernel function:
* __kernel_sin ... sine function on [-pi/4,pi/4]
* __kernel_cos ... cose function on [-pi/4,pi/4]
* __ieee754_rem_pio2 ... argument reduction routine
*
* Method.
* Let S,C and T denote the sin, cos and tan respectively on
* [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
* in [-pi/4 , +pi/4], and let n = k mod 4.
* We have
*
* n sin(x) cos(x) tan(x)
* ----------------------------------------------------------
* 0 S C T
* 1 C -S -1/T
* 2 -S -C T
* 3 -C S -1/T
* ----------------------------------------------------------
*
* Special cases:
* Let trig be any of sin, cos, or tan.
* trig(+-INF) is NaN, with signals;
* trig(NaN) is that NaN;
*
* Accuracy:
* TRIG(x) returns trig(x) nearly rounded
*/
#include "fdlibm.h"
#ifdef __STDC__
double sin(double x)
#else
double sin(x)
double x;
#endif
{
double y[2],z=0.0;
int n, ix;
/* High word of x. */
ix = __HI(x);
/* |x| ~< pi/4 */
ix &= 0x7fffffff;
if(ix <= 0x3fe921fb) return __kernel_sin(x,z,0);
/* sin(Inf or NaN) is NaN */
else if (ix>=0x7ff00000) return x-x;
/* argument reduction needed */
else {
n = __ieee754_rem_pio2(x,y);
switch(n&3) {
case 0: return __kernel_sin(y[0],y[1],1);
case 1: return __kernel_cos(y[0],y[1]);
case 2: return -__kernel_sin(y[0],y[1],1);
default:
return -__kernel_cos(y[0],y[1]);
}
}
}
The problem is you need to build libm.a from the fdlibm files. If you look at readme file it explains:
CONFIGURE
To build FDLIBM, edit the supplied Makefile or create
a local Makefile by running "sh configure"
using the supplied configure script contributed by Nelson Beebe
(note: after downloading all the files and makefile, you can simply type make and it will build libm.a)
This will create libm.a (which you can link with instead of the normal math library). After you build the library, you need only #include "fdlibm.h" in your source file and compile similar to:
gcc -Wall -Wextra -pedantic -std=c11 -Ofast -L./ -o test_s_sin test_s_sin.c -lm
This will compile your code (named test_s_sin.c above) to executable.
The reason you cannot simply build s_sin.c with gcc is if you look in s_sin.c, you will find it depends on a number of additional externally defined functions from fdlibm (which in turn depend on other source file in the library). For example in s_sin.c you have:
/* High word of x. */
ix = __HI(x);
/* |x| ~< pi/4 */
ix &= 0x7fffffff;
if(ix <= 0x3fe921fb) return __kernel_sin(x,z,0);
/* sin(Inf or NaN) is NaN */
else if (ix>=0x7ff00000) return x-x;
/* argument reduction needed */
else {
n = __ieee754_rem_pio2(x,y);
switch(n&3) {
case 0: return __kernel_sin(y[0],y[1],1);
case 1: return __kernel_cos(y[0],y[1]);
case 2: return -__kernel_sin(y[0],y[1],1);
default:
return -__kernel_cos(y[0],y[1]);
}
Where you have the functions or macros __HI(), __kernel_sin(), __ieee754_rem_pio2(), etc.. all required by s_sin.c. These are provided by the other sources in fdlibm, but are all meant to work together as a library rather than single source files you can cherry-pick from.
Related
Well, I think my problem is a little bit interesting and I want to understand what's happening on my Ubuntu box.
I compiled and linked the following useless piece of code with gcc -lm -o useless useless.c:
/* File useless.c */
#include <stdio.h>
#include <math.h>
int main()
{
int sample = (int)(0.75 * 32768.0 * sin(2 * 3.14 * 440 * ((float) 1/44100)));
return(0);
}
So far so good. But when I change to this:
/* File useless.c */
#include <stdio.h>
#include <math.h>
int main()
{
int freq = 440;
int sample = (int)(0.75 * 32768.0 * sin(2 * 3.14 * freq * ((float) 1/44100)));
return(0);
}
And I try to compile using the same command line, and gcc responds:
/tmp/cctM0k56.o: In function `main':
ao_example3.c:(.text+0x29): undefined reference to `sin'
collect2: ld returned 1 exit status
And it stops. What is happening? Why can't I compile that way?
I also tried a sudo ldconfig -v without success.
There are two different things going on here.
For the first example, the compiler doesn't generate a call to sin. It sees that the argument is a constant expression, so it replaces the sin(...) call with the result of the expression, and the math library isn't needed. It will work just as well without the -lm. (But you shouldn't count on that; it's not always obvious when the compiler will perform this kind of optimization and when it won't.)
(If you compile with
gcc -S useless.c
and take a look at useless.s, the generated assembly language listing, you can see that there's no call to sin.)
For the second example, you do need the -lm option -- but it needs to be at the end of the command line, or at least after the file (useless.c) that needs it:
gcc -o useless useless.c -lm
or
gcc useless.c -lm -o useless
The linker processes files in order, keeping track of unresolved symbols for each one (sin, referred to by useless.o), and then resolving them as it sees their definitions. If you put the -lm first, there are no unresolved symbols when it processes the math library; by the time it sees the call to sin in useless.o, it's too late.
Well, I think my problem is a little bit interesting and I want to understand what's happening on my Ubuntu box.
I compiled and linked the following useless piece of code with gcc -lm -o useless useless.c:
/* File useless.c */
#include <stdio.h>
#include <math.h>
int main()
{
int sample = (int)(0.75 * 32768.0 * sin(2 * 3.14 * 440 * ((float) 1/44100)));
return(0);
}
So far so good. But when I change to this:
/* File useless.c */
#include <stdio.h>
#include <math.h>
int main()
{
int freq = 440;
int sample = (int)(0.75 * 32768.0 * sin(2 * 3.14 * freq * ((float) 1/44100)));
return(0);
}
And I try to compile using the same command line, and gcc responds:
/tmp/cctM0k56.o: In function `main':
ao_example3.c:(.text+0x29): undefined reference to `sin'
collect2: ld returned 1 exit status
And it stops. What is happening? Why can't I compile that way?
I also tried a sudo ldconfig -v without success.
There are two different things going on here.
For the first example, the compiler doesn't generate a call to sin. It sees that the argument is a constant expression, so it replaces the sin(...) call with the result of the expression, and the math library isn't needed. It will work just as well without the -lm. (But you shouldn't count on that; it's not always obvious when the compiler will perform this kind of optimization and when it won't.)
(If you compile with
gcc -S useless.c
and take a look at useless.s, the generated assembly language listing, you can see that there's no call to sin.)
For the second example, you do need the -lm option -- but it needs to be at the end of the command line, or at least after the file (useless.c) that needs it:
gcc -o useless useless.c -lm
or
gcc useless.c -lm -o useless
The linker processes files in order, keeping track of unresolved symbols for each one (sin, referred to by useless.o), and then resolving them as it sees their definitions. If you put the -lm first, there are no unresolved symbols when it processes the math library; by the time it sees the call to sin in useless.o, it's too late.
I cant compile my own version of firmware with using of system_upgrade_start function. The IoT_Demo from SDK examples is compiling with success. In my case the compiler throwing the error only on when I am using system_upgrade_start when I removing just this function(not the system_upgrade_userbin_check()) it compiles with no errors. What I need to do to make my firmware?
my user main for example:
/* main.c -- MQTT client example
*
* Copyright (c) 2014-2015, Tuan PM <tuanpm at live dot com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Redis nor the names of its contributors may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "ets_sys.h"
#include "driver/uart.h"
#include "driver/hw_timer.h"
#include "osapi.h"
#include "mqtt.h"
#include "wifi.h"
#include "debug.h"
#include "gpio.h"
#include "user_interface.h"
#include "mem.h"
#include "os_type.h"
// #include "driver/key.h"
#include "config.h"
#include "espconn.h"
#include "upgrade.h"
LOCAL void ICACHE_FLASH_ATTR
user_esp_platform_upgrade_rsp(void *arg)
{
struct upgrade_server_info *server = arg;
struct espconn *pespconn = server->pespconn;
char *action = NULL;
if (server->upgrade_flag == true) {
INFO("user_esp_platform_upgarde_successfully\n");
action = "device_upgrade_success";
} else {
INFO("user_esp_platform_upgrade_failed\n");
}
os_free(server->url);
server->url = NULL;
os_free(server);
server = NULL;
}
/******************************************************************************
* FunctionName : user_esp_platform_upgrade_begin
* Description : Processing the received data from the server
* Parameters : pespconn -- the espconn used to connetion with the host
* server -- upgrade param
* Returns : none
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR
user_esp_platform_upgrade_begin(struct espconn *pespconn, struct upgrade_server_info *server)
{
uint8 user_bin[9] = {0};
uint8 devkey[41] = {0};
server->pespconn = pespconn;
// os_memcpy(devkey, esp_param.devkey, 40);
os_memcpy(server->ip, pespconn->proto.tcp->remote_ip, 4);
#ifdef UPGRADE_SSL_ENABLE
server->port = 443;
#else
server->port = 80;
#endif
server->check_cb = user_esp_platform_upgrade_rsp;
server->check_times = 120000;
if (server->url == NULL) {
server->url = (uint8 *)os_zalloc(512);
}
if (system_upgrade_userbin_check() == UPGRADE_FW_BIN1) {
os_memcpy(user_bin, "user2.bin", 10);
} else if (system_upgrade_userbin_check() == UPGRADE_FW_BIN2) {
os_memcpy(user_bin, "user1.bin", 10);
}
os_sprintf(server->url,
"GET /v1/device/rom/?action=download_rom&version=%s&filename=%s "
"HTTP/1.0\r\nHost: %s:%d\r\n%s",
server->upgrade_version, user_bin, IP2STR(server->ip),
server->port, "devkey");
INFO("%s\n",server->url);
#ifdef UPGRADE_SSL_ENABLE
if (system_upgrade_start_ssl(server) == false) {
#else
if (system_upgrade_start(server) == false) {
#endif
INFO("upgrade is already started\n");
}
}
static void ICACHE_FLASH_ATTR app_init(void) {
}
void ICACHE_FLASH_ATTR user_init(void) {
}
compiling output:
make firmware/user1.bin
Makefile:322: warning: overriding recipe for target 'firmware'
Makefile:275: warning: ignoring old recipe for target 'firmware'
/home/fdistorted/esp8266/SDK_GCC/crosstool-NG/builds/xtensa-lx106-elf/bin/xtensa-lx106-elf-gcc -Iuser -Idriver -Imqtt -Imodules -Iuser/include -Idriver/include -Imqtt/include -Imodules/include -Iinclude -I/home/fdistorted/esp8266/SDK_GCC/ESP8266_NONOS_SDK-2.1.0/include-I/home/fdistorted/esp8266/SDK_GCC/ESP8266_NONOS_SDK-2.1.0/include/json -g -Wpointer-arith -Wundef -Wl,-EL -Wno-implicit-function-declaration -fno-inline-functions -nostdlib -mlongcalls -mtext-section-literals -ffunction-sections -fdata-sections -fno-builtin-printf -DICACHE_FLASH -DBUID_TIME=\"2017-Nov-05_23:12:26_EET\" -DMQTT_DEBUG_ON -DDEBUG_ON -D_STDINT_H -DLOCAL_CONFIG_AVAILABLE -c user/user_main.c -o build/user/user_main.o
/home/fdistorted/esp8266/SDK_GCC/crosstool-NG/builds/xtensa-lx106-elf/bin/xtensa-lx106-elf-ar cru build/esp_mqtt.a build/user/rfinit.obuild/user/user_main.o build/user/user_json.o build/driver/hw_timer.o build/driver/uart.o build/driver/key.o build/mqtt/mqtt.o build/mqtt/ringbuf.o build/mqtt/mqtt_msg.o build/mqtt/queue.o build/mqtt/proto.o build/mqtt/utils.o build/modules/config.o build/modules/wifi.o
/home/fdistorted/esp8266/SDK_GCC/crosstool-NG/builds/xtensa-lx106-elf/bin/xtensa-lx106-elf-gcc -L/home/fdistorted/esp8266/SDK_GCC/ESP8266_NONOS_SDK-2.1.0/lib -Tbuild/eagle.esphttpd1.v6.ld -nostdlib -Wl,--no-check-sections -u call_user_start -Wl,-static -g -O2 -Wl,--start-group -lc -lgcc -lphy -lpp -lnet80211 -lwpa -lmain -llwip -lcrypto -lssl -ljson -ldriver build/esp_mqtt.a -Wl,--end-group -o build/esp_mqtt.user1.out
build/esp_mqtt.a(user_main.o): In function `user_esp_platform_upgrade_rsp':
user_main.c:(.irom0.text+0xa0): undefined reference to `system_upgrade_start'
build/esp_mqtt.a(user_main.o): In function `user_esp_platform_upgrade_begin':
/home/fdistorted/esp8266/esp_mqtt/user/user_main.c:114: undefined reference to `system_upgrade_start'
collect2: error: ld returned 1 exit status
Makefile:263: recipe for target 'build/esp_mqtt.user1.out' failed
make: *** [build/esp_mqtt.user1.out] Error 1
The -lupgrade parameter needed to be added to compiler command.
If the compiler command generates automatically the variable SDK_LIBS must have upgrade literal for example:
SDK_LIBS = c gcc phy pp net80211 wpa main lwip crypto ssl json driver upgrade
I have a simple code which compiles differently depending whether it's saved with .c or .cu extension:
#include <stdio.h>
#include <complex.h>
int main()
{
float num;
float eps_i, eps_s, tau_d, sigma;
float pi, wave_freq, eps_0;
eps_i = 43.0;
eps_s = 2.4;
tau_d = 0.3;
sigma = 4.75;
pi = 3.14;
wave_freq = 0.015;
eps_0 = 40.234;
float complex c1 = 0.0 + 2.0 * pi * wave_freq * tau_d * I;
float complex c2 = 0.0 + sigma / (2.0 * pi * wave_freq * eps_0) * I;
num = creal(eps_i + (eps_s - eps_i) / (1.0 + (0.0 + 2.0 * pi * wave_freq * tau_d * I)) -
(0.0 + sigma / (2.0 * pi * wave_freq * eps_0) * I));
printf("%g\n", num);
}
If I compile it using nvcc test.c it works exactly how I expected it. However if I run nvcc test.cu I get:
test.cu(18): error: expected a ";"
test.cu(19): error: "complex" has already been declared in the current scope
test.cu(19): error: expected a ";"
test.cu(21): error: identifier "I" is undefined
test.cu(21): error: identifier "creal" is undefined
test.cu(18): warning: variable "complex" was declared but never referenced
test.cu(19): warning: variable "complex" was declared but never referenced
5 errors detected in the compilation of "/var/folders/3z/8bl4b3yx0c3_5tgf35dr_z180000gp/T//tmpxft_00015a75_00000000-9_test.cpp1.ii".
I understand that .cu is treated as code containing CUDA code and .c is just host code, but I would expect them to behave the same in this instance. Notice that it doesn't complain about #include <complex.h> at all. What am I missing?
From comments, this problem would appear to be specific to CUDA 7.5 on OS X El Capitan with the latest XCode. The provided repro case seems to work on every other platform it was tested on. It has been recommended that a bug report be raised with NVIDIA.
[This answer has been added as a community wiki entry to get this question off the unanswered list]
The project I am trying to compile on OS X is: https://github.com/Ramblurr/PietCreator
Am unfortunately unable to fix the problems with the following lines:
width = info_ptr->width;
height = info_ptr->height;
ncol = 2 << (info_ptr->bit_depth - 1);
Which produce the errors:
file.c: In function ‘read_png’:
file.c:1117: error: dereferencing pointer to incomplete type
file.c:1118: error: dereferencing pointer to incomplete type
file.c:1119: error: dereferencing pointer to incomplete type
Full code of the read_png function below:
#include <png.h>
#include <math.h>
png_byte bit_depth;
png_structp png_ptr;
png_infop info_ptr;
int number_of_passes;
png_bytep * row_pointers;
int
read_png (char *fname)
{
char header [8];
FILE *in;
int i, j, ncol, rc;
if (! strcmp (fname, "-")) {
/* read from stdin: */
vprintf ("info: not trying to read png from stdin\n");
return -1;
}
if (! (in = fopen (fname, "rb"))) {
fprintf (stderr, "cannot open `%s'; reason: %s\n", fname,
strerror (errno));
return -1;
}
if (! in || (rc = fread (header, 1, 8, in)) != 8
|| png_sig_cmp ((unsigned char *) header, 0, 8) != 0) {
return -1;
}
if (! (png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, 0, 0, 0))
|| ! (info_ptr = png_create_info_struct (png_ptr))) {
return -1;
}
png_init_io (png_ptr, in);
png_set_sig_bytes (png_ptr, 8);
png_read_png (png_ptr, info_ptr,
PNG_TRANSFORM_STRIP_16 | PNG_TRANSFORM_STRIP_ALPHA
| PNG_TRANSFORM_EXPAND, NULL);
/** | PNG_TRANSFORM_PACKING | PNG_TRANSFORM_SHIFT **/
row_pointers = png_get_rows (png_ptr, info_ptr);
width = info_ptr->width;
height = info_ptr->height;
ncol = 2 << (info_ptr->bit_depth - 1);
vprintf ("info: got %d x %d pixel with %d cols\n", width, height, ncol);
alloc_cells (width, height);
for (j = 0; j < height; j++) {
png_byte *row = row_pointers [j];
for (i = 0; i < width; i++) {
png_byte *ptr = & row [i * 3];
/* ncol always 256 ? */
int r = (ptr [0] * 256) / ncol;
int g = (ptr [1] * 256) / ncol;
int b = (ptr [2] * 256) / ncol;
int col = ((r * 256 + g) * 256) + b;
int col_idx = get_color_idx (col);
if (col_idx < 0) {
if (unknown_color == -1) {
fprintf (stderr, "cannot read from `%s'; reason: invalid color found\n",
fname);
return -1;
} else {
/* set to black or white: */
col_idx = (unknown_color == 0 ? c_black : c_white);
}
}
set_cell (i, j, col_idx);
}
}
return 0;
}
I think it is by design of the creator of png.h module.
It should be that png_infop is declared as a pointer to a struct in "png.h". The actual struct declaration and definition should be in "png.c".
The author does not want to expose the internals of the struct so the struct is defined in the "png.c".
This means you cannot access any member of the struct (i.e: info_ptr->width, info_ptr->height, info_ptr->bit_depth.
The struct members are not meant to be accessed by user.
I bet there are functions to access those members if the author thinks that you will need the width, height, or bit_depth information (i.e: getWidth(info_ptr), getHeight(info_ptr), ...).
You need to look in png.h (or its documentation), find out what the type png_infop is a pointer to, and then find out how you're supposed to access its fields. Assuming that this pointer is really the right thing to get that data from, then either you need to include the definition of that type (so that the compiler knows about its data members width etc) from some other header, or else there are getter functions you're supposed to call that take a png_infop parameter and return the info you're after.
[Edit: looks as if you're supposed to use png_get_IHDR, or png_get_image_width etc.]
I compiled the project on Mac OS X 10.6.8 successfully.
git clone https://github.com/Ramblurr/PietCreator.git
cd PietCreator
mkdir build
cd build
cmake ../
-- The C compiler identification is GNU
-- The CXX compiler identification is GNU
-- Checking whether C compiler has -isysroot
-- Checking whether C compiler has -isysroot - yes
-- Checking whether C compiler supports OSX deployment target flag
-- Checking whether C compiler supports OSX deployment target flag - yes
-- Check for working C compiler: /usr/bin/gcc
-- Check for working C compiler: /usr/bin/gcc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Checking whether CXX compiler has -isysroot
-- Checking whether CXX compiler has -isysroot - yes
-- Checking whether CXX compiler supports OSX deployment target flag
-- Checking whether CXX compiler supports OSX deployment target flag - yes
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Looking for Q_WS_X11
-- Looking for Q_WS_X11 - not found.
-- Looking for Q_WS_WIN
-- Looking for Q_WS_WIN - not found.
-- Looking for Q_WS_QWS
-- Looking for Q_WS_QWS - not found.
-- Looking for Q_WS_MAC
-- Looking for Q_WS_MAC - found
-- Looking for QT_MAC_USE_COCOA
-- Looking for QT_MAC_USE_COCOA - found
-- Found Qt-Version 4.7.4 (using /usr/local/bin/qmake)
-- Looking for gdImagePng in /usr/local/lib/libgd.dylib
-- Looking for gdImagePng in /usr/local/lib/libgd.dylib - found
-- Found ZLIB: /usr/include (found version "1.2.3")
-- Found PNG: /usr/X11R6/lib/libpng.dylib
-- Looking for gdImageJpeg in /usr/local/lib/libgd.dylib
-- Looking for gdImageJpeg in /usr/local/lib/libgd.dylib - found
-- Found JPEG: /usr/local/lib/libjpeg.dylib
-- Looking for gdImageGif in /usr/local/lib/libgd.dylib
-- Looking for gdImageGif in /usr/local/lib/libgd.dylib - found
-- Found GD: /usr/local/lib/libgd.dylib
-- Found GIF: /usr/local/lib/libgif.dylib
-- Looking for include files HAVE_GD_H
-- Looking for include files HAVE_GD_H - found
-- Looking for include files HAVE_PNG_H
-- Looking for include files HAVE_PNG_H - not found.
-- Looking for include files HAVE_GIF_LIB_H
-- Looking for include files HAVE_GIF_LIB_H - found
-- Configuring done
-- Generating done
-- Build files have been written to: /Developer/workspace/png/PietCreator/build
After running make the application was compiled successfully:
Linking CXX executable pietcreator
[ 95%] Built target pietcreator
[ 97%] Generating NPietTest.moc
Scanning dependencies of target npiettest
[100%] Building CXX object npiet/CMakeFiles/npiettest.dir/test/NPietTest.cpp.o
Linking CXX executable npiettest
[100%] Built target npiettest
The only problems I ran into were all related to missing dependencies when executing cmake ../. I had to download/compile/install Qt 4.7.4 and Qt-mobility 1.2.0. After that, I also needed libgd and giflib but then I used brew for the job.
I suggest you try another git clone and try to compile it again from scratch.
If you would like to know, brew installed gd 2.0.36RC1 and giflib 4.1.6.
You usually get this error when you have a forward declaration in the header and you don't include the file for the corresponding class in the source file:
//header.h
class B;
class A{
A();
B* b;
}
//source.cpp
#include "header.h"
//include "B.h" //include header where B is defined to prevent error
A::A()
{
b->foo(); //error, B is only a forward declaration
}
Therefore, you need to include the appropriate header, a forward declaration is not enough.
incomplete reference errors typically occur when you have a construct as under:
struct foo;
int bar(void) {
struct foo *p;
p->a = 0;
}
here The foo struct is declared however its actual content is not known, And will yield a dereferencing to an incomplete type error.
The philosophy behind this is to force a formal API usage to manipulate data structures. this ensures that future API can change the structure much more easily without affecting legacy programs.
So typically an API header will do something like this:
/*
* foo.h part of foo API
*/
struct foo;
extern void foo_set_a(struct foo *p, int value);
extern int foo_get_a(struct foo *p);
It will internally implement the foo API functions ... for instance:
/*
* foo.c ... implements foo API
*/
struct foo {
int a;
};
void foo_set_a(struct foo *p, int value) {
p->a = value;
}
int foo_get_a(struct foo *p) {
return p->a;
}
and then the user of foo API can:
use_foo() {
struct foo *my_foo;
foo_set_a(my_foo, 1);
}