CMake - libtiff cross-compilation - cmake

For my Android application, I want to port a C++ code which needs libtiff.
I have downloaded sources of libtiff and I try to compile them to generate libtiff.so in different architectures :
arm64-v8a
armeabi-v7a
x86
x86_64
But all I have succeeded in is to generate a libtiff.dylib...
What can I do to generate .so instead of .dylib in the 4 previous architecture ?
Here are my command lines :
> cd libtiff
> mkdir install
> cmake -DCMAKE_BUILD_TYPE=RELEASE -DCMAKE_INSTALL_PREFIX=install --enable-shared .
> make
> make install
Note: I'm on Mac and compilation stuff is not my favorite subject ^^

I've found a way to cross-compile this lib with Android tools.
Here are the command lines to generate, for example, the arm64-v8a version
> [CMAKE_BIN_PATH]/cmake -DANDROID_ABI=arm64-v8a -DCMAKE_BUILD_TYPE=Release -DANDROID_PLATFORM=android-21 -DANDROID_NDK=[NDK_PATH] -DCMAKE_INSTALL_PREFIX=install -DCMAKE_TOOLCHAIN_FILE=[NDK_PATH]/build/cmake/android.toolchain.cmake -DCMAKE_MAKE_PROGRAM=[CMAKE_BIN_PATH]/ninja -G Ninja
> [CMAKE_BIN_PATH]/ninja
> [CMAKE_BIN_PATH]/ninja install
or, in a one-line version
> [CMAKE_BIN_PATH]/cmake -DANDROID_ABI=arm64-v8a -DCMAKE_BUILD_TYPE=Release -DANDROID_PLATFORM=android-21 -DANDROID_NDK=[NDK_PATH] -DCMAKE_INSTALL_PREFIX=install -DCMAKE_TOOLCHAIN_FILE=[NDK_PATH]/build/cmake/android.toolchain.cmake -DCMAKE_MAKE_PROGRAM=[CMAKE_BIN_PATH]/ninja -G Ninja && [CMAKE_BIN_PATH]/ninja && [CMAKE_BIN_PATH]/ninja install
In details:
[CMAKE_BIN_PATH] is the path of cmake: /Library/Android/sdk/cmake/3.6.4111459/bin
[NDK_PATH] is the path of the NDK: /Library/Android/sdk/ndk-bundle
CMAKE_INSTALL_PREFIX is a flag to specify the install dir. In my case, I've decided to create the install dir in the libtiff dir
CMAKE_TOOLCHAIN_FILE: if a flag to specify the toolchain to use. Use the Android toolchain file inside the NDK dir, and not in the cmake dir
CMAKE_MAKE_PROGRAM is a flag to specify the path of ninja, located in the cmake dir
-G is the specify the build system generator, Ninja here

Related

How do I configure cmake to work with rsp files when using IAR compiler

