Compiling frameworks on mac

Nypan84
Posts: 3
Joined: Wed Feb 03, 2010 12:36 pm

Compiling frameworks on mac

Post by Nypan84 »

Im getting an annoying error and I do currently not have that much time to look in to it my self.

Im compiling on OS X 10.5.8 and the source is bullet-2.76-beta-r1945.

When running cmake with:

cmake -DBUILD_SHARED_LIBS=ON -DFRAMEWORK=ON -DCMAKE_INSTALL_PREFIX=/Library/Frameworks -DCMAKE_INSTALL_NAME_DIR=/Library/Frameworks -DCMAKE_OSX_ARCHITECTURES='ppc;i386;x86_64'

I get the error:

CMake Error at src/BulletSoftBody/CMakeLists.txt:47 (SET_TARGET_PROPERTIES):
set_target_properties called with incorrect number of arguments.

Hope someone can help me with pinpointing what is causing this.
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA

Re: Compiling frameworks on mac

Post by Erwin Coumans »

Are you using Bullet 2.75 or latest trunk/2.76 beta?

Thanks,
Erwin
Nypan84
Posts: 3
Joined: Wed Feb 03, 2010 12:36 pm

Re: Compiling frameworks on mac

Post by Nypan84 »

I said that is use the bullet-2.76-beta-r1945 source in my original post so yeah that would be the beta.

Any idea what could be causing it?
Nypan84
Posts: 3
Joined: Wed Feb 03, 2010 12:36 pm

Re: Compiling frameworks on mac

Post by Nypan84 »

Not getting anywhere with the beta I tried the 2.75 release and I still get no luck.

Now cmake works fine but when running make it fails miserably and generates the following output:

