Opened 9 years ago

Closed 9 years ago

Last modified 9 years ago

#3167 closed defect (fixed)

Windows build broken, lwin_geojson.c undefined reference to json_..

Reported by: robe Owned by: strk
Priority: blocker Milestone: PostGIS 2.2.0
Component: postgis Version: master
Keywords: Cc: esseffe

Description (last modified by robe)

Seems something in r13650 broke winnie's build. She compiles against json 0.12 so not sure if its something with the way I have things configured or specific to mingw or json 0.12.

configure output looks like this:

  PostGIS is now configured for i686-w64-mingw32

 -------------- Compiler Info ------------- 
  C compiler:           i686-w64-mingw32-gcc -g -O2
  C++ compiler:         i686-w64-mingw32-g++ -g -O2
  SQL preprocessor:     /mingw/bin/cpp -traditional-cpp -w -P

 -------------- Dependencies -------------- 
  GEOS config:          /projects/geos/rel-3.5.0devw32gcc481/bin/geos-config
  GEOS version:         3.5.0dev
  GDAL config:          /projects/gdal/rel-1.11.1w32gcc481/bin/gdal-config
  GDAL version:         1.11.1
  SFCGAL config:        /projects/CGAL/rel-sfcgal-1.0.5w32gcc481/bin/sfcgal-config
  SFCGAL version:       1.0.5
  PostgreSQL config:    /projects/postgresql/rel/pg9.4w32gcc481/bin/pg_config
  PostgreSQL version:   PostgreSQL 9.4.1
  PROJ4 version:        48
  Libxml2 config:       /projects/libxml/rel-libxml2-2.7.8w32gcc481/bin/xml2-config
  Libxml2 version:      2.7.8
  JSON-C support:       yes
  PCRE support:       no
  PostGIS debug level:  0
  Perl:                 /bin/perl

 --------------- Extensions --------------- 
  PostGIS Raster:       enabled
  PostGIS Topology:     enabled
  SFCGAL support:       enabled
  Address Standardizer support:       disabled

 -------- Documentation Generation -------- 
  xsltproc:             /projects/xsltproc/xsltproc
  xsl style sheets:     /projects/docbook/docbook-xsl-1.76.1
  dblatex:              
  convert:              /c/Windows/system32/convert
  mathml2.dtd:          http://www.w3.org/Math/DTD/mathml2/mathml2.dtd

end of compile looks like this before it kicks the bucket.

