queezythegreat / arduino-cmake

Arduino CMake Build system
644 stars 216 forks source link

CMAKE_TOOLCHAIN_FILE only recognized on command line #38

Closed zeeMonkeez closed 12 years ago

zeeMonkeez commented 12 years ago

cloned git repository (a2175e8683c40236f6f35f895b74a104c4f23f27). Then I added the following lines to CMakeLists.txt in the example directory:

cmake_minimum_required(VERSION 2.8)
set(CMAKE_TOOLCHAIN_FILE /Users/username/Documents/Arduino/test/arduino-cmake/cmake/ArduinoToolchain.cmake) 

cmake .. then fails with

CMake Error at CMakeLists.txt:15 (generate_arduino_example):
  Unknown CMake command "generate_arduino_example".

However, calling cmake -DCMAKE_TOOLCHAIN_FILE=/Users/username/Documents/Arduino/test/arduino-cmake/cmake/ArduinoToolchain.cmake .. works.

I'm on OS X 10.7.3.

queezythegreat commented 12 years ago

Hi, I've tried to reproduce your problem with no luck. When I specify the toolchain file from the configuration file it works without any problems. Could you please provide some additional information, such as the configuration file containing the CMAKE_TOOLCHAIN_FILE.

zeeMonkeez commented 12 years ago

Hi, Thanks for working on it. This happens with the plain vanilla example config, following the instructions in the README file. cmake --version returns cmake version 2.8.8 Is there anything else that would help?

On 8 May 2012, at 20:20, Tomasz Bogdal wrote:

Hi, I've tried to reproduce your problem with no luck. When a specify the toolchain file from the configuration file it works without any problems. Could you please provide some additional information, such as the configuration file containing the CMAKE_TOOLCHAIN_FILE.


Reply to this email directly or view it on GitHub: https://github.com/queezythegreat/arduino-cmake/issues/38#issuecomment-5583813

Jonas Zimmermann Institute of Neuroscience Newcastle University UK office: +44 191 2225028 mobile: +44 759 5824960

queezythegreat commented 12 years ago

So you only changed the toolchain path, and the example does not work without modifications? Could you please include the full output of the command (with the error you got)...

zeeMonkeez commented 12 years ago

Basically yes; the example CMakeLists.txt doesn't contain the two lines in the original issue message, which I have added. The complete error is

-- The C compiler identification is GNU 4.2.1
-- The CXX compiler identification is Clang 3.1.0
-- Checking whether C compiler has -isysroot
-- Checking whether C compiler has -isysroot - yes
-- Checking whether C compiler supports OSX deployment target flag
-- Checking whether C compiler supports OSX deployment target flag - yes
-- Check for working C compiler: /usr/bin/gcc
-- Check for working C compiler: /usr/bin/gcc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
CMake Error at CMakeLists.txt:14 (generate_arduino_example):
  Unknown CMake command "generate_arduino_example".

-- Configuring incomplete, errors occurred!

Which to my eyes looks like as if the build environment is determined before CMakeLists.txt is read and thus CMAKE_TOOLCHAIN_FILE gets set. Sorry, completely new to cmake.

queezythegreat commented 12 years ago

OK, I now understand your problem. There are two CMakeList.txt file in the example, one at the root and another in the example directory. The one at the root is the main configuration file. Within that config the example directorry is included (using add_subdirectory()).

In CMake each directory part of the build must contain a CMakeLists.txt file (just like make has the Makefile). Every CMake project must have the project() command, which is usually only in the main config file. When configuring the build system, you specify the path to the directory containing the main configuration file (in this case the one in the root directory). The error you are getting is because you are specifying the example directory instead of the directory above.

With the following directory structure:

|-- CMakeLists.txt      # <======= Main configuration file (root)
|-- README.rst
|-- cmake
|   |-- ArduinoToolchain.cmake
|   `-- Platform
|       `-- Arduino.cmake
|-- configure
|-- configure.bat
`-- example
    |-- Blink
    |   |-- Blink.ino
    |   `-- config.h
    |-- CMakeLists.txt      # <====== Config for example directory
    |-- blink.cpp
    |-- blink_lib.cpp
    `-- blink_lib.h

We create a build directory:

mkdir build

We now have this:

|-- CMakeLists.txt
|-- README.rst
|-- build                       # <====== Build directory
|-- cmake
|-- configure
|-- configure.bat
`-- example

