thestk / rtaudio

A set of C++ classes that provide a common API for realtime audio input/output across Linux (native ALSA, JACK, PulseAudio and OSS), Macintosh OS X (CoreAudio and JACK), and Windows (DirectSound, ASIO, and WASAPI) operating systems.
Other
1.51k stars 322 forks source link

LNK2038 and many LNK2005 errors when compiling with MSVC #256

Closed nyanpasu64 closed 4 years ago

nyanpasu64 commented 4 years ago

I upgraded to RtAudio master 52518e9. In a1ddca0c452c05a5f5d0b36d5a5648296061d4e2, RtAudio was changed so that on MSVC, it will link to static MSVCRT.

(https://cmake.org/cmake/help/v3.15/prop_tgt/MSVC_RUNTIME_LIBRARY.html seems to be a more elegant API than string slicing, but only exists on CMake 3.15 and later.)

However my app links to RtAudio statically but MSVCRT dynamically. Since RtAudio links to MSVCRT statically, I get rtaudiod.lib(RtAudio.cpp.obj):-1: error: LNK2038: mismatch detected for 'RuntimeLibrary': value 'MTd_StaticDebug' doesn't match value 'MDd_DynamicDebug' in sync.cpp.obj and many LNK2005 errors for standard library symbols.

I noticed that protobuf now allows the user to choose between static or dynamic MSVCRT, using dependent options.

https://github.com/protocolbuffers/protobuf/blob/master/cmake/CMakeLists.txt

https://github.com/protocolbuffers/protobuf/blob/e492e5a4ef16f59010283befbde6112f1995fa0f/cmake/CMakeLists.txt#L180

However I dislike when libraries I build as part of my program use options, because they get persisted to the filesystem and are difficult to set programmatically (if I want to change their value from my CMakeLists, I must delete the CMakeCache.txt file).

Additionally, RTAUDIO_BUILD_SHARED_LIBS and RTAUDIO_BUILD_STATIC_LIBS are variables, not options. I don't think dependent options can depend on variables.

I came up with a fairly elegant solution I applied locally. I can send a PR if desired.

if (NOT DEFINED RTAUDIO_STATIC_LIBC)
  set(RTAUDIO_STATIC_LIBC ${RTAUDIO_IS_STATIC})
endif()

# In MSVC, set MD/MT appropriately for a static library
# (From https://github.com/protocolbuffers/protobuf/blob/master/cmake/CMakeLists.txt)
if(MSVC AND RTAUDIO_STATIC_LIBC)
  ...

Is it worth adding a RTAUDIO_SHARED_LIBC variable as well? That would increase complexity and I don't have the motivation to implement that.

EDIT: RTAUDIO_MSVC_STATIC_RUNTIME? RTAUDIO_STATIC_MSVC(RT)?

radarsat1 commented 4 years ago

(inappropriate comment on cmake's fitness as a build system edited out 😅... sorry, way too much time spent trying to get cmake configurations "just right" lately)

Sure, go ahead and make a PR, thanks, much appreciated. I agree the choice of which runtime to link and whether shared or static libraries are built should be distinct. And we should move towards CMake 3.15 eventually and whatever help it provides for this. I dragged it back to 3.10 when someone complained about moving it forward.. can't win.