View Issue Details Jump to Notes ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0010190CMakeCMakepublic2010-01-26 09:142010-02-01 09:52
ReporterArtyom 
Assigned ToBill Hoffman 
PrioritynormalSeveritymajorReproducibilityalways
StatusclosedResolutionno change required 
PlatformOSOS Version
Product VersionCMake-2-6 
Target VersionFixed in Version 
Summary0010190: CMakes names import and static library using same naming convention causes collapse.
DescriptionIn many cases when you create library project you create two builds of same
library -- static and dynamic with same name.

For Example:

add_library(foo SHARED foo.cpp)
set_target_properties(foo PROPERTIES CLEAN_DIRECT_OUTPUT 1 OUTPUT_NAME "foo")
add_library(foo-s STATIC foo.cpp)
set_target_properties(foo-s PROPERTIES CLEAN_DIRECT_OUTPUT 1 OUTPUT_NAME "foo")

On most platforms (including win32) it works right according to system
conventions, however, under MSVC builds (MSVC9 reproduced) it creates
import library and static library with SAME file name. This is incorrect:

Linux/gcc: (ok)

    shared: libfoo.so
    import: ---
    static: libfoo.a

Cygwin/gcc: (ok)

    shared: cygfoo.dll
    import: libfoo.dll.a
    static: libfoo.a

Windows/MinGW: (ok)

    shared: libfoo.dll
    import: libfoo.dll.a
    static: libfoo.a

Windows/MSVC: (wrong)

    shared: foo.dll
    import: foo.lib
    static: foo.lib <---- Collides!!!

Suggested fix:

Use boost naming convention for libraries.

    shared: foo.dll
    import: foo.lib
    static: libfoo.lib
Tagsdll, import library, msvc, static library
Attached Files

 Relationships
related to 0010216closedBill Hoffman Add a CMake way to create a static and shared library at the same time 

  Notes
(0019312)
Bill Hoffman (manager)
2010-01-26 09:33

Unfortunately, that is not the default for Windows developers. However, you can do it in your project by setting that target property for the library prefix.
(0019313)
Artyom (reporter)
2010-01-26 09:39

Any convention would be fine, even like foo.dll foo_imp.lib foo.lib -- all the time this is clear which to use and they do not collide.
(0019315)
Bill Hoffman (manager)
2010-01-26 09:58

The convention on windows is libraryname.lib. So, the convention is to have them collide... If you try and create a static and a shared library with the same name in the VS IDE is says you can not do that. Since there is no accepted convention, CMake really can not just pick one. It is up to each project to pick one that works for them. If we were to make a change like this it would break numerous projects using CMake. Also, it only shows up when you try and build shared and static at the same time. Many projects build either shared or static but not both at the same time.
(0019316)
Artyom (reporter)
2010-01-26 10:14
edited on: 2010-01-26 10:16

But there should be a solution for projects that actually do this.
because if(msvc) set_target_proper.... endif() is workaround, not solution.

I don't this that this is reasonable to enter specific rules for specific Windows compiler. All platforms have conventions, all platforms support both types of libraries. So should Windows/MSVC.

There should be at least error message about collision and not silent ignorance (I had waste few work days to find this bug!)

> If we were to make a change like this it would break numerous
> projects using CMake. Also, it only shows up when you try and
> build shared and static at the same time.

The point that probably that project that do not build both versions would
probably have no issues at all.

You may also change suffix only if OUTPUT_NAME differs from target-name,
or there are static and shared libraries with same OUTPUT_NAME.

>
> Many projects build either shared or static but not both at the same time.
>

But most cross-platform projects create both, also most of project
that migrate from autotools/libtool in order to support MSVC would
have exactly this problem.

(0019320)
Brad King (manager)
2010-01-26 11:36

Use the PREFIX property to get 'lib' on the static library:

add_library(foo SHARED foo.cpp)
set_target_properties(foo PROPERTIES CLEAN_DIRECT_OUTPUT 1 OUTPUT_NAME "foo")
add_library(foo-s STATIC foo.cpp)
set_target_properties(foo-s PROPERTIES CLEAN_DIRECT_OUTPUT 1 OUTPUT_NAME "foo" PREFIX "lib")
(0019347)
Bill Hoffman (manager)
2010-01-28 08:42
edited on: 2010-01-28 08:47

I assume this is your blog entry:

"CppCMS Blog :: Why CMake sucks... (once more)":

http://www.google.com/url?sa=X&q=http://art-blog.no-ip.info/cppcms/blog/post/54&ct=ga&cd=b2K2vXGOQdI&usg=AFQjCNEBKWkfUDh_Fj-MrnSKTW5gvzddTQ [^]

Did you try Brad's suggestion? There is no need for an "if(MSVC)" as you suggest in your "not so nicely" titled blog entry:
if(MSVC)
   set_target_properties(cppcms PROPERY IMPORT_SUFFIX "_imp.lib")
endif()

This should work:
set_target_properties(foo-s PROPERTIES CLEAN_DIRECT_OUTPUT 1 OUTPUT_NAME "foo" PREFIX "lib")

It will cause this:
    shared: foo.dll
    import: foo.lib
    static: libfoo.lib

All the other platforms already use lib for static, so they would remain unchanged.

I suppose we could create a convenience macro add_static_shared(foo ...) that would create automatically set those properties and create two targets.

(0019360)
Artyom (reporter)
2010-01-29 01:35

> I assume this is your blog entry: ...

Yes, indeed.

> This should work:
> set_target_properties(foo-s PROPERTIES CLEAN_DIRECT_OUTPUT 1 OUTPUT_NAME "foo" PREFIX "lib")

