skypjack / uvw

Header-only, event based, tiny and easy to use libuv wrapper in modern C++ - now available as also shared/static library!
MIT License
1.82k stars 207 forks source link

Error when building on Windows - multiple rules generate _deps/libuv-build/uv.lib #308

Closed kenkopelson closed 4 months ago

kenkopelson commented 9 months ago

The following error is generated when compiling on Windows 10 using clang++:

ninja: error: build.ninja:914: multiple rules generate _deps/libuv-build/uv.lib

From what I can see, the build.ninja file has the following section in it:

#############################################
# Link the shared library _deps\libuv-build\uv.dll

build _deps/libuv-build/uv.dll _deps/libuv-build/uv.lib: C_SHARED_LIBRARY_LINKER__uv_Debug _deps/libuv-build/CMakeFiles/uv.dir/src/fs-poll.c.obj _deps/libuv-build/CMakeFiles/uv.dir/src/idna.c.obj _deps/libuv-build/CMakeFiles/uv.dir/src/inet.c.obj _deps/libuv-build/CMakeFiles/uv.dir/src/random.c.obj _deps/libuv-build/CMakeFiles/uv.dir/src/strscpy.c.obj _deps/libuv-build/CMakeFiles/uv.dir/src/strtok.c.obj _deps/libuv-build/CMakeFiles/uv.dir/src/thread-common.c.obj _deps/libuv-build/CMakeFiles/uv.dir/src/threadpool.c.obj _deps/libuv-build/CMakeFiles/uv.dir/src/timer.c.obj _deps/libuv-build/CMakeFiles/uv.dir/src/uv-common.c.obj _deps/libuv-build/CMakeFiles/uv.dir/src/uv-data-getter-setters.c.obj _deps/libuv-build/CMakeFiles/uv.dir/src/version.c.obj _deps/libuv-build/CMakeFiles/uv.dir/src/win/async.c.obj _deps/libuv-build/CMakeFiles/uv.dir/src/win/core.c.obj _deps/libuv-build/CMakeFiles/uv.dir/src/win/detect-wakeup.c.obj _deps/libuv-build/CMakeFiles/uv.dir/src/win/dl.c.obj _deps/libuv-build/CMakeFiles/uv.dir/src/win/error.c.obj _deps/libuv-build/CMakeFiles/uv.dir/src/win/fs.c.obj _deps/libuv-build/CMakeFiles/uv.dir/src/win/fs-event.c.obj _deps/libuv-build/CMakeFiles/uv.dir/src/win/getaddrinfo.c.obj _deps/libuv-build/CMakeFiles/uv.dir/src/win/getnameinfo.c.obj _deps/libuv-build/CMakeFiles/uv.dir/src/win/handle.c.obj _deps/libuv-build/CMakeFiles/uv.dir/src/win/loop-watcher.c.obj _deps/libuv-build/CMakeFiles/uv.dir/src/win/pipe.c.obj _deps/libuv-build/CMakeFiles/uv.dir/src/win/thread.c.obj _deps/libuv-build/CMakeFiles/uv.dir/src/win/poll.c.obj _deps/libuv-build/CMakeFiles/uv.dir/src/win/process.c.obj _deps/libuv-build/CMakeFiles/uv.dir/src/win/process-stdio.c.obj _deps/libuv-build/CMakeFiles/uv.dir/src/win/signal.c.obj _deps/libuv-build/CMakeFiles/uv.dir/src/win/snprintf.c.obj _deps/libuv-build/CMakeFiles/uv.dir/src/win/stream.c.obj _deps/libuv-build/CMakeFiles/uv.dir/src/win/tcp.c.obj _deps/libuv-build/CMakeFiles/uv.dir/src/win/tty.c.obj _deps/libuv-build/CMakeFiles/uv.dir/src/win/udp.c.obj _deps/libuv-build/CMakeFiles/uv.dir/src/win/util.c.obj _deps/libuv-build/CMakeFiles/uv.dir/src/win/winapi.c.obj _deps/libuv-build/CMakeFiles/uv.dir/src/win/winsock.c.obj
  LANGUAGE_COMPILE_FLAGS = -O0 -D_DEBUG -D_DLL -D_MT -Xclang --dependent-lib=msvcrtd -g -Xclang -gcodeview
  LINK_LIBRARIES = -lpsapi.lib  -luser32.lib  -ladvapi32.lib  -liphlpapi.lib  -luserenv.lib  -lws2_32.lib  -ldbghelp.lib  -lole32.lib  -luuid.lib  -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 -loldnames
  OBJECT_DIR = _deps\libuv-build\CMakeFiles\uv.dir
  POST_BUILD = cd .
  PRE_LINK = cd .
  RESTAT = 1
  TARGET_COMPILE_PDB = _deps\libuv-build\CMakeFiles\uv.dir\
  TARGET_FILE = _deps\libuv-build\uv.dll
  TARGET_IMPLIB = _deps\libuv-build\uv.lib
  TARGET_PDB = _deps\libuv-build\uv.pdb

