kcat / alure

Alure is a utility library for OpenAL, providing a C++ API and managing common tasks that include file loading, caching, and streaming
zlib License
70 stars 20 forks source link

Alure libraries can't be linked dynamically on Windows #43

Open Huy-Ngo opened 4 years ago

Huy-Ngo commented 4 years ago

When I tried to build Windows wheel for palace, I has successfully installed OpenAL and alure libraries. However, when the wheel is being built, it is as if these libraries are not there.

Building Custom Rule C:/projects/alure/CMakeLists.txt
  -- Install configuration: "Release"
  -- Installing: C:/Program Files (x86)/alure/lib/alure2.lib
  -- Installing: C:/Program Files (x86)/alure/bin/alure2.dll
  -- Installing: C:/Program Files (x86)/alure/lib/alure2_s.lib
  -- Installing: C:/Program Files (x86)/alure/lib/cmake/Alure2/Alure2Config.cmake
  -- Installing: C:/Program Files (x86)/alure/lib/cmake/Alure2/Alure2Config-release.cmake
  -- Installing: C:/Program Files (x86)/alure/include/AL/alure2.h
  -- Installing: C:/Program Files (x86)/alure/include/AL/alure2-aliases.h
  -- Installing: C:/Program Files (x86)/alure/include/AL/alure2-typeviews.h
  -- Installing: C:/Program Files (x86)/alure/include/AL/alure2-alext.h
  -- Installing: C:/Program Files (x86)/alure/include/AL/efx.h
  -- Installing: C:/Program Files (x86)/alure/include/AL/efx-presets.h
...
  LINK : fatal error LNK1181: cannot open input file 'libalure2-NOTFOUND.obj'
  error: command 'C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\BIN\\x86_amd64\\link.exe' failed with exit status 1181

Please take a look at the full log

Here is the CMakeLists.txt file:

cmake_minimum_required(VERSION 2.6.0)
project(palace)
find_package(Alure2 REQUIRED CONFIG)

get_target_property(include_dirs Alure2::alure2 INTERFACE_INCLUDE_DIRECTORIES)
message("alure2_include_dirs=${include_dirs}")

get_target_property(link_libraries Alure2::alure2 INTERFACE_LINK_LIBRARIES)
get_target_property(libalure2 Alure2::alure2 IMPORTED_LOCATION_NOCONFIG)
message("alure2_extra_objects=${link_libraries};${libalure2}")
kcat commented 4 years ago

It looks like Alure is installed with Release mode, so it should have the IMPORTED_LOCATION_RELEASE property, rather than IMPORTED_LOCATION_NOCONFIG.

From what I can see, the target should have the property IMPORTED_CONFIGURATIONS, which contains a list of configurations the found package has available. You can instead get the IMPORTED_LOCATION property to get any configuration, however this doesn't guarantee which configuration you'll get if there's more than one. So, at least if it's possible to have more than one build configuration installed at a time, it would probably be better to get the IMPORTED_CONFIGURATIONS property and search for a desired one (RELEASE, MINSIZEREL, RELWITHDEBINFO, DEBUG, etc), then get the specific imported location you want, or fall back to the generic IMPORTED_LOCATION if you don't find a desired config listed.

McSinyx commented 4 years ago

@kcat, thanks for the pointer to our problem! I can't get IMPORTED_LOCATION to work on my GNU/Linux system, so I look it up and turns out

Projects may skip IMPORTED_LOCATION if the configuration-specific property IMPORTED_LOCATION_<CONFIG> is set. To get the location of an imported target read one of the LOCATION or LOCATION_<CONFIG> properties.

@Huy-Ngo, I think using just LOCATION may work for our case.

Huy-Ngo commented 4 years ago

Thanks. I will try that.

McSinyx commented 4 years ago

@kcat, as seen in the linked palace's PR, both IMPORTED_LOCATION_RELEASE and LOCATION gives DLLs. I'm not familiar with the build system on Windows but it seems that we need .lib files instead for linkage. I am wondering if it's safe to substitude bin/*.dll with lib/*.lib or is there any more canonical method to get the .libs.

kcat commented 4 years ago

It looks like IMPORTED_IMPLIB contains the .lib name for Windows. Though annoyingly, it doesn't seem to be used on other platforms (aside from AIX). I unfortunately don't see a target property that holds the file to link with at link time for any given platform (the .so on Linux, the .a or .dll on MinGW, the .lib on MSVC, etc).

As far as CMake goes, you're normally supposed to just specify Alure2::alure2 for a target you want to link against, and it automatically applies the proper libs and compile switches and stuff for that target. But I don't know how you'd access or print that information manually.

McSinyx commented 4 years ago

It looks like IMPORTED_IMPLIB contains the .lib name for Windows.

Thanks, I've just recognized that we made a typo when trying this. I'm looking forward to seeing it working. Edit: IMPORTED_IMPLIB gives libalure2-NOTFOUND :disappointed:

I unfortunately don't see a target property that holds the file to link with at link time for any given platform

I don't think that's a problem, since CMake's output it parsed by Python build tools, so we can apply some simple conditional to get what we want. We couldn't found a way to build using CMake target directly because it is really difficult (I'm not sure if it's entirely impossible) to make Python, Cython in CMake to work together and output to a hook where we can continue in Python build procedure to build a wheel.

SeanTolstoyevski commented 4 years ago

It is not a good idea to use Cmake directly with Python. Windows users don't like doing these.

All popular python packages have a compiled .whl version. Setting this up is always great.

Alure cannot be compiled with vs2019.

I compiled it with MinGW.

McSinyx commented 4 years ago

@SeanTolstoyevski, FYI we're trying to build the wheels to distribute to our users :wink: And since python.org provide CPython binaries compiled by VC++, we can't use MinGW. We do expect to have to perform some hacks to get it working, but at the time of writing we haven't figured out what are those yet :smile:

I'm cross-linking McSinyx/palace#99 for the ease of future reference.