aws / aws-sdk-cpp

AWS SDK for C++
Apache License 2.0
1.98k stars 1.06k forks source link

Unresolved External Symbols when using Static Libraries #2734

Closed jasonabuzzell closed 1 year ago

jasonabuzzell commented 1 year ago

Describe the bug

Hi there! I'm currently trying to build static, release libraries for C++ code, and I'm running into linker errors. I provided the sample code and reproduction steps below (the basic AWS initialization, and how I make the libraries).

Unsure what I'm missing here, but I'm guessing I need to fill another field with where the static libraries are. Thank you for the help!

Expected Behavior

I expect the code to build and run without linker errors.

Current Behavior

I am getting linker errors for my libraries, as shown below:

main.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) void __cdecl Aws::ShutdownAPI(struct Aws::SDKOptions const &)" (_imp?ShutdownAPI@Aws@@YAXAEBUSDKOptions@1@@z)
main.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) void __cdecl Aws::InitAPI(struct Aws::SDKOptions const &)" (_imp?InitAPI@Aws@@YAXAEBUSDKOptions@1@@z)

Reproduction Steps

#define USE_IMPORT_EXPORT
#define USE_WINDOWS_DLL_SEMANTICS

#include <aws/core/Aws.h>
int main(int argc, char** argv)
{
    Aws::SDKOptions options;
    Aws::InitAPI(options);
    {
        // make your SDK calls here.
    }
    Aws::ShutdownAPI(options);
    return 0;
}

To get the static libraries needed for this, I did the following steps:

Get CMake 3.21.7 and add to PATH C:\Users\Jason > git clone --recurse-submodules https://github.com/aws/aws-sdk-cpp 2.5 C:\Users\Jason > git submodule update --init --recursive C:\Users\Jason > mkdir sdk_build C:\Users\Jason > cd sdk_build C:\Users\Jason\sdk_build > cmake "..\aws-sdk-cpp" -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH="C:/Program Files (x86)/aws-cpp-sdk-all" DFORCE_SHARED_CRT=OFF -DBUILD_SHARED_LIBS=OFF C:\Users\Jason\sdk_build > cmake --build . --config=Release C:\Users\Jason\sdk_build > cmake --install . --config=Release In Visual Studio, add "C:\Program Files (x86)\aws-cpp-sdk-all\include" to Release Configuration: Additional Include Directories In Visual Studio, add "aws-cpp-sdk-core.lib;aws-cpp-sdk-s3.lib;aws-c-auth.lib;aws-c-cal.lib;aws-c-common.lib;aws-c-compression.lib;aws-c-event-stream.lib;aws-checksums.lib;aws-c-http.lib;aws-c-io.lib;aws-c-mqtt.lib;aws-crt-cpp.lib;aws-c-s3.lib;aws-c-sdkutils.lib;aws-cpp-sdk-lambda.lib;%(AdditionalDependencies)" to Release Configuration: Additional Dependencies Add the project folder under Release Configuration: Additional Library Directories to get static libraries. Copy above libs and corresponding dependencies and add them to the project folder (next to main.cpp) Build and run in Release mode.

Possible Solution

No response

Additional Information/Context

No response

AWS CPP SDK version used

Latest (1.11.162)

Compiler and Version used

Visual Studio 17 2022

Operating System and version

Windows 10, Version 22H2

jmklix commented 1 year ago

Not sure if this is your problem, but it looks like you're missing a - before DFORCE_SHARED_CRT=OFF It should be this:

cmake "..\aws-sdk-cpp" -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX="C:/Program Files (x86)/aws-cpp-sdk-all" -DFORCE_SHARED_CRT=OFF -DBUILD_SHARED_LIBS=OFF

Also note that you probably want to use -DBUILD_ONLY="<the services that you want to use>" to improve the time/size needed to build

jmklix commented 1 year ago

What does the CMakeLists.txt look like?

github-actions[bot] commented 1 year ago

Greetings! It looks like this issue hasn’t been active in longer than a week. We encourage you to check if this is still an issue in the latest release. Because it has been longer than a week since the last update on this, and in the absence of more information, we will be closing this issue soon. If you find that this is still a problem, please feel free to provide a comment or add an upvote to prevent automatic closure, or if the issue is already closed, please feel free to open a new one.

jasonabuzzell commented 1 year ago

Hi jmklix! Thank you for catching that missing hyphen. I made sure to run through the steps again from the beginning, making sure the hyphen was in there and I was only building S3, but I still am seeing the prior linker errors. I also do briefly see an error pop up when I cmake the "..\aws-sdk-cpp" folder, not sure what is happening there: image

