Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Linking with libpe-sieve.a fails (MinGW) #71

Open
hillu opened this issue Aug 3, 2020 · 8 comments
Open

Linking with libpe-sieve.a fails (MinGW) #71

hillu opened this issue Aug 3, 2020 · 8 comments

Comments

@hillu
Copy link
Contributor

hillu commented Aug 3, 2020

Hi,

when trying to build this simple no-op program t.c

#include "pe_sieve_api.h"
int main() {
  PEsieve_params pp = {0};
  PESieve_scan(pp);
}

…using this following Makefile…

CC=x86_64-w64-mingw32-g++
CFLAGS=-I_pe-sieve/include
LDFLAGS=-L_pe-sieve -lpe-sieve
_t/t: _t/t.c
	$(CC) $(CFLAGS) -o $@ $< $(LDFLAGS)

…I get the following error:

x86_64-w64-mingw32-g++ -I_pe-sieve/include -o _t/t _t/t.c -L_pe-sieve -lpe-sieve
/usr/bin/x86_64-w64-mingw32-ld: /tmp/ccGImspX.o:t.c:(.text+0x76): undefined reference to `__imp_PESieve_scan'
collect2: error: ld returned 1 exit status
make: *** [Makefile:6: _t/t] Error 1

Seems to me like PESieve_scan is not a visible symbol.

Adding a __declspec(dllexport) to PESIEVE_API_FUNC seems to fix the linker error, but I am not at all sure if this is the right way.

(After that the linker complained about missing symbols from -llibpeconv and ultimately about missing symbols that could be resolved using -lpsapi -lntdll -lshlwapi, but the main issue was the non-visible PESieve_scan symbol.)

@hillu
Copy link
Contributor Author

hillu commented Aug 3, 2020

Uh, I think I got the solutionn wrong. If make sure that neither dllimport nor dllexport are seen by the C++ compiler, I can build the static library and link against it. Seems that there's nothing wrong with the static library itself but with pe_sieve_api.h as it is processed as included from t.c.

@hasherezade
Copy link
Owner

Thank you for reporting. I am currently very busy, but I will fix it as soon as I will get a bit free.
Can you please share as many details as possible on the full process of how are you building it, so that I can reproduce it quickly?

@hillu
Copy link
Contributor Author

hillu commented Aug 5, 2020

I think the only missing piece is the script I used to fetch and build pe-sieve in the subdirectory _pesieve that is referenced in the Makefile:

#!/bin/sh

set -e

test -d _pe-sieve \
    || git clone --recurse-submodules https://github.com/hasherezade/pe-sieve _pe-sieve
cd _pe-sieve

cmake . \
    -DCMAKE_C_COMPILER=x86_64-w64-mingw32-gcc \
    -DCMAKE_CXX_COMPILER=x86_64-w64-mingw32-g++ \
    -DCMAKE_SYSTEM_NAME=Windows-GNU \
    -DPESIEVE_AS_STATIC_LIB=1

make -j4

@hasherezade
Copy link
Owner

hi, can you please try again after my last updates? I tried it on my side and it seems to work...

linked

@hillu
Copy link
Contributor Author

hillu commented Aug 14, 2020

With a freshly-checked-out pe-sieve (1fa2fd1) and libpeconv (8cbfef1d10e2d5cf05f81be101d050e9f0094693), I can confirm that libpe-sieve.a gets built. (This hadn't been a problem anyway when I reported this issue.)

However, it still cannot be linked against my little test porgram:

$ make -f Makefile.t
x86_64-w64-mingw32-g++ -I_pe-sieve/include -o _t/t _t/t.c -L_pe-sieve -lpe-sieve
/usr/bin/x86_64-w64-mingw32-ld: /tmp/cclLZtTs.o:t.c:(.text+0x76): undefined reference to `__imp_PESieve_scan'
collect2: error: ld returned 1 exit status
make: *** [Makefile.t:5: _t/t] Error 1

@hasherezade
Copy link
Owner

thanks for checking. it is weird because it managed to build Hollows Hunter using this script, and had no linking problems. can you share a script that you used for building your test app? I will keep trying...

@jpohls1
Copy link
Contributor

jpohls1 commented Jul 26, 2023

I'm running into the same issue. Here is a full script to reproduce the error:

#!/bin/sh

set -e
set -x

git clone --depth=1 --recurse-submodules https://github.com/hasherezade/pe-sieve pe-sieve
cd pe-sieve

cmake . \
    -DCMAKE_C_COMPILER=x86_64-w64-mingw32-gcc \
    -DCMAKE_CXX_COMPILER=x86_64-w64-mingw32-g++ \
    -DCMAKE_SYSTEM_NAME=Windows-GNU \
    -DPESIEVE_AS_STATIC_LIB=1
# Second cmake call is necessary, otherwise make fails with
# make[2]: windres: No such file or directory
cmake .

make -j`nproc`

cat <<EOT > test.cpp
#include "pe_sieve_api.h"
int main() {
  PEsieve_params pp = {0};
  PESieve_scan(pp);
}
EOT

x86_64-w64-mingw32-g++ -I./include -L. -lpe-sieve test.cpp

At the end, it fails with:

/usr/bin/x86_64-w64-mingw32-ld: /tmp/ccIxfGFH.o:test.cpp:(.text+0x3b): undefined reference to `__imp_PESieve_scan'
collect2: error: ld returned 1 exit status

@jpohls1
Copy link
Contributor

jpohls1 commented Jul 27, 2023

I figured it out, here is the full command line to link statically with MinGW for anyone else struggling:

x86_64-w64-mingw32-g++ -DPESIEVE_STATIC_LIB=1 -I./include test.cpp -L. -L./libpeconv/libpeconv/ -lpe-sieve -llibpeconv -lpsapi -lntdll -lshlwapi -limagehlp

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants