queezythegreat / arduino-cmake

Arduino CMake Build system
648 stars 216 forks source link

Libraries not detected #12

Closed treaves closed 12 years ago

treaves commented 12 years ago

This is a more focused report of the issue where libraries are not found. For this report, reference code https://code.launchpad.net/~treaves/+junk/blinkqp .

This project has a libraries folder at the root of the project. The libraries folder contains a single library, qp. If this is all I do, then cmake displayes: -- Generating blink -- Generating Arduino Wire library -- Configuring done -- Generating done No qp generation. And the build fails with lots of undefined references.

To be able to build the project, I must both:

Once those two things are done, the compile finishes correctly.

NOTE: do to the other open linkage issue, to cleanly compile the code you must also uncomment the last three lines in project.cpp, which contain the loop() function.

treaves commented 12 years ago

I updated the arduino-cmake code, and changed the board to an uno, so, you should have no trouble try now.

queezythegreat commented 12 years ago

I'll look at your project again, I got mislead by the board ID and assumed I needed the sanguino patch.

queezythegreat commented 12 years ago

So I've built your project with no problems. I've just changed the includes to Arduino.h (as I am using Arduino 1.0) and fixed the linking problem by manualy linking the firmware. Also I was using the latest version of Arduino CMake on Arch Linux.

The problems you have with library detection did not come up, everything got found.

-- Generating qp
-- Generating blink
-- Generating Arduino Wire library
-- Configuring done
-- Generating done
-- Build files have been written to: /home/queezy/dev/blinkqp/build
[ 72%] Built target uno_CORE
[ 80%] Built target qp
[ 88%] Built target uno_Wire
[100%] Built target blink

What operating system are you using?

Here is the diff of my changes:

=== modified file 'src/blink.cpp'
--- src/blink.cpp   2012-01-06 19:34:37 +0000
+++ src/blink.cpp   2012-01-15 13:28:25 +0000
@@ -1,6 +1,6 @@
 #include "blink.h"

-#include <WProgram.h>
+#include <Arduino.h>
 #include <Wire.h>
 #include "qp_port.h"

=== modified file 'src/bsp.cpp'
--- src/bsp.cpp 2012-01-06 19:34:37 +0000
+++ src/bsp.cpp 2012-01-15 13:28:47 +0000
@@ -1,6 +1,6 @@
 #include "qp_port.h"
 #include "bsp.h"
-#include <WProgram.h>
+#include <Arduino.h>
 #include "project.h"

 Q_DEFINE_THIS_FILE

=== modified file 'src/project.cpp'
--- src/project.cpp 2012-01-06 19:34:37 +0000
+++ src/project.cpp 2012-01-15 13:29:35 +0000
@@ -1,5 +1,5 @@
 #include "project.h"
-#include <WProgram.h>
+#include <Arduino.h>
 #include "blink.h"

 Q_DEFINE_THIS_FILE
@@ -23,6 +23,7 @@
     BlinkQP::Blink->start(1, blinkQueueStore, Q_DIM(blinkQueueStore), (void *)0, 0);
 }

+#ifndef ARDUINO
 void* operator new(size_t size) {
     return malloc(size);
 }
@@ -30,6 +31,7 @@
 void operator delete(void* ptr) {
     free(ptr);
 }
+#endif

 //............................................................................
 //extern "C" void loop() {
treaves commented 12 years ago

The version you had checked out was a bit old; I'd already changed the references to Arduino.h. Also, it sill had the manual library addition in it. I've just commited the change, you just need to do a bzr pull at the root. the build will fail with:

[ 86%] Built target uno_Wire
Scanning dependencies of target blink
[ 91%] Building CXX object src/CMakeFiles/blink.dir/project.cpp.obj
In file included from /Users/treaves/Development/qp/blinkqp/src/project.cpp:1:
/Users/treaves/Development/qp/blinkqp/src/project.h:4:21: error: qp_port.h: No such file or directory
In file included from /Users/treaves/Development/qp/blinkqp/src/project.cpp:1:
/Users/treaves/Development/qp/blinkqp/src/project.h:12: error: 'Q_USER_SIG' was not declared in this scope
/Users/treaves/Development/qp/blinkqp/src/project.h:19: error: expected initializer before 'const'
/Users/treaves/Development/qp/blinkqp/src/project.h:21: error: 'QSubscrList' does not name a type
/Users/treaves/Development/qp/blinkqp/src/project.h:28: error: 'QEvent' was not declared in this scope
In file included from /Users/treaves/Development/qp/blinkqp/src/project.cpp:3:
/Users/treaves/Development/qp/blinkqp/src/blink.h:33: error: expected class-name before '{' token
/Users/treaves/Development/qp/blinkqp/src/blink.h:35: error: 'QState' does not name a type
/Users/treaves/Development/qp/blinkqp/src/blink.h:36: error: 'QState' does not name a type
/Users/treaves/Development/qp/blinkqp/src/blink.h: In constructor 'BlinkQP::blink::blink()':
/Users/treaves/Development/qp/blinkqp/src/blink.h:39: error: class 'BlinkQP::blink' does not have any field named 'QActive'
/Users/treaves/Development/qp/blinkqp/src/blink.h:39: error: 'QStateHandler' was not declared in this scope
/Users/treaves/Development/qp/blinkqp/src/blink.h:39: error: 'initial' is not a member of 'BlinkQP::blink'
/Users/treaves/Development/qp/blinkqp/src/blink.h: At global scope:
/Users/treaves/Development/qp/blinkqp/src/blink.h:45: error: expected constructor, destructor, or type conversion before '*' token
/Users/treaves/Development/qp/blinkqp/src/project.cpp:10: error: expected constructor, destructor, or type conversion before 'void'
/Users/treaves/Development/qp/blinkqp/src/project.cpp: In function 'void loop()':
/Users/treaves/Development/qp/blinkqp/src/project.cpp:30: error: 'QF' has not been declared
make[2]: *** [src/CMakeFiles/blink.dir/project.cpp.obj] Error 1
make[1]: *** [src/CMakeFiles/blink.dir/all] Error 2
make: *** [all] Error 2
[~/Development/qp/blinkqp/builds/unix ] 
queezythegreat commented 12 years ago

I've checked out the latest version. Depending how you want to treat the QP library, you can do two things. The first is treating QP as a normal CMake library:

CMake Library

=== modified file 'CMakeLists.txt'
--- CMakeLists.txt  2012-01-15 14:57:05 +0000
+++ CMakeLists.txt  2012-01-15 17:57:00 +0000
@@ -21,6 +21,9 @@
 #===================================================================================================
 include_directories(
     ${CMAKE_SOURCE_DIR}/src
+    ${CMAKE_SOURCE_DIR}/libraries/qp
 )

+add_subdirectory(libraries)
 add_subdirectory(src)
+

=== modified file 'src/CMakeLists.txt'
--- src/CMakeLists.txt  2012-01-15 14:57:05 +0000
+++ src/CMakeLists.txt  2012-01-15 17:56:35 +0000
@@ -32,5 +32,7 @@
     bsp.cpp
 )

+set(${FirmwareName}_LIBS qp)
+

 generate_arduino_firmware(${FirmwareName})

You add libraries/qp to the include search path using include_directories command, so that you can include qp_port.h. Then you add the libraries subdirectory using add_subdirectory. Finally you use the _LIBS directive to add qp as a linker dependency of your firmware.

Arduino Library

The second option is to make the QP library a Arduino type library. In order to do that, add a qp.h header which includes the qp_port.h header, remove the CMakeLists.txt file from the libraries directory (not needed). Use the link_directories command to tell arduino-cmake to look for arduino type libraries in the libraries directory. Finally replace all includes from qp_port.h to qp.h (this will cause arduino-cmake library dectection system to kick in). Here is a diff of the changes required:

=== modified file 'CMakeLists.txt'
--- CMakeLists.txt  2012-01-15 14:57:05 +0000
+++ CMakeLists.txt  2012-01-15 18:06:35 +0000
@@ -23,4 +23,6 @@
     ${CMAKE_SOURCE_DIR}/src
 )

+link_directories(${CMAKE_SOURCE_DIR}/libraries)
+
 add_subdirectory(src)

=== removed file 'libraries/CMakeLists.txt'
--- libraries/CMakeLists.txt    2012-01-06 15:16:42 +0000
+++ libraries/CMakeLists.txt    1970-01-01 00:00:00 +0000
@@ -1,15 +0,0 @@
-set(qp_BOARD ${board})
-
-# Source headers
-set(qp_HDRS
-    qp/qp_port.h
-)
-
-# Source implementation files
-set(qp_SRCS
-    qp/qp.cpp
-    qp/qp_port.cpp
-)
-
-#  Target generation
-generate_arduino_library(qp)