As to what my CMakeLists.txt looks like (and I assume you aren't referring to the ones in "sdk_build"), I was hoping to do this all through a Visual Studio project without a CMakeLists.txt (as I had done that successfully with the Debug version of the AWS SDK). I am using a framework on top of C++ (JUCE), so if there is a way to do this directly in .vcxproj arguments, that would be awesome!

I did attempt to do this CMakeLists, which looks like below (following https://docs.aws.amazon.com/sdk-for-cpp/v1/developer-guide/build-cmake.html); I'm not sure what parts I should be replacing with my own arguments:

# Set the minimum required version of CMake for this project.
cmake_minimum_required(VERSION 3.13)

# Set the AWS service components used by this project.
set(SERVICE_COMPONENTS s3)

# Set this project's name.
project("hello_s3")

# Set the C++ standard to use to build this target.
# At least C++ 11 is required for the AWS SDK for C++.
set(CMAKE_CXX_STANDARD 11)

# Use the MSVC variable to determine if this is a Windows build.
set(WINDOWS_BUILD ${MSVC})

if (WINDOWS_BUILD) # Set the location where CMake can find the installed libraries for the AWS SDK.
    string(REPLACE ";" "/aws-cpp-sdk-all;" SYSTEM_MODULE_PATH "${CMAKE_SYSTEM_PREFIX_PATH}/aws-cpp-sdk-all")
    list(APPEND CMAKE_PREFIX_PATH ${SYSTEM_MODULE_PATH})
endif ()

# Find the AWS SDK for C++ package.
find_package(AWSSDK REQUIRED COMPONENTS ${SERVICE_COMPONENTS})

if (WINDOWS_BUILD)
    # Copy relevant AWS SDK for C++ libraries into the current binary directory for running and debugging.

    set(BIN_SUB_DIR "/Release") # if you are building from the command line you may need to uncomment this
    # and set the proper subdirectory to the executables' location.

    AWSSDK_CPY_DYN_LIBS(SERVICE_COMPONENTS "" ${CMAKE_CURRENT_BINARY_DIR}${BIN_SUB_DIR})
endif ()

add_executable(${PROJECT_NAME}
        hello_s3.cpp)

target_link_libraries(${PROJECT_NAME}
        ${AWSSDK_LINK_LIBRARIES})

After including the statiic .libs in the same folder and running cmake from terminal, I see this error: image

Thank you for your time!

jmklix commented 1 year ago

If you are looking to do this in visual studio you might want to try using the vcpkg. You can find the steps for how to do this with this sdk here. For further questions about using vcpkg look here.

To use this sdk with JUCE I would check out using the forms here to see how others have done it

Or you can try to build the sdk and your project with cmake. This is what I have the most experience with and want I can help you the most with. I noticed another error in my previous comment which I forgot to correct. Make sure you are using -DCMAKE_INSTALL_PREFIX while you build the sdk and -DCMAKE_PREFIX_PATH while you are building your sample application. The error you are seeing at the end is that it can't find the core library at the default install location. Can you try fixing that, building the sample according to the steps here, and see if that works for you?

jasonabuzzell commented 1 year ago

Thank you jmklix! I got the Release configuration working with the vcpkg method; looks like I call everything from C++ with no problem now. Thank you for also finding a JUCE-friendly resource, I really appreciate you going the extra mile!

There is something strange though that I should probably mention if anyone else is following this route; Aws.h requires that the AWS_SDK_VERSION_MAJOR / MINOR / PATCH be specified, which it isn't using the vcpkg method. I defined some bogus numbers prior to including that header (shown below), but I was wondering if there was a way I should be doing this. image

Thank you again for all of the help! I'll keep the thread open in case, but the actual issue has been resolved!

jmklix commented 1 year ago

I'm glad I was able to help you. If you run into any other problems it's better if you open a new issue/discussion. Closing this issue for now, but please let me know if you have any other problems

github-actions[bot] commented 1 year ago

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see. If you need more assistance, please either tag a team member or open a new issue that references this one. If you wish to keep having a conversation with other community members under this issue feel free to do so.

SerrgeiL commented 9 months ago

I had same problem with link functions from static libraries. Just not define USE_IMPORT_EXPORT when you want to use static libraries. Remove any definition in code before includes of AWS SDK headers. USE_IMPORT_EXPORT need only for dynamic libraries https://github.com/aws/aws-sdk-cpp/blob/main/docs/SDK_usage_guide.md#build-defines.