cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
project(ImageProc)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
find_package(PCL 1.2 REQUIRED)
find_package(OpenCV REQUIRED)
add_definitions( -fPIC -Wall -O3)
include_directories(${PCL_INCLUDE_DIRS})
#link_directories(${PCL_LIBRARY_DIRS}) Dont think neccesary..
add_definitions(${PCL_DEFINITIONS})
add_executable (ImageProc svm.cpp ImageProc.cpp testImageProc.cpp)
target_link_libraries (ImageProc ${OpenCV_LIBS} ${PCL_LIBRARIES})
add_library(ImageProcLib STATIC svm.cpp ImageProc.cpp)
target_link_libraries (ImageProcLib ${OpenCV_LIBS} ${PCL_LIBRARIES})
Currently, I run this and open with VS C++ and generate an exe and lib.
The exe runs on my machine.
Current limitations:
When I pass the exe to my friend, he cant run it on his machine as he gets hit by host of missing dlls.
When I use the lib files, to create a new project in VS C++, there is a fatal error in not finding a header file.
I know, I can manually add all the dlls and or package all the header and library files for the lib. But it is definitely cumbersome and ugly also.
Question:
Does CMake offer a way, so that when compiling into
An exe (it will automatically find all the necessary dlls into bin directory)
Into a lib (it will automatically source out all the header files and also the neccesary library for the linking part into the lib directory)
Preparing your package for deployment on other development environment can still be a tough task. You will need to setup your own interfaces/API correctly and will need to deal with cross-dll issues, different runtimes, etc.
However, there are a few tools from CMake at your disposal:
Check out the Install and Export. You can use it to specify (in your CMakeLists.txt) which files are necessary for deployment. This way, you can mark which header-files, but also which targets (libs and exes) should be deployed.
Also take a look at CPack in combination with NSIS, which can be used to build NSIS installers of your project.
Together with the InstallRequiredSystemLibraries and BundleUtilities you can then prepare an install or package target. See also this and this question demonstrating how third-party dlls can be added to such a deployment package.
InstallRequiredSystemLibraries is very useful for appending vcredist to your own package installer, which you will surely need if you are installing your project on a non-development pc.
Related
I have a c++ third party shared library "My3rdParty" in windows and linux that I need my own c++ shared library "MySharedLib" to link to. My build needs to build on windows for windows, on windows for linux and on linux for linux. I created a findMy3rdparty.cmake module so I can use findPackage on My3rdParty file that uses findLibrary and findPackage to get the headers and libs and dlls and that works fine, then I create an imported target. 3rdParty library is the .so in linux and the .lib in windows. There's another find library for the shared library if its a windows target.
if( NOT TARGET My3rdParty )
add_library( My3rdParty STATIC IMPORTED PUBLIC ${My3rdParty_LIBRARY} )
endif()
set_target_properties( My3rdParty PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${My3rdParty_INCLUDE_DIRS}"
IMPORTED_LOCATION "${My3rdParty_LIBRARY}"
INTERFACE_LINK_LIBRARIES "${My3rdParty_LIBRARY}"
IMPORTED_IMPLIB "${My3rdParty_LIBRARY}"
)
The libs and dlls and so's are stored in variables and are moved to the correct spot in the build dir and install dir.
This compiles and links fine for everything and runs fine on windows on my windows computer but running on a linux machine it doesn't. On Linux MySharedLib.so is looking for a My3rdParty.so in a windows file format on the windows build machine which i'm pretty sure is because of Imported_Location. I think how the My3rdParty Target is being made is wrong. How should it be setup?
: error MySharedLIb.so could not find
c://filepathtolinuxsharedlibonbuildcomputer/My3rdParty.so
I've tried a few variations of setting these target properties and not setting them and settings them depending on windows/linux target, etc.
I don't really want to mess with things like rpath and ld_library_path, etc because all the other so files that I build are working and linking and running fine in linux and I'm pretty confident the error is in the generation of the 3rd party target.
How should you link libs, dlls, sos, and headers in a cross compilation compatible way when the install is not to system folders in linux?
Solution was to not set IMPORTED_IMPLIB and not set IMPORTED_LOCATION.
I also changed the add_library line to be
add_library( My3rdParty INTERFACE IMPORTED )
I have a simple QT project. I'm developing on Linux. But it's meant to be deployed to Linux, Mac and Windows ultimately.
I'm attempting to package it for distribution. I'm running into problems locating the dependencies and packaging them up and doing this in an idiomatic way (IOW: No hardcoded paths to DLLs or including the DLLs in my source repo)
For the Windows port, I'm using MinGW and compiling like this:
mingw64-cmake -G "Unix Makefiles" .. -DCMAKE_INSTALL_PREFIX=../install -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=/usr/share/mingw/toolchain-mingw64.cmake
make && ctest && make install && cpack -G "TGZ" && cpack -G "NSIS64"
I've set it to product a tar.gz file and an NSIS installer. There's no particular reason for NSIS and not Wix at the moment. This is just to figure things out.
It compiles a Windows executable, but it does not include the DLLs necessary to run the program. It's these:
Libgcc_s_seh-1.dll
Qt5Core.dll
Qt5Gui.dll
A quick find on my computer shows me that those DLLs are present here:
/usr/x86_64-w64-mingw32/sys-root/mingw/bin/Qt5Widgets.dll
/usr/x86_64-w64-mingw32/sys-root/mingw/bin/libgcc_s_seh-1.dll
...
Is there a way to automatically get CPack to dig up the DLLs and include them in the installer?
Here is my CMakeLists.txt file:
cmake_minimum_required(VERSION 2.8.11)
project(myapp)
enable_testing()
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
find_package(Qt5Core REQUIRED)
find_package(Qt5Gui REQUIRED)
find_package(Qt5Widgets REQUIRED)
add_executable(myapp WIN32 main.cpp mainwindow.cpp resources.qrc)
target_link_libraries(myapp Qt5::Widgets)
target_link_libraries(myapp Qt5::Core)
target_link_libraries(myapp Qt5::Gui)
INSTALL(TARGETS myapp
BUNDLE DESTINATION .
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
)
INSTALL(FILES ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS} DESTINATION bin COMPONENT Libraries)
IF(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS)
INSTALL(PROGRAMS ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS} DESTINATION bin COMPONENT System)
ENDIF(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS)
INCLUDE(CPack)
I've looked around for some help on this. The best thing I came across was
this link
But it's not looking so idiomatic. If we look closer at the CMakeLists.txt file, it's got machine-specific hard coded paths that are certain to change in the future:
IF( WIN32 AND ${ARCH_32BIT})
SET(QT_INSTALLED_PATH "C:/QtMSVCX86/Qt5.5.0/5.5/msvc2013" )
ELSEIF(WIN32 AND ${ARCH_64BIT})
SET(QT_INSTALLED_PATH "C:/QtMSVCX64/Qt5.5.0/5.5/msvc2013_64" )
ELSEIF(UNIX AND NOT MINGW AND ${ARCH_32BIT})
SET(QT_INSTALLED_PATH "/opt/Qt5.5.0/5.5/gcc/" )
ELSEIF(UNIX AND NOT MINGW AND ${ARCH_64BIT})
SET(QT_INSTALLED_PATH "/opt/Qt5.5.0/5.5/gcc_64/" )
ENDIF()
SET(CMAKE_AUTOMOC ON)
SET(CMAKE_AUTOUIC ON)
SET(CMAKE_AUTORCC ON)
FIND_PACKAGE(Qt5Widgets PATHS ${QT_INSTALLED_PATH} NO_DEFAULT_PATH)
FIND_PACKAGE(Qt5Qml PATHS ${QT_INSTALLED_PATH} NO_DEFAULT_PATH)
FIND_PACKAGE(Qt5Quick PATHS ${QT_INSTALLED_PATH} NO_DEFAULT_PATH)
Have a look at CMake's Bundle Utilities It contains a FIXUP_BUNDLE macro which collects all the necessary dependencies of an executable, including Qt. It works basically the same way on Windows, Linux and Mac. You could start by adding FIXUP_BUNDLE(myapp) to your CMake file. the actual dependency resolving and copying happens during the CPack run. Depending on project size and complexity, some tweaks are necessary, but in general I have seen it used successfully in larger cross-platform Qt projects with a CMake based build system
I am trying to build c file included by ndk under cygwin
In Android.mk, I add -I/usr/include to LOCAL_FLAGS like
LOCAL_FLAGS := -I/usr/include
And I have checked that openssl does under /usr/include
But when I run ndk-build under by project dir, it output
"fatal error: openssl/ssl.h: No such file or directory"
I think I have specified the include directory, but not solve this problem.
Is there any other way can I try?
You seem to have some gaps in your knowledge:
C code compiles to processor's native instruction set. Your desktop/build machine probably has a different architecture from your Android device(thus a different instruction set).
NDK doesn't just compile, it cross-compiles. It means that the NDK runs on the build machine, but the executable it produces cannot run on the build machine(different instruction sets).
All libraries on your desktop are in your desktop's processoer's instruction set. Thus, you cannot link any program build by the NDK using the desktop's libraries. This means:
No includes from '/usr/include/'
No libs from /lib, /usr/lib, /lib64 or /usr/lib64
No Cygwin packages under on Windows
What you need to do is build your own openssl using the NDK and use that to link against when you build your executable.
Please note that the answer is missing a lot of information (at least 3 Bachelor's level Computer Science courses worth of information).
I have successfully build libcurl for android as a shared library, both armeabi-v7a and x86, and one of my project depends on it. I have set "LOCAL_SHARED_LIBRARIES := libcurl", the problem is where should I put those libcurl.so files?
I tried putting them under (project)/jni/lib/(platform)/libcurl.so, and ndk-build gives me a whole load of linking error. (project)/lib/(platform)/libcurl.so will not work too because ndk-build will clear this directory before build.
So I tried again, building 1 platform at a time, however I still have no idea where to put it. jni/libcurl.so will not work.
Simple, follow this, download curl source from http://curl.haxx.se/
- prepare the toolchain of the Android NDK for standalone use; this can
be done by invoking the script:
./build/tools/make-standalone-toolchain.sh
which creates a usual cross-compile toolchain. Lets assume that you put
this toolchain below /opt then invoke configure with something like:
export PATH=/opt/arm-linux-androideabi-4.4.3/bin:$PATH
./configure --host=arm-linux-androideabi [more configure options]
make
Done.
I wanted to write small streaming software using VLC compoents on windows. So i look for : lib and headers file for VLC on windows. Instead of compiling it , to make it faster i looked for ready builds for windows. And i found on: http://nightlies.videolan.org/build/win32/last/
I download it (debug) : Find include file directory and lib. But lib directory contains trange (at least for me) file extensions such as libvlc.la and libvlc.dll.a
What are they? Can i use them in Visual C++?
The .la files are libtool convenience libraries, they're useless and only cause trouble (in this case).
The .a files are (import) libraries for GCC/MinGW, just like .lib for MSVC.
VLC can only be built with GCC, because MSVC lacks the proper C99 support. So all debug info will be generated by and for a GNU toolchain (GCC/Binutils/GDB). If you want to use the proper DLL in Visual Studio, you should be able to create an import library from the included .def file and the dll.