How to statically link PROJ to pybind11 - cmake

I'm interested in statically linking PROJ to a library created with pybind11.
but, I get error by cmake.
Why am I getting this error and how can I fix it?
My CMakeLists.txt is this.
cmake_minimum_required(VERSION 3.4)
project(myearth LANGUAGES CXX)
add_subdirectory(pybind11)
pybind11_add_module(myearth MyEarth.cpp)
include_directories(${CMAKE_SOURCE_DIR}/PROJ/include)
add_library(proj4 STATIC IMPORTED)
set_target_properties(proj4 PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/PROJ/lib/libproj.a)
target_link_libraries(myearth PRIVATE proj4)
CMake Error.
I think fPIC option is for shared library. so, libproj.a is not necessary this option because this is static library.
(venv) ~/Projects/LinkLibTest/MySample/build$ make
[ 50%] Building CXX object CMakeFiles/myearth.dir/MyEarth.cpp.o
[100%] Linking CXX shared module myearth.cpython-36m-x86_64-linux-gnu.so
/usr/bin/ld: ../PROJ/lib/libproj.a(proj_4D_api.o): relocation R_X86_64_PC32 against symbol `pj_errno' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: bad value
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/myearth.dir/build.make:98: myearth.cpython-36m-x86_64-linux-gnu.so] Error 1
make[1]: *** [CMakeFiles/Makefile2:100: CMakeFiles/myearth.dir/all] Error 2
make: *** [Makefile:91: all] Error 2
(venv) ~/Projects/LinkLibTest/MySample/build$
I created libproj.a by the following command.
$ ./configure --prefix=/output --disable-shared
$ sudo make
$ sudo make install
Linux Mint 20.3 64bit
CMake v3.22.2
PROJ v5.2.0 (https://proj.org/)
Python v3.6.8
Thank you.

Shared libraries must have position independent code, but your version of PROJ was built without it; you will have to rebuild PROJ with PIC.
$ ./configure --prefix=/output --with-pic

Related

Unable to build FreeRTOS WIN32 demo in Clion

Below is the CmakeLists file that I'm using. I'm using the linker flags from eclipse as it seems to build in eclipse properly.
project(new1 LANGUAGES CXX C)
set(CMAKE_VERBOSE_MAKEFILE ON)
set(CMAKE_CXX_STANDARD 14)
# Compiler options for compiling MinGW targets.
set(CMAKE_C_FLAGS_DEBUG "-D_WIN32_WINNT=0x0601 -DprojCOVERAGE_TEST=0 -fmessage-length=0 -Wcast-qual")
#-------------------------------------------------------------
# Linker options for Linking MinGW targets.
set(CMAKE_EXE_LINKER_FLAGS "-Xlinker -lwinmm")
#-------------------------------------------------------------
include_directories(FreeRTOS/Source/include
FreeRTOS/Source/portable/MSVC-MingW
/)
add_subdirectory(FreeRTOS/Source)
add_executable(application main.cpp)
target_link_libraries(application kernel)
target_link_libraries(application winmm.lib)
The below is the build output
"C:\Program Files\JetBrains\CLion 2020.1.1\bin\cmake\win\bin\cmake.exe" -E cmake_link_script CMakeFiles\application.dir\link.txt --verbose=1
"C:\Program Files\JetBrains\CLion 2020.1.1\bin\cmake\win\bin\cmake.exe" -E remove -f CMakeFiles\application.dir/objects.a
"F:\TrueSTUDIO for STM32 9.0.0\PCTools\bin\ar.exe" cr CMakeFiles\application.dir/objects.a #CMakeFiles\application.dir\objects1.rsp
"F:\TrueSTUDIO for STM32 9.0.0\PCTools\bin\g++.exe" -g -Xlinker -lwinmm -Wl,--whole-archive CMakeFiles\application.dir/objects.a -Wl,--no-whole-archive -o application.exe -Wl,--out-implib,libapplication.dll.a -Wl,--major-image-version,0,--minor-image-version,0 #CMakeFiles\application.dir\linklibs.rsp
FreeRTOS/Source/portable/MSVC-MingW/libport.a(port.c.obj):port.c:(.text+0x15): undefined reference to `timeGetDevCaps#8'
FreeRTOS/Source/portable/MSVC-MingW/libport.a(port.c.obj):port.c:(.text+0x2d): undefined reference to `timeBeginPeriod#4'
FreeRTOS/Source/portable/MSVC-MingW/libport.a(port.c.obj):port.c:(.text+0xd5): undefined reference to `timeGetDevCaps#8'
FreeRTOS/Source/portable/MSVC-MingW/libport.a(port.c.obj):port.c:(.text+0xe7): undefined reference to `timeEndPeriod#4'
collect2.exe: error: ld returned 1 exit status
mingw32-make.exe[3]: *** [application.exe] Error 1
mingw32-make.exe[2]: *** [CMakeFiles/application.dir/all] Error 2
mingw32-make.exe[1]: *** [CMakeFiles/application.dir/rule] Error 2
mingw32-make.exe: *** [application] Error 2
Can somebody help please.
So, there was no issue with linking the winmm library it is just that I'm linking this to a wrong target. It was a dependency of the windows port in freeRTOS/Source/Portable.

How to add Ziplib library in Clion on Ubuntu

I'm trying to add ZipLip into my project using Clion on ubuntu, but I have this output:
====================[ Build | TryZip | Debug ]==================================
/home/david/Snap/clion-2019.2.4/bin/cmake/linux/bin/cmake --build
/home/david/CLionProjects/TryZip/cmake-build-debug --target TryZip -- -j 2
[ 13%] Built target bzip2
[ 31%] Built target zlib
[ 83%] Built target lzma
[ 95%] Built target ZipLib
Scanning dependencies of target TryZip
[ 97%] Linking CXX executable ../bin/TryZip
/usr/bin/ld: cannot find -lExternalLibrary/ZipLib
collect2: error: ld returned 1 exit status
CMakeFiles/TryZip.dir/build.make:102: recipe for target '../bin/TryZip' failed
make[3]: *** [../bin/TryZip] Error 1
CMakeFiles/Makefile2:109: recipe for target 'CMakeFiles/TryZip.dir/all' failed
make[2]: *** [CMakeFiles/TryZip.dir/all] Error 2
CMakeFiles/Makefile2:116: recipe for target 'CMakeFiles/TryZip.dir/rule' failed
make[1]: *** [CMakeFiles/TryZip.dir/rule] Error 2
Makefile:131: recipe for target 'TryZip' failed
make: *** [TryZip] Error 2
This is my Cmakefile.txt
cmake_minimum_required(VERSION 3.15)
project(TryZip)
if(BOOST_FILESYSTEM)
include_directories(${BOOST_INCLUDE_DIR})
link_directories(${BOOST_LIB_DIR})
add_definitions(-DUSE_BOOST_FILESYSTEM)
else()
if(MSVC)
add_definitions(-DFILESYSTEM_EXPERIMENTAL)
endif()
endif()
if(BOOST_FILESYSTEM)
if(UNIX)
find_package(Boost COMPONENTS system filesystem REQUIRED)
target_link_libraries(${Boost_FILESYSTEM_LIBRARY}
${Boost_SYSTEM_LIBRARY})
endif()
endif()
add_subdirectory(ExternalLibrary/ZipLib)
link_libraries(ExternalLibrary/ZipLib)
include_directories(ExternalLibrary/ZipLib)
set(CMAKE_CXX_STANDARD 17)
add_executable(TryZip main.cpp ExternalLibrary/ZipLib/ZipFile.cpp)
target_link_libraries(TryZip ZipLib)
Can someone help me to solve this please?
My ZipLib folder is in the same folder as my cmakefile.txt file.
The call to link_libraries() appears to accept the wrong arguments in this case. The link_libraries() command takes arguments of existing CMake targets, or library names. It is also redundant with your target_link_libraries() call, as this already links ZipLib to TryZip.
Try removing the call to link_libraries(), as this CMake function is deprecated and its use is highly discouraged. The include_directories() call is similarly deprecated, in favor of the target-specific command, so consider using target_include_directories() instead.
Assuming your added sub-directory ExternalLibrary/ZipLib contains an additional CMakeLists.txt file for configuring the ZipLib target, you should not need to add the ZipFile.cpp file again. If this file is already compiled in the sub-directory into the target ZipLib, you do not need to compile it again into TryZip.
add_subdirectory(ExternalLibrary/ZipLib)
set(CMAKE_CXX_STANDARD 17)
add_executable(TryZip main.cpp)
target_include_directories(TryZip PRIVATE ExternalLibrary/ZipLib)
target_link_libraries(TryZip PRIVATE ZipLib)
EDIT: Based on your feedback, it appears ZipLib also depends on pthread but somehow it is not getting linked correctly. You might try to add the following to your ExternalLibrary/ZipLib/CMakeLists.txt file (if it doesn't already exist), to utilize CMake's FindThreads module:
find_package(Threads REQUIRED)
...
target_link_libraries(ZipLib PUBLIC Threads::Threads)

cmake 3.10 cant internally test the blas library

I cant get working my blas library with cmake. I have arch-linxux, both blas and cmake are installed with pacman. Cant understand where is problem :-(. I made cmake to print out the output of macro CHECK_FORTRAN_FUNCTION_EXISTS, because it fails there. Maybe I dont have proper configuration of ld?
My simple testing CMakeLists.txt:
cmake_minimum_required(VERSION 2.8)
project(Test C Fortran)
find_package(BLAS)
Error part from output:
-- Looking for Fortran sgemm
-- Change Dir: /home/jiri/test_lapack/CMakeFiles/CMakeTmp
Run Build Command:"/usr/bin/make" "cmTC_486fc/fast"
/usr/bin/make -f CMakeFiles/cmTC_486fc.dir/build.make CMakeFiles/cmTC_486fc.dir/build
make[1]: Entering directory '/home/jiri/test_lapack/CMakeFiles/CMakeTmp'
Building Fortran object CMakeFiles/cmTC_486fc.dir/testFortranCompiler.f.o
/usr/bin/gfortran -c /home/jiri/test_lapack/CMakeFiles/CMakeTmp/testFortranCompiler.f -o CMakeFiles/cmTC_486fc.dir/testFortranCompiler.f.o
Linking Fortran executable cmTC_486fc
/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTC_486fc.dir/link.txt --verbose=1
/usr/bin/gfortran CMakeFiles/cmTC_486fc.dir/testFortranCompiler.f.o -o cmTC_486fc /usr/local/lib64/libblas.a
/usr/bin/ld: /usr/local/lib64/libblas.a(sgemm.f.o): relocation R_X86_64_32 against `.rodata' can not be used when making a PIE object; recompile with -fPIC
/usr/bin/ld: /usr/local/lib64/libblas.a(xerbla.f.o): relocation R_X86_64_32S against `.rodata' can not be used when making a PIE object; recompile with -fPIC
/usr/bin/ld: final link failed: Nonrepresentable section on output
collect2: error: ld returned 1 exit status
make[1]: *** [CMakeFiles/cmTC_486fc.dir/build.make:99: cmTC_486fc] Error 1
make[1]: Leaving directory '/home/jiri/test_lapack/CMakeFiles/CMakeTmp'
make: *** [Makefile:126: cmTC_486fc/fast] Error 2
-- Looking for Fortran sgemm - not found

cmake on windows. Link libraries in folder

Disclaimer: I'm new to cmake so i have no idea what I'm doing.
All guides and tutorials i find seem to think I'm running a 20 man team that needs to work together.
All I'm trying to do is put all my libraries in an include folder and lib folder.
In visual studio and code::blocks i just set up the linker in the IDE, but cmake is a little hard for me to wrap my head around.
I've set include and link directories with
include_directories(${PROJECT_SOURCE_DIR}/include)
link_directories(${PROJECT_SOURCE_DIR}/lib)
Then i try to
target_link_libraries(${PROJECT_NAME} jsoncpp)
This however produces undefined references. Is there a simple way to add and link libraries without me having to google and add a cmake module for each one?
Edit:
attempts:
target_link_libraries(${PROJECT_NAME} libjsoncpp.a)
error: undefined reference
target_link_libraries(${PROJECT_NAME} libjsoncpp)
error: cannot find -llibjsoncpp
target_link_libraries(${PROJECT_NAME} jsoncpp)
error: undefined reference
target_link_libraries(${PROJECT_NAME} C:/Repos/prosjekt-bad-racoon/lib/libjsoncpp.a)
error: undefined reference
target_link_libraries(${PROJECT_NAME} ${PROJECT_SOURCE_DIR}/lib/libjsoncpp.a)
error: undefined reference
Edit:
Full cmake file
cmake_minimum_required(VERSION 3.8)
project(prosjekt_bad_racoon)
set(CMAKE_CXX_STANDARD 11)
include_directories(${PROJECT_SOURCE_DIR}/include)
link_directories(${PROJECT_SOURCE_DIR}/lib)
set(SOURCE_FILES main.cpp Core.cpp Core.h Collider.cpp Collider.h Player.cpp Player.h Texture.cpp Texture.h AudioController.cpp AudioController.h)
add_executable(prosjekt_bad_racoon ${SOURCE_FILES})
set(EXECUTABLE_NAME ${PROJECT_NAME})
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake_modules" ${CMAKE_MODULE_PATH})
target_link_libraries(${PROJECT_NAME} libjsoncpp.a)
find_package(SFML 2 REQUIRED system window graphics network audio)
if(SFML_FOUND)
include_directories(${SFML_INCLUDE_DIR})
target_link_libraries(${EXECUTABLE_NAME} ${SFML_LIBRARIES})
link_directories("${PROJECT_SOURCE_DIR}")
endif()
"C:\Program Files\JetBrains\CLion 2017.2.2\bin\cmake\bin\cmake.exe" --build C:\Repos\prosjekt-bad-racoon\cmake-build-debug --target prosjekt_bad_racoon -- -j 2
[ 14%] Linking CXX executable prosjekt_bad_racoon.exe
CMakeFiles\prosjekt_bad_racoon.dir/objects.a(Core.cpp.obj): In function `ZN4CoreC2Ev':
C:/Repos/prosjekt-bad-racoon/Core.cpp:3: undefined reference to `Json::Value::Value(char const*)'
CMakeFiles\prosjekt_bad_racoon.dir/objects.a(Core.cpp.obj): In function `ZN4CoreD2Ev':
C:/Repos/prosjekt-bad-racoon/Core.cpp:8: undefined reference to `Json::Value::~Value()'
collect2.exe: error: ld returned 1 exit status
CMakeFiles\prosjekt_bad_racoon.dir\build.make:236: recipe for target 'prosjekt_bad_racoon.exe' failed
mingw32-make.exe[3]: *** [prosjekt_bad_racoon.exe] Error 1
CMakeFiles\Makefile2:66: recipe for target 'CMakeFiles/prosjekt_bad_racoon.dir/all' failed
mingw32-make.exe[2]: *** [CMakeFiles/prosjekt_bad_racoon.dir/all] Error 2
CMakeFiles\Makefile2:78: recipe for target 'CMakeFiles/prosjekt_bad_racoon.dir/rule' failed
mingw32-make.exe[1]: *** [CMakeFiles/prosjekt_bad_racoon.dir/rule] Error 2
Makefile:117: recipe for target 'prosjekt_bad_racoon' failed
mingw32-make.exe: *** [prosjekt_bad_racoon] Error 2

CMake: satisfying dependencies when building shared object file (.so) from object file (.o)

I am able to do this without CMake using a handwritten Makefile, like so:
g++ $(CXSCINC) -c -fPIC cellComplex_extern.cpp -o cellComplex_extern.o
g++ $(CXSCINC) -shared -Wl -o cellComplex_lib.so cellComplex_extern.o $(CXSCLIB) -lcxsc
This gets me shared library cellComplex_lib.so, which then gets picked up by ctypes as a dynamically linked library (lib = ctypes.cdll.LoadLibrary('./cellComplex_lib.so') for later use.
My project has moved to CMake as a build system and I am looking to emulate the functionality of my Makefile above.
So far I have discovered the add_library() command for CMakeLists.txt, but the link to the CXSC library is never made (as evidenced by horrible complaining when I run make after cmake.
How can I tell CMake to build cellComplex_lib with the third-party library CXSC?
-- non-working CMakeLists.txt --
add_library(include/python/cellComplex_extern OBJECT
include/python/cellComplex_extern.cpp ${all_headers})
add_library(include/python/cellComplex_lib SHARED
include/python/cellComplex_extern)
target_link_libraries(include/python/cellComplex_lib ${CXSC_LIB_DIR}/libcxsc.a)
Result of running cmake followed by make:
.
.
.
[ 75%] Built target include/python/cellComplex_extern
Linking CXX shared library libinclude/python/cellComplex_lib.dylib
ld: can't open output file for writing: libinclude/python/cellComplex_lib.dylib, errno=2 for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [libinclude/python/cellComplex_lib.dylib] Error 1
make[1]: *** [CMakeFiles/include/python/cellComplex_lib.dir/all] Error 2
make: *** [all] Error 2
I think you need to use target_link_libraries
target_link_libraries(include/python/cellComplex_lib ${CXSLIB})
This is what I use during Win32 development:
link_directories(${LIB_ROOT_DIR}/lib ${LIB_ROOT_DIR2}/lib/morelibs)
add_library(MyDll1 SHARED File1.cpp File2.cpp)
add_library(MyDll2 SHARED File3.cpp File4.cpp)
add_dependencies(MyDll2 Dll1)
target_link_libraries(MyDll2 Dll1 some.lib another.lib)
Here you specify that Dll2 requires Dll1 and two other external lib's.