This has the following targets at the top:

build _deps/libuv-build/uv.dll _deps/libuv-build/uv.lib

Then, further down in the build.ninja file (generated by CMake), we have the following:

#############################################
# Link the static library _deps\libuv-build\uv.lib

build _deps/libuv-build/uv.lib: C_STATIC_LIBRARY_LINKER__uv_a_Debug _deps/libuv-build/CMakeFiles/uv_a.dir/src/fs-poll.c.obj _deps/libuv-build/CMakeFiles/uv_a.dir/src/idna.c.obj _deps/libuv-build/CMakeFiles/uv_a.dir/src/inet.c.obj _deps/libuv-build/CMakeFiles/uv_a.dir/src/random.c.obj _deps/libuv-build/CMakeFiles/uv_a.dir/src/strscpy.c.obj _deps/libuv-build/CMakeFiles/uv_a.dir/src/strtok.c.obj _deps/libuv-build/CMakeFiles/uv_a.dir/src/thread-common.c.obj _deps/libuv-build/CMakeFiles/uv_a.dir/src/threadpool.c.obj _deps/libuv-build/CMakeFiles/uv_a.dir/src/timer.c.obj _deps/libuv-build/CMakeFiles/uv_a.dir/src/uv-common.c.obj _deps/libuv-build/CMakeFiles/uv_a.dir/src/uv-data-getter-setters.c.obj _deps/libuv-build/CMakeFiles/uv_a.dir/src/version.c.obj _deps/libuv-build/CMakeFiles/uv_a.dir/src/win/async.c.obj _deps/libuv-build/CMakeFiles/uv_a.dir/src/win/core.c.obj _deps/libuv-build/CMakeFiles/uv_a.dir/src/win/detect-wakeup.c.obj _deps/libuv-build/CMakeFiles/uv_a.dir/src/win/dl.c.obj _deps/libuv-build/CMakeFiles/uv_a.dir/src/win/error.c.obj _deps/libuv-build/CMakeFiles/uv_a.dir/src/win/fs.c.obj _deps/libuv-build/CMakeFiles/uv_a.dir/src/win/fs-event.c.obj _deps/libuv-build/CMakeFiles/uv_a.dir/src/win/getaddrinfo.c.obj _deps/libuv-build/CMakeFiles/uv_a.dir/src/win/getnameinfo.c.obj _deps/libuv-build/CMakeFiles/uv_a.dir/src/win/handle.c.obj _deps/libuv-build/CMakeFiles/uv_a.dir/src/win/loop-watcher.c.obj _deps/libuv-build/CMakeFiles/uv_a.dir/src/win/pipe.c.obj _deps/libuv-build/CMakeFiles/uv_a.dir/src/win/thread.c.obj _deps/libuv-build/CMakeFiles/uv_a.dir/src/win/poll.c.obj _deps/libuv-build/CMakeFiles/uv_a.dir/src/win/process.c.obj _deps/libuv-build/CMakeFiles/uv_a.dir/src/win/process-stdio.c.obj _deps/libuv-build/CMakeFiles/uv_a.dir/src/win/signal.c.obj _deps/libuv-build/CMakeFiles/uv_a.dir/src/win/snprintf.c.obj _deps/libuv-build/CMakeFiles/uv_a.dir/src/win/stream.c.obj _deps/libuv-build/CMakeFiles/uv_a.dir/src/win/tcp.c.obj _deps/libuv-build/CMakeFiles/uv_a.dir/src/win/tty.c.obj _deps/libuv-build/CMakeFiles/uv_a.dir/src/win/udp.c.obj _deps/libuv-build/CMakeFiles/uv_a.dir/src/win/util.c.obj _deps/libuv-build/CMakeFiles/uv_a.dir/src/win/winapi.c.obj _deps/libuv-build/CMakeFiles/uv_a.dir/src/win/winsock.c.obj
  LANGUAGE_COMPILE_FLAGS = -O0 -D_DEBUG -D_DLL -D_MT -Xclang --dependent-lib=msvcrtd -g -Xclang -gcodeview
  OBJECT_DIR = _deps\libuv-build\CMakeFiles\uv_a.dir
  POST_BUILD = cd .
  PRE_LINK = cd .
  TARGET_COMPILE_PDB = _deps\libuv-build\CMakeFiles\uv_a.dir\uv_a.pdb
  TARGET_FILE = _deps\libuv-build\uv.lib
  TARGET_PDB = _deps\libuv-build\uv.pdb