I updated as additional possible solution. However, I hope that indeed for all platfroms the static libraries start with "lib" so it would not break something on some other rare platfrom.

> your "not so nicely" titled blog entry

To be honest, this is not my first post on big issues I have with CMake,
however, most of them I had written in my Hebrew blog: http://art-blog.no-ip.info/newpress/blog/cat/28 [^]

For example:

Missing replacement of AC_SEARCH_LIB that can search for functions in
standard library as well (like gethostbyname in libc, nls and socket).
Missing sizeof check in Cross Compilation, autotools solved this issue very
long time ago (and it is quite simple).
Missing simple option like "./configure --help" that would show all options
that can be turned on/off and so on.
Broken pkg-config support when you need to use for loop to add all flags!
when the flags are more then one library, instead of a single line!

And so on.

I indeed think that CMake is not mature as autotools are, however it has
a big advantage -- support of MSVC that auto* do not have.

So I hope that the situation would improve (otherwise I would not post this
bug report).

> I suppose we could create a convenience macro add_static_shared(foo ...) that
> would create automatically set those properties and create two targets.


You absolutly right, it would solve all such issues, without breaking backward
compatibility.

But you should think carefully about:

- How do I disable shared or static when I need (as --disable-(static|shared))
- How can I use shared name to link executables with library and it would pic
  shared by default unless CMAKE_DISABLE_SHARED given, for example:
  
  add_shared_static(foo ....)
  add_executable(bar)
  target_linke_libraries(bar foo)

- How can I set different options for different "subtargets"
- Also creation of libtool ".la" would be very nice ;-), this would allow
  for static only libraries run as

  libtool --mode=link g++ foo.cpp -lbar

  instead of

  g++ foo.cpp -lbar -lz -lboost_foo -lboost_zee -lgcrypt -l...

But this is defenatly optional ;)

Think of libtool... They indeed do very good job in all this.
Unfortunalty I'm not too familiar with CMake to create such modules.

Thanks,
  Artyom
(0019368)
Bill Hoffman (manager)
2010-01-29 13:55

This should work for you:
macro(add_static_shared name sources)
  add_library(${name} SHARED ${sources})
  add_library(${name}-static STATIC ${sources})
  set_target_properties(${name}-static PROPERTIES OUTPUT_NAME "foo")
  set_target_properties(${name}-static PROPERTIES PREFIX "lib")
endmacro(add_static_shared)

If you want an official way to do this in CMake, please create a new feature request bug.

Missing replacement of AC_SEARCH_LIB that can search for functions in
standard library as well (like gethostbyname in libc, nls and socket). - This certainly can be done in CMake, see the curl CMake file included with Cmake.

Missing sizeof check in Cross Compilation - CMake has been able to do this for over a year now.

Broken pkg-config support when you need to use for loop to add all flags! - Not sure what you are talking about here, but pkg-config is not something that we like to rely on because it is not found on all platforms. Many debian based projects do not even support it...


Missing simple option like "./configure --help" that would show all options
that can be turned on/off and so on. - This is hard to do because of the CMake language, but the cmake-gui can show the options. It is very easy to create a CMake file where options depend on other options. However, there are a few ways to do this that we have thought about. Most likely this feature will be implemented this year...

You have to remember that CMake is cross platform. So, it has to live in very different worlds. What seems totally obvious to a Linux developer maybe totally foreign to a Windows developer. I think CMake is full featured enough to get the job done, and done well. However, depending on how a project was developed CMake needs to support different styles. Creating shared and static libraries at the same time is a style that is supported, but needs some customization.

However, I think we have exhausted this bug report... If you don't mind, I am going to close it. If you want to discuss any of these issues on the CMake mailing list, that would be a better place for this type of discussion. Anyway, as a result of this, the FAQ has been updated with an example that shows how to make the libraries not get clobbered on windows. So, thanks for that.
(0019373)
Artyom (reporter)
2010-01-31 06:55

I don't mind. Probably it may be converted to feature request for add_static_shared

 Issue History
Date Modified Username Field Change
2010-01-26 09:14 Artyom New Issue
2010-01-26 09:30 Artyom Tag Attached: dll
2010-01-26 09:30 Artyom Tag Attached: import library
2010-01-26 09:30 Artyom Tag Attached: msvc
2010-01-26 09:30 Artyom Tag Attached: static library
2010-01-26 09:33 Bill Hoffman Note Added: 0019312
2010-01-26 09:33 Bill Hoffman Status new => assigned
2010-01-26 09:33 Bill Hoffman Assigned To => Bill Hoffman
2010-01-26 09:39 Artyom Note Added: 0019313
2010-01-26 09:58 Bill Hoffman Note Added: 0019315
2010-01-26 10:14 Artyom Note Added: 0019316
2010-01-26 10:16 Artyom Note Edited: 0019316
2010-01-26 11:36 Brad King Note Added: 0019320
2010-01-28 08:42 Bill Hoffman Note Added: 0019347
2010-01-28 08:47 Bill Hoffman Note Edited: 0019347
2010-01-29 01:35 Artyom Note Added: 0019360
2010-01-29 13:55 Bill Hoffman Note Added: 0019368
2010-01-31 06:55 Artyom Note Added: 0019373
2010-02-01 09:52 Bill Hoffman Status assigned => closed
2010-02-01 09:52 Bill Hoffman Resolution open => no change required
2010-02-01 09:54 Bill Hoffman Relationship added related to 0010216


Copyright © 2000 - 2018 MantisBT Team