(Linux) Unable to link archives via cmake - cmake

On the command line, the following produces an executable:
g++ -o a.out main.cpp class1.cc class2.cc /usr/lib/libgsl.a /usr/lib/libgslcblas.a
However I am unsure how to get cmake to work properly.
When I add a line like
include_directories(/usr/lib/)
link_libraries(usr/lib/libgsl.a usr/libgslcblas.a)
the configuring seems to work but building fails:
CMakeFiles/kmv.dir/main.o: In function `main':
main.cpp:27: undefined reference to `gsl_matrix_alloc'
main.cpp:35: undefined reference to `gsl_matrix_fscanf'
collect2: ld returned 1 exit status
make[2]: *** [kmv] Error 1
make[1]: *** [CMakeFiles/kmv.dir/all] Error 2
make: *** [all] Error 2
*** Failed ***
Seems to be a synthax problem. Any hint is welcome. Thank you.

Instead of
include_directories(/usr/lib)
link_libraries(usr/lib/libgsl.a usr/libgslcblas.a)
try
add_executable (targetName main.cpp class1.cc class2.cc)
target_link_libraries(targetName gsl gslcblas)
Where targetName is the name of the output binary you intend to create. The path /usr/lib should already be in the default library search path for CMake, so you shouldn't have to specify that, but if you did have to specify a custom library path, you would do it like so
link_directories(/some/custom/library/path)
The include_directories CMake directive is used for adding header search paths, not library search paths...

Probably, link_libraries is deprecated
http://www.cmake.org/pipermail/cmake/2009-April/028439.html
Try using target_link_libraries instead.

Related

How to statically link PROJ to pybind11

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

You have called ADD_LIBRARY for library pugixml without any source files

I am working on quickrank: https://github.com/hpclab/quickrank. when I compile it I get error
cmake .. -DCMAKE_CXX_COMPLIER=/usr/bin/g++ -DCMAKE_BUILD_TYPE=Release
You have called ADD_LIBRARY for library pugixml without any source files. This typically indicates a problem with your CMakeLists.txt file
-- Configuring done
CMake Error: Cannot determine link language for target "pugixml".
CMake Error: CMake can not determine linker language for target: pugixml
CMake Error: CMake can not determine linker language for target: pugixml
-- Generating done
-- Build files have been written to: /home/students/s4438236/quickrank/build_
s4438236#moss:~/quickrank/build_$ make
make[2]: *** No rule to make target `CMakeFiles/pugixml.dir/build'. Stop.
make[1]: *** [CMakeFiles/pugixml.dir/all] Error 2
make: *** [all] Error 2
I do find source file under the lib\pugixml folder, how can I fix this error?
When you call the add_library CMake command, you must provide source files for this target. If we examine the top-level CMakeLists.txt file, we see where the error is occurring:
# external libraries
file(GLOB_RECURSE pugixml_sources ${CMAKE_SOURCE_DIR}/lib/pugixml/src/*.cpp)
add_library(pugixml STATIC ${pugixml_sources})
The CMake error suggests that the pugixml_sources variable is empty, which hints that the /lib/pubixml may have also been empty. If you initially didn't run the git clone command with --recursive, you would not have gotten the pugixml submodule.
Seeing as you said the pugixml sources are now there, I would suggest deleting your CMake cache and the CMake build folder. Running CMake again from scratch will likely allow it to see the pugixml source files.

Undefined reference to `XF86VidModeQueryExtension'

I am trying to compile libfreenect2 from libfreenect2 and it turns out that when I run the make file after having done cmake CMakeLists.txt in step 5, I keep having the following errors:
Linking CXX executable /home/lex/libfreenect2/examples/protonect/bin/Protonect
/home/lex/libfreenect2/examples/protonect/lib/libfreenect2.so: undefined reference to `XF86VidModeQueryExtension'
/home/lex/libfreenect2/examples/protonect/lib/libfreenect2.so: undefined reference to `XF86VidModeGetGammaRampSize'
/home/lex/libfreenect2/examples/protonect/lib/libfreenect2.so: undefined reference to `XF86VidModeGetGammaRamp'
/home/lex/libfreenect2/examples/protonect/lib/libfreenect2.so: undefined reference to `XF86VidModeSetGammaRamp'
collect2: error: ld returned 1 exit status
make[2]: *** [/home/lex/libfreenect2/examples/protonect/bin/Protonect] Error 1
make[1]: *** [CMakeFiles/Protonect.dir/all] Error 2
make: *** [all] Error 2
Does anyone have any idea on how to fix this?
Your program appears to depend upon libXxf86vm. You will need to add something like
-lXxf86vm
to the link command line. Be sure to install the development package. I am surprised the CMakeLists.txt did not have this.
Installing Mesa3D seems to fix my issue. It's something that probably had to do with the dependencies of libfreenect2 during the cmake installation.

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.

How to install gfortran under macports and use it with cmake?

hope someone can me help. I need to compile some code. I installed everything I needed with macports, in /opt/local/. And it's working how it should, except gFortran. I get this error:
ld: library not found for -lgfortran
collect2: ld returned 1 exit status
make[2]: *** [vigranumpy/private/graph/tws/svs.dylib] Error 1
make[1]: *** [vigranumpy/private/graph/tws/CMakeFiles/svs.dir/all] Error 2
make: *** [all] Error 2
I want everything to be installed in /opt/local/, because I don't want to touch the system (/usr/). gFortran isn't available for macports. You can install it with gcc46 as a variant. But if I use the gcc46 instead the default compilers, then the code before want compile.
How can I fix that?
Kind regards
See the CMake FAQ on how to use a different compiler:
http://www.cmake.org/Wiki/CMake_FAQ#How_do_I_use_a_different_compiler.3F
To use gfortran from macports as the fortran compiler, you should:
export FC=/opt/local/bin/gfortran
export CC=/opt/local/bin/gcc
export CXX=/opt/local/bin/g++
...prior to calling CMake. Then, after calling CMake with such environment variables set, it will cache the compiler paths in the CMakeCache.txt file, so for subsequent runs, you do not need the environment variables set anymore.
For mixed language (C, C++, Fortran) projects, it's important that the compilers all play nicely with each other.
This advice only works with the "Unix Makefiles" generator. I do not know of anybody who is using fortran via Xcode in conjunction with CMake.