This has the exact same target at the top, as the file in the SHARED library:

build _deps/libuv-build/uv.lib

As I'm sure you know, the static build uses the uv.lib file to contain all the contents of the library, while the same file in the shared build is used as the interface library file to the DLL. Even through the files are named the same, they will be different depending on whether they are linked for static or shared. Thus, it is invalid to build both the static and shared files, if the .lib file is named the same thing for each. It seems that the build files should only build the STATIC OR THE SHARED, but not both. Or call the files something different.

kenkopelson commented 9 months ago

It seems that you have this line in the root CMakeLists.txt file (line #41):

if(BUILD_UVW_SHARED_LIB)
    set(BUILD_UVW_LIBS BOOL:ON)
endif()

This seems it could be wrong, since it will force the static lib to be built if the shared lib is requested. As I looked down further, I found this section, which seems to require both flags, but the files are not called the same: one is "uv" and the other is "uv_a".

if(FETCH_LIBUV AND BUILD_UVW_LIBS)
    # libuv is only fetched when both above conditions are true
    install(DIRECTORY ${libuv_SOURCE_DIR}/include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/uvw/uv/include)
    if (BUILD_UVW_SHARED_LIB)
        install(TARGETS uv EXPORT uvwConfig LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/uvw)
    else()
        install(TARGETS uv_a EXPORT uvwConfig ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}/uvw)
    endif()
endif(FETCH_LIBUV AND BUILD_UVW_LIBS)

The build.ninja file does not have those file name differences, so perhaps that is where the error is.

kenkopelson commented 9 months ago

As I perused through the CMakeLists.txt files, it appeared that an assumption was made that the uvw.lib file produced during STATIC library build is compatible with uvw.lib file produced during SHARED library build. This is not the case, so it looks like a bit of rework will be required to get the make files working properly. I need to use this library very soon, so if there is any way you can fix this in a timely fashion, it would be incredibly appreciated. I like the work you did on this, and would like to put it to good use.

skypjack commented 9 months ago

To be honest, I don't understand yet if you're hitting a wall with the static lib, the shared lib or while trying to mix them in the same executable. Can we start from what you're trying to do? Just to exclude XY-problems first of all. Thanks. 👍

skypjack commented 4 months ago

Closing this issue as starving. Feel free to reopen it or continue the discussion here if needed. Thanks.