I'm building a library ( libproj
) using g++-9 and CMake (on Xenial, on Travis), so I can statically link it in a Rust crate. My build.rs
sets up and runs CMake with the following config:
cmake proj-7.0.1
-DBUILD_SHARED_LIBS=ON
-DBUILD_TESTING=OFF
-DCMAKE_BUILD_TYPE=Release
-DCMAKE_CXX_FLAGS="-std=c++11 -fPIC"
-DCMAKE_INSTALL_PREFIX=[path snipped]/out
-DCMAKE_C_FLAGS= -ffunction-sections -fdata-sections -fPIC -m64
-DCMAKE_C_COMPILER=/usr/bin/gcc-9
-DCMAKE_CXX_COMPILER=/usr/bin/g++-9
-DCMAKE_ASM_FLAGS= -ffunction-sections -fdata-sections -fPIC -m64
-DCMAKE_ASM_COMPILER=/usr/bin/gcc-9
Which builds and installs libproj
successfully .
I then tell cargo to statically link it:
cargo:root=[path snipped]/out
cargo:rustc-link-search=native=[path snipped]/out/lib
cargo:rustc-link-lib=static=proj
However, the link step fails, saying I can't use relocation in a shared object:
note: /usr/bin/ld: [path snipped]/out/lib/libproj.a(4D_api.cpp.o): relocation
R_X86_64_32 against `.rodata.str1.8' can not be used when making a
shared object; recompile with -fPIC`
[path snipped]/out/lib/libproj.a(4D_api.cpp.o): error adding symbols: Bad value
collect2: error: ld returned 1 exit status
What am I doing wrong here? I've also tried to build libproj
as a static lib by setting BUILD_SHARED_LIBS
to OFF
as per the install instructions , but that hasn't had any effect.
UPDATE:
I've managed to enable PIC for g++ (by default it's only enabled for gcc)
running: "cmake" "-Wdev" "--debug-output" "[snipped]/proj-7.0.1" "-DCMAKE_CXX_FLAGS=-std=c++11" "-DCMAKE_CXX_FLAGS=-fPIC" "-DBUILD_SHARED_LIBS=OFF" "-DCMAKE_INSTALL_PREFIX=[snipped]/out" "-DCMAKE_C_FLAGS= -ffunction-sections -fdata-sections -fPIC -m64" "-DCMAKE_C_COMPILER=/usr/bin/gcc-9" "-DCMAKE_CXX_COMPILER=/usr/bin/g++-9" "-DCMAKE_ASM_FLAGS= -ffunction-sections -fdata-sections -fPIC -m64" "-DCMAKE_ASM_COMPILER=/usr/bin/gcc-9" "-DCMAKE_BUILD_TYPE=Debug" "-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON"
Resulting in the following g++-9 invocation, which includes -fPIC
:
/usr/bin/g++-9 -DCURL_ENABLED -DMUTEX_pthread -DPROJ_LIB=\"/[snip]/proj\" -DTIFF_ENABLED -I/[snip]/src -I/[snip]/include -I/[snip]/src -I/usr/include/x86_64-linux-gnu -fPIC -g -fvisibility=hidden -Wall -Wextra -Wswitch -Wshadow -Wunused-parameter -Wmissing-declarations -Wformat -Wformat-security -std=c++11 -o CMakeFiles/proj.dir/aasincos.cpp.o -c /[snip]/proj/proj-7.0.1/src/aasincos.cpp
However, I know get a completely different error (thousands of lines), that looks like my static library hasn't been correctly linked to the c++11 stdlib:
Error :
undefined reference to std::allocator<char>::allocator()
UPDATE 2:
I've managed to remove the -nodefaultlibs
flag from ld
. The latest g++ invocation:
/usr/bin/g++-9 -I/[snipped]/src -I/[snipped]/include -I/[snipped]/src -isystem /[snipped]/include -isystem /[snipped]/googletest -fPIC -g -fvisibility=hidden -Wall -Wextra -Wswitch -Wshadow -Wunused-parameter -Wmissing-declarations -Wformat -Wformat-security -pthread -std=c++11 -o CMakeFiles/proj_context_test.dir/proj_context_test.cpp.o -c /[snipped]/proj_context_test.cpp
And I've managed to add lstdc++
to the linker invocation:
"cc" "-Wl,--as-needed" "-Wl,-z,noexecstack" "-m64" "-L" "/[snip]/lib" "/home/travis/build/georust/proj-sys/target/debug/deps/proj_sys-95cbd73f2c3f0bde.20tasg77xuhsj5z6.rcgu.o" "/home/travis/build/georust/proj-sys/target/debug/deps/proj_sys-95cbd73f2c3f0bde.57y4784ihm3qw715.rcgu.o" "-o" "/[snip]/deps/proj_sys-95cbd73f2c3f0bde" "/home/travis/build/georust/proj-sys/target/debug/deps/proj_sys-95cbd73f2c3f0bde.3kiafs23968zh4mj.rcgu.o" "-Wl,--gc-sections" "-pie" "-Wl,-zrelro" "-Wl,-znow" "-L" "/home/travis/build/georust/proj-sys/target/debug/deps" "-L" "/home/travis/build/georust/proj-sys/target/debug/build/proj-sys-aff2ac9d43b77886/out/lib" "-L" "/home/travis/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-lsqlite3" "-lcurl" "-ltiff" "-lstdc++" "-Wl,-Bstatic" "-Wl,--whole-archive" "-lproj" "-Wl,--no-whole-archive" [trimmed rlib details] "-Wl,--end-group" "/home/travis/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcompiler_builtins-2541f1e09df1c67d.rlib" "-Wl,-Bdynamic" "-ldl" "-lrt" "-lpthread" "-lgcc_s" "-lc" "-lm" "-lrt" "-lpthread" "-lutil" "-lutil"
But the undefined reference error remains.
As I can see from your example, you have quotation marks around CMAKE_CXX_FLAGS
and do not have ones around CMAKE_C_FLAGS
. It looks odd.
I have built libgproj
myself with cmake
+ your flags and with make VERBOSE=1
.
I can see, that C-files compiled without fPIC
, m64
and fdata-sections
. I suppose, that the cause is in the quotation marks around CMAKE_C_FLAGS
. I saw your log in Travis, and there is configuration for cmake
from cargo
:
"cmake" "/home/travis/build/georust/proj-sys/PROJSRC/proj/proj-7.0.1" "-DBUILD_SHARED_LIBS=ON" "-DBUILD_TESTING=OFF" "-DCMAKE_BUILD_TYPE=Release" "-DCMAKE_CXX_FLAGS=-std=c++11 -fPIC" "-DCMAKE_INSTALL_PREFIX=/home/travis/build/georust/proj-sys/target/debug/build/proj-sys-03a5fe6428bb060a/out" "-DCMAKE_C_FLAGS= -ffunction-sections -fdata-sections -fPIC -m64" "-DCMAKE_C_COMPILER=/usr/bin/gcc-9" "-DCMAKE_CXX_COMPILER=/usr/bin/g++-9" "-DCMAKE_ASM_FLAGS= -ffunction-sections -fdata-sections -fPIC -m64" "-DCMAKE_ASM_COMPILER=/usr/bin/gcc-9"
Note, that -DCMAKE_C_FLAGS
and CMAKE_CXX_FLAGS
escaped with their values, and not values by itself. I suppose, that these options become in the shell:
cmake -DCMAKE_C_FLAGS= -ffunction-sections -fdata-sections -fPIC -m64 -DCVMAKE_CXX_FLAGS=-std=c++11 -fPIC
I have tried this command, without quotation marks and cmake just ignored unknown options. So it will not fail.
I suggest you to add cmake option -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON
to cmake configuration or VERBOSE=1
to the make
options, if you can, and then you can see real compile options passed to gcc in Travis.
You will see somethig like this:
[ 19%] Building C object src/CMakeFiles/proj.dir/wkt1_generated_parser.c.o
cd [some path]/PROJ/cmake_build/src && /usr/bin/cc -DCURL_ENABLED -DMUTEX_pthread
-DPROJ_LIB=\"/usr/local/share/proj\" -DTIFF_ENABLED -I[some path]PROJ/src -I[some
path]/PROJ/include -I[some path]/PROJ/cmake_build/src -O3 -DNDEBUG -
fvisibility=hidden -Wall -Wextra -Wswitch -Wshadow -Wunused-parameter -Wmissing-
declarations -Wformat -Wformat-security -Wmissing-prototypes -std=c99 -o
CMakeFiles/proj.dir/wkt1_generated_parser.c.o -c [some
path]/PROJ/src/wkt1_generated_parser.c
Conclusion:
You can try adding verbosity to see real compile options.
You can try to escape options properly, if it's necessary after first step.
Also I want to note, that SHARED_BUILD_LIBS=ON
in my test forbids building static lib, which you want to link. When I set shared libs building setting option to OFF
, static lib was built.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.