cmake -DBUILD_SHARED_LIBS=ON -DFRAMEWORK=ON -DCMAKE_INSTALL_PREFIX=/Library/Frameworks -DCMAKE_INSTALL_NAME_DIR=/Library/Frameworks -DCMAKE_OSX_ARCHITECTURES='ppc;i386;x86_64' -DCMAKE_BUILD_TYPE=RelWithDebugInfo
OPENGL FOUND
/System/Library/Frameworks/AGL.framework/System/Library/Frameworks/OpenGL.framework
GLUT FOUND
-framework GLUT
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75
13:54:53 ~/Dropbox/Programming Backup/OGRE/bullet-2.75 Nypan$ make[ 0%] Building CXX object src/LinearMath/CMakeFiles/LinearMath.dir/btConvexHull.o
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp: In function 'btVector3 PlaneLineIntersection(const btPlane&, const btVector3&, const btVector3&)':
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp:99: error: 'btDot' was not declared in this scope
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp: In function 'btVector3 PlaneProject(const btPlane&, const btVector3&)':
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp:106: error: 'btDot' was not declared in this scope
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp: In function 'btVector3 TriNormal(const btVector3&, const btVector3&, const btVector3&)':
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp:113: error: 'btCross' was not declared in this scope
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp: In function 'btScalar DistanceBetweenLines(const btVector3&, const btVector3&, const btVector3&, const btVector3&, btVector3*, btVector3*)':
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp:123: error: 'btCross' was not declared in this scope
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp:125: error: 'btDot' was not declared in this scope
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp: In function 'int PlaneTest(const btPlane&, const btVector3&)':
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp:173: error: 'btDot' was not declared in this scope
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp: In function 'btVector3 PlaneLineIntersection(const btPlane&, const btVector3&, const btVector3&)':
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp:99: error: 'btDot' was not declared in this scope
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp: In function 'btVector3 PlaneProject(const btPlane&, const btVector3&)':
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp:106: error: 'btDot' was not declared in this scope
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp: In function 'btVector3 TriNormal(const btVector3&, const btVector3&, const btVector3&)':
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp:113: error: 'btCross' was not declared in this scope
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp: In function 'btScalar DistanceBetweenLines(const btVector3&, const btVector3&, const btVector3&, const btVector3&, btVector3*, btVector3*)':
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp:123: error: 'btCross' was not declared in this scope
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp:125: error: 'btDot' was not declared in this scope
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp: In function 'int PlaneTest(const btPlane&, const btVector3&)':
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp:173: error: 'btDot' was not declared in this scope
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp: In function 'btVector3 orth(const btVector3&)':
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp:241: error: 'btCross' was not declared in this scope
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp: In function 'int above(btVector3*, const int3&, const btVector3&, btScalar)':
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp:316: error: 'btDot' was not declared in this scope
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp: In function 'btVector3 PlaneLineIntersection(const btPlane&, const btVector3&, const btVector3&)':
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp:99: error: 'btDot' was not declared in this scope
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp: In function 'btVector3 PlaneProject(const btPlane&, const btVector3&)':
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp:106: error: 'btDot' was not declared in this scope
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp: In function 'btVector3 TriNormal(const btVector3&, const btVector3&, const btVector3&)':
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp:113: error: 'btCross' was not declared in this scope
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/Linear/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp: In member function 'int4 HullLibrary::FindSimplex(btVector3*, int, btAlignedObjectArray<int>&)':
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp:498: error: 'btCross' was not declared in this scope
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp:521: error: 'btDot' was not declared in this scope
Math/btConvexHull.cpp: In function 'btScalar DistanceBetweenLines(const btVector3&, const btVector3&, const btVector3&, const btVector3&, btVector3*, btVector3*)':
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp:123: error: 'btCross' was not declared in this scope
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp:125: error: 'btDot' was not declared in this scope
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp: In function 'int PlaneTest(const btPlane&, const btVector3&)':
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp:173: error: 'btDot' was not declared in this scope
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp: In function 'btVector3 orth(const btVector3&)':
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp:241: error: 'btCross' was not declared in this scope
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp: In function 'int above(btVector3*, const int3&, const btVector3&, btScalar)':
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp:316: error: 'btDot' was not declared in this scope
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp: In member function 'int4 HullLibrary::FindSimplex(btVector3*, int, btAlignedObjectArray<int>&)':
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp:498: error: 'btCross' was not declared in this scope
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp:521: error: 'btDot' was not declared in this scope
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp: In member function 'int HullLibrary::calchullgen(btVector3*, int, int)':
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp:567: error: 'btDot' was not declared in this scope
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp: In member function 'int HullLibrary::calchullgen(btVector3*, int, int)':
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp:567: error: 'btDot' was not declared in this scope
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp:595: error: 'btCross' was not declared in this scope
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp:617: error: 'btDot' was not declared in this scope
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp: In function 'btVector3 orth(const btVector3&)':
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp:241: error: 'btCross' was not declared in this scope
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp: In function 'int above(btVector3*, const int3&, const btVector3&, btScalar)':
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp:316: error: 'btDot' was not declared in this scope
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp: In member function 'int4 HullLibrary::FindSimplex(btVector3*, int, btAlignedObjectArray<int>&)':
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp:498: error: 'btCross' was not declared in this scope
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp:521: error: 'btDot' was not declared in this scope
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp: In member function 'int HullLibrary::calchullgen(btVector3*, int, int)':
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp:567: error: 'btDot' was not declared in this scope
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp:595: error: 'btCross' was not declared in this scope
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp:617: error: 'btDot' was not declared in this scope
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp: In function 'int maxdirsterid(const T*, int, const T&, btAlignedObjectArray<int>&) [with T = btVector3]':
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp:493: instantiated from here
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp:261: error: 'btCross' was not declared in this scope
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp: In function 'int maxdirfiltered(const T*, int, const T&, btAlignedObjectArray<int>&) [with T = btVector3]':
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp:258: instantiated from 'int maxdirsterid(const T*, int, const T&, btAlignedObjectArray<int>&) [with T = btVector3]'
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp:493: instantiated from here
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp:231: error: 'btDot' was not declared in this scope
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp:595: error: 'btCross' was not declared in this scope
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp:617: error: 'btDot' was not declared in this scope
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp: In function 'int maxdirsterid(const T*, int, const T&, btAlignedObjectArray<int>&) [with T = btVector3]':
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp:493: instantiated from here
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp:261: error: 'btCross' was not declared in this scope
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp: In function 'int maxdirsterid(const T*, int, const T&, btAlignedObjectArray<int>&) [with T = btVector3]':
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp:493: instantiated from here
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp:261: error: 'btCross' was not declared in this scope
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp: In function 'i/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp: In function 'int maxdirfiltered(const T*, int, const T&, btAlignedObjectArray<int>&) [with T = btVector3]':
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp:258: instantiated from 'int maxdirsterid(const T*, int, const T&, btAlignedObjectArray<int>&) [with T = btVector3]'
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp:493: instantiated from here
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp:231: error: 'btDot' was not declared in this scope
nt maxdirfiltered(const T*, int, const T&, btAlignedObjectArray<int>&) [with T = btVector3]':
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp:258: instantiated from 'int maxdirsterid(const T*, int, const T&, btAlignedObjectArray<int>&) [with T = btVector3]'
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp:493: instantiated from here
/Users/Nypan/Dropbox/Programming Backup/OGRE/bullet-2.75/src/LinearMath/btConvexHull.cpp:231: error: 'btDot' was not declared in this scope
lipo: can't figure out the architecture type of: /var/folders/-k/-kvSsnxKEWO3xyhQ1bhxvE+++TI/-Tmp-//cc4k9Xpb.out
make[2]: *** [src/LinearMath/CMakeFiles/LinearMath.dir/btConvexHull.o] Error 1
make[1]: *** [src/LinearMath/CMakeFiles/LinearMath.dir/all] Error 2
make: *** [all] Error 2

