Let's say I have libTiff, libpng, zlib and libjpeg. How do I tell wxWidgets to use those instead of builtin or installed ones on the system?
I'm quite new to wxWidgets and trying to add it as a dependency to my CMake project, which in return already depends and builds (using ExternalProject) the above mentioned libraries. I do not want to mix versions (which is bound to happen if I use builtin or ones already installed on the system). I also want to keep all the dependencies separate from what is already present on the system for easier distribution.
I have checked setup.h.in where the preprocessor macros are defined (here: wxUSE_ZLIB, wxUSE_LIBJPEG, wxUSE_LIBTIFF and wxUSE_LIBPNG). I also see that inside <root of wxWidgets git repo>/build/cmake/lib/ I have various *.cmake include files that handle different 3rd party dependencies.
I am however confused what I need to pass to my cmake command in order to configure wxWidgets to use versions of the libraries mentioned above from a specific location. I have defined PNG_LIBRARIES, JPEG_LIBRARIES etc. (pointing at where the *.lib (on Windows) or *.so (on Linux) files are. In addition I have defined the ..._INCLUDE_DIRS accordingly.
Currently this is the state of my external project description (the ... are placeholders of valid paths)
ExternalProject_Add(wxWidgets
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/deps/wxwidgets
INSTALL_DIR ...
DOWNLOAD_DIR ""
TMP_DIR ...
STAMP_DIR ...
LOG_DIR ...
BINARY_DIR ...
SOURCE_DIR ...
INSTALL_COMMAND "${CMAKE_COMMAND}" -E echo "Skipping install step for dependency libzmq"
INSTALL_PREFIX ...
BUILD_ALWAYS OFF
# For build configurations see https://wiki.wxwidgets.org/WxWidgets_Build_Configurations
# Also setup.h.in and <wxWidgets_root>/build/cmake/libs
CMAKE_ARGS
"-DCMAKE_BUILD_TYPE=Release"
"-DBUILD=release"
"-DSHARED=1"
"-DMONOLITHIC=1"
"-DwxBUILD_TESTS=OFF"
"-DwxBUILD_DEMOS=OFF"
"-DwxBUILD_BENCHMARKS=OFF"
"-DwxUSE_GUI=1" # <---- forces dependency requirement for PNG, ZLIB, JPEG, TIFF
"-DwxUSE_OPENGL=1"
"-DwxUSE_ZLIB=sys"
"-DZLIB_LIBRARY=${ZLIB_LIBRARIES}" # <---- from another ExternalProject
"-DZLIB_INCLUDE_DIRS=${ZLIB_INCLUDE_DIRS}" # <---- from another ExternalProject
"-DwxUSE_LIBJPEG=sys"
"-DJPEG_LIBRARY=${JPEG_LIBRARIES}" # <---- from another ExternalProject
"-DJPEG_INCLUDE_DIR=${JPEG_INCLUDE_DIRS}" # <---- from another ExternalProject
"-DwxUSE_LIBPNG=sys"
"-DPNG_LIBRARY=${PNG_LIBRARIES}" # <---- from another ExternalProject
"-DPNG_PNG_INCLUDE_DIR=${PNG_INCLUDE_DIRS}" # <---- from another ExternalProject
"-DwxUSE_LIBTIFF=builtin" # TODO Add libTiff to external project dependencies and use here
)
What I basically did is initially put stuff on OFF. wxWidgets's configuration is smart enough to warn me that (since I included wxUSE_GUI, which requires those libs) the respective libraries are missing and it will use builtin instead. From there I found out which variables it is actually looking for and by setting wxUSE_... to sys for the respective library. For now I am getting closer to configuring the build:
1>------ Rebuild All started: Project: ZERO_CHECK, Configuration: Debug x64 ------
1>Checking Build System
2>------ Rebuild All started: Project: wxWidgets, Configuration: Debug x64 ------
2>Creating directories for 'wxWidgets'
2>Building Custom Rule C:/Users/.../Documents/.../CMakeLists.txt
2>No download step for 'wxWidgets'
2>No update step for 'wxWidgets'
2>No patch step for 'wxWidgets'
2>Performing configure step for 'wxWidgets'
2>-- Selecting Windows SDK version 10.0.17763.0 to target Windows 10.0.19042.
2>-- cotire 1.8.0 loaded.
2>-- Found ZLIB: C:/Users/.../CMakeBuilds/ef5b5ada-ee42-7735-988a-ae37c735ccff/build/deps/build/zlib/Debug/zlibd.lib (found version "1.2.11")
2>-- Found JPEG: C:/Users/rcr-aa/CMakeBuilds/ef5b5ada-ee42-7735-988a-ae37c735ccff/build/deps/build/jpeg/Debug/jpeg.lib (found version "90")
2>-- Found PNG: C:/Users/.../CMakeBuilds/ef5b5ada-ee42-7735-988a-ae37c735ccff/build/deps/build/png/Debug/libpng16d.lib (found version "1.6.38.git")
2>-- Which libraries should wxWidgets use?
2> wxUSE_STL: OFF (use C++ STL classes)
2> wxUSE_REGEX: builtin (enable support for wxRegEx class)
2> wxUSE_ZLIB: sys (use zlib for LZW compression)
2> wxUSE_EXPAT: builtin (use expat for XML parsing)
2> wxUSE_LIBJPEG: sys (use libjpeg (JPEG file format))
2> wxUSE_LIBPNG: sys (use libpng (PNG image format))
2> wxUSE_LIBTIFF: builtin (use libtiff (TIFF file format))
2> wxUSE_LIBLZMA: OFF (use liblzma for LZMA compression)
2>
2>-- Configured wxWidgets 3.1.6 for Windows-10.0.19042
2> Min OS Version required at runtime: Windows Vista / Windows Server 2008 (x64 Edition)
2> Which GUI toolkit should wxWidgets use? msw
2> Should wxWidgets be compiled into single library? OFF
2> Should wxWidgets be linked as a shared library? ON
2> Should wxWidgets support Unicode? ON
2> What wxWidgets compatibility level should be used? 3.0
2>-- Configuring done
While looking around I also checked the *.cmake files for the libraries I want to use a custom version of to confirm what needs to be set. An example for zlib can be seen below:
#############################################################################
# Name: build/cmake/lib/zlib.cmake
# Purpose: Use external or internal zlib
# Author: Tobias Taschner
# Created: 2016-09-21
# Copyright: (c) 2016 wxWidgets development team
# Licence: wxWindows licence
#############################################################################
if(wxUSE_ZLIB STREQUAL "builtin")
# TODO: implement building zlib via its CMake file, using
# add_subdirectory or ExternalProject_Add
wx_add_builtin_library(wxzlib
src/zlib/adler32.c
src/zlib/compress.c
src/zlib/crc32.c
src/zlib/deflate.c
src/zlib/gzclose.c
src/zlib/gzlib.c
src/zlib/gzread.c
src/zlib/gzwrite.c
src/zlib/infback.c
src/zlib/inffast.c
src/zlib/inflate.c
src/zlib/inftrees.c
src/zlib/trees.c
src/zlib/uncompr.c
src/zlib/zutil.c
)
if(WIN32)
# Define this to get rid of many warnings about using open(),
# read() and other POSIX functions in zlib code. This is much
# more convenient than having to modify it to avoid them.
target_compile_definitions(wxzlib PRIVATE _CRT_NONSTDC_NO_WARNINGS)
endif()
set(ZLIB_LIBRARIES wxzlib) # <----------- set via -DZLIB_LIBRARIES in my ExternalProject
set(ZLIB_INCLUDE_DIRS ${wxSOURCE_DIR}/src/zlib) # <----------- set via -DZLIB_INCLUDE_DIRS in my ExternalProject
elseif(wxUSE_ZLIB)
find_package(ZLIB REQUIRED)
endif()
My biggest problem here is that I apparently have to set the configuration for each and every 3rd party dependency (in my case set every other dependency to builtin)
2>CMake Error at build/cmake/functions.cmake:591 (add_library):
2> Cannot find source file:
2>
2> C:/Users/.../Documents/.../deps/wxwidgets/3rdparty/pcre/src/pcre2_auto_possess.c
2>
2> Tried extensions .c .C .c++ .cc .cpp .cxx .cu .mpp .m .M .mm .ixx .cppm .h
2> .hh .h++ .hm .hpp .hxx .in .txx .f .F .for .f77 .f90 .f95 .f03 .hip .ispc
2>Call Stack (most recent call first):
2> build/cmake/lib/regex.cmake:13 (wx_add_builtin_library)
2> build/cmake/lib/CMakeLists.txt:28 (include)
2>
2>
2>CMake Error at build/cmake/functions.cmake:591 (add_library):
2> Cannot find source file:
2>
2> C:/Users/.../Documents/.../deps/wxwidgets/src/expat/expat/lib/xmlparse.c
2>
2> Tried extensions .c .C .c++ .cc .cpp .cxx .cu .mpp .m .M .mm .ixx .cppm .h
2> .hh .h++ .hm .hpp .hxx .in .txx .f .F .for .f77 .f90 .f95 .f03 .hip .ispc
2>Call Stack (most recent call first):
2> build/cmake/lib/expat.cmake:13 (wx_add_builtin_library)
2> build/cmake/lib/CMakeLists.txt:28 (include)
2>
2>
2>CMake Error at build/cmake/functions.cmake:591 (add_library):
2> Cannot find source file:
2>
2> C:/Users/.../Documents/.../deps/wxwidgets/src/tiff/libtiff/tif_win32.c
2>
2> Tried extensions .c .C .c++ .cc .cpp .cxx .cu .mpp .m .M .mm .ixx .cppm .h
2> .hh .h++ .hm .hpp .hxx .in .txx .f .F .for .f77 .f90 .f95 .f03 .hip .ispc
2>Call Stack (most recent call first):
2> build/cmake/lib/tiff.cmake:19 (wx_add_builtin_library)
2> build/cmake/lib/CMakeLists.txt:28 (include)
2>
2>
2>CMake Error at build/cmake/functions.cmake:591 (add_library):
2> No SOURCES given to target: wxregex
2>Call Stack (most recent call first):
2> build/cmake/lib/regex.cmake:13 (wx_add_builtin_library)
2> build/cmake/lib/CMakeLists.txt:28 (include)
2>
2>
2>CMake Error at build/cmake/functions.cmake:591 (add_library):
2> No SOURCES given to target: wxexpat
2>Call Stack (most recent call first):
2> build/cmake/lib/expat.cmake:13 (wx_add_builtin_library)
2> build/cmake/lib/CMakeLists.txt:28 (include)
2>
2>
2>CMake Error at build/cmake/functions.cmake:591 (add_library):
2> No SOURCES given to target: wxtiff
2>Call Stack (most recent call first):
2> build/cmake/lib/tiff.cmake:19 (wx_add_builtin_library)
2> build/cmake/lib/CMakeLists.txt:28 (include)
2>
2>
2>CMake Generate step failed. Build files cannot be regenerated correctly.
2>C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\IDE\VC\VCTargets\Microsoft.CppCommon.targets(209,5): error MSB6006: "cmd.exe" exited with code 1.
2>Done building project "wxWidgets.vcxproj" -- FAILED.
Since I am not familiar with wxWidgets I would like to ask if I can just set all the rest of the dependencies to builtin.
First of all, you have to set things up so that the existing libraries can be found, either by CMake (using its find_package()) or configure (which uses pkg-config).
Second, with CMake, I believe that you need to explicit set options such as wxUSE_LIBPNG to sys. When building using configure, this is already the default, as configure will look for the system libraries first, and only fall back on the built-in ones if system ones are not found, but you can also use its command line options such as --with-libpng=sys to force using the system libraries (and fail the configuration if they're not found).
Related
I am trying to build a library that is dependent on GDCM. So, I've installed GDCM following instructions that were provided in INSTAL.txt file and did not have any trouble doing it. But, when I tried to use cmake to build the library that is dependent on it, I am getting following message:
CMake Error at /usr/local/lib/gdcm-3.0/GDCMTargets.cmake:37 (message):
Some (but not all) targets in this export set were already defined.
Targets Defined:
gdcmjpeg8;gdcmjpeg12;gdcmjpeg16;gdcmuuid;gdcmCommon;gdcmDICT;gdcmDSED;gdcmIOD;gdcmMSFF
Targets not yet defined:
gdcmexpat;gdcmopenjp2;gdcmcharls;gdcmzlib;socketxx;gdcmMEXD
Call Stack (most recent call first):
/usr/local/lib/gdcm-3.0/GDCMConfig.cmake:39 (include)
CMakeLists.txt:109 (find_package)
-- Configuring incomplete, errors occurred!
See also "/home/stefan/Desktop/BioClinica/bdtk/CMakeFiles/CMakeOutput.log".
See also "/home/stefan/Desktop/BioClinica/bdtk/CMakeFiles/CMakeError.log
Here is a portion of the code (from reported line GDCMConfig.make:37) from /usr/local/lib/gdcm-3.8/GDCMConfig.make file:
if(EXISTS ${SELF_DIR}/GDCMTargets.cmake)
# This is an install tree
include(${SELF_DIR}/GDCMTargets.cmake)
get_filename_component(GDCM_INCLUDE_ROOT "${SELF_DIR}/../../include/gdcm-3.0" ABSOLUTE)
set(GDCM_INCLUDE_DIRS ${GDCM_INCLUDE_ROOT})
get_filename_component(GDCM_LIB_ROOT "${SELF_DIR}/../../lib" ABSOLUTE)
set(GDCM_LIBRARY_DIRS ${GDCM_LIB_ROOT})
else()
if(EXISTS ${SELF_DIR}/GDCMExports.cmake)
# This is a build tree
set( GDCM_INCLUDE_DIRS "/home/stefan/gdcm-3.0.7/gdcm/Source/Common;/home/stefan/gdcm-3.0.7/gdcmbin/Source/Common;/home/stefan/gdcm-3.0.7/gdcm/Source/DataStructureAndEncodingDefinition;/home/stefan/gdcm-3.0.7/gdcm/Source/MediaStorageAndFileFormat;/home/stefan/gdcm-3.0.7/gdcm/Source/MessageExchangeDefinition;/home/stefan/gdcm-3.0.7/gdcm/Source/DataDictionary;/home/stefan/gdcm-3.0.7/gdcm/Source/InformationObjectDefinition")
set(GDCM_LIBRARY_DIRS "/home/stefan/gdcm-3.0.7/gdcmbin/bin/.")
include(${SELF_DIR}/GDCMExports.cmake)
else()
message(FATAL_ERROR "ooops")
endif()
endif()
I work with cmake and ninja in Windows 7. It worked flawless, till i opend an older version of my IDE. Now cmake uses the wrong compiler. Instead of
C:/Program Files (x86)/Embarcadero/Studio/19.0/bin/bcc32x.exe it now tries to use C:/Program Files (x86)/Embarcadero/RAD Studio/9.0/bin/bcc32x.exe.
Of course I read similar Questions here on stackoverflow and tried the solutions described there, but nothing seems to work (How do you set CMAKE_C_COMPILER and CMAKE_CXX_COMPILER for building Assimp for iOS? for example). Even reinstallation of cmake does nothing. My windows environment variables are ok.
When i try to set CMake variables at command line like this:
cmake -G Ninja -D CMAKE_C_COMPILER="C:\\Program Files
(x86)\\Embarcadero\\Studio\\19.0\\bin\\bcc32x.exe" -D
CMAKE_CXX_COMPILER="C:\\Program Files (x86)\\Embarcadero\\Studio\\19.0
\\bin\\bcc32x.exe"
cmd Output was
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. Alle Rechte vorbehalten.
C:\Users\cld>cd c:\
c:\>cmake -G Ninja -D CMAKE_C_COMPILER="C:\\Program Files
(x86)\\Embarcadero\\Studio\\19.0\\bin\\bcc32x.exe" -D
CMAKE_CXX_COMPILER="C:\\Program Files (x86)\\Embarcadero\\Studio\\19.0
\\bin\\bcc32x.exe"
C:\Users\cld\Desktop\smallCmakeTest
-- The C compiler identification is Embarcadero 7.30.36015
-- The CXX compiler identification is Embarcadero 7.30.36015
-- Check for working C compiler: C:/Program Files (x86)/Embarcadero/RAD
Studio/9.0/bin/bcc32x.exe
-- Check for working C compiler: C:/Program Files (x86)/Embarcadero/RAD
Studio/9.0/bin/bcc32x.exe -- broken
CMake Error at C:/Program Files (x86)/CMake/share/cmake-3.10/Modules
/CMakeTestCCompiler.cmake:52 (message):
The C compiler
"C:/Program Files (x86)/Embarcadero/RAD Studio/9.0/bin/bcc32x.exe"
is not able to compile a simple test program.
It fails with the following output:
Change Dir: C:/Users/cld/Desktop/smallCmakeTest/CMakeFiles/CMakeTmp
Run Build Command:"C:/ninja/ninja.exe" "cmTC_c1b2f"
[1/2] Building C object CMakeFiles\cmTC_c1b2f.dir\testCCompiler.c.obj
FAILED: CMakeFiles/cmTC_c1b2f.dir/testCCompiler.c.obj
"C:\Program Files (x86)\Embarcadero\RAD Studio\9.0\bin\bcc32x.exe"
-I"C:\Program Files (x86)\Embarcadero\RAD Studio\9.0\include\windows\crtl"
-I"C:\Program Files (x86)\Embarcadero\RAD Studio\9.0\
include\windows\sdk" -I"C:\Program Files (x86)\Embarcadero\RAD Studio\9.0
\include\windows\rtl" -I"C:\Program Files (x86)\Embarcadero\RAD Studio\9.0
\include\dinkumware64" -tM -O0 -v -oCMakeFiles\cmTC_
c1b2f.dir\testCCompiler.c.obj -c testCCompiler.c
CreateProcess failed: The system cannot find the file specified.
ninja: build stopped: subcommand failed.
CMake will not be able to correctly generate this project.
Call Stack (most recent call first):
CMakeLists.txt:1 (project)
CMake Error at CMakeLists.txt:1 (project):
The CMAKE_CXX_COMPILER:
C:/Program Files (x86)/Embarcadero/RAD Studio/9.0/bin/bcc32x.exe
is not a full path to an existing compiler tool.
Tell CMake where to find the compiler by setting either the environment
variable "CXX" or the CMake cache entry CMAKE_CXX_COMPILER to the full
path
to the compiler, or to the compiler name if it is in the PATH.
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)
should be added at the top of the file. The version specified may be
lower
if you wish to support older CMake versions for this project. For
more
information run "cmake --help-policy CMP0000".
This warning is for project developers. Use -Wno-dev to suppress it.
-- Configuring incomplete, errors occurred!
See also "C:/Users/cld/Desktop/smallCmakeTest/CMakeFiles
/CMakeOutput.log".
See also "C:/Users/cld/Desktop/smallCmakeTest/CMakeFiles
/CMakeError.log".
I'm debugging a cmake file which fails to find certain packages (using find_package()). What does find_package() actually do when it searches for packages, and can I simulate it with a command line call (without invoking cmake)?
1. What find_package does:
From the documentation of find_package():
CMake searches for a file called Find.cmake in the CMAKE_MODULE_PATH followed by the CMake installation. If the file is found, it is read and processed by CMake.
On Linux, the default scripts usually are located here:
ls /usr/share/cmake*/Modules/Find*.cmake
2. How to use find_package on the command-line:
# cmake --find-package -DNAME=Boost -DCOMPILER_ID=GNU -DLANGUAGE=C -DMODE=EXIST
Boost found
# cmake --find-package -DNAME=Boost -DCOMPILER_ID=GNU -DLANGUAGE=C -DMODE=COMPILE
-I/usr/include
# cmake --find-package -DNAME=Boost -DCOMPILER_ID=GNU -DLANGUAGE=C -DMODE=LINK
-rdynamic
I am trying to built a "Hello World" project with Qt 5 and cmake under MinGW.
This is the CMakeLists.txt file (taken from the on-line doc):
project(Qt5_cmake_test)
cmake_minimum_required(VERSION 2.8.11)
set(CMAKE_PREFIX_PATH "C:/Qt/Qt5.1.1/5.1.1/mingw48_32")
# Find includes in corresponding build directories
set(CMAKE_INCLUDE_CURRENT_DIR ON)
# Instruct CMake to run moc automatically when needed.
set(CMAKE_AUTOMOC ON)
# Find the QtWidgets library
find_package(Qt5Widgets)
# Add the source files from the current directory
aux_source_directory(. SRC_LIST)
# Tell CMake to create the executable
add_executable(${PROJECT_NAME} WIN32 ${SRC_LIST})
# Use the Widgets module from Qt5
target_link_libraries(${PROJECT_NAME} Qt5::Widgets)
The source code is the one generated automatically when creating a new project (which produces an empty window).
Configuring from the Windows command prompt with: cmake -G "MinGW Makefiles" ..\Qt5_cmake_test
I get these errors:
CMake Error at C:/Program Files (x86)/CMake 2.8/share/cmake-2.8/Modules/CMakeMinGWFindMake.cmake:20 (message):
sh.exe was found in your PATH, here:
C:/Program Files (x86)/Git/bin/sh.exe
For MinGW make to work correctly sh.exe must NOT be in your path.
Run cmake from a shell that does not have sh.exe in your PATH.
If you want to use a UNIX shell, then use MSYS Makefiles.
Call Stack (most recent call first):
CMakeLists.txt:8 (project)
CMake Error: Error required internal CMake variable not set, cmake may be not be built correctly.
Missing variable is:
CMAKE_C_COMPILER_ENV_VAR
CMake Error: Error required internal CMake variable not set, cmake may be not be built correctly.
Missing variable is:
CMAKE_C_COMPILER
CMake Error: Could not find cmake module file:C:/Users/pietro.mele/projects/tests/buildSystem_test/Qt5_cmake_test-build/CMakeFiles/2.8.11.2/CMakeCCompiler.cmake
CMake Error: Error required internal CMake variable not set, cmake may be not be built correctly.
Missing variable is:
CMAKE_CXX_COMPILER_ENV_VAR
CMake Error: Error required internal CMake variable not set, cmake may be not be built correctly.
Missing variable is:
CMAKE_CXX_COMPILER
CMake Error: Could not find cmake module file:C:/Users/pietro.mele/projects/tests/buildSystem_test/Qt5_cmake_test-build/CMakeFiles/2.8.11.2/CMakeCXXCompiler.cma
ke
CMake Error: CMAKE_C_COMPILER not set, after EnableLanguage
CMake Error: CMAKE_CXX_COMPILER not set, after EnableLanguage
-- Configuring incomplete, errors occurred!
So it seems it is not able to find the compiler. Is there a way to let cmake find it on its own, or just giving it the CMAKE_PREFIX_PATH directory?
Do I have to manually specify all those variables in the makefile or as environment variables in Windows?
I tried both from the standard Windows command prompt and from the one provided by Qt, with the same result. Is it OK to build from the Windows command prompt, or should I do it from the MinGW's shell?
Platform:
Qt 5.1
CMake 2.8.11.2
MinGW/GCC 4.8
Windows 7
Get the git path out of your PATH before running cmake.
Here is the magic to do that:
set PATH=%PATH:C:/Program Files (x86)/Git/bin;=%
This CMakeLists.txt file works properly:
project(Qt5_cmake_test)
cmake_minimum_required(VERSION 2.8.11)
set(CMAKE_PREFIX_PATH "C:/Qt/Qt5.1.1/5.1.1/mingw48_32")
# Find includes in corresponding build directories
set(CMAKE_INCLUDE_CURRENT_DIR ON)
# Instruct CMake to run moc automatically when needed.
set(CMAKE_AUTOMOC ON)
# Find the Qt libraries
find_package(Qt5Core REQUIRED)
find_package(Qt5Widgets REQUIRED)
# Add the source files from the current directory
aux_source_directory(. SRC_LIST)
# Tell CMake to create the executable
add_executable(${PROJECT_NAME} WIN32 ${SRC_LIST})
# Use Qt5 modules
target_link_libraries(${PROJECT_NAME}
Qt5::Widgets
Qt5::WinMain)
The changes are:
Added find_package(Qt5Core REQUIRED).
Added Qt5::WinMain to target_link_libraries.
In some of my answer here on SO, I have described. CMake does not like sh.exe.
sh.exe was found in your PATH, here:
C:/Program Files (x86)/Git/bin/sh.exe
Solution : Rename C:/Program Files (x86)/Git/bin/sh.exe shortly.
For example:
C:/Program Files (x86)/Git/bin/shxx.exe
But do not forget when everything is built. rename properly again.
I'm trying to use CMake for building a project which uses the MSPGCC cross-compiler for a MSP430 microcontroller. To successfully compile any simple program with it, we need to pass a compile flag indicating the target processor, or else it fails like this:
$ msp430-gcc -o test test.c
In file included from test.c:1:0:
/usr/local/lib/gcc/msp430/4.6.3/../../../../msp430/include/msp430.h:813:2: warning: #warning Unable to identify and include MCU header, use -mmcu=MCU [-Wcpp]
/usr/local/lib/gcc/msp430/4.6.3/../../../../msp430/bin/ld: cannot open linker script file memory.x: No such file or directory
collect2: ld returned 1 exit status
Hence, if I indicate the processor using the -mmcu switch it works fine. The problem is, although I'm already specifying this in my CMakeLists.txt file:
cmake_minimum_required (VERSION 2.6)
project (test-project C)
set (SOURCES
test.c
)
add_executable (test-project ${SOURCES})
set (CPU_FLAG "-mmcu=msp430f148")
set (CMAKE_C_FLAGS ${CPU_FLAG})
set (CMAKE_EXE_LINKER_FLAGS ${CPU_FLAG})
CMake complains the compiler failed the test to compile a simple program, which I bet is happening because it is probably not using the -mmcu switch (note the message about not being able to open linker script file memory.x):
$ cd ~/git/test-project
$ mkdir build
$ cd build
$ cmake -DCMAKE_TOOLCHAIN_FILE=../msp430.cmake ..
-- The C compiler identification is GNU 4.6.3
-- Check for working C compiler: /usr/local/bin/msp430-gcc
-- Check for working C compiler: /usr/local/bin/msp430-gcc -- broken
CMake Error at /usr/share/cmake-2.8/Modules/CMakeTestCCompiler.cmake:52 (MESSAGE):
The C compiler "/usr/local/bin/msp430-gcc" is not able to compile a simple
test program.
It fails with the following output:
Change Dir: /home/claudio/git/test-project/build/CMakeFiles/CMakeTmp
Run Build Command:/usr/bin/gmake "cmTryCompileExec2889462763/fast"
/usr/bin/gmake -f CMakeFiles/cmTryCompileExec2889462763.dir/build.make
CMakeFiles/cmTryCompileExec2889462763.dir/build
gmake[1]: Entering directory
`/home/claudio/git/test-project/build/CMakeFiles/CMakeTmp'
/usr/bin/cmake -E cmake_progress_report
/home/claudio/git/test-project/build/CMakeFiles/CMakeTmp/CMakeFiles 1
Building C object
CMakeFiles/cmTryCompileExec2889462763.dir/testCCompiler.c.o
/usr/local/bin/msp430-gcc -o
CMakeFiles/cmTryCompileExec2889462763.dir/testCCompiler.c.o -c
/home/claudio/git/test-project/build/CMakeFiles/CMakeTmp/testCCompiler.c
Linking C executable cmTryCompileExec2889462763
/usr/bin/cmake -E cmake_link_script
CMakeFiles/cmTryCompileExec2889462763.dir/link.txt --verbose=1
/usr/local/bin/msp430-gcc
CMakeFiles/cmTryCompileExec2889462763.dir/testCCompiler.c.o -o
cmTryCompileExec2889462763 -rdynamic
/usr/local/lib/gcc/msp430/4.6.3/../../../../msp430/bin/ld: cannot open
linker script file memory.x: No such file or directory
collect2: ld returned 1 exit status
gmake[1]: Leaving directory
`/home/claudio/git/test-project/build/CMakeFiles/CMakeTmp'
gmake[1]: *** [cmTryCompileExec2889462763] Error 1
gmake: *** [cmTryCompileExec2889462763/fast] Error 2
CMake will not be able to correctly generate this project.
Call Stack (most recent call first):
CMakeLists.txt:3 (project)
-- Configuring incomplete, errors occurred!
Just for the record, my toolchain file is as follows, and my PATH variable allows it to find the compiler binaries at /usr/local/bin:
# the name of the target operating system
#SET(CMAKE_SYSTEM_NAME Linux)
# which C and C++ compiler to use
SET(CMAKE_C_COMPILER msp430-gcc)
SET(CMAKE_CXX_COMPILER msp430-g++)
# here is the target environment located
SET(CMAKE_FIND_ROOT_PATH /usr/local/msp430)
# adjust the default behaviour of the FIND_XXX() commands:
# search headers and libraries in the target environment, search
# programs in the host environment
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
All that said, can anyone tell me how to check which compile flags CMake is using to carry the compiler test, and how can we pass custom flags (like -mmcu, for instance) so it doesn't fail it?
According to the Docs:
http://www.cmake.org/Wiki/CMake_Cross_Compiling#The_toolchain_file
you should use the CMakeForceCompiler thing
INCLUDE(CMakeForceCompiler)
# this one is important
SET(CMAKE_SYSTEM_NAME eCos)
# specify the cross compiler
CMAKE_FORCE_C_COMPILER(arm-elf-gcc GNU)
CMAKE_FORCE_CXX_COMPILER(arm-elf-g++ GNU)
# where is the target environment
SET(CMAKE_FIND_ROOT_PATH /home/alex/src/ecos/install )
# search for programs in the build host directories
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# for libraries and headers in the target directories
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
(copy&paste from the docs)
Using it fine here for my MSP430 too
The other answer here is outdated.
The toolchain file should include the required flags in the appropriate CMAKE_<KIND>_FLAGS(_<CONFIG>)_INIT variables, like so:
set(CMAKE_C_FLAGS_INIT "-mmcu=msp430f148")
set(CMAKE_CXX_FLAGS_INIT "-mmcu=msp430f148")
set(CMAKE_EXE_LINKER_FLAGS_INIT "-mmcu=msp430f148")
CMake's compiler detection routines will use these flags when compiling a test executable. The full list is available in the CMake variables documentation, but the full list (at time of writing) is:
CMAKE_<LANG>_FLAGS_<CONFIG>_INIT
CMAKE_<LANG>_FLAGS_INIT
CMAKE_EXE_LINKER_FLAGS_<CONFIG>_INIT
CMAKE_EXE_LINKER_FLAGS_INIT
CMAKE_MODULE_LINKER_FLAGS_<CONFIG>_INIT
CMAKE_MODULE_LINKER_FLAGS_INIT
CMAKE_SHARED_LINKER_FLAGS_<CONFIG>_INIT
CMAKE_SHARED_LINKER_FLAGS_INIT
CMAKE_STATIC_LINKER_FLAGS_<CONFIG>_INIT
CMAKE_STATIC_LINKER_FLAGS_INIT
Where <CONFIG> is any ALL CAPS config name including, but not limited to, DEBUG, RELWITHDEBINFO, MINSIZEREL, and RELEASE. The non-<CONFIG> variants apply to all configurations and are augmented by the <CONFIG> variants.
And, where <LANG> is any of the languages known to enable_language(), currently including CXX, C, CUDA, OBJC, OBJCXX, Fortran, HIP, ISPC, and ASM. The current list may be found in the enable_language documentation.