libtool: link: i686-w64-mingw32-gcc -shared  .libs/stringbuffer.o .libs/bytebuffer.o .libs/measures.o .libs/measures3d.o .libs/box2d.o .libs/ptarray.o .libs/lwgeom_api.o .libs/lwgeom.o .libs/lwpoint.o .libs/lwline.o .libs/lwpoly.o .libs/lwtriangle.o .libs/lwmpoint.o .libs/lwmline.o .libs/lwmpoly.o .libs/lwcollection.o .libs/lwcircstring.o .libs/lwcompound.o .libs/lwcurvepoly.o .libs/lwmcurve.o .libs/lwmsurface.o .libs/lwpsurface.o .libs/lwtin.o .libs/lwout_wkb.o .libs/lwin_geojson.o .libs/lwin_wkb.o .libs/lwin_twkb.o .libs/lwout_wkt.o .libs/lwout_twkb.o .libs/lwin_wkt_parse.o .libs/lwin_wkt_lex.o .libs/lwin_wkt.o .libs/lwin_encoded_polyline.o .libs/lwutil.o .libs/lwhomogenize.o .libs/lwalgorithm.o .libs/lwsegmentize.o .libs/lwlinearreferencing.o .libs/lwprint.o .libs/vsprintf.o .libs/g_box.o .libs/g_serialized.o .libs/g_util.o .libs/lwgeodetic.o .libs/lwgeodetic_tree.o .libs/lwtree.o .libs/lwout_gml.o .libs/lwout_kml.o .libs/lwout_geojson.o .libs/lwout_svg.o .libs/lwout_x3d.o .libs/lwout_encoded_polyline.o .libs/lwgeom_debug.o .libs/lwgeom_geos.o .libs/lwgeom_geos_clean.o .libs/lwgeom_geos_node.o .libs/lwgeom_geos_split.o .libs/lwgeom_transform.o .libs/effectivearea.o .libs/varint.o .libs/lwgeom_sfcgal.o .libs/lwspheroid.o   -L/projects/postgresql/rel/pg9.4w32gcc481/lib -L/projects/gdal/rel-1.11.1w32gcc481/lib -L/projects/rel-libiconv-1.13.1w32gcc481/lib -L/projects/geos/rel-3.5.0devw32gcc481/lib -lgeos_c -L/projects/proj/rel-4.8.0w32gcc481/lib /projects/proj/rel-4.8.0w32gcc481/lib/libproj.dll.a -L/projects/json-c/rel-0.12w32gcc481/lib -L/projects/CGAL/rel-sfcgal-1.0.5w32gcc481/lib /projects/CGAL/rel-sfcgal-1.0.5w32gcc481/lib/libSFCGAL.dll    -o .libs/liblwgeom-2-2-0dev.dll -Wl,--enable-auto-image-base -Xlinker --out-implib -Xlinker .libs/liblwgeom.dll.a
.libs/lwin_geojson.o: In function `findMemberByName':
e:\jenkins\postgis\branches\2.2\liblwgeom/lwin_geojson.c:59: undefined reference to `json_object_get_object'
e:\jenkins\postgis\branches\2.2\liblwgeom/lwin_geojson.c:61: undefined reference to `json_object_get_object'
e:\jenkins\postgis\branches\2.2\liblwgeom/lwin_geojson.c:67: undefined reference to `json_object_get_object'
.libs/lwin_geojson.o: In function `parse_geojson_coord':
e:\jenkins\postgis\branches\2.2\liblwgeom/lwin_geojson.c:89: undefined reference to `json_object_get_type'
e:\jenkins\postgis\branches\2.2\liblwgeom/lwin_geojson.c:93: undefined reference to `json_object_array_length'
e:\jenkins\postgis\branches\2.2\liblwgeom/lwin_geojson.c:103: undefined reference to `json_object_array_get_idx'
e:\jenkins\postgis\branches\2.2\liblwgeom/lwin_geojson.c:104: undefined reference to `json_object_get_double'
e:\jenkins\postgis\branches\2.2\liblwgeom/lwin_geojson.c:108: undefined reference to `json_object_array_get_idx'
e:\jenkins\postgis\branches\2.2\liblwgeom/lwin_geojson.c:109: undefined reference to `json_object_get_double'
e:\jenkins\postgis\branches\2.2\liblwgeom/lwin_geojson.c:115: undefined reference to `json_object_array_get_idx'
e:\jenkins\postgis\branches\2.2\liblwgeom/lwin_geojson.c:116: undefined reference to `json_object_get_double'
.libs/lwin_geojson.o: In function `parse_geojson':
e:\jenkins\postgis\branches\2.2\liblwgeom/lwin_geojson.c:476: undefined reference to `json_object_get_string'
.libs/lwin_geojson.o: In function `parse_geojson_geometrycollection':
e:\jenkins\postgis\branches\2.2\liblwgeom/lwin_geojson.c:444: undefined reference to `json_object_get_type'
e:\jenkins\postgis\branches\2.2\liblwgeom/lwin_geojson.c:446: undefined reference to `json_object_array_length'
e:\jenkins\postgis\branches\2.2\liblwgeom/lwin_geojson.c:450: undefined reference to `json_object_array_get_idx'
.libs/lwin_geojson.o: In function `parse_geojson_linestring':
e:\jenkins\postgis\branches\2.2\liblwgeom/lwin_geojson.c:186: undefined reference to `json_object_get_type'
.libs/lwin_geojson.o: In function `parse_geojson_multipoint':
e:\jenkins\postgis\branches\2.2\liblwgeom/lwin_geojson.c:288: undefined reference to `json_object_get_type'
e:\jenkins\postgis\branches\2.2\liblwgeom/lwin_geojson.c:290: undefined reference to `json_object_array_length'
e:\jenkins\postgis\branches\2.2\liblwgeom/lwin_geojson.c:295: undefined reference to `json_object_array_get_idx'
.libs/lwin_geojson.o: In function `parse_geojson_polygon':
e:\jenkins\postgis\branches\2.2\liblwgeom/lwin_geojson.c:219: undefined reference to `json_object_get_type'
e:\jenkins\postgis\branches\2.2\liblwgeom/lwin_geojson.c:225: undefined reference to `json_object_array_length'
e:\jenkins\postgis\branches\2.2\liblwgeom/lwin_geojson.c:235: undefined reference to `json_object_array_get_idx'
e:\jenkins\postgis\branches\2.2\liblwgeom/lwin_geojson.c:236: undefined reference to `json_object_get_type'
e:\jenkins\postgis\branches\2.2\liblwgeom/lwin_geojson.c:241: undefined reference to `json_object_array_length'
e:\jenkins\postgis\branches\2.2\liblwgeom/lwin_geojson.c:253: undefined reference to `json_object_array_get_idx'
.libs/lwin_geojson.o: In function `parse_geojson_multilinestring':
e:\jenkins\postgis\branches\2.2\liblwgeom/lwin_geojson.c:330: undefined reference to `json_object_get_type'
e:\jenkins\postgis\branches\2.2\liblwgeom/lwin_geojson.c:332: undefined reference to `json_object_array_length'
e:\jenkins\postgis\branches\2.2\liblwgeom/lwin_geojson.c:337: undefined reference to `json_object_array_get_idx'
e:\jenkins\postgis\branches\2.2\liblwgeom/lwin_geojson.c:340: undefined reference to `json_object_get_type'
e:\jenkins\postgis\branches\2.2\liblwgeom/lwin_geojson.c:342: undefined reference to `json_object_array_length'
e:\jenkins\postgis\branches\2.2\liblwgeom/lwin_geojson.c:346: undefined reference to `json_object_array_get_idx'
.libs/lwin_geojson.o: In function `parse_geojson_linestring':
e:\jenkins\postgis\branches\2.2\liblwgeom/lwin_geojson.c:188: undefined reference to `json_object_array_length'
e:\jenkins\postgis\branches\2.2\liblwgeom/lwin_geojson.c:192: undefined reference to `json_object_array_get_idx'
.libs/lwin_geojson.o: In function `parse_geojson_multipolygon':
e:\jenkins\postgis\branches\2.2\liblwgeom/lwin_geojson.c:382: undefined reference to `json_object_get_type'
e:\jenkins\postgis\branches\2.2\liblwgeom/lwin_geojson.c:384: undefined reference to `json_object_array_length'
e:\jenkins\postgis\branches\2.2\liblwgeom/lwin_geojson.c:388: undefined reference to `json_object_array_get_idx'
e:\jenkins\postgis\branches\2.2\liblwgeom/lwin_geojson.c:390: undefined reference to `json_object_get_type'
e:\jenkins\postgis\branches\2.2\liblwgeom/lwin_geojson.c:393: undefined reference to `json_object_array_length'
e:\jenkins\postgis\branches\2.2\liblwgeom/lwin_geojson.c:397: undefined reference to `json_object_array_get_idx'
e:\jenkins\postgis\branches\2.2\liblwgeom/lwin_geojson.c:399: undefined reference to `json_object_get_type'
e:\jenkins\postgis\branches\2.2\liblwgeom/lwin_geojson.c:404: undefined reference to `json_object_array_length'
e:\jenkins\postgis\branches\2.2\liblwgeom/lwin_geojson.c:407: undefined reference to `json_object_array_get_idx'
.libs/lwin_geojson.o: In function `lwgeom_from_geojson':
e:\jenkins\postgis\branches\2.2\liblwgeom/lwin_geojson.c:524: undefined reference to `json_tokener_new'
e:\jenkins\postgis\branches\2.2\liblwgeom/lwin_geojson.c:525: undefined reference to `json_tokener_parse_ex'
e:\jenkins\postgis\branches\2.2\liblwgeom/lwin_geojson.c:535: undefined reference to `json_tokener_free'
e:\jenkins\postgis\branches\2.2\liblwgeom/lwin_geojson.c:545: undefined reference to `json_object_get_string'
e:\jenkins\postgis\branches\2.2\liblwgeom/lwin_geojson.c:552: undefined reference to `json_object_put'
e:\jenkins\postgis\branches\2.2\liblwgeom/lwin_geojson.c:529: undefined reference to `json_tokener_error_desc'
e:\jenkins\postgis\branches\2.2\liblwgeom/lwin_geojson.c:530: undefined reference to `json_tokener_free'
e:\jenkins\postgis\branches\2.2\liblwgeom/lwin_geojson.c:531: undefined reference to `json_object_put'
collect2.exe: error: ld returned 1 exit status
Makefile:152: recipe for target `liblwgeom.la' failed
make[1]: *** [liblwgeom.la] Error 1
make[1]: Leaving directory `/projects/postgis/branches/2.2/liblwgeom'
GNUmakefile:14: recipe for target `all' failed
make: *** [all] Error 1