When using the IAR compiler I get an error when creating a library. This uses "iarchive.exe" in the IAR bin directory to create a library file.
The issue occurs when the number of object files exceeds the Windows10 command line limit (about 8000 bytes).
When the limit is exceeded CMake creates a ".rsp" file and the response file has a 3 bytes (Byte Order Mark) at the start of the file.
I am using a licensed version of the IAR compiler.
The tools are version 7.2.
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(IAR_INSTALL_DIR "C:/Program Files (x86)/IAR Systems/Embedded
Workbench 7.2")
architectures
set(TOOLKIT_DIR "${IAR_INSTALL_DIR}/${CMAKE_SYSTEM_PROCESSOR}")
if(UNIX)
set(ENV{PATH} "${TOOLKIT_DIR}/bin:$ENV{PATH}")
else()
set(ENV{PATH} "${TOOLKIT_DIR}/bin;$ENV{PATH}")
endif()
Compiler and Assembler
set(CMAKE_C_COMPILER "icc${CMAKE_SYSTEM_PROCESSOR}")
set(CMAKE_CXX_COMPILER "icc${CMAKE_SYSTEM_PROCESSOR}")
set(CMAKE_ASM_COMPILER "iasm${CMAKE_SYSTEM_PROCESSOR}")
SET(CMAKE_C_USE_RESPONSE_FILE_FOR_OBJECTS 0)
To configure cmake
cmake -H.. -B. -G "Ninja Multi-Config" -DCMAKE_TOOLCHAIN_FILE=..\iar-toolchain.cmake
I have also tried:
cmake -H.. -B. -G "NMake Makefiles" -DCMAKE_TOOLCHAIN_FILE=..\iar-toolchain.cmake
Below is the error message generated during the build.
C:\Firmware\SRFN\build>cmake --build . --target SrfnDcu
[1/20] Linking C static library Debug\libpsp_dcu_k64f120m.a
FAILED: Debug/libpsp_dcu_k64f120m.a
cmd.exe /C "cd . && C:\PROGRA~2\IARSYS~1\EMBEDD~1.2\arm\bin\iarchive.exe Debug\libpsp_dcu_k64f120m.a --create -f CMakeFiles\psp_dcu_k64f120m.Debug.rsp && cd ."
Fatal error[La001]: could not open file "C:\Firmware\SRFN\build\CMakeFiles\p
sp_dcu_k64f120m.dir\Debug\DCU\OS\mqx\source\psp\cortex_m\compiler\iar
\comp.c.o"
Fatal error detected, aborting.
One solution to the problem was to use a newer version of "iarchive.exe" that was in IAR Version 8.2.
Basically is seems that IAR updated "iarchive.exe" to support this.

Is it possible to determine whether CMake install(CODE) is called from the "install" or "package" stage?

I'm using CMake v3.21.0 to invoke Qt's windeployqt during the install stage by the means of the install(CODE) command as follows:
install(
CODE "
execute_process(
COMMAND \"${CMAKE_COMMAND}\" -E
env PATH=\"${windeployqt_ROOT_DIR}\"
\"${windeployqt_EXECUTABLE}\"
# TODO(2021-08-25 by wolters): This is a different path when CPack is`
# used. How to check for this case and obtain the correct output path?
--dir \"${CMAKE_INSTALL_PREFIX}/${args_INSTALL_SUFFIX}\"
--no-quick-import
--no-system-d3d-compiler
--no-virtualkeyboard
--no-compiler-runtime
--no-webkit2
--no-angle
--no-opengl-sw
--verbose 0
\"\$<TARGET_FILE:${args_TARGET}>\"
)
"
COMPONENT runtime
)
This works fine if installing the project:
cmake --build . --config RelWithDebInfo --target install
But when creating a CPack package the files created by windeployqt are not part of the package (ZIP in this case):
cpack -G ZIP -C RelWithDebInfo -D CPACK_COMPONENTS_ALL="runtime"
I know that the issue is the usage of ${CMAKE_INSTALL_PREFIX} in the CODE.
For the install target this is correct.
For the package target this is not correct. Instead the build directory for the current CPack generator should be used, e.g. ${CMAKE_CURRENT_BINARY_DIR}/_CPack_Packages/win64/ZIP/${CPACK_PACKAGE_FILE_NAME}.
My questions are:
Is there a way to differentiate between install and package target in the CODE section? (pseudo-code: if(CMAKE_IS_PACKAGING))
If there is a way: Is it possible to obtain or dynamically build the directory path to the actual CPack temporary "install" directory?
If both problems can be solved the files generated by windeployqt should be part of the packages generated by CPack.
The variable CMAKE_INSTALL_PREFIX should not be expanded in the CMakeLists.txt, as you are doing. Its actual value at invocation time is available inside the install(CODE) fragments.
Consider the following snippet:
cmake_minimum_required(VERSION 3.21)
project(test NONE)
install(CODE [[message(STATUS "HERE: ${CMAKE_INSTALL_PREFIX}")]])
Note that [[ ... ]] escapes variable expansions (you could also use backslashes). Now if you configure this project with -DCMAKE_INSTALL_PREFIX=/tmp/install, you'll see the message print as you expect.
$ cmake -S . -B build -DCMAKE_INSTALL_PREFIX=/tmp/install
-- Configuring done
-- Generating done
-- Build files have been written to: /home/alex/test/build
$ cmake --build build/ --target install
[0/1] Install the project...
-- Install configuration: ""
-- HERE: /tmp/install
If you now run the install script again without reconfiguring or rebuilding, it will still work:
$ cmake --install build/ --prefix /tmp/other-prefix
-- Install configuration: ""
-- HERE: /tmp/other-prefix
This is how CPack runs your install rules. It does not use the configuration-time value of CMAKE_INSTALL_PREFIX. It expects your project to be relocatable (i.e. bug-free).

cmake ignoring CMAKE_INSTALL_PREFIX inside CMakeLists.txt

I have a small project with a very simple CMakeLists.txt file. At the bottom of this file, I have the following lines:
set (CMAKE_INSTALL_PREFIX /opt/myprod)
message (STATUS "CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}")
install (TARGETS myprod DESTINATION bin)
However, when I run:
sudo make install
I get the following:
[100%] Built target myprod
Install the project...
-- Install configuration: ""
-- Up-to-date: /usr/bin/myprod
-- Up-to-date: /usr/bin/myprod
cmake always puts my executable under /usr/bin when it should be under /opt/myprod/bin.
And, yes, the last line is always repeated. Does anyone know how I can fix this?
Using cmake 3.20.3 on Fedora 34.
Your issue cannot be reproduced with the level of detail you've given:
File CMakeLists.txt:
cmake_minimum_required(VERSION 3.20)
project(myprod)
add_executable(myprod main.cpp)
set(CMAKE_INSTALL_PREFIX /opt/myprod)
message (STATUS "CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}")
install (TARGETS myprod DESTINATION bin)
File main.cpp
int main() { return 0; }
Commands:
$ cmake -S . -B build
...
$ cmake --build build/
$ sudo cmake --build build/ --target install
[sudo] password for alex:
[0/1] Install the project...
-- Install configuration: "Release"
-- Installing: /opt/myprod/bin/myprod
$ sudo rm -rf /opt/myprod/
So as you can see, /opt/myprod survived to the final output.
The install() command is responsible for generating the cmake_install.cmake script in the build directory. As far as I know, the very first one reads CMAKE_INSTALL_PREFIX, so you must have another call to install() in your project that you aren't showing us.
Furthermore, you should not set CMAKE_INSTALL_PREFIX inside the CMakeLists.txt; it is designed to be set externally as a cache variable. Hard-coding it is bad because someone else might wish to install your project to a different location besides /opt. Maybe they're on a different operating system or Linux distribution. Maybe even your whims change. In any case, one shouldn't need to edit a file to change the install prefix.
Since you're using CMake 3.20, I strongly encourage you to move such settings to presets.

Use LLVM in a cmake build

I'm trying to build my own project that use LLVM. I downloaded the source code and the precompiled package on the official web site (last version).
http://releases.llvm.org/download.html
I downloaded :
LLVM source code
Clang for Windows (64-bit)
FYI, I don't build LLVM... only want to use it !
I followed the instruction here :
http://llvm.org/docs/CMake.html#embedding-llvm-in-your-project
in the section : "Embedding LLVM in your project"
So, I added this code :
find_package(LLVM REQUIRED CONFIG)
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
message("LLVM_INCLUDE_DIRS=${LLVM_INCLUDE_DIRS}")
message("LLVM_DEFINITIONS=${LLVM_DEFINITIONS}")
But I got several cmake error messages, here is my output :
-- Using LLVMConfig.cmake in: C:\\Luciad_src\\libs\\LLVM\\cmake\\modules
LLVM_INCLUDE_DIRS=
LLVM_DEFINITIONS=
CMake Error at C:/Luciad_src/libs/LLVM/cmake/modules/LLVM-Config.cmake:31 (list):
list sub-command REMOVE_ITEM requires two or more arguments.
Call Stack (most recent call first):
C:/Luciad_src/libs/LLVM/cmake/modules/LLVM-Config.cmake:256 (is_llvm_target_library)
components/query/CMakeLists.txt:15 (llvm_map_components_to_libnames)
Is there a problem with my script, or the packages I use ? Any idea ?
Thanks for your help
You can have the LLVM as binary or source package.
The binary package does not include CMake support. If you compare both installations (binary on the left, source after building and installing it on the right) you can see the difference:
LLVM-5.0.0-win64.exe
<=> llvm-5.0.1.src.tar.xz (build and installed)
So you need to build and install the source package first to get CMake support. On my Windows machine I needed a cmd shell with administrator rights, a Visual Studio installation, go to the downloaded and extracted sources and do:
> mkdir mybuilddir
> cd mybuilddir
> cmake ..
> cmake --build . --config Release --target INSTALL
If I now use your CMake example I get:
-- Found LLVM 5.0.1
-- Using LLVMConfig.cmake in: C:/Program Files (x86)/LLVM/lib/cmake/llvm
LLVM_INCLUDE_DIRS=C:/Program Files (x86)/LLVM/include
LLVM_DEFINITIONS=-DLLVM_BUILD_GLOBAL_ISEL -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE -D_CRT_NONSTDC_NO_WARNINGS -D_SCL_SECURE_NO_DEPRECATE -D_SCL_SECURE_NO_WARNINGS -DUNICODE -D_UNICODE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
-- Configuring done

CMake putting build files in source directory

I am very new to CMake. A friend wrote a simple CMakeLists.txt for the project I am coding myself. I am using svn and have just checked out an old version on the same machine into a different folder. Now, in the original source directory (where CMakeLists.txt is located) I create the directory 'build', cd into there, and for the time being run the code
cmake -DCMAKE_BUILD_TYPE=Debug ..
This nicely puts all of the files in the build directory
-- Build files have been written to: ~/MixedFEMultigrid/build
Now when I check out to another directory, create another 'build' directory in that one and then run the CMake command I get the following
-- Build files have been written to: ~/oldCode
where oldCode is actually the parent directory. I have no idea why this is happening. Can someone explain this to me? The full CMakeLists.txt file is given below,
cmake_minimum_required (VERSION 2.6)
project (MixedFEMultigrid)
FIND_PACKAGE(LAPACK REQUIRED)
set( SRC_FILES multigrid.c
gridHandling.c
interpolation.c
linApprox.c
params.c
sparseMatrix.c
testing.c
richardsFunctions.c
definitions.c
newtonIteration.c
)
#Adds the executable with all the dependencies
add_executable (multigrid ${SRC_FILES})
#Specifies the libraries to link to the target
TARGET_LINK_LIBRARIES(multigrid ${LAPACK_LIBRARIES} m)
# Update if necessary
set(CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long -pedantic -fstrict-aliasing -std=c99 -O3")
As per the comment by escrafford I am updating to show what I do on the command line.
cd ~
mkdir oldCode
cd oldCode
svn co <repository>
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Debug ..
The build files are then put into the directory 'oldCode' instead of the 'build' directory. The following, on the other hand, puts the build files into the 'build' directory
cd ~
mkdir MixedFEMultigrid
cd MixedFEMultigrid
svn co <repository>
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Debug ..
That comes from a in-source cmake execution
Remember to remove cmake cache:
$ rm CMakeCache.txt
$ mkdir debug
$ cd debug
$ cmake -DCMAKE_BUILD_TYPE=Debug ..
That has another benefit, given that cmake do not provide a clean target
$ cd ..
$ rm -rf debug
is the equivalent of make clean or more precisely make distclean