I need to make a cross-compiled OpenSSL for a MIPS device. I've tried following the documentation. Set OPENSSL_USE_STATIC_LIBS to true and set target_link_libraries to the library files you need.
CMakeLists.txt:
compileAsC99()
if(NOT ${use_http})
message(FATAL_ERROR "program being generated without HTTP support")
endif()
set(program_c_files
...
)
set(program_h_files
...
)
include_directories(...)
add_executable(program ${program_c_files} ${program_h_files})
set(OPENSSL_USE_STATIC_LIBS TRUE)
#target_link_libraries(program OpenSSL::Crypto)
target_link_libraries(program /home/program/mips/lib/libssl.so.1.1)
target_link_libraries(program /home/program/mips/lib/libcrypto.so.1.1)
It compiles fine without warnings, but checking the resulting binary tells me that it's still shared library.
readelf -d program:
Dynamic section at offset 0x1bc contains 35 entries:
Tag Type Name/Value
0x00000001 (NEEDED) Shared library: [libssl.so.1.1]
0x00000001 (NEEDED) Shared library: [libcrypto.so.1.1]
0x0000000f (RPATH) Library rpath: [/home/program/mips/lib]
I don't understand what I'm doing wrong.
EDIT: Already looked at Linking statically OpenSSL crypto library in CMake but it didn't tell me anything new.
EDIT 2: Updated the CMakeLists.txt file according to the reply:
CMakeLists.txt:
compileAsC99()
if(NOT ${use_http})
message(FATAL_ERROR "program being generated without HTTP support")
endif()
set(program_c_files
...
)
set(program_h_files
...
)
include_directories(...)
add_executable(program ${program_c_files} ${program_h_files})
find_package(OpenSSL REQUIRED)
if(OPENSSL_FOUND)
set(OPENSSL_USE_STATIC_LIBS TRUE)
message("OPENSSL FOUND!")
endif()
target_link_libraries(program OpenSSL::Crypto)
Output:
-- IoT Client SDK Version = 1.2.11
-- Provisioning client OFF
-- target architecture: GENERIC
-- Cross compiling not using pkg-config
-- Found CURL: /home/program/mips/lib/libcurl.a (found version "7.63.0")
-- Found CURL: /home/program/mips/lib/libcurl.a
-- target architecture: GENERIC
-- target architecture: GENERIC
-- target architecture: GENERIC
-- target architecture: GENERIC
-- iothub architecture: GENERIC
OPENSSL FOUND!
-- Configuring done
-- Generating done
EDIT PROSPERITY:
If you, future people, run into the undefined reference to dlopen, I added the following to my CMakeLists.txt file
target_link_libraries(program ${CMAKE_DL_LIBS})
Setting to TRUE, variable OPENSSL_USE_STATIC_LIBS forces find_package(OpenSSL) to search the static library. So this variable works only with that call, and if you use its results:
set(OPENSSL_USE_STATIC_LIBS TRUE)
find_package(OpenSSL REQUIRED)
target_link_libraries(program OpenSSL::Crypto)
If you have already executed cmake without setting of OPENSSL_USE_STATIC_LIBS, then you need to remove CMake cache (CMakeCache.txt under build directory) before new attempt. Otherwise, already found (shared!) libraries will be used and no re-search will be performed.
Related
I want to add a LuaJIT wrapper to libgit2 so that it can be used in neovim.
The cmake configuration is as follows:
cmake_minimum_required(VERSION 3.22.2)
project("git2-neovim")
message(STATUS "cmake binary directory: ${CMAKE_BINARY_DIR}")
# Compile commands are output to "compile_commands.json", so that tools such as "ccls" can provide assistance.
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
# Set gcc compile options.
set(CMAKE_C_FLAGS_DEBUG "$ENV{CFLAGS} -Wall -g3 -ggdb")
set(CMAKE_C_FLAGS_RELEASE "$ENV{CFLAGS} -O3 -Wall")
set(
SRC_FILES
src/libgit2.c
)
add_library(${PROJECT_NAME} SHARED ${SRC_FILES})
find_package(PkgConfig REQUIRED)
if (PKG_CONFIG_FOUND)
pkg_check_modules(LIBGIT2 REQUIRED libgit2)
include_directories(${LIBGIT2_INCLUDE_DIRS})
target_link_libraries(${PROJECT_NAME} ${LIBGIT2_LIBRARIES})
endif(PKG_CONFIG_FOUND)
This generates a "libgit2-neovim.so" file, but I want to generate a "libgit2.so" file.
Since I only use it in neovim, there is no conflict with the real libgit2.
environmental information:
operating system: Archlinux
cmake version: 3.25.1
============================== replenish ============================
When LuaJIT is looking for a shared library, it will only automatically add the file of the shared library according to the operating system, and will not add a prefix. The example is as follows:
require("demo")
The lua code above loads the "demo.so" file but not the "libdemo.so" file.
Therefore, I want to set in cmake, compile in any operating system, the output shared library must have "lib" prefix.
How does cmake set the file name of the dynamic library to be built?
The output filename is controlled by target properties https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#library-output-artifacts , and the default is composed of https://cmake.org/cmake/help/latest/variable/CMAKE_SHARED_LIBRARY_PREFIX.html followed by library name followed by https://cmake.org/cmake/help/latest/variable/CMAKE_SHARED_LIBRARY_SUFFIX.html .
I want to generate a "libgit2.so" file
So name your library git2 not git2-neovim.
add_library(git2
or set LIBRARY_OUTPUT_NAME target property of the target.
I am using nativefiledialog-cmake in my C++ project as a submodule. When I generate the build files using CMake, it does not generate properly as it cannot find the gtk/gtk.h file needed for one of nativefiledialog's source files : nfd_gtk.c.
I have installed the following GTK and GTK dependency packages:
gtk2
gtk3
gtk4
gtk2-devel
gtk3-devel
gtk4-devel
gtk4-devel-tools
glib
glib-devel
gdk-pixbuf2-devel
atk
atk-devel
gobject-introspection
gobject-introspection-devel
libepoxy
libepoxy-devel
and ls /usr/include | grep gtk returns
gtk-2.0
gtk-3.0
gtk-4.0
gtk-unix-print-2.0
The GTK headers are inside these folders.
This is nativefiledialog-cmake's CMakeLists.txt file:
include(CheckIncludeFile)
set(SOURCES src/nfd_common.c)
macro(REQUIRE_INCLUDE_FILE path name)
CHECK_INCLUDE_FILE(${path} ${name})
if (NOT ${name})
message(FATAL_ERROR "${path} not found")
endif ()
endmacro()
# add specific implementations
if (WIN32)
REQUIRE_INCLUDE_FILE(windows.h HAS_WINDOWS)
list(APPEND SOURCES src/nfd_win.cpp)
elseif (APPLE)
REQUIRE_INCLUDE_FILE(AppKit/AppKit.h HAS_APPKIT)
list(APPEND SOURCES src/nfd_cocoa.m)
elseif (UNIX)
REQUIRE_INCLUDE_FILE(gtk/gtk.h HAS_GTK)
list(APPEND SOURCES src/nfd_gtk.c)
elseif (UNIX)
message(FATAL_ERROR "Cannot detect your system, please report to https://github.com/aarcangeli/nativefiledialog-cmake/issues")
endif ()
add_library(nativefiledialog ${SOURCES})
target_include_directories(nativefiledialog PUBLIC src/include)
I have tried adding this line (returned from pkg-config --cflags gtk+-3.0) to tell the compiler where the GTK headers are located with no avail:
set(FLAGS "${FLAGS} -I/usr/include/gtk-3.0 -I/usr/include/pango-1.0 -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -I/usr/include/sysprof-4 -I/usr/include/harfbuzz -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/libmount -I/usr/include/blkid -I/usr/include/fribidi -I/usr/include/libxml2 -I/usr/include/cairo -I/usr/include/pixman-1 -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/gio-unix-2.0 -I/usr/include/cloudproviders -I/usr/include/atk-1.0 -I/usr/include/at-spi2-atk/2.0 -I/usr/include/dbus-1.0 -I/usr/lib64/dbus-1.0/include -I/usr/include/at-spi-2.0 -pthread")
How do I get CMake to generate properly?
First of all I am quite not sure how you arrived at the set(FLAGS "${FLAGS} ...") line, because unless you've specified some additional logic, that just creates a variable FLAGS, it is not a standard CMake variable IIRC.
Perhaps what you meant to use was target_compile_options(), where you can specify additional compile options to a given target which in your case is most likely nativefiledialog. That might fix your issue i.e.:
target_compile_options(nativefiledialog PUBLIC "$<$<CONFIG:DEBUG>:${DEBUG_FLAGS}>")
target_compile_options(nativefiledialog PUBLIC "$<$<CONFIG:RELEASE>:${RELEASE_FLAGS}>")
Or in your case:
target_compile_options(nativefiledialog PUBLIC "${FLAGS}")
This however is not good practice and I would recommend rewriting nativefiledialog's CMakeLists.txt.
Bare in mind that this is in no way your fault, the nativefiledialog has a very bad CMakeLists.txt because the author didn't use any prebuild CMake functionalities like find_package(GTK).
In my CMake project, I'm copying external libraries that I hold in a special folder to my output folder and import them as an IMPORTED target.
For example, for libusb:
find_path(LibUsb_INCLUDE_DIR NAMES libusb.h PATHS ${CMAKE_CURRENT_SOURCE_DIR}/LibUsb/Include)
if(NOT LibUsb_INCLUDE_DIR)
message(FATAL_ERROR "LibUsb: include directory wasn't found")
endif()
find_library(LibUsb_LIBRARY NAMES usb-1.0 libusb-1.0 PATHS ${OUTPUT_BIN_DIR})
if(NOT LibUsb_LIBRARY)
message(FATAL_ERROR "LibUsb: library wasn't found")
endif()
add_library(LibUsb UNKNOWN IMPORTED GLOBAL)
set_target_properties(LibUsb PROPERTIES IMPORTED_LOCATION ${LibUsb_LIBRARY})
set_target_properties(LibUsb PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${LibUsb_INCLUDE_DIR})
message(STATUS "LibUsb: found at ${LibUsb_LIBRARY}")
The CMake output is:
...
-- Building for: Visual Studio 15 2017
-- The C compiler identification is MSVC 19.0.24234.1
-- The CXX compiler identification is MSVC 19.0.24234.1
...
-- CMAKE SYSTEM: Windows-10.0.17763
-- CMAKE VERSION: 3.13.4
...
-- LibUsb: copy binaries
-- VsCan: copy binaries
-- LibUsb: found at C:/myproj/Build/Windows-Debug/Output/Bin/libusb-1.0.lib
-- VsCan: found at C:/myproj/Build/Windows-Debug/Output/Bin/vs_can_api.lib
...
LibUsb is found correctly and if I print LibUsb_LIBRARY the path is correct. Everything compiles correctly on Linux.
On Windows compilation I'm getting fatal error LNK1107: invalid or corrupt file.
What am I doing wrong?
I want to compile the Emotiv EPOC module for BCI2000. In that module CMakeLists file contains following(below the following error log).
The compiler gives the following error,
-- Selecting Windows SDK version to target Windows 10.0.10586.
CMake Error at CMakeLists.txt:21 (BCI2000_INCLUDE):
Unknown CMake command "BCI2000_INCLUDE".
CMake Warning (dev) in CMakeLists.txt:
No cmake_minimum_required command is present. A line of code such as
cmake_minimum_required(VERSION 3.10)```
CMakeLists.txt contains this,
###########################################################################
## $Id$
## Authors: griffin.milsap#gmail.com
## Description: Build information for the Emotiv module
# Set the executable name
SET( EXECUTABLE_NAME Emotiv )
# Set the project specific sources
SET( SRC_PROJECT
EmotivADC.cpp
lib/edk.imports.cpp
)
SET( HDR_PROJECT
EmotivADC.h
lib/edk.imports.h
)
INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR}/lib/include )
BCI2000_INCLUDE( "SOURCEFILTER" )
IF( WIN32 )
# Create the signal source module
BCI2000_ADD_SIGNAL_SOURCE_MODULE(
"${EXECUTABLE_NAME}"
"${SRC_PROJECT}" "${HDR_PROJECT}"
"${CMAKE_CURRENT_SOURCE_DIR}/dll/edk.dll"
"${CMAKE_CURRENT_SOURCE_DIR}/dll/edk_utils.dll"
)
ELSE()
MESSAGE( "--- No Emotiv libraries for this OS. Will not build." )
ENDIF()
How can I fix this?
Looks like they are function calls, but how do I import those function calls from another file if they are declared somewhere?
The project has to be compiled according to the instructions in this,
https://www.bci2000.org/mediawiki/index.php/Programming_Reference:Build_System
And it says the supported Visual Studio editions are 9(2008) and 10 only or you can compile it with CodeBlocks with MinGW.
And the supportive modules should be included into the source folder of BCI2000 and compile it as a whole project not as seperate modules. Then it recognized the functions defined in the parent project.
There are cMakeList files for submodules. But they cannot be compiled on their own.
I am using CLion editor (with CMake) for my C project,
I've never used an external library though,
my question is how do I link an external lib (for ex. libxml2) to my project?
I've seen some questions similar to this but none worked for me.
My project is compiled on Windows, and I have libxml .dll, include, and .lib files(binaries for Windows).
Edit: My CMakeLists.txt file after the answer suggested:
cmake_minimum_required(VERSION 3.2)
project(time_table)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(SOURCE_FILES
course.c
course.h
day.h
defines.h
find_tables.c
find_tables.h
item.h
parse_info.c
parse_info.h
table.c
table.h
time_table.c grades.c grades.h)
link_libraries(C:/Users/Gal/Desktop/time_table/libxml2-2.7.8.win32/lib)
add_executable(time_table ${SOURCE_FILES})
target_link_libraries(time_table libxml2)
and this is what I get:
"C:\Program Files (x86)\JetBrains\CLion 1.1.1\bin\cmake\bin\cmake.exe" --build C:\Users\Gal\.clion11\system\cmake\generated\2eda76ff\2eda76ff\Debug --target time_table -- -j 8
[ 14%] Linking C executable time_table.exe
c:/mingw/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe: cannot find -llibxml2
collect2.exe: error: ld returned 1 exit status
mingw32-make.exe[3]: *** [time_table.exe] Error 1
CMakeFiles\time_table.dir\build.make:225: recipe for target 'time_table.exe' failed
CMakeFiles\Makefile2:66: recipe for target 'CMakeFiles/time_table.dir/all' failed
mingw32-make.exe[2]: *** [CMakeFiles/time_table.dir/all] Error 2
CMakeFiles\Makefile2:78: recipe for target 'CMakeFiles/time_table.dir/rule' failed
mingw32-make.exe[1]: *** [CMakeFiles/time_table.dir/rule] Error 2
What is wrong?
There is a key work for libraries installed on your machine. <lib_name>_INCLUDE_DIR and <lib_name>_LIBRARIES once you have done find_package. This works for me.
find_package(LibXml2 REQUIRED)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/<my_stuff> ${LIBXML2_INCLUDE_DIR})
add_executable(<my_exe> <my_source_files>)
target_link_libraries(<my_exe> ${LIBXML2_LIBRARIES})
---- Just a note for your curiosity ----
If you ever needed to build (1) a (static) library of your calculations, maybe reusable, and (2) an executable that uses that library and LIBXML2, do this.
find_package(LibXml2 REQUIRED)
# add a calculation library: file "lib<mycalc>.a"
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/<your header files folder> ${LIBXML2_INCLUDE_DIR})
add_library(<mycalc> STATIC ${CMAKE_CURRENT_SOURCE_DIR}/<your src files folder>)
target_link_libraries(<mycalc> ${LIBXML2_LIBRARIES})
# add the executable: file <my_exe>
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/<your header files folder> ${LIBXML2_INCLUDE_DIR})
add_executable(<my_exe> <your exe src files>)
target_link_libraries(<my_exe> <mycalc> ${LIBXML2_LIBRARIES})
Assume that full path to the library(.lib) can be expressed as
<library_dir>/<library_name>.lib
For compile executable, which uses this library, you need:
CMakeLists.txt:
link_libraries(<library_dir>)
add_excutable(<my_exe> ..)
target_link_libraries(<my_exe> <library_name>)
For use(run) compiled executable, you need to have <library_name>.dll either under one of the directory, listed in the PATH environment variable, or within same directory with executable.
there are 32bit and 64bit version of libxml2, to be found here.
you can put them below the PATH - or the C:\Windows directory.
With moderns CMake (version 3.2 or newer), it got much easier:
Search for the library. CMake has an according find module, thus it boils down to
find_package(LibXml2 REQUIRED)
Then you can link the library it to your target foo
target_link_libraries(foo PUBLIC LibXml2::LibXml2)
That's it folks! No fiddling around with headers and libraries, all done automatically.
If you have not installed the library, you might want to set LibXml2_DIR to the location where LibXml2 is located, i.e., by passing -DLibXml2_DIR=C:\software\libxml2 to your CMake call. That will help CMake finding LibXml2.