title: How to statically link libusb (1.0) into C++ executable with CMake?
body: <p>Using CLion and CMake (3.12.2) with MinGW (W64 6.0), I am trying to compile a simple 'Stub' executable using some libusb example code.  I would like for the executable to be statically linked, and not require the .dll to be placed alongside it upon execution. Eventually, I would like to statically link on Linux as well, as these executables will run in a cgi-bin.  </p>
  
  <p>I've tried linking in libusb-1.0.a included with the libusb files specifically for mingw-w64 with no luck. </p>
  
  <p>Here is the simple example program:</p>
  
  <pre class="lang-cpp prettyprint-override"><code>// This program was copied from Wikipedia: https://en.wikipedia.org/wiki/C%2B%2B#Language
  
  #include &lt;iostream&gt;
  #include &lt;cstdio&gt;
  #include &lt;libusb.h&gt;
  
  using namespace std;
  
  static void print_devs(libusb_device **devs) {
      libusb_device *dev;
      int i = 0, j = 0;
      uint8_t path[8];
  
      while ((dev = devs[i++]) != NULL) {
          struct libusb_device_descriptor desc;
          int r = libusb_get_device_descriptor(dev, &amp;desc);
          if (r &lt; 0) {
              fprintf(stderr, "failed to get device descriptor");
              return;
          }
  
          printf("%04x:%04x (bus %d, device %d)",
                 desc.idVendor, desc.idProduct,
                 libusb_get_bus_number(dev), libusb_get_device_address(dev));
  
          r = libusb_get_port_numbers(dev, path, sizeof(path));
          if (r &gt; 0) {
              printf(" path: %d", path[0]);
              for (j = 1; j &lt; r; j++)
                  printf(".%d", path[j]);
          }
          printf("&lt;br /&gt;\n");
      }
  }
  
  int main() {
      cout &lt;&lt; "Content-type: text/html\r\n\r\n";
  
  
      libusb_device **devs;
      int r;
      ssize_t cnt;
  
      r = libusb_init(NULL);
      if (r &lt; 0)
          return r;
  
      cnt = libusb_get_device_list(NULL, &amp;devs);
      if (cnt &lt; 0) {
          libusb_exit(NULL);
          return (int) cnt;
      }
  
      // Output HTML boilerplate
      cout &lt;&lt; "&lt;!doctype html&gt;\n";
      cout &lt;&lt; "&lt;html lang=\"en\"&gt;\n";
      cout &lt;&lt; "&lt;head&gt;\n";
      cout &lt;&lt; "&lt;/head&gt;\n";
      cout &lt;&lt; "&lt;body&gt;\n";
      cout &lt;&lt; "Hello, world!&lt;br /&gt;\n\n";
      cout &lt;&lt; "Listing USB devices...&lt;br /&gt;&lt;br /&gt;\n";
      print_devs(devs);
      cout &lt;&lt; "&lt;/body&gt;\n";
      cout &lt;&lt; "&lt;/html&gt;";
      libusb_free_device_list(devs, 1);
  
      libusb_exit(NULL);
      return 0;
  
  }
  </code></pre>
  
  <p>Here is the CMakeLists.txt:</p>
  
  <pre><code>cmake_minimum_required (VERSION 2.8.4)
  
  # Temporary project
  project (Stub)
  
  
  # Add the stub file for compilation as an executable.
  add_executable (Stub stub.cpp)
  
  # Add libraries
  
  if (UNIX)
     target_link_libraries(Stub -L/${CMAKE_SOURCE_DIR}/dependencies/lib/Linux/x64 usb-1.0 udev pthread)
  endif (UNIX)
  
  # For windows
  if(WIN32)
     link_directories(${CMAKE_SOURCE_DIR}/dependencies/lib/windows/x86)
     target_link_libraries(Stub ${CMAKE_SOURCE_DIR}/dependencies/libusb-1.0.a ${CMAKE_SOURCE_DIR}/dependencies/lib/windows/x86/libusb-1.0.lib)
  endif(WIN32)
  
  # Add include directories
  target_include_directories(Stub PUBLIC ${CMAKE_SOURCE_DIR}/dependencies/include/libusb-1.0)
  </code></pre>
  
  <p>I have tried to remove "target_include_directories", but the build fails, and I end up having to put this back in.  No matter how I tweak it, the build either fails, or the resulting executable is dependent on the .dll when I try to execute it.  On the Linux side of things, I am not sure if the static linking is possible with CMake due to the need for udev. I am completely unfamiliar with CMake and how it works to accomplish this task on both OS halves of my project.</p>