Change History (13)

comment:1 by robe, 9 years ago

Description: modified (diff)

comment:2 by darkblueb, 9 years ago

both libjson 0.11 and 0.12 build, link and check fine here; debian linux, 11 from package and 12 from source. Oddly however, config.log shows #include <json/json.h> failing, while I see on disk only

/usr/include/json-c/json.h
/usr/include/jsoncpp/json/json.h
/usr/include/postgresql/9.3/server/utils/json.h

comment:3 by robe, 9 years ago

I think that error is expected for newer json-c and one os the flags we use to know its newer json. I get that error too.

One more question did you point at json version to use using the ../configure --with-jsondir

I'm guess I'm going to have to test with newer and older. Sounds like it might not be json specific. mingw is sometimes picky about order of includes, so I might need to flip order somewhere.

comment:4 by robe, 9 years ago

Owner: changed from pramsey to strk
Priority: mediumblocker

comment:5 by strk, 9 years ago

I don't see libjson_c in the link line you reported ?

comment:6 by strk, 9 years ago

Cc: esseffe added

Alessandro, can you help with this ? Regina found -no-undefined broke her windows build

comment:7 by robe, 9 years ago

okay it seems the main culprit is because I build json-c statically instead of dynamically and the

LDFLAGS += -no-undefined

