I compiled tshark with cmake.
I running command cmake -DBUILD_wireshark=off; make CFLAGS="-static", then i found BUILD_wiresharktshark in build/run, but it's dynamic link, and dependency more xxx.so.
What should i do? Thanks;
I only need the filter. May be there is a best way?
Solved!
I use confiugre:
./configure --enable-static=yes --enable-wireshark=no --disable-gtktest --enable-shared=no --with-zlib=no -with-gnutls=no --with-krb5=no --with-adns=no --with-geoip=no --with-plugins=no --enable-editcap=no --enable-capinfos=no --enable-mergecap=no --enable-text2pcap=no --enable-idl2wrs=no --enable-dftest=no --enable-randpkt=no --enable-rawshark=no --enable-dumpcap=no --enable-androiddump=no --with-gcrypt=no --with-libsmi=no --without-portaudio --without-lua --disable-glibtestst --with-gtk2=no --with-gtk3=no
But, a lots of librarys not provide static version on my OS(Fedora 32).
Next, i build a lots of static librarys: c-ares, eudev-1.5, libgcrypt-1.8.7, glib, libnl-3.2.25, libusb.
Then, successed :-).
Oh, --enable-dumpcap=no is optional, because i needn't capture network packets.
Related
Looking around on the net I have seen a lot of code like this:
include(FindPkgConfig)
pkg_search_module(SDL2 REQUIRED sdl2)
target_include_directories(app SYSTEM PUBLIC ${SDL2_INCLUDE_DIRS})
target_link_libraries(app ${SDL2_LIBRARIES})
However that seems to be the wrong way about doing it, as it only uses the include directories and libraries, but ignored defines, library paths and other flags that might be returned by pkg-config.
What would be the correct way to do this and ensure that all compile and link flags returned by pkg-config are used by the compiled app? And is there a single command to accomplish this, i.e. something like target_use(app SDL2)?
ref:
include()
FindPkgConfig
First of, the call:
include(FindPkgConfig)
should be replaced with:
find_package(PkgConfig)
The find_package() call is more flexible and allows options such as REQUIRED, that do things automatically that one would have to do manually with include().
Secondly, manually calling pkg-config should be avoid when possible. CMake comes with a rich set of package definitions, found in Linux under /usr/share/cmake-3.0/Modules/Find*cmake. These provide more options and choice for the user than a raw call to pkg_search_module().
As for the mentioned hypothetical target_use() command, CMake already has that built-in in a way with PUBLIC|PRIVATE|INTERFACE. A call like target_include_directories(mytarget PUBLIC ...) will cause the include directories to be automatically used in every target that uses mytarget, e.g. target_link_libraries(myapp mytarget). However this mechanism seems to be only for libraries created within the CMakeLists.txt file and does not work for libraries acquired with pkg_search_module(). The call add_library(bar SHARED IMPORTED) might be used for that, but I haven't yet looked into that.
As for the main question, this here works in most cases:
find_package(PkgConfig REQUIRED)
pkg_check_modules(SDL2 REQUIRED sdl2)
...
target_link_libraries(testapp ${SDL2_LIBRARIES})
target_include_directories(testapp PUBLIC ${SDL2_INCLUDE_DIRS})
target_compile_options(testapp PUBLIC ${SDL2_CFLAGS_OTHER})
The SDL2_CFLAGS_OTHER contains defines and other flags necessary for a successful compile. The flags SDL2_LIBRARY_DIRS and SDL2_LDFLAGS_OTHER are however still ignored, no idea how often that would become a problem.
More documentation here http://www.cmake.org/cmake/help/latest/module/FindPkgConfig.html
If you're using cmake and pkg-config in a pretty normal way, this solution works.
If, however, you have a library that exists in some development directory (such as /home/me/hack/lib), then using other methods seen here fail to configure the linker paths. Libraries that are not found under the typical install locations would result in linker errors, like /usr/bin/ld: cannot find -lmy-hacking-library-1.0. This solution fixes the linker error for that case.
Another issue could be that the pkg-config files are not installed in the normal place, and the pkg-config paths for the project need to be added using the PKG_CONFIG_PATH environment variable while cmake is running (see other Stack Overflow questions regarding this). This solution also works well when you use the correct pkg-config path.
Using IMPORTED_TARGET is key to solving the issues above. This solution is an improvement on this earlier answer and boils down to this final version of a working CMakeLists.txt:
cmake_minimum_required(VERSION 3.14)
project(ya-project C)
# the `pkg_check_modules` function is created with this call
find_package(PkgConfig REQUIRED)
# these calls create special `PkgConfig::<MODULE>` variables
pkg_check_modules(MY_PKG REQUIRED IMPORTED_TARGET any-package)
pkg_check_modules(YOUR_PKG REQUIRED IMPORTED_TARGET ya-package)
add_executable(program-name file.c ya.c)
target_link_libraries(program-name PUBLIC
PkgConfig::MY_PKG
PkgConfig::YOUR_PKG)
Note that target_link_libraries does more than change the linker commands. It also propagates other PUBLIC properties of specified targets like compiler flags, compiler defines, include paths, etc., so, use the PUBLIC keyword with caution.
It's rare that one would only need to link with SDL2. The currently popular answer uses pkg_search_module() which checks for given modules and uses the first working one.
It is more likely that you want to link with SDL2 and SDL2_Mixer and SDL2_TTF, etc... pkg_check_modules() checks for all the given modules.
# sdl2 linking variables
find_package(PkgConfig REQUIRED)
pkg_check_modules(SDL2 REQUIRED sdl2 SDL2_ttf SDL2_mixer SDL2_image)
# your app
file(GLOB SRC "my_app/*.c")
add_executable(my_app ${SRC})
target_link_libraries(my_app ${SDL2_LIBRARIES})
target_include_directories(my_app PUBLIC ${SDL2_INCLUDE_DIRS})
target_compile_options(my_app PUBLIC ${SDL2_CFLAGS_OTHER})
Disclaimer: I would have simply commented on Grumbel's self answer if I had enough street creds with stackoverflow.
Most of the available answers fail to configure the headers for the pkg-config library. After meditating on the Documentation for FindPkgConfig I came up with a solution that provides those also:
include(FindPkgConfig)
if(NOT PKG_CONFIG_FOUND)
message(FATAL_ERROR "pkg-config not found!" )
endif()
pkg_check_modules(<some-lib> REQUIRED IMPORTED_TARGET <some-lib>)
target_link_libraries(<my-target> PkgConfig::<some-lib>)
(Substitute your target in place of <my-target> and whatever library in place of <some-lib>, accordingly.)
The IMPORTED_TARGET option seems to be key and makes everything then available under the PkgConfig:: namespace. This was all that was required and also all that should be required.
There is no such command as target_use. But I know several projects that have written such a command for their internal use. But every project want to pass additional flags or defines, thus it does not make sense to have it in general CMake. Another reason not to have it are C++ templated libraries like Eigen, there is no library but you only have a bunch of include files.
The described way is often correct. It might differ for some libraries, then you'll have to add _LDFLAGS or _CFLAGS. One more reason for not having target_use. If it does not work for you, ask a new question specific about SDL2 or whatever library you want use.
If you are looking to add definitions from the library as well, the add_definitions instruction is there for that. Documentation can be found here, along with more ways to add compiler flags.
The following code snippet uses this instruction to add GTKGL to the project:
pkg_check_modules(GTKGL REQUIRED gtkglext-1.0)
include_directories(${GTKGL_INCLUDE_DIRS})
link_directories(${GTKGL_LIBRARY_DIRS})
add_definitions(${GTKGL_CFLAGS_OTHER})
set(LIBS ${LIBS} ${GTKGL_LIBRARIES})
target_link_libraries([insert name of program] ${LIBS})
I'm cross compiling on Windows 7 and I use this compiler:
gcc-linaro-arm-linux-gnueabihf-4.7-2013.03\bin\arm-linux-gnueabihf-g++.exe
I want to use libcurl for some HTTP requests but when I link using -libcurl I get the infamous message that the linker couldn't find that library. I tried searching on the internet for the correct library for this architecture (ARMHF) but I can't find anything. Or maybe I did find it but I'm doing things wrong? My linking call is long but here it is:
This is the one that works, if I add -libcurl or anything related it breaks...
C:\vde\toolchains\windows\vos2\gcc-linaro-arm-linux-gnueabihf-4.7-2013.03\bin\arm-linux-gnueabihf-g++.exe -o out\RefApp -Wl,-rpath=C:\vde\SDKs\vos2\vos2-sdk-winx86-release-31010800\vos2\usr\lib -Wl,-r
path=C:\vde\SDKs\vos2\vos2-sdk-winx86-release-31010800\vos2\usr\local\lib -Wl,-rpath=C:\vde\SDKs\vos2\vos2-sdk-winx86-release-31010800\vos2\lib -Wl,-rpath=C:\vde\SDKs\vos2\vos2-sdk-winx86-release-3101
0800\vos2\usr\local\lib\svcmgr C:\desarrollo\corvet\out\corvet.a -LC:\desarrollo\RefApp\lib -LC:\vde\SDKs\vos2\vos2-sdk-winx86-release-31010800\vos2\usr\local\lib -LC:\vde\SDKs\vos2\vos2-sdk-winx86-re
lease-31010800\vos2\lib -LC:\vde\SDKs\vos2\vos2-sdk-winx86-release-31010800\vos2\usr\local\lib\svcmgr -LC:\vde\ADKs\adk-full-4.6.5-610\vos2\lib -L -LC:\desarrollo\corvet\out -lrt -llog -lvfiguiprt -l
vfiipc -lTLV_Util -lpthread -lvfiplatforminfo -lsvc_utility -lvfibuzzer -lsvc_powermngt -lsvc_led -lvfisysinfo -lvfisysbar -lsqlite -lexpat -linf -lcom -levt -ltecclient -lmsrclient -lEMV_CT_Link -lEM
V_CT_Client -lEMV_CTLS_Link -lEMV_CTLS_Client -lNFC_Framework -lNFC_Client -lsvc_tms -lUtils -lseccmd-static -lsvc_sound -lccp -lcrypto -lsec -lseccmd-static -lsecins -lvfisvc -lvfisyspm -lvfimac -lvf
isec -lAdkCapX
I also tried downloading some libcurl libraries I found on debian page and that were supposedly for ARMHF, put them in some folder and used -L(routetofolder) but that didn't work either.
Hope you guys can help me out.
Thanks!
Well, libcurl is there in what you get from the vendor (if you look at /usr/lib you will find it there). It's a problem with your linking.
You might want to try looking at how dynamic libraries dependencies are resolved at linking and later at runtime on linux systems. It will also help you understand what may be happening on vos2 platform when you will try using your own dynamic libraries that may have conflicting names and linker can resolve them to something existing on the same device but at a location that you might not have permissions to read, because it belongs to different usrXX or sysXX.
Reading /etc/ld.so.conf from the device will help you understand the locations and search order done by dynamic linker. You can get the file from the device or simply find it in OS.rfsbundle (look in skeletonfs) and set your linking options right. I think it's not normally distributed with sysroot by the vendor but you can manually add it.
I'm trying to adjust 3rd person code to my needs. This code is provided with CMake config files used to build and install it. There is possibility to choose one of libraries. And in code is often used #ifdef USE_FTD2XX directive. I saw that this is defined in CMamkeFiles.txt file like here:
option(USE_FTD2XX "Use FTDI libFTD2XX instead of free libftdi" ON)
if(USE_FTD2XX)
find_package(libFTD2XX)
endif(USE_FTD2XX)
if(LIBFTD2XX_FOUND)
include_directories(${LIBFTD2XX_INCLUDE_DIR})
add_definitions( -DUSE_FTD2XX )
else(LIBFTD2XX_FOUND)
set(LIBFTD2XX_LIBRARIES "")
endif(LIBFTD2XX_FOUND)
But if I simply use *.c and *.cpp files and I analyse and run it simply from IDE (Codeblocks), how could I set using this library in C++ code instead of in CMake? I'm also sure that I want use always this one so it can be fixed.
Should I simply #define USE_FTD2XX in main file?
You cannot simply #define USE_FTD2XX because you also need specific linker options for this to work (i.e. the library to link with). If the option is OFF in cmake, the specific link options won't be present in the Makefile and most likely you'll have linker errors.
So CMake takes care of everything automatically for you, but you need to re-generate your makefiles each time you want to toggle options on/off.
If only headers were involved and no library to link with (like some parts of the Boost framework), then yeah, defining USE_FTD2XX in your should be enough.
I am using the DDK to build a project. Several of the build targets generate small internal libraries -- for simplicity, let's call them LibA.lib, LibB.lib, and LibC.lib. But the code for LibA references code from LibB and LibC. To use LibA in a project, you also need to include LibB.lib, and LibC.lib to resolve all of the dependencies. What I want to do is link LibB and LibC into LibA such that a user only needs to include LibA.lib. How can I accomplish this?
The SOURCES file for LibA looks something like this:
TARGETNAME=LibA
TARGETTYPE=LIBRARY
TARGETPATH=..\lib\$(DDKBUILDENV)
INCLUDES = .; \
..\LibB; \
..\LibC; \
$(CRT_INC_PATH) \
$(SDK_INC_PATH)
SOURCES = LibA_main.cpp \
LibA_file2.cpp \
LibA_file3.cpp
I understand that you can manually link libraries with link.exe; e.g.,
link.exe /lib LibA.lib LibB.lib LibC.lib
But if possible, I would like some way to achieve this same effect as a part of the build process for LibA, because some targets at a later point of the build process rely on LibA.
Thanks!
I realize this is a late answer and it may not even be what you want in the end. However, ddkbuild.cmd has a pretty nifty mechanism to run actions before and after a build inside a particular directory.
We use this in one of our driver libraries which necessarily gets built as a number of static libraries and as a final step linked into one big static library much like you want. If you are able to use something like ddkbuild.cmd in your project, this would provide a solution and it's a solution that would work in automated builds, too.
NB: as far as I'm aware you cannot achieve what you want directly with build.exe. However, it's well possible that with some make (NMake) file acrobatics you could achieve a similar result. So the question is whether it's worth reinventing the wheel when there is one already.
I have encountered the same situation as you. Google a lot of and still have no solution. Fortunately, I found a way to resolve it finally. You can try it, add the below statement in your libA sources file.
LIBRARIAN_FLAGS = $(LIBRARIAN_FLAGS) libB.lib libC.lib
The lib utility can combine libraries. Using your example, the command would be:
lib /out:CombinedLib.lib LibA.lib LibB.lib LibC.lib
In my SConscript I have the following line:
Program("xtest", Split("main.cpp"), LIBS="mylib fltk Xft Xinerama Xext X11 m")
How do I get scons to use mylib.a instead of mylib.so, while linking dynamically with the other libraries?
EDIT: Looking to use as few platform specific hacks as possible.
Passing the full filepath wrapped in a File node will force static linking. For example:
lib = File('/usr/lib/libfoo.a')
Program('bar', 'main.c', LIBS = [lib])
Will produce the following linker command line
g++ -o bar main.o /usr/lib/libfoo.a
Notice how the "-l" flag is not passed to the linker for this LIBS entry. This effectively forces static linking. The alternative is to modify LINKFLAGS to get what you want with the caveat that you are bypassing the library dependency scanner -- the status of the library will not be checked for rebuilds.
To make this platform independent you append the env['SHLIBSUFFIX'] onto the library you want to use. env['SHLIBSUFFIX'] gives you this environments suffix for shared libraries.
You also have the ['SHLIBPREFIX'], ['LIBPREFIX'], ['LIBSUFFIX'] and ['PROGSUFFIX'], all useful for situations like this.
Edit:
I obviously haven't made myself understood, so I will clarify.
The return value of these lookups are strings to the pre/suffixes that platform uses. In that way you can refer to the file you need on each platform. Note that you cannot use it as a pure string, it has to be embedded as a file node as BennyG suggests. Working with nodes are anyway the best solution as file nodes are much more versatile than a string.
Hope this helps.