Next we enter the build directory:

cd build

We configure the build system:

cmake ..

whre .. is the path to the directory containing the main configuration file.

Then we build:

make
zeeMonkeez commented 12 years ago

D'Oh. I see. Sorry for the noise. Is there a recommended place to put this whole project, i.e. a place cmake would be looking for it and the main CMakeLists.txt of my project could reference the toolchain by something like

set(CMAKE_TOOLCHAIN_FILE ${SOME_CMAKE_VAR}/arduino-cmake/cmake/ArduinoToolchain.cmake) 

thus making my CMakeLists.txt portable? I couldn't find anything in cmake's docs...

queezythegreat commented 12 years ago

I don't quite follow you, the example:

set(CMAKE_TOOLCHAIN_FILE cmake/ArduinoToolchain.cmake)

is the same as:

set(CMAKE_TOOLCHAIN_FILE ${CMAKE_SOURCE_DIR}/cmake/ArduinoToolchain.cmake)

where CMAKE_SOURCE_DIR variable is the full path to the source directory.

If you want to use a environment variable:

set(CMAKE_TOOLCHAIN_FILE $ENV{ENVIRONMENT_VARIABLE}/cmake/ArduinoToolchain.cmake)

where ENVIRONMENT_VARIABLE is the name of the environment variable.

You can also copy the contents of the cmake directory into the Modules directory, located within the CMake.app application (/Applications/CMake.app/Contents/share/cmake-2.8/Modules). Then you would only need to use the following:

set(CMAKE_TOOLCHAIN_FILE ArduinoToolchain)

In the README.rst there is a section relating to bundling Arduino CMake with your project: Arduino CMake - Bundling Arduino CMake. Currently this is most most portable way of using Arduino CMake until I get it included with the official CMake release.

queezythegreat commented 12 years ago

Closing issue, assuming question has been answered.

ToyAuthor commented 8 years ago

I have same problem. Now I fix it.

This one failed.

project(PROJECT_NAME) set(CMAKE_TOOLCHAIN_FILE "${CMAKE_CURRENT_SOURCE_DIR}/toolchain.cmake")

This one looks fine.

set(CMAKE_TOOLCHAIN_FILE "${CMAKE_CURRENT_SOURCE_DIR}/toolchain.cmake") project(PROJECT_NAME)

jerrylogansquare commented 7 years ago

I had a similar issue. I had to put function calls AFTER the project() command. Odd.

samacumen commented 7 years ago

@queezythegreat Your step by step explanations are simply great and helped. You should probably write a book on CMake :+1:

docbrown commented 6 years ago

@ToyAuthor I know this is an old issue, but in case anyone else stumbles across this on Google like I did: it doesn't work when you set CMAKE_TOOLCHAIN_FILE after invoking project() because project() is what actually kicks off the compiler detection process. So variables like CMAKE_TOOLCHAIN_FILE, CMAKE_SYSTEM_NAME, CMAKE_C_COMPILER, etc must be set before project() is called, otherwise CMake just uses the defaults for the host system.

baziorek commented 3 years ago

For me it worked when I have:

-DCMAKE_TOOLCHAIN_FILE="/home/agh/Pulpit/blockchain/iroha_code/vcpkg/scripts/buildsystems/vcpkg.cmake"

I just added to CMakeLists.txt:

include("/home/agh/Pulpit/blockchain/iroha_code/vcpkg/scripts/buildsystems/vcpkg.cmake")
Henry586 commented 2 years ago

I have same problem. Now I fix it.

This one failed. project(PROJECT_NAME) set(CMAKE_TOOLCHAIN_FILE "${CMAKE_CURRENT_SOURCE_DIR}/toolchain.cmake")

This one looks fine. set(CMAKE_TOOLCHAIN_FILE "${CMAKE_CURRENT_SOURCE_DIR}/toolchain.cmake") project(PROJECT_NAME)

it works!