causes it for some reason to try to build dynamically which it can't cause I have no dll. I confirmed if I take that line out things work fine. With that line in, I get this message:

*** Warning: This system can not link to static lib archive /projects/json-c/rel-0.12w32gcc481/lib/libjson-c.la.
*** I have the capability to make that library automatically link in when
*** you link to this library.  But I can only do this if you have a
*** shared version of the library, which you do not appear to have.

and the libjson-c.a no longer gets added to the link statement.

comment:8 by strk, 9 years ago

Resolution: fixed
Status: newclosed

I've reverted the offending commit with r13677. Then I guess Alessandro is back to being unable to build a shared version of liblwgeom, but as he doesn't have a ticket Regina wins :)

Seriously, Alessandro please file a ticket for your issue !

comment:9 by robe, 9 years ago

Okay I put in a new ticket at #3170 and will do some tests to see if I can get json-c to give me static linking with what you took out and also have liblwgeom remain static for me.

comment:10 by esseffe, 9 years ago

just few clarifications about MinGW, -no-undefined and related

step #1: why is required declaring -no-undefined


every canonical build system producing some library should be always expected to create and install both the static and the dynamic versions of the library.

this is usually true on any standard Linux, where the canonical ./configure script will always create both the static (*.a) and the dynamic (*.so) libraries (unless you pass an explicit --disable-static or --disable-shared option) and following this approach users will be absolutely free to link the one or the other accordingly to their specific requirements.

