对于C来说我是一个相对较新的人,对于使用CMake从源代码进行构建我还是一个新手。我找到了我想在Github上使用的库:
https://github.com/kolrabi/steamcontroller
我目前在确定存储库中的示例文件时遇到麻烦。当我不知道如何更改构建目录或避免在make文件顶部添加检查时,我决定对其进行编辑并删除,以查看其效果是否更好(这是我第一次使用CMake)。在注释掉在MakeLists.txt文件(MakeFiles.txt的前三行)中引发异常的最上面的IF语句后,它给出以下错误:
$ make
Scanning dependencies of target SteamController
[ 11%] Building C object
CMakeFiles/SteamController.dir/steamcontroller_linux.c.o
[ 22%] Building C object
CMakeFiles/SteamController.dir/steamcontroller_win32.c.o
[ 33%] Building C object
CMakeFiles/SteamController.dir/steamcontroller_feedback.c.o
[ 44%] Building C object
CMakeFiles/SteamController.dir/steamcontroller_setup.c.o
[ 55%] Building C object
CMakeFiles/SteamController.dir/steamcontroller_state.c.o
[ 66%] Building C object
CMakeFiles/SteamController.dir/steamcontroller_wireless.c.o
[ 77%] Linking C shared library cygSteamController-0.1.dll
CMakeFiles/SteamController.dir/steamcontroller_feedback.c.o:steamcontroller_feedback.c:(.text+0x175): undefined reference to `SteamController_HIDSetFeatureReport'
...
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/SteamController.dir/build.make:225:
cygSteamController-0.1.dll] Error 1
make[1]: *** [CMakeFiles/Makefile2:105: CMakeFiles/SteamController.dir/all]
Error 2
make: *** [Makefile:128: all] Error 2
我相信这与头文件common.h有关。由于结构错误,该头文件没有包含在库中,但我不确定这是不是我的项目,尽管我不确定。预先感谢您的帮助。
一旦示例可以运行,我便试图在自己的C程序中包括对Steam控制器的支持。
以下是与示例和CMake文件有关的一些代码:
已编辑CMakeLists.txt(顶部IF语句已被注释掉):
#IF ( ${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR} )
# MESSAGE ( FATAL_ERROR "Prevented in-tree built. Please create a build directory outside of the source code and call cmake from there" )
#ENDIF ( )
CMAKE_MINIMUM_REQUIRED ( VERSION 2.6 )
PROJECT ( LibSteamController C )
IF ( CMAKE_COMPILER_IS_GNUCC )
SET ( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Werror" )
ELSEIF ( MSVC )
SET ( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W4 /WX" )
ENDIF ( )
OPTION ( BUILD_STATIC_LIB "Build static library" FALSE )
SET ( SOURCES
steamcontroller_linux.c
steamcontroller_win32.c
steamcontroller_feedback.c
steamcontroller_setup.c
steamcontroller_state.c
steamcontroller_wireless.c
)
IF ( BUILD_STATIC_LIB )
ADD_LIBRARY ( SteamController STATIC ${SOURCES} )
ELSE ( )
ADD_LIBRARY ( SteamController SHARED ${SOURCES} )
SET_TARGET_PROPERTIES ( SteamController PROPERTIES
VERSION "0.1.2"
SOVERSION "0.1" )
ENDIF ( )
ADD_DEFINITIONS ( -DSTEAMCONTROLLER_BUILDING_LIBRARY )
IF ( WIN32 )
TARGET_LINK_LIBRARIES ( SteamController setupapi hid )
ENDIF ( )
ADD_EXECUTABLE ( SteamControllerExample example.c )
TARGET_LINK_LIBRARIES ( SteamControllerExample SteamController )
INSTALL ( TARGETS SteamController
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
)
INSTALL ( FILES steamcontroller.h
DESTINATION include
)
example.c:
#include "steamcontroller.h"
#include <stdio.h>
int main() {
SteamControllerDeviceEnum *pEnum = SteamController_EnumControllerDevices();
while (pEnum) {
SteamControllerEvent event;
SteamControllerDevice *pDevice = SteamController_Open(pEnum);
if (pDevice) {
... Test Connection ...
SteamController_Close(pDevice);
}
pEnum = SteamController_NextControllerDevice(pEnum);
}
return 0;
}
common.h:
#pragma once
#include <stdint.h>
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#if _MSC_VER
#define inline __inline
#endif
void Debug_DumpHex(const void *pData, size_t count);
#define USB_VID_VALVE 0x28de
#define USB_PID_STEAMCONTROLLER_WIRED 0x1102
#define USB_PID_STEAMCONTROLLER_WIRELESS 0x1142
#define USB_PID_STEAMCONTROLLER_DONGLE_BOOTLOADER 0x1042
#define STEAMCONTROLLER_CLEAR_MAPPINGS 0x81 // 1000 0001
#define STEAMCONTROLLER_GET_ATTRIBUTES 0x83 // 1000 0011
#define STEAMCONTROLLER_UNKNOWN_85 0x85 // 1000 0101
#define STEAMCONTROLLER_SET_SETTINGS 0x87 // 1000 0111 // seems to reset config
#define STEAMCONTROLLER_UNKNOWN_8E 0x8E // 1000 1110
#define STEAMCONTROLLER_TRIGGER_HAPTIC_PULSE 0x8F // 1000 1111
#define STEAMCONTROLLER_START_BOOTLOADER 0x90 // 1001 0000
#define STEAMCONTROLLER_SET_PRNG_ENTROPY 0x96 // 1001 0110
#define STEAMCONTROLLER_TURN_OFF_CONTROLLER 0x9F // 1001 1111
#define STEAMCONTROLLER_DONGLE_GET_VERSION 0xA1 // 1010 0001
#define STEAMCONTROLLER_ENABLE_PAIRING 0xAD // 1010 1101
#define STEAMCONTROLLER_GET_STRING_ATTRIBUTE 0xAE // 1010 1110
#define STEAMCONTROLLER_UNKNOWN_B1 0xB1 // 1011 0001
#define STEAMCONTROLLER_DISCONNECT_DEVICE 0xB2 // 1011 0010
#define STEAMCONTROLLER_COMMIT_DEVICE 0xB3 // 1011 0011
#define STEAMCONTROLLER_DONGLE_GET_WIRELESS_STATE 0xB4 // 1011 0100
#define STEAMCONTROLLER_PLAY_MELODY 0xB6 // 1011 0110
#define STEAMCONTROLLER_GET_CHIPID 0xBA // 1011 1010
#define STEAMCONTROLLER_WRITE_EEPROM 0xC1 // 1100 0001
typedef struct {
uint8_t reportPage;
uint8_t featureId;
uint8_t dataLen;
uint8_t data[62];
} SteamController_HIDFeatureReport;
bool SteamController_HIDSetFeatureReport(const SteamControllerDevice *pDevice, SteamController_HIDFeatureReport *pReport);
bool SteamController_HIDGetFeatureReport(const SteamControllerDevice *pDevice, SteamController_HIDFeatureReport *pReport);
bool SteamController_Initialize(const SteamControllerDevice *pDevice);
uint8_t SteamController_ReadRaw(const SteamControllerDevice *pDevice, uint8_t *buffer, uint8_t maxLen);
static inline uint8_t LowByte(uint16_t value) { return value & 0xff; }
static inline uint8_t HighByte(uint16_t value) { return (value >> 8) & 0xff; }
static inline void StoreU16(uint8_t *pDestination, uint16_t value) {
pDestination[0] = (value >> 0) & 0xff;
pDestination[2] = (value >> 8) & 0xff;
}
static inline void StoreU32(uint8_t *pDestination, uint32_t value) {
pDestination[0] = (value >> 0) & 0xff;
pDestination[1] = (value >> 8) & 0xff;
pDestination[2] = (value >> 16) & 0xff;
pDestination[3] = (value >> 24) & 0xff;
}