=== added file 'libraries/qp/qp.h'
--- libraries/qp/qp.h   1970-01-01 00:00:00 +0000
+++ libraries/qp/qp.h   2012-01-15 18:05:17 +0000
@@ -0,0 +1,1 @@
+#include "qp_port.h"

=== modified file 'src/blink.cpp'
--- src/blink.cpp   2012-01-14 00:06:35 +0000
+++ src/blink.cpp   2012-01-15 18:07:04 +0000
@@ -2,7 +2,7 @@

 #include <Arduino.h>
 #include <Wire.h>
-#include "qp_port.h"
+#include "qp.h"

 Q_DEFINE_THIS_FILE

=== modified file 'src/blink.h'
--- src/blink.h 2012-01-06 19:34:37 +0000
+++ src/blink.h 2012-01-15 18:07:15 +0000
@@ -22,7 +22,7 @@
 #define Blink_H

 #include <stdint.h>
-#include "qp_port.h"
+#include "qp.h"
 #include "project.h"
 #include "bsp.h"

=== modified file 'src/bsp.cpp'
--- src/bsp.cpp 2012-01-14 00:06:35 +0000
+++ src/bsp.cpp 2012-01-15 18:07:25 +0000
@@ -1,4 +1,4 @@
-#include "qp_port.h"
+#include "qp.h"
 #include "bsp.h"
 #include <Arduino.h>
 #include "project.h"

=== modified file 'src/project.h'
--- src/project.h   2012-01-14 00:06:35 +0000
+++ src/project.h   2012-01-15 18:05:43 +0000
@@ -1,7 +1,7 @@
 #ifndef PROJECT_H
 #define PROJECT_H

-#include "qp_port.h"
+#include "qp.h"
 #include <stdint.h>
 #include "bsp.h"

I hope these examples clear up any problems you where having. If not I'll try to shed some more light on the subject.

treaves commented 12 years ago

The first solution is, of course, what I have been doing. The second I also tried, and it still does not work.

Perhaps just do it the standard cmake way, and update your documents.

queezythegreat commented 12 years ago

So the second patch does not work for you? What OS and Arduino version are you using? Are Arduino's standard libraries detected properly?

treaves commented 12 years ago

There is no advantage to your changes; I have it working by telling cmake to build that directory as a library, which is what you've done. So that nets out. Then, you change the library around, which I do not need to do. So I'm not sure why you'd think your proposal is better.

queezythegreat commented 12 years ago

Well the second option has the advantage of being Arduino compatible, if you plan of distributing your library.

Anyways I'm trying to figuer out why the library detection does not work for you. Both solutions I gave you in the previous comment work on my machine, so if they don't work for you I want to fix it. So any information you can provide would be greatly apreciated.

treaves commented 12 years ago

It's not my library; it's an Arduino library.

And I'm a bit confused as to the options you're saying you offered.

1) add the library to cmake. I was doing this, and continue to do this. So this isn't an option, but, what I'm doing.

2) change the qp.cpp to qp.h, and still use cmake.

Did I not understand one of these offered options?

queezythegreat commented 12 years ago

Ok, I'm starting to understand why you where having problems with QP. So the reason why the QP library is not being detected is because the library's directory name does not match the header.

When I wrote the Arduino library detection code I was assuming that the main header in the library must match the directory name (so if I'm including some_lib.h the library's directory would be some_lib). Hence the qp library was not being detected because it does not contain qp.h, so in my patch I modified it.

If you change the library directory from qp to qp_port (so that it matches the qp_port.h import) auto detection should work. Just remember to add link_directories(${CMAKE_SOURCE_DIR}/libraries) before add_subdirectory(src) in the main CMakeLists.txt.

By the way in the documentation I wrote:

An Arduino library is any directory which contains a header named after the directory, simple. Any source files contained within that directory is part of the library. Here is a example of library a called ExampleLib:

ExampleLib/
  |-- ExampleLib.h
  |-- ExampleLib.cpp
  `-- OtherLibSource.cpp

The QP library is the first library that I've encountered that does not conform to that format.

treaves commented 12 years ago

O.K., it was the link_directories(${CMAKE_SOURCE_DIR}/libraries) I was missing.

And yes, I read what you wrote. However, the way the qp library is structured is very valid with the Arduino IDE; if you copy the qp directory into the 'default' Arduino IDE libraries directory, then qp will show up in the 'add library' list in the IDE. So it may be easier for your code to check fir directory & .h, but, appearently directory & .cpp is valid.

Thanks for all your help.