I wanted to include that in a .txt file, but fore some reason txt files are not allowed.

Anyway this is starting to get annoying, anyone have a clue as to why I cant compile the 2.75 source on mac?
deets
Posts: 3
Joined: Fri Mar 05, 2010 4:05 pm

Re: Compiling frameworks on mac

Post by deets »

I tried this today, with the released 2.76 version.

CMAKE-command:

Code: Select all

cmake -DBUILD_SHARED_LIBS=ON -DFRAMEWORK=ON -DCMAKE_INSTALL_PREFIX=/Library/Frameworks -DCMAKE_INSTALL_NAME_DIR=/Library/Frameworks -DCMAKE_BUILD_TYPE=RelWithDebugInfo -DBUILD_EXTRAS=OFF -DBUILD_DEMOS=OFF 
This gave me an linking error in BulletMultiThreaded. I fixed that by patching

Code: Select all

 src/BulletMultiThreaded/CMakeLists.txt
to introduce dependencies to the missing libs - this is my patch:

Code: Select all

 IF (BUILD_SHARED_LIBS)
 	TARGET_LINK_LIBRARIES(BulletMultiThreaded BulletCollision BulletDynamics)
 ENDIF (BUILD_SHARED_LIBS)
Once that was fixed, everything build fine, but no Framework was generated.

Then I found out that there seems to be a variabel "INSTALL_LIBS" that is set to "OFF".

Activating this gave me the same error the OP posted:

Code: Select all

mac-dir-2:bullet-2.76 deets$ cmake -DBUILD_SHARED_LIBS=ON -DFRAMEWORK=ON -DCMAKE_INSTALL_PREFIX=/Library/Frameworks -DCMAKE_INSTALL_NAME_DIR=/Library/Frameworks -DCMAKE_BUILD_TYPE=RelWithDebugInfo -DBUILD_EXTRAS=OFF -DBUILD_DEMOS=OFF -DINSTALL_LIBS=ON
OPENGL FOUND
/System/Library/Frameworks/AGL.framework/System/Library/Frameworks/OpenGL.framework
GLUT FOUND
-framework GLUT
CMake Error at src/BulletSoftBody/CMakeLists.txt:49 (SET_TARGET_PROPERTIES):
  set_target_properties called with incorrect number of arguments.


CMake Error at src/BulletDynamics/CMakeLists.txt:103 (SET_TARGET_PROPERTIES):
  set_target_properties called with incorrect number of arguments.


-- Configuring incomplete, errors occurred!
Any suggestions?
deets
Posts: 3
Joined: Fri Mar 05, 2010 4:05 pm

Re: Compiling frameworks on mac

Post by deets »

A short update: removing the lines cmake complained about sucessfully created the frameworks. I didn't toy around with them so far, but assume they are not complete because they miss headers - at least that's what I presume a line such as

Code: Select all

			SET_TARGET_PROPERTIES(BulletDynamics PROPERTIES PUBLIC_HEADER ${Root_HDRS})
does, but at least the build itself works.
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA

Re: Compiling frameworks on mac

Post by Erwin Coumans »

There is an issue for it now:
http://code.google.com/p/bullet/issues/detail?id=357

Thanks for the report,
Erwin
User avatar
Erwin Coumans
Site Admin
Posts: 4221
Joined: Sun Jun 26, 2005 6:43 pm
Location: California, USA

Re: Compiling frameworks on mac

Post by Erwin Coumans »

Bullet is currently only supported/tested as a static library. Shared library and framework features are an external contribution that are not tested at all.

Apparently it requires quotes and a few more fixes. I tried to make some fixes here: http://code.google.com/p/bullet/issues/detail?id=357

Code: Select all

SET_TARGET_PROPERTIES(BulletDynamics PROPERTIES PUBLIC_HEADER "${Root_HDRS}")
One issue is that there seems to be several frameworks generated, shouldn't we just create a single framework?
How about public headers? They depend on the full Bullet/src header hierarchy.
BulletDynamics.framework cannot compile without the BulletCollision headers (which are in a different framework).

Can someone help improving this and make a test for shared libraries/framework?
Thanks,
Erwin
deets
Posts: 3
Joined: Fri Mar 05, 2010 4:05 pm

Re: Compiling frameworks on mac

Post by deets »

If I can help, I'm happy to.

My primary concern with Bullet is wrapping it with Python/ctypes - for this, I began enhancing the C-API, but that's a new post.

However, these require shared libraries to be working. So I'm willing to put some effort into that. However, I'm not experienced with cmake, nor do I know *how* you want to write tests for the shared libraries. Any pointers are welcome.

Regarding the multiple-framework thing - yes, I think a single one would be preferrable.