on Windows there is a subtle difference: there are no *.so shared libraries, here we have *.dll dynamic libraries which are based on a completely different architecture. MinGW/MSYS still continues to be able to generate both static and dynamic libraries even on Windows, but due to technical limitations imposed by the intrinsic DLL design a further -no-undefined option is expected to be explicitly passed to libtool.

if -no-undefined isn't specified you'll simply get the static *.a library and no DLL at all will be created.

practically all FLOSS libraries I'm aware of usually define someway -no-undefined so to nicely create both the static and the dynamic libraries even when using MinGW on Windows. the unique remarkable exception I know to this standard rule is represented by libgeotiff (and liblwgeom, of course). in this case manually patching the corresponding Makefile,in is always required before running ./configure: this hack effectively works, but it surely is rather inelegant.

step #2: static vs dynamic linkage


assuming that in the previous steps we've effectively built and installed both the static and the dynamic versions of the same library (let say libxyz), it's now time to link libxyz to some other library or may be to some application.

gcc (and MinGW) allows us to freely choose between static and dynamic linkage as we wish better, but there are few critical details requiring careful consideration.

when a fine control about the linkage mode is absolutely required the best approach is the one to always explicitly select the required library object thus completely by-passing any possible interference from the build tools.

this will certainly statically link libxyz

gcc abcd.c -o abdd.exe /usr/local/lib/libxyz.a

this will surely dynamically link libxyz

gcc abcd.c -o abcd.c /usr/local/lib/libxyz.dll.a

and this too will dynamically link libxyz

gcc abcd.c -o abcd.c /usr/local/bin/libxyz-0.dll

finally, a last case exists, and it's rather ambiguous

gcc abcd.c -o abcd.exe -lxyz

in this specific case we are substantially leaving gcc absolutely free to choose its preferred version of libxyz; and if a possibility exists gcc will always opt for dynamic linkage, because this one is the standard assumption on any Linux. Just in only one case we can get a statically linked executable following this approach: if only a single version of the library exists, and it actually is the static member.

please notice: gcc -static abcd.c -o abcd.exe -lxyz

this will surely create a statically linked executable, because the -static flag now informs gcc about your preferences.

I easily guess that the link problems reported by Regina after (correctly) introducing the -no-undefined option can be easily tracked back to some incomplete linker directive hopefully relying on the incorrect assumption that only the static library should exists.

my 5 cents, Sandro

comment:11 by robe, 9 years ago

oh so 2 cents wasn't good enough, you had to give us 3 additional cents :)

Anyway I still have to try building without libjson to make sure that is the only spot at fault and if I understand you correctly, I need to perhaps rebuild json with (allowing dynamic and static creation) and do a -static somewhere for liblwgeom so I get my preferred static behavior, and then we can put back that line so you can have your preferred dynamic back.

comment:12 by robe, 9 years ago

Just an fyi on this. I have had 0 success getting static compile. I think I may need to just bite the bullet and ship the extra json dll. As Sandro ( esseffe ) pointed out, its the proper thing to do tgo have the LDFLAGS += -no-undefined line in there.

I'll give it one more try and if I fail, I'll just put back that line after I have buildbot set to build with a dynamic jsonc. Yes it is only json c giving me headache.

comment:13 by robe, 9 years ago

Okay I put back that line at r13732 as noted in #3170

I was able to still keep my static linking, by compiling json-c as usual (with just --enable-static --disable-shared, so didn't need to recompile)

BUT - and not sure this is right I hacked the include/libjson-c.la

By changing line 11 that read:

# Names of this library.
library_names=''

to

# Names of this library.
library_names='libjson-c.a'

And that seemed to do the trick. I'm not knowledgeable enough to know why this worked and couldn't find it described on web, but seemd to do the trick for me.

I'll know for sure if Winnie passes thru all her tests. I only tested on my mingw64-w64 9.4 dev instance.

Note: See TracTickets for help on using tickets.